linux核心設計的藝術 從16位轉向32位

2021-06-25 19:53:10 字數 4097 閱讀 3734

首先,setup要獲取一系列系統硬體資訊

[cpp]view plain

copy

print

?

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

print

?

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

print

?

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

print

?

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.配置 可...