自製 os 極簡教程1:寫一個作業系統有多難

為什麼叫極簡教程呢?聽我慢慢說

不知道正在閱讀本文的你,是否是因為想自己動手寫一個作業系統。我覺得可能每個程式設計師都有個作業系統夢,或許是想親自動手寫出來一個,或許是想徹底吃透作業系統的知識。不論是為了滿足程式設計師們自帶的成就感,還是為了面試找工作時能更深入地和面試官探討(裝逼)。

寫一個作業系統有多難

會者不難,難者不會。

冷啟動

對於零基礎的人,甚至是電腦知識零基礎的人來說,難。難點並不在於作業系統的程式碼量本身,而在於任何一個事物發展初期都會遇到的困境,冷啟動

我不知道應該看哪本書作為入門書籍,甚至不知道應該看書還是看網路上的文章,還是找一個領路者帶你入門,甚至還在被一些討論自己做一個作業系統到底有沒有意義這個問題糾結著。

好多人在這個冷啟動時期,就被弄得沒脾氣了。

你可能比較幸運,找到了一本入門書籍,剛好作者的文筆和思路比較對你的胃口,於是度過了冷啟動時期。

但你也可能不太幸運,找了一本難讀的書籍,或者是優秀的作品但剛好不對你的胃口,於是就從入門到放棄了。

我當時的第一本啟蒙書籍,是《30 天自製作業系統》,好多人的第一本可能也是這個,因為書的標題就直戳了當地寫了 自製作業系統 這幾個字,而且一看哇 30 天就能搞定,一下讓好多不敢跨出第一步的人有了信心。

這本書會把讀者當作完全沒有電腦基礎的小白,所以很多地方非常友好,跟著它走一遍完全可以讓你度過冷啟動時期了。

但這本書同樣也有讓人想中途放棄的一些點,比如我就很煩這些地方。一個是它從官網上下載的源碼是日語注釋的,搞的當時我好多地方還找我朋友幫我翻譯。另一個是他用的工具都是這個作者自己寫的,這固然比較牛逼,但我就想難不成做作業系統連個現成的業界常用的工具也沒有么,我學了你的工具也沒有普適性啊。再有就是作者後面的篇幅花好多時間講圖形介面要怎麼做,怎麼在螢幕上畫一個個方框作為窗口,還想互不影響。這個因人而異吧,我是覺得不必花費如此大的篇幅,這不是想寫作業系統的人的痛點所在。

總之,通過一本書,或者一篇文章,或者一個領路人的帶領之下,你邁出了第一步,度過了冷啟動時期,來到了初期

初期

你照葫蘆畫瓢,一個指令都不敢修改,終於照著書上的程式碼,成功在一個虛擬機或者真機上看到了「hello world」,或者牛逼一點看到了 AAABBB 執行緒切換方式交替列印的字元串。

這時候你寫作業系統的恐懼已經沒有了,但你不滿足於現狀,因為這個「hello world」並不是你自己的東西,你甚至都不知道裡面的程式碼是什麼含義,可能當時只是 copy 過來的。

你不在需要一個手把手教你的書籍,更多的是需要告訴你通用的原理,以及作業系統思想的書籍。

我在這個時期的書籍是《作業系統真相還原》,這本書一上來就講述了一些你可能感到困惑的問題,

0.1 作業系統是什麼

0.2 你想研究到什麼程度

0.3 寫作業系統,哪些需要我來做

0.4 軟體是如何訪問硬體的

0.5 應用程式是什麼,和作業系統是如何配合到一起的

0.6 為什麼稱為「陷入」內核

0.7 記憶體訪問為什麼要分段

0.8 什麼是平坦模型

我一看這目錄我的媽呀,這不就是我讀完《30 天自製作業系統》後所產生的疑問么!於是這本書可以說是我在這條路上,讀的最爽的書,一個個疑問就是在這本書里被一一找到答案的。

不過其實我覺得對於有電腦基礎並且還不錯的人來說,這本書完全可以作為冷啟動時期的第一本書了。

這本書不會像 30 天一樣,在手把手這種細節上下太大功夫,比如 30 天這本書很逗,居然在教你如何用鍵盤按出 512 個 0 這個問題上寫了好多行,還說你家如果有小貓的話可以棒棒忙。所以這本書的篇幅會放在一些真正重點的問題上。

