一步步编写操作系统 07 开机启动bios
bios是如何蘇醒的
bios其實一直睡在某個地方,直到被喚醒……前面熱火朝天的說了bios的功能和內存布局,似乎還沒說到正題上,bios是如何啟動的呢。因為bios是計算機上第一個運行的軟件,所以它不可能自己加載自己,由此可以知道,它是由硬件加載的。那這個硬件是誰呢?其實前面已經提到過了,相當于是只讀存儲器ROM,因為它一直就睡在那里不動。
大家知道,只讀存儲器中的內容是不可擦除的,也就是它不像動態隨機訪問存儲器DRAM那樣,掉電后,里面的數據就會丟失。這種存儲介質是用來存儲一成不變的數據,當數據寫進去后,便與日月同輝,庭前坐看花開花落,不朽于天地萬物之間,哈哈,有點夸張了。
bios代碼所做的工作也是一成不變的,而且在正常情況下,其本身是不需要修改的,平時聽說的那些主板壞了要刷bios屬于例外。于是bios順理成章地便被寫進此ROM。ROM也是塊內存,內存就需要被訪問。此ROM被映射在低端1M內存的頂部,即地址0xF0000~0xFFFFF處,可以參考表1-1頂部的bios部分。只要訪問此處的地址便是訪問了bios,這個映射是由硬件完成的。
bios本身是個程序,程序要執行,就要有個入口地址才行,此入口地址便是0xFFFF0。最重要的一點來了,知道了bios在哪里后,cpu如何去執行它,即cpu中的cs:ip值是如何組合成0xFFFF0的。如果大家不了解內存的分段訪問機制,可以參考第0章,里面有講解cpu為什么分段方式內存。說正事,cpu訪問內存是用段地址+偏移地址來實現的,由于在實模式之下,段地址需要乘以16后才能與偏移地址相加,求出的和便是物理地址,cpu便拿此地址直接用了。這個“段基址:段內偏移地址”的組合是0xffff:0嗎?或者是0xF000:0xFFF0?或者是更奇葩一點的組合:0xFEEE:0x1110? 或者您想出的組合比我的還奇葩,好啦,不折磨大家了,還是說正事要緊。既然做為第一個運行的程序都沒開始執行,自然就沒辦法用軟件搞定這件事了,還是得靠硬件支持才行。在開機的一瞬間,也就是接電的一瞬間,cpu的cs:ip寄存器被強制初始化為0xF000:0xFFF0。由于開機的時候是處于實模式,再重復一遍加深印象,在實模式下的段基址要乘以16,也就是左移4位,于是0xF000:0xFFF0的等效地址將是0xFFFF0。上面說過了,此地址便是bios的入口地址。當我給出這個地址后,不知道大家意識到什么沒有。bios是在實模式下運行的,而實模式只能訪問1M空間(20位地址線,2的20次方是1M)。而地址0xFFFF0距1M只有16個字節了(見表1-1除標題外的第一行),這么小的空間夠干嗎?bios又要檢測硬件、做各種初始化工作、還要建立中斷向量表……16字節的機器指令肯定干不了這么多事。也許有的同學會問,超過寄存器寬度會怎么樣呢?比如0xFFFF0+16,這樣就溢出了,由于實模式下的寄存器寬度是16位,0xFFFF0+16已經超過了其最大值0xFFFFF。溢出的部分就會回卷到0,又會重新開始,即0xFFFF0+16等于0,0xFFFF0+17等于1。
既然此處只有16字節的空間了,這只能說明bios真正的代碼不在這,那此處的代碼只能是個跳轉指令才能解釋得通了。好,既然心里有了推斷,那咱們就來證明這個推斷正確與否。下圖是我在bochs中抓的圖,下面給大家分析一下這圖中的信息都代表什么。
?
首先得承認,這張圖有點超前了,這是在有了MBR后才能抓到的,否則會提示boot failed: not a bootable disk,而我們還沒有MBR,還沒有寫主引導記錄。先不管這張圖是怎么來的啦,反正大家馬上就能夠在自己的虛擬機里看到這張圖了,大概還有1柱香的工夫,可能是很長的那種香^—^。大家先注意框框中的內容。一共有3個,最上面左邊第1個標有cs:ip的那個框,cs寄存器的值是0xf000,ip寄存器的值是0xfff0,也就是段基址0xf000,段內偏移地址0xfff0,這個組合出來的地址便是0xffff0,這是處理器下一條待執行指令的地址。這與上面所說的bios入口地址是吻合的。另外,因為cs和ip寄存器中存儲的是下一條要執行的指令,目前還沒有執行,也就是說,當前還沒有執行bios,這是機器剛開機的那一刻。這一刻還是值得慶祝的,因為即使是計算機行業的同學都很少看到這一刻,何況我們讓這一刻停了下來,成為永恒。
按理說,既然讓cpu去執行0xFFFF0處的內容(目前還不知道其是指令還是數據),此內容應該是指令才行,否則這地址處的內容若是數據而不是指令,cpu硬是把它當成指令來譯碼的話,一定會弄巧成拙鑄成大錯。現在咱們又有了新的推斷,物理地址0xFFFF0處應該是指令,繼續探索。繼續看第二個框框,里面有條指令jmp far f000:e05b,這是條跳轉指令,也就是證明了在內存物理地址0xFFFF0處的內容是一條跳轉指令,我們的判斷是正確的。那cpu的執行流是跳到哪里了呢?段基址0xf000左移4位+0xe05b,即跳向了0xfe05b處,這是bios代碼真正開始的地方。
第三個框框cs:f000,其意義是cs寄存器的值是f000,與我們剛剛所說的加電時強制將cs置為f000是吻合的,正確。接下來bios便馬不停蹄的檢測內存,顯卡等外設信息,當檢測通過,并初始化好硬件后,開始在內存中0x000~0x3FF處建立數據結構,中斷向量表IVT并填寫中斷例程。
好了,終于到了接力的時刻,這是這場接力賽的第一棒,它將交給誰呢,咱們下回再說。
總結
以上是生活随笔為你收集整理的一步步编写操作系统 07 开机启动bios的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于Xldown和Xlup的用法(Exc
- 下一篇: 巴菲特“最后的午餐”1.28亿成交:买家