Linix 啟動過程詳解


啟動linux kernel過程:

PC/AT機內存使用區域圖:
|-----------------------------------------------------| 0xffffffff(=4GB)
|           jmp ROM_BIOS_LOCACTION
|-----------------------------------------------------| 0xfffffff0(=4GB-16B)
|                   ROM BIOS                          |
|-----------------------------------------------------| 0xfffeffff(=4GB - 64KB)
|
|-----------------------------------------------------| 16MB
|
|-----------------------------------------------------| 0x100000(=1MB)
|                 ROM BIOS Map                        |
|-----------------------------------------------------| 0xf0000(=960KB)
|                 Other BIOS Map                      |
|-----------------------------------------------------| 0xe0000
|                Other Card ROM BIOS                  |
|-----------------------------------------------------| 0xc7fff
|                    VGA ROM BIOS                     |
|-----------------------------------------------------| 0xc0000(=768KB)
|                  Video buffer                       |
|-----------------------------------------------------| 0xa0000(=640KB)(=640 * 1024B)
|
|-----------------------------------------------------| 0x00500
|                   BIOS  Data                        |
|-----------------------------------------------------| 0x00400
|                Interrupt Vector                     |
|-----------------------------------------------------| 0x00000

Note!!!
1) 為保持計算機在軟件上的兼容,PC/AT在1MB以下物理內存使用分配上依然與8086兼容,因為
8086只有20根地址線,只能尋址1MB,只是原來系統ROM中BIOS一直處於CPU所能尋址的內存最
高端位置處,而BIOS原來所在位置(指BIOS在8086機器所能尋址的位置)被用作現在機器BIOS的
Shadow區域,即:把BIOS復制到此位置處.
2) 除了0xA0000~0xFFFFF(total=384KB): 用於I/O設備
   0xfffe0000~0xffffffff(total=128KB): 用於BIOS
其余部分都可以作為系統內存

1.當計算機系統上電或者按下復位按鈕時:
CPU: cs = 0xF000,ip=0xFFF0, 故,段基地址=0xFFFF0000,段長度=64KB,CPU代碼指針指向
0xFFFFFFF0,即:4GB空間最后一個64KB的最后一個16字節處,這里存放一條跳轉指令,主機將
該跳轉指令安排為BIOS的初始化程序的入口地址.

Note!!!(author: bogdan)
Bochs在BIOS程序的第一條指令處中斷
[0xfffffff0]f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0
查看CS寄存器的值
cs:s=0xf000, dl=0x0000ffff, dh=0xff0093ff, valid=1
查看ip的值:
rip: 0x00000000:0000fff0
intel處理器,實模式下地址的計算為"段地址*16+偏移地址"即是f000*10+fff0=ffff0 即物理地址為[0x000ffff0];那么為什么會是[0xfffffff0]呢?


