作業系統之旅 引導你的作業系統(一)

2021-10-24 02:30:49 字數 3987 閱讀 9342

話說作為乙個非專業人士,我寫寫**也只是滿足一下自己的好奇心,費了很大的勁兒寫出來的東西也就自己看看。一旦覺得有什麼不好的,亦或是有什麼新的想法,就立刻動手改。甚至重寫也不覺得有一點點可惜。整個專案就是自己整著玩兒,用專業的話來說,整個專案也沒有什麼里程碑。就這樣兜兜轉轉,我居然將views重寫了兩遍。直到目前,整個專案還在不斷的修改、前進中。

整個過程中,真正的感悟是:原來感覺神秘的作業系統知識,書本上那些晦澀的概念,親自動手試過後,便有透徹的理解,再也不會感覺困難了。雖然我並沒有從事乙份程式設計師的職位,但通過寫views讓我對技術不再懼怕。在現實世界中,企業對技術到底是買還是自研總有無法避免的爭論。特別是我從事的夕陽行業中的朝陽方向,當你有了這樣乙份「深入鑽研」的經歷後,在這種爭論面前就會微微一笑,對自己的行業有更多的展望。

關於我從事的行業,未來有機會我想再開個專欄在仔細說說吧。廢話講的太多了,讓我們回到views,讓我娓娓道來~ 

(下面開始的闡述都是我對x86系統及os的理解,很多東西都是自己悟出來的,不免存在謬誤,請各位輕拍)

按照經典理論及網上的很多作業系統教學,你需要準備一張軟盤。用組合語言寫乙個512位元組的「引導程式」,通過該引導程式再讀取軟盤後續的連續扇區,這些扇區中可能儲存這你的os的「核心」(kernel)。我地第一版系統也是這麼寫的。通過經典的bios int13h呼叫(ah=2)可以讀取軟盤中的「絕對扇區」。此外還需要注意程式要定位到07c0:9000位置,才能執行。

這種做法會給你極大的滿足感。彷彿不用花多少時間,就能在」裸機「上執行一段程式。我也曾經迷戀過。但這並沒有什麼好處,反而會給你後續除錯帶來諸多麻煩。每次需要執行時,你需要把512位元組的引導程式和」核心」寫入磁碟上指定的區域(因為引導程式容量太小,無法分析fat12格式來載入核心檔案),否則載入很容易失敗。

看到這兒你可能已經暈乎了。沒關係,其實,在後來的版本中,我嘗試了一種直接在dos中載入核心的方法。ms-dos能支援檔案的隨意讀取,因此從磁碟上正確地載入乙個核心檔案就是一件非常容易的事情。但...,dos是什麼...,這又是怎麼一回事情呢?說到這兒,故事要從intel x86架構開始說起啦。

intel自從製造記憶體晶元競爭不過日本人(這又是另乙個有趣的故事了,很好地詮釋了企業「戰略」,有機會我們可以再開貼聊聊)後,就開始發力pc處理器晶元的研發。2023年,intel發布了8086處理器。該處理器的發布初步奠定了intel在pc處理器領域的地位。這個8086是16位的處理器,在當時可是相當先進的存在。8086可是大名鼎鼎的「x86架構」的始祖,你現在辦公電腦上用的intel晶元都還完全相容8086的呢。

8086支援20位的位址線,理論上能訪問1mb的記憶體。其中,384kb被系統保留(我們後面還會提到這塊保留區域,敬請期待),軟體真正能用的空間也就640kb。這就是著名的dos只能使用640kb記憶體說法的由來。說到dos,年輕的朋友們可能都沒聽說過。他的全名叫disk operation system,磁碟作業系統。是比爾蓋茨發家致富的第一桶金。這是個簡單的作業系統,主要就是讓你能往磁碟上讀寫檔案,並且完成「應用程式載入」的功能。這簡單粗糙的東西,當年可是玩電腦必學的基礎。當年要在電腦上玩「紅警」遊戲,就是通過這個dos把遊戲程式載入進來的。

dos是個脆弱的系統,很容易就可以把它整崩了。這倒不僅僅是dos的鍋,而是當時的cpu很傻很天真,它不對需要執行的指令做很多的檢查,就忠實地執行。乙個無法無天的應用程式能把作業系統掀個底朝天,搞得不好cpu就一聲不吭reset(重啟)了。當然反過來說,也給了應用開發人員無窮無盡的空間。應用程式幾乎能夠訪問到所有系統資源,甚至繞開作業系統直接操縱硬體。這在現在是難以想象的。一批想象力豐富的天才程式設計師們開發出了各種令人難以置信的程式。舉個例子,在那個年代,應用程式都會劫持中斷,在響應中斷時做一些自己的事兒。大名鼎鼎的雷布斯同學,早年寫得**裡面也用類似技巧:

各位看官,**中的 oldint2f_addr變數就是用來進行中斷劫持的:-)

顯而易見,在8086這種晶元上,是不可能開發出什麼現代化的作業系統的。所以,看到過很多人批評dos的文章,就我的理解而言,dos是適應那個年代軟硬體環境而出現的產物。比爾蓋茨還是有觀察力的,這dos,就如維秘內衣秀的模特,多乙份則肥,少乙份則柴。在加上比爾蓋茨母親的「關係」,妥妥的成功,不是蓋的。

