歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux0.11內核--idt(中斷描述符表的初始化)head.s分析

head.s被編譯成system模塊的最前面部分,故而稱為頭部。

這段程序處於地址的絕對0處,首先是加載各個數據段寄存器,重新設置中斷描述符表 idt,共 256 項,並使各個表項均指向一個只報錯誤的啞中斷

程序。然後重新設置全局描述符表 gdt。接著使用物理地址 0 與 1M 開始處的內容相比較的方法,檢測 A20 地址線是否已真的開啟(如果沒有開

啟,則在訪問高於 1Mb 物理內存地址時 CPU 實際只會訪問(IP MOD,如果檢測下來發現沒有開啟,則進入死循環。然後程序測試 PC 機是否含有數

學1Mb)地址處的內容)協處理器芯片(80287、80387 或其兼容芯片),並在控制寄存器 CR0 中設置相應的標志位。接著設置管理內存的分頁處

理機制,將頁目錄表放在絕對物理地址 0 開始處(也是本程序所處的物理內存位置,因此這段程序將被覆蓋掉),緊隨後面放置共可尋址 16MB 內存

的 4 個頁表,並分別設置它們的表項。最後利用返回指令將預先放置在堆棧中的/init/main.c 程序的入口地址彈出,去運行 main()程序。

下面看一下idt表的初始化。 首先設置ds,es,fs,gs選擇符為setup.s中設置的數據段
  1. movl $0x10,%eax  
  2. mov %ax,%ds  
  3. mov %ax,%es  
  4. mov %ax,%fs  
  5. mov %ax,%gs  
然後設置系統的堆棧 lss stack_start,%esp   #表示_stack_start ss:esp 其中stack_start在/kernel/sched.c中定義了 然後進入setup_idt子程序
  1. setup_idt:  
  2.     lea ignore_int,%edx  
  3.     movl $0x00080000,%eax  
  4.     movw %dx,%ax        /* selector = 0x0008 = cs */  
  5.     movw $0x8E00,%dx    /* interrupt gate - dpl=0, present */  
  6.     lea idt,%edi  
  7.     mov $256,%ecx  
  8. rp_sidt:  
  9.     movl %eax,(%edi)  
  10.     movl %edx,4(%edi)  
  11.     addl $8,%edi  
  12.     dec %ecx  
  13.     jne rp_sidt  
  14.     lidt idt_descr  
  15.     ret  
idt表項的結構如下圖 這段子程序就是循環設置了256項idt描述符,全部指向ignore_int中斷門,以後使用的時候再重新設置
  1. /* This is the default interrupt "handler" :-) */  
  2. int_msg:  
  3.     .asciz "Unknown interrupt/n/r"  
  4. .align 2  
  5. ignore_int:  
  6.     pushl %eax  
  7.     pushl %ecx  
  8.     pushl %edx  
  9.     push %ds  
  10.     push %es  
  11.     push %fs  
  12.     movl $0x10,%eax  
  13.     mov %ax,%ds  
  14.     mov %ax,%es  
  15.     mov %ax,%fs  
  16.     pushl $int_msg  
  17.     call printk  
  18.     popl %eax  
  19.     pop %fs  
  20.     pop %es  
  21.     pop %ds  
  22.     popl %edx  
  23.     popl %ecx  
  24.     popl %eax  
  25.     iret  
其中idt標號的地址就是idt表的其實地址  位於head.s的233行 定義如下
  1. .align 8  
  2. idt:    .fill 256,8,0       # idt is uninitialized  
其中.align n 偽指令的含義 在x86 ELF格式中,要在8字節處對齊,應該用 .align 8 而在a.out格式中,要在8字節處對齊,應該用 .align 3       (2^n),現在一般用elf格式。
Copyright © Linux教程網 All Rights Reserved