linux引導程式剖析(三)

2021-04-20 01:44:28 字數 4270 閱讀 5229

該部分程式是在核心**的開頭部分,用來

做一些初始化的操作,比如重新設定idt,gdt,

設定頁表等,最後將控制轉移到核心的main函式。

.text

.globl _idt,_gdt,_pg_dir,_tmp_floppy_area

這個標誌是站位的,之後該程式會將頁目錄表存放在該處

將head.s的開頭部分覆蓋。也就是說把頁目錄表放在記憶體

最開始處。

_pg_dir:

程式開始

startup_32:

段選擇符0x10表示,rpl為0,在全域性描述符表

中,索引值為2,

movl $0x10,%eax

用段選擇符載入各個段暫存器

在setup.s程式中,設定了gdt表,0x10表示

核心資料段,記憶體基位址為0

mov %ax,%ds

mov %ax,%es

mov %ax,%fs

mov %ax,%gs

設定系統堆疊,_stack_start定義在kernel/sched.c中

/*long user_stack [ page_size>>2 ] ;

檢查a20位址線是否開啟,如果沒開啟,

最高20位位址 + 1必將回環

1: incl %eax  

movl %eax,0x000000 

cmpl %eax,0x100000

je 1b

檢查協處理器是否存在

movl %cr0,%eax  

andl $0x80000011,%eax 

設定協處理器存在標誌位

orl $2,%eax 

movl %eax,%cr0

呼叫協處理器檢查子過程

call check_x87

安裝頁表

jmp after_page_tables

check_x87:

向協處理器傳送初始化命令

fninit

取狀態值

fstsw %ax

如果為0表示協處理器不存在

cmpb $0,%al

je 1f   

取cr0暫存器進行重置協處理器標誌位mp,em

movl %cr0,%eax

xorl $6,%eax  

movl %eax,%cr0

ret.align 2

fsetpm的機器碼,看作空操作即可。

1: .byte 0xdb,0xe4 

ret安裝中斷描述符表

setup_idt:

將所有中斷描述符項對應的中斷處理子程式設定成

亞中斷處理子程式的函式位址

lea ignore_int,%edx

0x00080000對應idt表描述符

0x0008表示指向核心**段的選擇符,

movl $0x00080000,%eax

將idt描述符的開始2個位元組付值為啞中斷處理子程式

的偏移位址

movw %dx,%ax 

0x8e00表示中斷描述符的高4個位元組的

值。存在位置位,dpl位0級。

movw $0x8e00,%dx

設定256項中斷描述符表

lea _idt,%edi

mov $256,%ecx

rp_sidt:

movl %eax,(%edi)

movl %edx,4(%edi)

addl $8,%edi

dec %ecx

jne rp_sidt

載入中斷描述符表暫存器

lidt idt_descr

retsetup_gdt:

載入全域性描述附表暫存器

lgdt gdt_descr

ret第乙個也表的位置0x1000

.org 0x1000

pg0:

第二個也表的位置0x2000

.org 0x2000

pg1:

第三個頁表的位置0x3000

.org 0x3000

pg2:

第四個頁表的位置0x4000

.org 0x4000

pg3:

為軟盤驅動預留緩衝,大小為1024byte.

.org 0x5000

_tmp_floppy_area:

.fill 1024,1,0

after_page_tables:

為init/main.c壓入輸入引數

引數char * enivorn

pushl $0

引數char ** argc

pushl $0

引數int argv

pushl $0

main函式返回位址

pushl $l6

壓入函式位址 

pushl $_main

安裝頁表

jmp setup_paging

main函式不會返回,否則宕機

l6:jmp l6

啞中斷處理子程式列印的資訊

int_msg:

.asciz "unknown interrupt/n/r"

.align 2

啞中斷處理子程式

ignore_int:

pushl %eax

pushl %ecx

pushl %edx

push %ds

push %es

push %fs

僅僅重新用核心資料段描述符載入各個段暫存器

在螢幕上列印"unknown interrupt"

movl $0x10,%eax

mov %ax,%ds

mov %ax,%es

mov %ax,%fs

pushl $int_msg

call _printk

popl %eax

pop %fs

pop %es

pop %ds

popl %edx

popl %ecx

popl %eax

iret

.align 2

安裝頁表

setup_paging:

一共5個頁表,每個頁表1024個表項

movl $1024*5,%ecx 

初始化eax暫存器為0

edi暫存器為0

xorl %eax,%eax

xorl %edi,%edi

開始載入頁目錄表和頁表

cld;rep;stosl

設定頁目錄表項

7表示頁目錄表項對應的頁表具有讀寫許可權,以及該頁在記憶體中

movl $pg0+7,_pg_dir

movl $pg1+7,_pg_dir+4 

movl $pg2+7,_pg_dir+8

movl $pg3+7,_pg_dir+12

在第四個頁表的最後乙個頁表項開始初始化頁表

movl $pg3+4092,%edi

初始化頁表所用的值:0xfff007,物理頁位址為:0xfff000,該頁可讀寫、存在記憶體中

movl $0xfff007,%eax

std迴圈初始化

1: stosl

subl $0x1000,%eax

jge 1b

頁目錄表的位址在記憶體中0x00000000

設定頁目錄表暫存器

xorl %eax,%eax

movl %eax,%cr3

movl %cr0,%eax

開啟cr0控制暫存器的pg位,啟用分頁機制

orl $0x80000000,%eax

movl %eax,%cr0 

ret定義中斷描述符表位址空間

.align 2

.word 0

idt_descr:

.word 256*8-1  

.long _idt

定義全域性描述符表位址空間

.align 2

.word 0

gdt_descr:

.word 256*8-1  

.long _gdt  

.align 3

_idt: .fill 256,8,0  

定義全域性描述符表

_gdt: .quad 0x0000000000000000 

.quad 0x00c09a0000000fff 

.quad 0x00c0920000000fff 

.quad 0x0000000000000000 

.fill 252,8,0 

Linux引導程式型別

bootloader monitor 描述 x86 arm powerpc lilo 否linux磁碟引導程式是否 否grub 否gnu的lilo替代程式是否 否loadlim 否從dos引導linux是否 否rolo 否從rom引導linux而不需要bios是否 否etherboot 否通過乙太網...

Linux 引導啟動程式(boot)

主要描述boot 目錄中的三個彙編 檔案,見列表3 1 所示。正如在前一章中提到的,這三個檔案雖然都是匯程式設計序,但卻使用了兩種語法格式。bootsect.s 和setup.s 採用近似於intel 的組合語言語法,需要使用intel8086 彙編編譯器和聯結器as86 和ld86 而head.s...

三 MFC框架程式剖析

1.cwnd 類 cwnd 類是mfc中乙個重要的類,它封裝了與視窗有關的操作。2.mfc 中的winmain mfc全域性物件 5.afxwinmain 函式 winmain 6.設計和註冊視窗 mfc已經為我們預定義了一些預設的標準視窗類,只需要選擇所需的視窗類,然後註冊就可以了。視窗類的註冊是...