你讀完這本書,結合著網上的資料和自己動手實踐,已經可以用自由意志來對照葫蘆畫瓢的作業系統進行微調了。此時你已經成功度過了初期,開始向中期邁進!

不過別看一句話就總結完了,這中間你很可能會放棄,因為單單這本書的知識量就非常龐大了,如果之前從沒有接觸過,想要消化它,不是一件簡單的事。

比如我在這個階段,就中途放棄過兩三次,因為我老想著跳過一些我覺得「沒用的」章節,可往往都是看到後面,又要重新翻回來把前面的補上。有的時候也因為,明明和書上寫的一樣,但我的程式就是報錯,導致後面的沒法進行。作業系統就是這樣,前面的載入 loader、設置中斷、設置分段分頁、進入保護模式這些步驟是串列的,每一步都不能出一丁點錯誤,否則後面的步驟會被前面的步驟卡住,遇到問題沒法跳過,就像你做一張數學試卷,必須從第一題開始順序做到最後一題,而且前面的正確了才能往後繼續做一樣。

中期

千辛萬苦來到中期,這裡的人可能已經不多了,但到了這裡你會認識一大批和你一樣在掙扎的人,新世界的大門可能就此打開,所以對你來說,其實你會覺得自己做作業系統的人好多啊,而且高手如雲。

因為雖然你可以按照自己的意志對寫好的作業系統有一些微調,也對作業系統的各個部分有了一個模糊的認識,但總是甩不開你所看的書的影子,簡單說就是沒見識

我當時呢,就被《作業系統真相還原》里的作業系統的思路舒服著,總是認為就應該把內核映射到記憶體高端的空間上,要用很取巧的辦法設計頁表。總之就是見識少,因為只知道一種實現方式,所以覺得天下的作業系統都是這個鬼樣。

因為好歹是有點知識量在了,這個階段一些作業系統領域的大牛(反正是比你厲害很多的人啦),會稍稍理一理你了,可能語氣會從原來的拉黑,變成「哦」,再到現在的「嗯嗯」。你也會加入到一些群或者一些社區當中,認識更多的大佬。你會發現,你眼中的這個作業系統,在他們眼裡就是個其中一種很常規的或者說很過時的方式而已。於是乎你在慢慢的影響下,也打開了思路,決定了解更多的作業系統。

我呢,當時的選擇是閱讀 linux 源碼,並嘗試仿寫一個(最後仿寫這一步放棄了)。

這我感覺,只要這一步你的選擇是了解一款經典的作業系統,那還能選什麼呢,只能是 linux 吧哈哈。

這一時期的書籍呢,也比較多,我的話是通過《linux 內核設計的藝術》來簡單了解 linux 的整個流程和脈絡,再通過《linux 內核完全注釋》配合著 linux 的源碼進行重點源碼逐行了解,還通過和一款開源作業系統 bookos 的作者進行交流,進一步了解一個成熟作業系統需要考慮的問題。

linux 有些了解後,便通過仿寫的形式來進一步加深理解。但仿寫最終放棄了,因為即便是 linux0.11 的源程式碼,裡面都非常複雜,完全仿寫還是很費時間的。於是便將自己認為純苦力的工作簡化,比如 linux 會根據記憶體大小來劃分記憶體區域,我就直接寫死了 32M 記憶體。再比如 linux 支援的硬碟數是動態變化的,我就直接只支援一塊硬碟,這樣裡面好多數組,for 循環,就都展開了,我覺得對理解一個作業系統,這些工作無關緊要。