解釋:
這時因為intel 286后,實模式下地址的計算根本就不是"段地址*16+偏移地址"
而是采用跟保護模式一樣的地址計算方式,即采用描述符。也就是說,實模式下
段寄存器的緩沖區也是有用的,段寄存器的緩沖區是“不可見的”,它有8個字節。
cs:s=0xf000, dl=0x0000ffff, dh=0xff0093ff, valid=1,其中dl,dh就是它的緩沖寄存器。
段寄存器緩沖區的值就是描述符的值,我們知道,當寄存器的值不變時(valid=1,描述符有效,
這時,段寄存器的值無關緊要,是什么值應該都可以)是從段寄存器的緩沖區中取基地址的,
從dl=0x0000ffff, dh=0xff0093ff(描述符), 可以看出,段界限=0ffff,基地址=ffff0000,
G=1(段界限粒度為字節,段大小限制為64k),d=0,avl=0,P=1(段已在內存中),DPL=0(ring0,特權級為0),
s=1(存儲段描述符),type=3(這里為什么不是大於等於8,我就不清楚了)所以物理地址是ffff0000+0000fff0=fffffff0,
即第一條指令的地址為[0xfffffff0]。接下來,實模式下,當段寄存器的地址發生變化的時候,就會把段寄存器的值左移4位,
放入段寄存器的緩沖器中的基地址部分,這應該是實模式轉移指令做的事情。這樣,在實模式下看起來,地址的計算方式就是"段地址*16+偏移地址"。
intel 為什么要這樣做呢?完全是為了向上兼容處理器惹的禍!我們知道實模式下的地址都是物理地址,我們的內存根本就不能達到[0xfffffff0],
那么這個地址在哪里呢?其實,cpu啟動的時候,這個地址應該是采取某種機制把它映射到rom中的(bios),在rom中執行到適當的時候,
會rombois拷貝到內存的1m后64k,並采用某種機制切換到內存中執行,以加快啟動的速度。
基於這樣的地址計算方式,其實在實模式下,完全可以訪問到大於1M的空間,
這樣做:合適地初始化各個描述符,做好必要的工作,暫時切換到保護模式,注意要開啟A20地址線,然后再切換回實模式,
不要關閉a20,這樣地址應該就不會回滾了。注意,進入保護模式不要開啟分頁,或者開啟分頁后保證線性地址是和物理地址一樣的,
為了防止找不到你的指令,回保護模式的時候也不要改變段寄存器的值,因為改變段寄存器的值就改變段寄存器的緩沖寄存器的值了,
這樣就訪問不到大於1M的內存了,當然,訪問不存在的地址可能會出現問題。

2.BIOS初始化過程包含兩部分工作: 系統加電自檢和系統自舉(OS的裝入和引導)
1)檢測電腦系統中的內存,顯卡等關鍵設備是否能夠正常工作.
2)查找顯卡的BIOS,然后調用顯卡BIOS的初始化代碼,用它完成顯卡的初始化工作.
3)查找其他設備的BIOS程序,找到之后同樣要調用這些BIOS的內部初始化代碼來初始化設備。
4)顯示BIOS自己的啟動代碼.
5)檢測CPU的類型和工作頻率,並將檢測結果顯示在屏幕上。
6)開始檢測系統中安裝的一些標准硬件設備(硬盤, CD-ROM等)
7)標准設備檢測完成后開始檢測一些即插即用設備

Note!!!
上述步驟是在打開電源開關或按Reset按鈕進行冷啟動時所要完成的各種初始化工作,如果
按Ctrl+Alt+Del鍵進行熱啟動時直接從第三步開始,同時會跳過第五步

8)BIOS在執行了一系列硬件檢測和初始化工作之后,就會把與原來PC機兼容的64KB BIOS代碼和
數據復制到低端1MB末端64KB處,然后跳轉到這個地方並且讓CPU進入真正的實模式模式工作.
9)加電自檢完成后,按照指定的啟動順序從軟盤,硬盤和光驅中尋找啟動設備。
Note!!
若硬盤是啟動設備:即硬盤的第一個扇區(0磁頭,0磁道,1扇區),硬盤最開始的512B,其最后兩個字節是0x55AA
這是引導扇區的標志,512個字節不能多一個字節也不能少一個字節.
10)找到啟動設備后,將啟動設備上的512個字節的OS引導程序加載到內存0x7c00處,並跳轉到這個地方繼續
執行引導操作.

3.到此開始執行Linux的引導程序boot
Path: boot/bootsect.s.
Func: 其被BIOS讀入到內存物理地址0x7c00(31KB)處,當它被執行時就會吧自己移動到內存
物理地址0x90000(576KB)處,並把啟動設備后2KB(= 4 sector)字節代碼(boot/setup.s)讀入到內存0x90200出,而
kernel的其他部分(system模塊)則被讀入到內存地址0x10000(64KB)開始處

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



JBoss啟動過程詳解 Cassandra啟動過程詳解 PC啟動過程詳解 ARM啟動過程詳解 Linux啟動過程詳解 linux啟動過程詳解 MySQL啟動過程詳解 Linux啟動過程詳解 linux啟動過程詳解 Windows啟動過程詳解
 
粤ICP备14056181号  © 2014-2021 ITdaan.com