歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux內核 >> 《Linux內核設計的藝術》學習筆記(一)從開機加電到執行main函數之前的過程

《Linux內核設計的藝術》學習筆記(一)從開機加電到執行main函數之前的過程

日期:2017/3/3 13:40:31   编辑:Linux內核

分享一個最近丟了手機心塞到爆炸的我,現在窮的只剩下滿腦子的智慧了,好了,我要開始學習了.

首先,搭建一個linux0.11的系統環境,貼出結果圖.

從開機加電到執行main函數之前的過程.

1. 啟動BIOS,准備實模式下的中斷向量表和中斷服務程序;

2. 從啟動盤加載操作系統程序到內存,加載操作系統程序的工作就是利用第一步中斷服務程序實現的;

3. 為執行32位的main函數做過渡工作.

啟動BIOS,准備實模式下的中斷向量表和中斷服務程序

cpu的硬件設計為加電即進入16位實模式下狀態運行,硬件邏輯設計為加電瞬間強行將CS的值置為0xF000,IP的值為0xFFF0,而這個位置就是BIOS的的地址范圍.(IP指令指針寄存器,記錄將要執行的指令在代碼段內的偏移地址,和cs組合即為將要執行的指令的內存地址). BIOS程序在內存中加載中斷向量表和中斷服務程序

加載操作系統內核程序為保護模式做准備(boot)

加載第一 部分內核代碼-bootsect引導程序 找到軟盤並加載第一扇區,該扇區的內容就是引導程序,其作用就是陸續把軟盤中的操作系統程序載入內存.

加載 第二部分內核代碼-setup

加載第三部分內核代碼-system模塊 將系統模塊載入內存

為執行32位的main函數做過渡工作

關中斷並將system移動到內存起始位置0x00000 這裡需要注意,0x00000這個位置原來存放這有BIOS建立的中斷向量表及BIOS數據區.這個復制動作將之前東西覆蓋,操作系統不再具備相應處理中斷的能力

設置中斷描述符表和全局描述符表

打開A20,實現32位尋址

為保護模式下執行head.s做准備

head.s開始執行

head.s

這裡補充一點,開機時的16位實模式與main函數執行需要的32位保護模式之間有很大的差距,這個差距就有head.s來做這項工作.這期間,head程序打開A20,打開pe,pg,廢棄舊的,16位的中斷響應機制,建立新的32位的IDT. 前4KB的代碼將被頁目錄覆蓋掉。這些代碼執行的操作包括:設置系統堆棧為_stack_start。重新設置GDTR和IDTR。gdt,idt表都定義在head.s的末端,長度均為256項(2KBYTE)。第2個頁面到第5個頁面是系統的4張頁表。最後一個頁表後面的代碼執行分頁操作,即填充的4個頁目錄和4張頁表的內容,實現對等映射,即物理地址=線性地址。每個頁表項屬性為存在並且用戶可讀寫。設置好後置CR3頁目錄地址即0。啟動分頁標志,CR0的PG標志置1。跳到main函數中執行。head還做了重要事情,就是用程序自身的代碼在程序自身所在的內存空間創建了內核分頁機制,即在0x000000的位置創建了頁目錄表,頁表,緩沖區,GDT,並將head程序已經執行過的代碼所占內存空間覆蓋

跳到main之前,內存布局如下:從0到16M

頁目錄4K(0x0開始)

頁表1 4K

頁表2 4K

頁表3 4K

頁表4 4K

軟盤緩沖區1K

head.s後半部分代碼

IDT表2K

GDT表2K

main.o代碼部分

內核其余部分(大約到512K,end值為結束地址)

setup保存的系統參數(90000H~900200)這個區間還保存著root_dev.

BIOS(640K-1M)

主內存區(1M-16M)

在執行main函數之前,先要執行三個由匯編代碼生成的程序,即bootset(加載bootset到0x07c00,然後復制到0X90000),setup(加載setup到ox90200)和head(先將head.s匯編成目標代碼,將用c語言編寫的內核程序編譯成目標代碼,然後鏈接成system模塊,head程序在前,內核)之後,才執行由main函數開始的用c語言編寫的操作系統內核程序.

寫不下去了…我覺得這本書將的非常好…還是自己看書吧哈哈哈

下午再整理吧…

Copyright © Linux教程網 All Rights Reserved