我想,intel也一定看到了這一點,指令執行前不進行檢查,顯然不行。甚至對一般的應用,應該鎖定他們的許可權,不讓他們進行訪問作業系統區域,改變中斷等操作,保護整個系統。所以,在後續的80286,80386中,intel引入了所謂的」保護模式「。在此模式下,作業系統具有訪問系統一切資源的能力,但被嚴密地保護起來。而應用程式可訪問資源被大大削弱。與之相對的,8086處理器上這麼實誠的,允許應用程式為所欲為的模式,intel把它成為」實模式「:-)。

」保護模式「可不僅僅只有強化保護那麼簡單。自從80386開始,intel處理器已經公升級到32位,能直接訪問最大4gb的記憶體空間(當時這是令人恐怖的),且支援分頁模式(未來我們會仔細講),支援指令級的任務切換等。一大堆新功能令人眼花繚亂。這些新功能都只能在」保護模式「中才能使用。至於」實模式「嗎,那就老老實實的相容8086吧,向後相容也是intel制勝的法寶之一。

在這種」相容「的思想下,8086之後的所有x86架構的晶元,在它上電的那一刻,是以」實模式「執行的。也就是說你辦公用的電腦,在上電一瞬間,居然只是一塊執行速度極快的8086... 作業系統將會在後續負責將cpu切換到」保護模式「,從而解鎖所有高階的處理器能力。

我們知道,16位的處理器,實際上應當只能訪問64kb的記憶體空間。那為什麼8086能訪問「多達1mb」的記憶體空間呢。原來,8086下的(實模式)將整個記憶體劃分為很多個64kb的區段。要訪問記憶體時,指定乙個區段後,就可以訪問連續的64kb記憶體。在經典教材中,我們稱這個區段為「段」(segment),用於訪問連續64kb的16位位址稱為基於「段」的偏移量(offset)。在8086中,有好幾個暫存器專門用來存放段的基底位址,intel稱他們叫「段暫存器」。當你需要訪問記憶體時,將段位址裝入乙個段暫存器,再給出偏移量,即可進行1mb空間內的任意位址訪問(實際情況更加複雜,以後用到後我們再來講)。

對稍微近代一點的pc來說,1mb記憶體空間實在太小了。所以,要訪問超過1mb空間,在保護模式中才能實現。在x86的32位保護模式下,段偏移量是乙個32位的位址,因此每個段的最大長度為4gb。配合修改「段」暫存器,幾乎可以訪問無限的記憶體。這也是為什麼所有現代的作業系統都啟用了保護模式。

大家都已經知道了,處理器初始化後處於實模式。而實模式僅可以訪問1mb記憶體。這個1mb空間還被分為兩段,640kb的「常規記憶體」和384kb的「保留記憶體」區域。這就意味著核心的尺寸如果超過640kb,那麼就必須拆分為2段,才能裝入。這對於核心的開發,編譯,鏈結都是個很大的問題。

所以,在我理解,核心裝入1mb以上的記憶體區域才是合理的。有人可能會問,那麼1mb以下的記憶體區域就浪費掉了?其實並沒有,因為這些記憶體空間可作為空閒記憶體,被作業系統動態分配使用。此外,某些早期的硬體裝置在進行dma傳送時要求分配的物理記憶體必須是低位址空間的記憶體,這時候,1mb以下的記憶體空間也就有了用武之地。我的views就使用了這樣的記憶體布局。有人可能還會問,那1mb以上空間不足以載入核心,怎麼辦。那我的回答是,這麼小記憶體的電腦,扔掉算了:-)

早期的linux的做法是將核心壓縮後,通過一段裝載程式將其裝入實模式的1mb空間,然後將cpu切換成保護模式,將已經裝載在記憶體中的壓縮核心解壓縮到1mb以上的記憶體空間,來完成核心的初步裝載。大家就不免要問了,這不是脫褲子放屁,多此一舉嗎。為什麼不先將cpu切換到保護模式,然後直接將核心裝載到1mb以上的記憶體空間呢?

哈哈。這就要講到大名鼎鼎的bios啦。大家知道,要從磁碟載入檔案,你需要磁碟驅動程式,檔案系統驅動程式等的支援。這些東西原本都是在核心裡面實現的。但現在我們是要載入核心... 所以...,這些驅動都還不存在。好在有bios(basic input and output system)。bios是固化的程式,提供對pc硬體的基本驅動能力,在沒有作業系統的驅動程式的情況下,也可以對硬體(如磁碟)進行一些基本操作。但有一點,bios只能在實模式下執行。這就解釋了linux為什麼必須要在實模式下裝載核心的原因:在保護模式下,需要自行實現簡易的裝置驅動程式才能讀取和載入核心。但這些驅動程式也是程式,也需要被載入。這就形成了乙個死結。這麼說,大家也就理解了,linux在實模式下載入核心是不得已而為之的無奈之舉了。

作業系統 作業系統 一 作業系統概述

好好學習,天天向上本文已收錄至我的github倉庫daydayup 歡迎star 之前一直沒有系統地學過作業系統,感覺自己在平時的學習過程中對於某些概念理解得一塌糊塗,比如中斷 記憶體 程序和執行緒等。所以打算系統的學習一下作業系統。一開始我是在b站看哈工大的李治軍老師講的,但是一上來就開始從彙編 ...

作業系統(一)

1.01 歷史 1.02 分類 作業系統 桌面作業系統 redhat fedora slackware ubuntu debian suse linux centos 伺服器作業系統 linux ubuntu deepin startos mint debain suse redhat centos...

作業系統(一)

1 單道批處理系統 batch processing system 2 多道批處理系統 multiprogrammed batch processing system 3 分時系統 time sharing system 程序控制 為作業建立程序 撤銷已結束的程序 控制程序狀態轉換。程序同步 為多個...