該部分程式是在核心**的開頭部分,用來
做一些初始化的操作,比如重新設定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已經為我們預定義了一些預設的標準視窗類,只需要選擇所需的視窗類,然後註冊就可以了。視窗類的註冊是...