IA32體系結構6(x86加電啓動過程概述)

第一條指令物理地址

加電啓動過程非常精妙,道理很簡單,加電時刻,所有的硬件部件基本都是沒法工作的狀態。至少內存裏什麼有用的東西也沒有,CPU的寄存器還是初始狀態,各種地址轉換表也沒有建立好。

首先我們來看下,CPU從上電到正常工作,在地址線上發出的第一個有效物理地址是什麼。這個在《Intel Architecture Software Developer Manual Volume 3》8.1.4節有說明:

第一條指令的物理地址是:0xFFFFFFF0。

怎麼來的呢?該小節也說得很清楚:

80386以上cpu,CS寄存器分爲兩部分:可見段選擇符部分和隱藏基地址部分。實地址模式,地址是按照CS*0x10+IP生成。硬件復位時刻,CS被加載爲0xF000,隱藏基地址部分被加載爲0xFFFF0000,EIP被加載爲0xFFF0。於是:

physical address = base address + EIP = 0xFFFF0000 + 0xFFF0 = 0xFFFFFFF0

實際上,80386以上CPU在計算物理地址的時候,遵循非常簡單的規則,就是將CS基地址部分和EIP簡單相加,得出最終物理地址。這個貌似既不是實模式的方法,也不是保護模式的方法(保護模式需要段氏頁式轉換),所有有很多資料稱之爲一種奇特的模式。一旦CS被重新更新過,計算地址的方式就變成真正的實模式方式,就是CS*0x10+IP。

執行第一條指令

以上我們知道cpu發出的第一個物理地址是0xFFFFFFF0,到這裏我們需要知道一點,cpu其實很傻逼,他根本不知道也不用知道這個地址對應的設備在哪裏,並且裏面有什麼。本質來說,cpu從這個地址來取指令,你給他什麼就是什麼。當時的IBM PC機主板上,準確點說是南橋北橋芯片,裏面存儲了一張物理地址映射表,這張表裏面將這個地址定向到了系統BIOS,在0xFFFFFFF0地址處,一般放置一條跳轉指令。跳轉到BIOS代碼中64K範圍內的某一條指令開始執行。接下來就是BIOS的執行,比如初始化、加電自檢等,完了之後,會將第一個可啓動設備的最開始一個扇區(512字節)的內容複製到絕對物理地址0x7c00處。linux0.11在這裏放置了bootsect代碼,當今的PC機,這個512字節一般存放MBR。MBR中包含446字節的執行代碼和64字節分區表。比如這段代碼可以存放grub引導程序第一部分,把grub後續部分引導加載運行,然後由grub來引導內核啓動。

映射表可以參見《linux內核完全註釋》2.3.1節和2.3.2節。

關於地址映射,可以參考:https://blog.csdn.net/sunxiaohusunke/article/details/88886233

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章