註:以下大部分內容摘自linux核心編程入門篇和linux核心完全注釋
對於linux的整個體繫結構有了一定的瞭解,看了每個目錄的檔案整體概要,那麼就
可以開始看核心的源碼了,首先那便是引導啟動了。
關於磁軌,扇區等資訊
在這有必要講一下磁軌和扇區等。
1、扇區:不是扇形的,即不是兩個半徑之間的地區,而是個四邊形:兩個半徑為兩邊,兩個大小同心圓作為兩外兩邊。
2、磁軌 :磁軌不是線性,而是個地區,有兩個大小同心圓組成
3、 柱面:不是面而是號碼相同的多個磁軌組成的柱體
4、 磁頭數:因為磁碟的雙面儲存性,使得計算時用磁頭數而沒有用碟片數
可以說:扇區是硬碟分割的最小單位。
儲存容量=磁頭數*磁軌(柱面)數*每道扇區數*每扇區位元組數
_______________________________|----- 磁軌的總位元組數--------|
________________|-------磁碟一個盤面的總位元組數----------------|
__________|----- 磁碟容量(磁頭數個盤面)--------------------|
關於8086寄存器
彙編代碼是基於8086的,所以先瞭解了這些寄存器,然後再看代碼會更好些。
1、資料寄存器,一般稱之為通用寄存器組
8086 有8個8位元據寄存器,
這些8位寄存器可分別組成16位寄存器:
AH&AL=AX:累加寄存器,常用於運算;
BH&BL=BX:基底位址暫存器,常用於地址索引;
CH&CL=CX:計數寄存器,常用於計數;
DH&DL=DX:資料寄存器,常用於資料傳遞。
2、地址寄存器/段地址寄存器
為了運用所有的記憶體空間,8086設定了四個段寄存器,專門用來儲存段地址:
CS(Code Segment):程式碼片段寄存器;
DS(Data Segment):資料區段寄存器;
SS(Stack Segment):堆棧段寄存器;
ES(Extra Segment):附加段寄存器。
當一個程式要執行時,就要決定程式碼、資料和堆棧各要用到記憶體的哪些位置,通過設定段寄存器CS,DS,SS來指向這些起始位置。
通常是將DS固定,而根據需要修改CS。所以,程式可以在可定址空間小於64K的情況下被寫成任意大小。所以,程式和其資料群組合起來的大小,限制在DS 所指的64K內,這就是COM檔案不得大於64K的原因。
3:特殊功能的寄存器
IP(Instruction Pointer):指令指標寄存器,與CS配合使用,可跟蹤程式的執行過程;
SP(Stack Pointer):堆棧指標,與SS配合使用,可指向目前的堆棧位置。
BP(Base Pointer):基址指標寄存器,可用作SS的一個相對基址位置;
SI(Source Index):源變址寄存器可用來存放相對於DS段之源變址指標;
DI(Destination Index):目的變址寄存器,可用來存放相對於 ES 段之目的變址指標。
還有一個標誌寄存器FR(FlagRegister)有以下九個有意義的標誌:
OF: 溢出標誌位OF用於反映有符號數加減運算所得結果是否溢出。如果運算結果超過當前運算位元所能表示的範圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0.
DF: 方向標誌DF位用來決定在串操作指令執行時有關指標寄存器發生調整的方向。
IF: 中斷允許標誌IF位用來決定CPU是否響應CPU外部的可屏蔽中斷髮出的插斷要求。但不管該標誌為何值,CPU都必須響應CPU外部的不可屏蔽中斷所發出的插斷要求,以及CPU內部產生的插斷要求。具體規定如下:
(1)、當IF=1時,CPU可以響應CPU外部的可屏蔽中斷髮出的插斷要求;
(2)、當IF=0時,CPU不響應CPU外部的可屏蔽中斷髮出的插斷要求。
TF: 狀態控制標誌位是用來控制CPU操作的,它們要通過專門的指令才能使之發生改變
SF: 符號標誌SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統中,有符號數採用補碼錶示法,所以,SF也就反映運算結果的加號或減號。運算結果為正數時,SF的值為0,否則其值為1。
ZF: 零標誌ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標誌位。
AF: 下列情況下,輔助進位標誌AF的值被置為1,否則其值為0:
(1)、在字操作時,發生低位元組向高位元組進位或借位時;
(2)、在位元組操作時,發生低4位向高4位進位或借位時。
PF: 奇偶標誌PF用於反映運算結果中“1”的個數的奇偶性。如果“1”的個數為偶數,則PF的值為1,否則其值為0。
CF: 進位標誌CF主要用來反映運算是否產生進位或借位。如果運算結果的最高位產生了一個進位或借位,那麼,其值為1,否則其值為0。)
關於BIOS啟動過程
1、 對電腦硬體執行一系列的測試,用來監測現在都有什麼裝置以及這些裝置是否正常工作。這個階段通常稱為POST(Power-on self-test,上電自檢)。這個階段中,會顯示一些資訊,例如BIOS版本號碼。
2、 初始化硬體裝置。這個階段在現代基於PCI的體繫結構中相當重要,因為它可以保證所有的硬體裝置操作不會引起IRQ線與I/O連接埠的衝突。在本階段的最後,會顯示系統中所有安裝的所有PCI裝置的一個列表。
3、 搜尋一個作業系統來啟動。實際上,根據BIOS的設定,這個過程可能要試圖訪問系統中磁碟片、硬碟和CD-ROM的第一個扇區(開機磁區)。
4、 只要找到一個有效裝置,就把第一個扇區的內容拷貝到RAM中從物理地址0x00007c00開始的位置,然後跳轉到這個地址處,開始執行剛才裝載進來的代碼。
下面看下BIOS的中斷,具體功能太多了,等調用了可以去查看。
00h 被零除
01h 單步
02h 不可屏中斷(NMI)
03h 斷點
04h 溢出
05h 螢幕列印
06--07h 保留
________________________________________
08h 日時鐘中斷
09h 鍵盤中斷
0Ah 保留/8259A從片中斷
0Bh 串列口2中斷
0Ch 串列口1中斷
0Dh 硬碟(XT)/並行口2中斷
0Eh 磁碟片中斷
0Fh 印表機/並行口1中斷
________________________________________
10h 視頻顯示I/O
11h 裝置配置檢測
12h 記憶體容量檢測
13h 磁碟I/O
14h 串列通訊I/O
15h 盒帶(PC)/多功能
16h 鍵盤I/O
17h 印表機I/O
18h ROM-BASIC
19h 自舉程式
1Ah 時鐘I/O
1Bh Ctrl-Break中止
1Ch 時鐘控制
1Dh 視頻初始化參數表
1Eh 磁碟片參數表
1Fh 圖形顯示擴充字元表
________________________________________
20h 程式終止退出
21h 系統功能調用
22h 程式結束位址
23h Ctrl-C處理
24h 嚴重錯誤處理
25h 磁碟扇區讀
26h 磁碟扇區寫
27h 程式終止駐留
28h 鍵盤空閑處理
29h 快速字元輸出
2Ah 保留
________________________________________
2B--2Dh 保留
2Eh 命令執行處理
2Fh 多路中斷,共用
________________________________________
30--31h 遠轉移至INT 21h入口
32--3Fh 保留
________________________________________
40h 磁碟片I/O
41h 硬碟機1基數表
42--45h 保留
46h 保留
47--5Bh 保留
5Ch 硬碟機2基數表
5D--6Fh 保留
________________________________________
70h 即時鐘中斷
71h 改向0Ah號中斷
72h 保留給IRQA
73h 保留給IRQB
74h 保留給IRQC
75h 副處理器中斷
76h 硬碟中斷
77h 保留給IRQF
________________________________________
78--7Fh 保留
________________________________________
80--F0h BASIC使用區
________________________________________
F1--FFh 保留
關於bootsect.s
bootsect.s代碼是磁碟引導塊程式,駐留在磁碟中的第一個扇區中(開機磁區,0磁軌(柱面),0磁頭,第1扇區)。在我們的電腦上電後。。。。。
1、首先ROM BIOS自檢,開機磁區由BIOS載入到記憶體0x7c00處(如果是嵌入式裝置的話,一般都是上電後,由bootloader中載入核心代碼到記憶體的);
2、然後將自己移動到記憶體0x90000處,該程式主要作用是首先將setup模組從磁碟載入到記憶體緊接著bootsect的後面位置(0x90200)。
3、然後利用BIOS中斷0x13取磁碟參數表中當前啟動引導盤的參數,接著在螢幕上顯示“loadingsystem..”字串。
4、再將system模組從磁碟上載入到記憶體0x10000開始的地方。隨後確定根檔案系統的裝置號,若沒有指定,則根據所儲存的引導盤的每磁軌扇區數判別出盤的類型和種類並儲存到其裝置號於root_dev(引導塊的0x508地址處)。
5、最後長跳轉到setup程式開始處(0x90200)執行setup程式。
而在多系統引導的時候,我們經常看到的grub,就類似替代了bootsect的功能使命。
關於setup.s
Setup程式的作用主要是利用ROM BIOS中斷讀取機器系統資料,並將這些資料儲存到0x90000開始的位置,其讀取並保留的參數如下表所示:
1、 setup程式將system模組0x10000--0x8fffff整塊向下移動到記憶體絕對位址0x00000處。
2、 載入中斷描述符表寄存器(idtr)和全域描述表寄存器(gdtr)。
3、 開啟A20地址線
4、 重新設定兩個中斷控制晶片8259A,將硬體中斷號重新設定為0x20—0x2f
5、 設定CPU的控制寄存器CR0(機器狀態字),進入32位保護模式運行
6、 跳轉到位於system模組最前面部分的head.s程式繼續運行。
關於head.s
head.s程式編譯後,被串連成system模組的最前面部分。從這裡開始核心完全都是在保護模式下運行了。功能如下:
1、載入各個資料區段寄存器,重新設定中斷描述符表,共256項,並使各個表項均指向一個只報錯誤的啞中斷程式。
2、重新設定通用描述元表。
3、使用物理地址0與1M開始處的內容相比較,檢測A20地址線是否開啟。
4、測試PC機是否含有數字副處理器晶片,並在控制器CR0中設定相應的標誌位。
5、設定管理記憶體的分頁處理機制,將頁目錄表放在絕對物理地址0開始處,緊隨後面放置共可定址16MB記憶體的4個頁表,並分別設定它們的表項。
6、利用返回指令將預先放置在堆棧中的/init/main.c程式的入口地址彈出,去運行main()程式。