這裡說個小插曲,讀 linux 源碼,有時候差點沒把我氣死。linus 這個人太調皮了,好多地方的注釋寫的大概是這種風格。/*_ emm,這裡我也不知道有啥用,不過先寫上吧,我樂意,嘿嘿 _/
對於正在苦苦理解源碼的我,簡直不友好

這時候找書便不再是你的難題了,你會自發的去找自己需要的書籍,並且每個人想關注的點不同,也會找不同的側重點去深入了解。比如 linux 早期版本中是沒有網路模組的,所以如果側重點在網路編程,那就專門找如《linux 內核網路模型》這種書。有時候一些驅動程式,和一些比較好的作業系統變編程習慣,我也會通過如《一個 64 位作業系統的實現》這類書的部分章節來強化。

而且這個階段你不在寂寞,會有很多同行者和你一起,也會有很多小白請教你問題。

後期

此時,一個作業系統的框架,你應該已經摸清楚了,但你不可能深入每一個細節。此時,也不是堅不堅持的問題了,而是選擇的問題。你要你的作業系統不但支援 x86 還支援 arm 么?你要把各種驅動程式都完善么?你要做優美的圖形化介面么?你要深入學習顯示卡方面的編程么?你要加入製作國產作業系統的大軍么?

我的選擇是不,所以我止步於此了。

因為我當初決定入坑的時候,是為了對我現在所做的工作有更深入的理解。我是個軟體工程師,是 Java 程式設計師,並不是專門做嵌入式,專門做內核開發的從業者。所以我認為再往後繼續深入可以,但已經沒必要向前中期那樣集中火力搞了,而是利用閑散時間能多了解就多了解,按需學習。

當然你也可以選擇繼續,我覺得不論是止步於此,還是繼續往下走,都是有好處的。

我的經歷小結

  • 冷啟動:《30 天自製作業系統》
  • 初期:《作業系統真相還原》
  • 中期:《linux 內核設計的藝術》《linux 內核完全注釋》+ linux0.11 源碼
  • 後期:止步

這個系列要寫什麼

要寫一個極簡的作業系統教程,帶你入坑

如果說屬於上述哪個階段的教程的話,我覺得處於冷冷啟動階段,因為無論是冷啟動、初期還是中期,都有讓人放棄的點,而這個冷冷啟動階段的極簡教程,會讓你在上面的各個階段,都不那麼容易放棄。

我曾經寫過這樣的系列,但一開始總是定很大的目標,期待讀者除了我的系列文章外,不需要讀任何資料就可以完全按照我的教程完成一個作業系統的製作,但往往很不現實,也沒有必要,完全不是一個系列文章該做的事。下面是我在部落格園折騰的系列們

系列文章無法做到足夠細緻,只有大部頭的書籍才能做到這一點。但上面的每一本書,部頭真的都非常大,很容易讓人放棄,從而錯失一本好書和一個入坑的機會,我在每本書上都放棄過兩三次。而網上,簡單的自製作業系統的文章,又過於簡單,完全無法讓人達到入坑的標準。

所以為了解決這個痛點,我決定根據自己的經歷,結合書本上的知識,反思之前寫過的教程中的一些缺點,出這樣一個極簡教程的系列,其知識密度介於大部頭書籍和網上的文章之間

該教程的核心目標是,讓讀者對製作一個作業系統的核心流程應該掌握的知識需要經歷的過程,和需要克服的心理障礙,做到心中有數,不再畏懼,做好入坑自製作業系統的正確姿勢。並且在深入學習的過程中,不斷的會有「哦,原來這個系列說的 xxx 就是這個意思呀」的正向回饋,這一點是非常重要的。
因為技術的學習過程中之所以會放棄,一個原因是興趣不夠,另一個原因就是「我理解了」這種正向回饋不夠。那本系列,我希望會在你後續深入學習的過程中,這個系列的影子會一直陪伴你,給你這種正向回饋和繼續下去的動力,當然,最好還能讓你提升興趣,甚至讓本不想親手製作作業系統的人,也打開這個新世界的大門。

本來還想寫個目錄,後來想想算了,中途的思路很可能要根據實際情況來調整,就當作給大家的期待吧。

先送你一份入坑禮物

這可能是 全網最簡單的作業系統 demo,啥也不能幹,就做到了能接受鍵盤參數往螢幕上列印。最誘人的一點就是,如果你是 Windows 作業系統,你直接源碼下載下來,點擊 run.bat,不用安裝任何環境,直接就可以運行。這可能是好多入坑小夥伴夢寐以求的一個 demo 吧,地址奉上:

//gitee.com/sunym1993/flash-4th-os.git

為什麼是 flash-4th-os 呢?因為我英文名叫 Flash,然後我寫的前三次都放棄了,這是我寫的第四個,哈哈哈。

有任何問題隨時回復公眾號,我會時常查看並回復。如果想私聊,也可以公眾號留下你的微信,我會加你

好的,那我們就敬請期待吧!