首先,setup要獲取一系列系統硬體資訊
[cpp]view plain
copy
?
mov ax,#initseg
mov ds,ax //設定段位址
mov ah,#0x03
xor bh,bh
int0x10 //呼叫0x10中斷獲取螢幕游標位置
mov [0],dx //將螢幕游標儲存至0x90000處
//呼叫0x15中斷,獲取記憶體資訊儲存至0x90002
mov ah,#0x88
int0x15mov [2],ax
//呼叫0x10中斷,獲取顯示卡資訊儲存至0x90004 - 0x90006
mov ah,#0x0f
int0x10
mov [4],bx
mov [6],ax
//呼叫0x10中斷,獲取vga/ega配置儲存至0x90008 - 0x900012
mov ah,#0x12
mov bl,#0x10
int0x10
mov [8],ax
mov [10],bx
mov [12],cx
//獲取hd0資訊
mov ax,#0x0000
mov ds,ax
lds si,[4*0x41]
mov ax,#initseg
mov es,ax
mov di,#0x0080
mov cx,#0x10
rep
movsb
//獲取hd1資訊
mov ax,#0x0000
mov ds,ax
lds si,[4*0x46]
mov ax,#initseg
mov es,ax
mov di,#0x0090
mov cx,#0x10
rep
movsb
//檢查是否存在hd1
mov ax,#0x01500
mov dl,#0x81
int0x13
jc no_disk1
cmp ah,#3
je is_disk1
no_disk1:mov ax,#initseg
mov es,ax
mov di,#0x0090
mov cx,#0x10
mov ax,#0x00
rep
stosb
is_disk1:
mov ax,#initseg
mov ds,ax //設定段位址
mov ah,#0x03
xor bh,bh
int 0x10 //呼叫0x10中斷獲取螢幕游標位置
mov [0],dx //將螢幕游標儲存至0x90000處
//呼叫0x15中斷,獲取記憶體資訊儲存至0x90002
mov ah,#0x88
int 0x15mov [2],ax
//呼叫0x10中斷,獲取顯示卡資訊儲存至0x90004 - 0x90006
mov ah,#0x0f
int 0x10
mov [4],bx
mov [6],ax
//呼叫0x10中斷,獲取vga/ega配置儲存至0x90008 - 0x900012
mov ah,#0x12
mov bl,#0x10
int 0x10
mov [8],ax
mov [10],bx
mov [12],cx
//獲取hd0資訊
mov ax,#0x0000
mov ds,ax
lds si,[4*0x41]
mov ax,#initseg
mov es,ax
mov di,#0x0080
mov cx,#0x10
repmovsb
//獲取hd1資訊
mov ax,#0x0000
mov ds,ax
lds si,[4*0x46]
mov ax,#initseg
mov es,ax
mov di,#0x0090
mov cx,#0x10
repmovsb
//檢查是否存在hd1
mov ax,#0x01500
mov dl,#0x81
int 0x13
jc no_disk1
cmp ah,#3
je is_disk1
no_disk1:mov ax,#initseg
mov es,ax
mov di,#0x0090
mov cx,#0x10
mov ax,#0x00
repstosb
is_disk1:
接下來為了方便進行核心的位址對映,將system模組從0x10000處移動至0x00000處
[cpp]view plain
copy
?
do_move:
mov es,ax //指定目標段基址
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax //指定源段基址
sub di,di
sub si,si
mov cx,#0x8000
rep
movsw
jmp do_move
do_move:
mov es,ax //指定目標段基址
add ax,#0x1000
cmp ax,#0x9000
jz end_move
mov ds,ax //指定源段基址
sub di,di
sub si,si
mov cx,#0x8000
repmovsw
jmp do_move
在移動完成之後,我們需要為32位位址重新建立定址方式,32位定址採用段描述符的方式,所以要新建乙個gdt(全域性描述表),以及gdtr(gdt基位址暫存器),idt(中斷描述表),idtr(idt基位址暫存器)
[cpp]view plain
copy
?
end_move:
mov ax,#setupseg
mov ds,ax
lidt idt_48
lgdt gdt_48
end_move:
mov ax,#setupseg
mov ds,ax
lidt idt_48
lgdt gdt_48
然後就是開啟a20暫存器,就可以實現32位定址
[cpp]view plain
copy
?
call empty_8042
mov al,#0xd1
out #0x64,al
call empty_8042
mov al,#0xdf
out #0x60,al
call empty_8042
Linux核心設計藝術筆記(二)
從開機加電到執行main函式期間,實現了核心程式到計算機記憶體的載入,從實模式到保護模式的轉變,並且開始重建保護模式下的中斷服務機制,記憶體分頁機制等前期工作,然後開始順理成章地呼叫並執行main函式。此時,系統仍處於中斷關閉模式。二 裝置環境初始化及啟用程序0 現在開始進入main函式中執行,此時...
Linux核心設計的藝術 前三章總結
特權級變化的本質是,cs,ds,es,fs,gs,ss的不同,特權級0從gdt中取得描述符,前面這些暫存器後3位為000,描述符特權級為00,特權級3從ldt中取得描述符,前面這些暫存器後3位為111,描述符特權級為11。中斷int 0x80從特權級3進入特權級0,並把資訊儲存在特權級0的堆疊中,i...
Linux核心設計與實現 之二 從核心出發
獲取核心源 從linux官方核心 可以隨意獲取 http www.kernel.org 安裝核心源 解壓縮 tar xvjf linux x.y.z.tar.bz2 不要把 usr src linux 目錄下的原始碼作為開發 使用補丁 patch pl patch x.y.z 編譯核心 1.配置 可...