Linux引導過程(內核版本:0.11)

來源:互聯網
上載者:User

 

黨電腦開啟電源後,x86系列的CPU一開始進入實模式。並從地址0xFFFF0開始自動執行程式,而這個地址是ROM-BIOS中的地址。也就是說,機器開機後會自動自行BIOS中的一段預設的代碼,這段代碼的主要執行系統自檢,並在物理地址0處初始化中斷向量。然後將啟動設備的第一個扇區(512字節)讀入到內存絕對地址0x7c00,然後自動跳轉到這裡,也就是將系統控制權交給了這個引導程式(bootsect.s)。bootsect.s的第一個動作是保護自己,將自己從0x7c00移到到0x90000(利用匯編中的字串移動指令)。

為什麼移動到0x90000而不是別的地方?因為此後bootsect.s會將system加載到0x10000,而Linus Torvalds給內核預設的最大值為512K(最新內核裡的說法是508K),0x90000-0x10000=0x80000=512K;第二個動作則是在緊隨bootsect.s的後面加載setup.s到0x90200(0x90200-0x90000=0x200=512),setup.s佔據4個磁盤扇區的空間(512x4=2048=0x800),這裡是利用BIOS的13中斷來讀取磁盤數據;第三步就是將system加載到0x10000處,同樣使用BIOS13中斷。為什麼一開始加載到0x10000而後來卻要在setup.s中移動到0x00000?因為開機後BIOS會將中斷向量表儲存在0x0000~0x0400處,setup.s中還要用到BIOS中斷,如果一開始就加載到0x00000,那......。而後來移動到0x00000應該是想使system中的地址和物理地址一致,而且此後linux再也不需要調用BIOS中斷了,它自己在setup.s中設置了256個啞中斷,指向一個只顯示"Unknown interrupt"的中斷處理常式。然後會在init的main()中各個硬體的初始化函數中一個一個地分別設定所用到的實際中斷向量。

所有的加載動作完成後,bootsect.s也就完成了自己的使命。最後一條指令就是條轉到0x90200,把以後的光榮任務交給setup.s。

setup.s首先利用BIOS中斷讀取有關內存/磁盤/顯示和其他參數,並將這些參數放到0x90000~0x901FF,也就是先前bootsect.s的地盤。現在還在實模式下,只能使用640K的常規內存,當然不能浪費寶貴的內存資源,要儘量廢物利用了緊接著setup.s就移動system到0x00000處,然後加載中斷描述符表寄存器(idt)和全據描述符表寄存器(gdt),開啟A20地址線(通過操作鍵盤控制器8042的P2口實現),重新設置兩個中斷控制器8259A,將硬體中斷號重新設置為0x20~0x2f,最後設置CPU的控制寄存器CR0,從而進入32位保護模式(置位CR0的0位),然後就讓位給head.s。

現在進入到head.s,這是CPU已經運行在保護模式了,head.s位於地址0x00000處。它開始加載各個數據段寄存器,重新設置中斷描述符idt(256項),指向一個只顯示"Unknown interrupt"的啞中斷處理常式。然後重設通用描述元表gdt,再檢測一下A20是否真的開啟(這個真的很重要,不然只能訪問1M的內存啊),沒有開啟的話就只好死機。如果檢查通過,接著就問是否有數學協處理器,有的話就置位CR0的1位。然後設置MM的分頁處理機制,並把頁目錄表放在0x00000處(也就是head.s自己所在的地方,它準備自殺了),自殺過程一開始就沒路可退了,只好趕緊執行最後一條指令跳轉到init/main.c的main()(通過返回指令將預先放在堆棧中的main.c的地址彈出來實現)

注:我閱讀內核使用的書是<Linux核心完全注釋(內核版本0.11)>,可以到http://oldlinux.org下載。

剛開始閱讀內核,這是第一篇筆記,錯漏之處,歡迎指正!更多筆記請留意我的blog。

我補充一點 在新版的核心中(有多新我不知道)bootsect.s會判斷system是否是Big_kernel(大記憶體編譯)如果是則將system裝入0x100000h(因為常規記憶體中裝不下),不是的話裝入0x10000h。在進入Setup.s執行後也要判斷Big_kernel,如果是則繼續執行,如果不是則將system搬到0x1000h處(我看書上這末寫的,我還沒看原碼不知道是否正確),我估計是因為開始的0x00000h-0x00400h是Bios中斷向量表,0x00401h-0x00800h是BIOS資料區,因此將其放在0x1000h。有些牽強所以我不太確定。
     至於如何將system裝入0x100000h需要瞭解一部分記憶體的知識。
00000h-9FFFFh  常規記憶體
0xA0000h-FFFFFh 上位記憶體
0x100000h-10FFEFh。為高端記憶體,10FFEF以後的所有記憶體都為擴充記憶體。
     其中高端記憶體雖然超過了1M但仍能在即時模式下訪問,在 bootsect.s中是通過int 15h實現。據說int 15h也是通過先進入保護模式處理完後在恢複我沒有找到這方面資料。以上是我的理解,我也是剛開始看時間不長,對代碼還不能全面把握,不對的地方還請指出。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.