【從頭到腳品讀 Linux 0.11 源碼】第一回 最開始的兩行代碼

從這一篇開始,您就將跟着我一起進入這操作系統的夢幻之旅!

別擔心,每一章的內容會非常的少,而且你也不要抱着很大的負擔去學習,只需要像讀小說一樣,跟着我一章一章讀下去就好。

話不多說,直奔主題。當你按下開機鍵的那一刻,在主板上提前寫死的固件程序 BIOS 會將硬盤中啓動區的 512 字節的數據,原封不動複製到內存中的 0x7c00 這個位置,並跳轉到那個位置進行執行。

啓動區的定義非常簡單,只要硬盤中的 0 盤 0 道 1 扇區的 512 個字節的最後兩個字節分別是 0x55 和 0xaa,那麼 BIOS 就會認爲它是個啓動區。

所以對於我們理解操作系統而言,此時的 BIOS 僅僅就是個代碼搬運工,把 512 字節的二進制數據從硬盤搬運到了內存中而已。所以作爲操作系統的開發人員,僅僅需要把操作系統最開始的那段代碼,編譯並存儲在硬盤的 0 盤 0 道 1 扇區即可。之後 BIOS 會幫我們把它放到內存裏,並且跳過去執行。

而 Linux-0.11 的最開始的代碼,就是這個用匯編語言寫的 bootsect.s,位於 boot 文件夾下。

通過編譯,這個 bootsect.s 會被編譯成二進制文件,存放在啓動區的第一扇區。

隨後就會如剛剛所說,由 BIOS 搬運到內存的 0x7c00 這個位置,而 CPU 也會從這個位置開始,不斷往後一條一條語句無腦地執行下去。

那我們的夢幻之旅,就從這個文件的第一行代碼開始啦!

mov ax,0x07c0
mov ds,ax

好吧,先連續看兩行。

這段代碼是用匯編語言寫的,含義是把 0x07c0 這個值複製到 ax 寄存器裏,再將 ax 寄存器裏的值複製到 ds 寄存器裏。那其實這一番折騰的結果就是,讓 ds 這個寄存器裏的值變成了 0x07c0。

ds 是一個 16 位的段寄存器,具體表示數據段寄存器,在內存尋址時充當段基址的作用。啥意思呢?就是當我們之後用匯編語言寫一個內存地址時,實際上僅僅是寫了偏移地址,比如:

mov ax, [0x0001]

實際上相當於

mov ax, [ds:0x0001]

ds 是默認加上的,表示在 ds 這個段基址處,往後再偏移 0x0001 單位,將這個位置的內存數據,複製到 ax 寄存器中。

形象地比喻一下就是,你和朋友商量去哪玩比較好,你說天安門、南鑼鼓巷、頤和園等等,實際上都是偏移地址,省略了北京市這個基址

當然你完全可以說北京天安門、北京南鑼鼓巷這樣,每次都加上北京這個前綴。不過如果你事先和朋友說好,以下我說的地方都是北京市裏的哈,之後你就不用每次都帶着北京市這個詞了,是不是很方便?

那 ds 這個數據段寄存器的作用就是如此,方便了描述一個內存地址時,可以省略一個基址,沒什麼神奇之處。

 

ds : 0x0001

北京市 : 南鑼鼓巷

 

再看,這個 ds 被賦值爲了 0x07c0,由於 x86 爲了讓自己在 16 位這個實模式下能訪問到 20 位的地址線這個歷史因素(不瞭解這個的就先別糾結爲啥了),所以段基址要先左移四位。那 0x07c0 左移四位就是 0x7c00,那這就剛好和這段代碼被 BIOS 加載到的內存地址 0x7c00 一樣了。

也就是說,之後再寫的代碼,裏面訪問的數據的內存地址,都先默認加上 0x7c00,再去內存中尋址。

爲啥統一加上 0x7c00 這個數呢?這很好解釋,BIOS 規定死了把操作系統代碼加載到內存 0x7c00,那麼裏面的各種數據自然就全都被偏移了這麼多,所以把數據段寄存器 ds 設置爲這個值,方便了以後通過這種基址的方式訪問內存裏的數據。

OK,趕緊消化掉前面的知識,那本篇就到此爲止,只講了兩行代碼,知識量很少,我沒騙你吧。

希望你能做到,對 BIOS 將操作系統代碼加載到內存 0x7c00,以及我們通過 mov 指令將默認的數據段寄存器 ds 寄存器的值改爲 0x07c0 方便以後的基址尋址方式,這兩件事在心裏認可,並且沒有疑惑,這才方便後面繼續進行。

後面的世界越來越精彩,欲知後事如何,且聽下回分解。

 

------- 本回擴展資料 -------

 

有關寄存器的詳細信息,可以參考 Intel 手冊:

Volume 1 Chapter 3.2 OVERVIEW OF THE BASIC EXECUTION ENVIRONMEN

有關計算機啓動部分的原理如果還不清楚,可以看我之前的一篇文章瞭解一下:

計算機的啓動過程

如果想了解計算機啓動時詳細的初始化過程,還是得參考 Intel 手冊:

Volume 3A Chapter 9 PROCESSOR MANAGEMENT AND INITIALIZATION

 

------- 關於本系列 -------

 

本系列的開篇詞看這

開篇詞

本系列的擴展資料看這,這裏有很多有趣的資料、答疑、互動參與項目,持續更新中,希望有你的參與。

https://github.com/sunym1993/flash-linux0.11-talk

本系列全局視角

最後,祝大家都能追更到系列結束,只要你敢持續追更,並且把每一回的內容搞懂,我就敢讓你在系列結束後說一句,我對 Linux 0.11 很熟悉。

另外,本系列完全免費,希望大家能多多傳播給同樣喜歡的人,同時給我的 GitHub 項目點個 star,這些就足夠讓我堅持寫下去了!我們下回見。

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