head.s
head.s 是系統模組的入口,其編譯器已經是gnu彙編,但從功能上將仍然屬於核心啟動階段,主要的功能是對386 cpu的初始化,如使用者堆疊、idt、gdt和頁表。因此從資料夾的歸屬看,它仍然放在boot資料夾中,與bootsect和setup一塊。head.s的核心功能(簡單的暫存器初始化不做贅述)如下:
structstack_start = ;
setup_idt:leaignore_int,%edx
movl $0x00080000,%eax
movw %dx,%ax /* selector = 0x0008 = cs */
movw $0x8e00,%dx /* interrupt gate - dpl=
0, present */
leaidt,%edi //設定idt中的256個中斷描述符
mov $256
,%ecx
rp_sidt:
movl %eax,(%edi)
movl %edx,
4(%edi)
addl $
8,%edi
dec%ecx
jnerp_sidt //如果ecs(256) != 0,則跳轉
lidt
idt_descr //載入中斷描述符表,這裡的idt_desscr包含了idt變數(256個中斷描述符)
ret
setup_gdt:lgdt
gdt_descr
ret
gdt_descr:.word
256*8-1 # so does gdt (not that that'
s any
.long gdt # magic number, but it works for me :^)
gdt: .quad 0x0000000000000000 /* null descriptor */
.quad 0x00c09a0000000fff /* 16mb */
.quad 0x00c0920000000fff /* 16mb */
.quad 0x0000000000000000 /* temporary - don
't use */
.fill
252,8,0 /* space for ldt'
s and tss
's etc */
注:在386體系的cpu中支援段頁式的記憶體管理方式,即邏輯位址(基位址+偏移)->通過分段管理->線性位址->通過分頁管理->實體地址。針對分頁管理386的機制是cr3暫存器指向頁表目錄,頁表目錄中的pde (page directory entry)指向乙個頁表,頁表中的pte(page table entry)指向乙個物理頁。因此386的線性位址實際上是三個偏移量:頁目錄表偏移量(找到頁表)、頁表的偏移量(找到物理頁)、物理頁的偏移量,三者的綜合完成具體物理頁面的轉換。
在linux的頁表初始化**中主要是三塊工作:
setup_paging:movl $
1024*5,%ecx /* 5 pages - pg_dir+4
page tables */
xorl %eax,%eax
xorl %edi,%edi /* pg_dir is at 0x000 */
cld;
rep;stosl
movl $pg0+7
,pg_dir /* set present bit/user r/w */pg_dir的位址是0x000,沒搞清楚為什麼?
movl $pg1+
7,pg_dir+4 /* --------- "
"--------- */
movl $pg2+
7,pg_dir+8 /* --------- "
"--------- */
movl $pg3+
7,pg_dir+12 /* --------- "
" --------- */
xorl %eax,%eax /* pg_dir is at 0x0000 */movl %eax,%cr3 /* cr3 - page directory start */ //cr3被設定成0x0000
movl %cr0,%eax
orl $0x80000000,%eax
movl %eax,%cr0 /* set paging (pg) bit */
ret /* this also flushes prefetch-queue */
linux 0 11 原始碼學習(五)
head.s head.s 是系統模組的入口,其編譯器已經是gnu彙編,但從功能上將仍然屬於核心啟動階段,主要的功能是對386 cpu的初始化,如使用者堆疊 idt gdt和頁表。因此從資料夾的歸屬看,它仍然放在boot資料夾中,與bootsect和setup一塊。head.s的核心功能 簡單的暫存...
linux 0 11 原始碼學習(六)
main.c main函式其實是核心的初始化,如果把核心功能比作業務軟體的話,就相當於是業務的初始化,從該檔案的資料夾歸屬 init資料夾 也可以看出這一點。main主函式很短,從 中可以基本看出整個核心的功能模組,如下 void main void for pause 注 在linux中fork乙...
linux 0 11 原始碼學習(十三)
字元裝置驅動 在linux 0.11版本中,字元裝置驅動原始碼分為三塊 向上暴露的字元裝置驅動介面tty io.c與tty ioctl.c,與塊裝置驅動一樣,在字元驅動檔案 read write.c 操作中被呼叫 實現串列埠的驅動rs io.s和serial.c 實現鍵盤驅動的keyboard.s以...