作業系統實驗

2021-10-05 15:46:17 字數 3417 閱讀 4819

分析bootloader進入保護模式的過程。

在剛進入bootloader的時候,最先執行的操作分別為關閉中斷、清除eflags的df位以及將ax, ds, es, ss暫存器初始化為0;

.globl start

start:

.code16

cli //關中斷

cld //清除方向標誌

xorw %ax,

%ax //ax清0

movw %ax,

%ds //ds清0

movw %ax,

%es //es清0

movw %ax,

%ss //ss清0

為何開啟a20,以及如何開啟a20?

seta20.1:

//等待8042鍵盤控制器不忙

inb $0x64

,%al //從0x64埠中讀入乙個位元組到al中

testb $0x2

,%al //測試al的第2位

jnz seta20.

1//al的第2位為0,則跳出迴圈

movb $0xd1

,%al //將0xd1寫入al中

outb %al, $0x64

//將0xd1寫入到0x64埠中

接下來往0x64寫入0xd1命令,表示修改8042的p2 port;

movb $0xd1

,%al//將0xdf入al中

outb %al, $0x64

//將0xdf入到0x64埠中,開啟a20

接下來繼續等待input buffer為空:

seta20.2:

//等待8042鍵盤控制器不忙

inb $0x64

,%al //從0x64埠中讀入乙個位元組到al中

testb $0x2

,%al //測試al的第2位

jnz seta20.

2//al的第2位為0,則跳出迴圈

接下來往0x60埠寫入0xdf,表示將p2 port的第二個位(a20)選通置為1;

movb $0xdf

,%al //將0xdf入al中

outb %al, $0x60

//將0xdf入到0x64埠中,開啟a20

如何初始化gdt表?

原因:進入保護模式後,會啟用段機制。邏輯位址會通過段基址對映,變成線性位址,在沒有頁模式之前,線性位址就是實體地址。需要進行位址轉換,就需要段描述符。因為有很多段,就形成了乙個全域性描述符表,也就是gdt。

a) 載入gdt表

lgdt gdtdesc       //載入gdt表
gdt的結構:

gdt:

seg_nullasm //空段

seg_asm

(sta_x|sta_r,

0x0,

0xffffffff

)//**段(可讀可執行)

seg_asm

(sta_w,

0x0,

0xffffffff

)//資料段(可讀可寫)

0x0:(基位址)

0xffffffff:(段大小)

大小是4g 在段設定好以後,就可以訪問4g的空間

基位址是0,就說明虛擬位址等於實體地址

gdtdesc:

.word 0x17

//段表的大小(size-1)

.long gdt //段表的位置

b) 進入保護模式:

通過將cr0暫存器pe位置1便開啟了保護模式

movl %cr0,

%eax //載入cro到eax

orl $cr0_pe_on,

%eax //將eax的第0位置為1

movl %eax,

%cr0 //將cr0的第0位置為1

上面已經開啟了保護模式,所以這裡需要用到邏輯位址。

ljmp $prot_mode_cseg, $protcseg

.code32

protcseg:

從此以後 就進入了32位位址空間了

d) 設定段暫存器,並建立堆疊

movw $prot_mode_dseg,

%ax //資料段的段描述符位址

movw %ax,

%ds

movw %ax,

%es

movw %ax,

%fs

movw %ax,

%gs

movw %ax,

%ss

使得訪問資料段的時候都能找到對應的位址空間

設定堆疊:

因為函式的呼叫和函式的變數等在堆疊所以需要設定好堆疊

movl $0x0

,%ebp //設定函式呼叫棧的開始位置

movl $start,

%esp //設定堆疊的空間大小為start esp做減操作

start從0x7c00一直壓棧 也就是往下走 所以就不會破壞空間

e) 轉到保護模式完成,進入boot主方法

call bootmain //呼叫bootmain函式
bootmain 實現載入ucore os

步驟:bootloader硬碟讀進 解析elf格式 **段 記憶體段放入記憶體位置

讀乙個扇區 bootloader位於第0個扇區 ucore os在第乙個扇區

bootmain(void) elfhdr是 對**段和資料段的記錄 包括size等 會將相應的**段和資料段讀入

作業系統實驗

一 實驗目的 理解vi的三種執行模式及其切方法。學會使用vi的各種操作命令進行文字檔案的編輯。用vi編寫linux下c程式,會用gcc編譯。二 實驗環境 一台裝有linux的機器 這裡預設是red hat linux 9 系統裡面有gcc編譯器。三 實驗內容 寫出主要的內容 首先用合法使用者登入系統...

實驗作業系統

實驗一 linux使用環境 實驗二 linux下c程式設計環境 1 設有乙個三位數,將它的百 十 個位上的3個數,各自求立方,然後加起來,正好等於這個3位數,請在linux環境下程式設計找出所有滿足條件的數,並編譯 除錯 執行你的程式。include int main return0 實驗三 程序觀...

作業系統實驗2

1 訊息的建立,傳送和接受。使用系統呼叫 msgget msgsnd msgrev 及msgctl 編制一長度為1k的訊息傳送和接受的程式。為了便於操作和觀察結果,用乙個程式做為 引子 先後fork 兩個子程序,server 和 client 程序通訊。server 端建立乙個key 為 75 的訊...