2011年12月28日 星期三

聊聊作業系統書籍 - Orange's 一個作業系統的實現、作業系統開發實戰手冊、30 天打造 OS!作業系統自作入門、自己動手寫嵌入式操作系統

the 1st edition: 2011/12/28
the 2nd edition: 2015/03/05
the 3nd edition: 2016/09/06 - 中國亞馬遜的電子書版本

有一個壞消息和好消息和大家分享, 壞消息是: 《Orange's 一個作業系統的實現》的簡體中文和繁體中文都絕版了; 好消息是中國亞馬遜出了電子書版本, 12 rmb 4.99 rmb, 更好的消息是 - 中國亞馬遜不需要用支付寶付款, 國人用慣的信用卡就可以付錢了, 也不用 vpn 到中國就可購買。

購買連結

這種價錢我除了替作者掉眼淚之外, 就只能支持買一本了。



光盤光碟怎麼辦? 于淵把程式碼放在: https://github.com/yyu/osfs00

對於需要或有興趣的專業書籍, 我一向不吝嗇, 有人肯出版這樣的書我就很高興了, 怎麼會嫌貴呢! 其實定價太離譜還是會嫌, 不過這幾本書的定價我還可以接受 (以書本技術內容和頁數來比較), 對於出版社願意做這樣自殺的行為, 讀者們要向他們致敬。這裡提到我購買的幾本中文書籍。順道列出其他英文大作或是教科書, 這些英文書籍不是不重要, 而是我沒能力看完他們, 只能買來收藏用。

我現在比較推薦《一步步写嵌入式操作系统: ARM 编程的方法与实践》這本書, 重點都圍繞在 os 上, 不用分心學習 x86 那折騰人的保護模式, 而且只需要模擬器就可以執行, 大局觀都顧到了, 小細節當然也要周全, 否則神功只學半套, 豈不可惜。有了大局觀, 細節就不會在那麼困難, 可以有能力渡化自己。

第一版我不記得購買的正確時間, 大約在 2007 的時候已經買了第一版, 而第二版大概是在 2010 年購入, 距離我的一小步 (201109) 還真的有點久, 我到 201109 才真的把這本看到一個可以上手的階段, 對我來說, 這不是一本容易的書 (我相信對大多數人也是), 而且也不是看完就沒事了, 我打算跟著書上程式碼, 實作出一個 os。也才有了 write os 這一系列文章。而到 201209 也還真的有點小東西可以見人, 我的 os 學習之旅竟然如此的漫長。

fig 1 第一版 fig 2 第二版

fig 1 是第一版, fig 2 是第二版, 第一版還沒消化完又出第二版了, 學習速度實在太慢。可惜這本好書被松崗製作的很糟糕, 松崗得好好加油才是, 不過封面倒是不錯, 以後封面漂亮的書籍得好好審視才行; 以同樣製作中國出版社的電腦書籍來說, 碁峰的《程式設計師的自我修養:連結、載入、程式庫》就製作的很棒,文句通順、翻譯辭彙令人讀來輕鬆愉快, 沒有詰屈聱牙的詞句、惱人的中國技術術語。

這本書真是可惜了, 直接買簡體版可能不會差太多。製作簡體中文的書籍難度應該比外文書籍容易許多, 如果因為出版社的不用心, 只做做繁體化中文的工作, 那實在也太不尊重台灣支持你的讀者了。現在我幾乎只買簡體中文的電腦書籍, 靠著淘寶/中國亞馬遜已經很容易購得, 出版社若只是做作簡體中文轉繁體中文肯定是沒有市場的, 尤其是價格還貴上不少, 你知道現在台灣工程師的薪水很低, 能省則省。

原文版本 (簡體版) 是于淵自己用 latex 排版而成, 作者自序有提到, 但是這段話在繁體中文版中被刪除了 (對我來說這很嚴重, 翻譯書籍沒有資格修改原文的任何文字), 所以我推測繁體中文版本不是用 latex 排版而成。雖然我喜歡 latex 排版的書, 但我並不會強人所難, 再說, 繁體中文版本的排版也很好 (這是唯一的優點了)。而使用 latex 排版可以保證書中程式碼和範例程式碼是一模一樣, latex 可以直接 include 程式碼成為 latex 檔案的一部分, 于淵用心良苦。

書附的 CD 也有不同, 原文版本裡頭除了程式碼還有該出版社的其他出版書籍, 順便打個廣告, 我很喜歡看一些出版社自己書籍的廣告, 可是不知道為什麼, 現在不太有出版社做這樣動作, 早期旗標會這麼做, 基本上我喜歡這本書, 多少也會相信其廣告的書籍品質也有相當水準, 出版社應該善用這點。

在來看看教科書, 我並不喜歡教科書的內容, 那只能有個基本概念, 無法靠著那些內容實作出一個作業系統, 而無法實作的東西, 我認為要稱得上「了解」二字, 恐怕猶如 0 到 1 那般的遙遠, 理論源於實踐,又指導實踐, 相輔相成, 功效更大。

fig 3 是我學生時代上課的書籍, 很有名的一本 os 書籍 - Operating System Concepts, 5th Edition, 它很有名, 但我認為能靠讀這本書而寫出 os 幾乎是不可能的。有人稱它為恐龍書, 不過說實在的, 若你這樣跟我說, 我不知道你是提這本書還是 compiler 那本, 因為 compiler 那本也是以恐龍當封面, 討論時請把書名說清楚, 用這樣的暱稱並不會使你看起來很高明。

fig 3. Operating System Concepts
實作之所以困難是因為細節, 細節很難可以在開始實作之前估算出來, 做到哪, 不足就到哪。以 x86 來說, 若無法以程式來認識保護模式 (進入保護模式, 權限切換, 中斷設定、分頁管理), 每一樣都是令人害怕的苦工, 又如何得以開發教科書上的分頁管理功能, 考試的分頁演算法很簡單, 要完成一個分頁功能很困難。若你無法體驗其中難度, 我可大概剖析一番。

在 x86 平台上, 得先進入保護模式, 開起分頁功能, 實作磁碟讀寫 (這個可難倒不少人), 製造出 page fault, 使用 idt 攔這個中斷, 把這分頁的資料寫到磁碟上。

我沒能實作這功能, 因為我還卡在磁碟讀寫這關, 這是我能想到的, 也許還有很多細節沒注意到, 所以 simple os 沒有支援分頁功能。

在更前面一點, 如果連作業系統之前的程式 (這稱作 bare-metal programming) 都寫不出來, 那連怎麼開始都成為問題了。



基本上我是以 Orange's 一個作業系統的實現為主, 其他兩本為輔, 因為其他兩本有提到 GUI 的實作, 這也是我有興趣的部份, 早期是以世紀末軟體革命作為我研究 GUI 實作書籍, 不過該書在這部份寫的不是很詳細, 現在有其他兩本可以輔助了, 而且完全用自己寫的程式碼來實作, 不使用繪圖函式庫。使用 c/bios function call (不過在 x86 有些無法避免, 還是得呼叫 bios call), 那不算是自己完成所有的東西, library 實在幫我們完成太多工作了, 我不喜歡我完成的少, library 完成的多。

除了 os 技術, 這本書珍貴的地方在於: 它是『中文』的, 同樣使用中文的你 (否則你應該看不懂本篇文章), 應該能理解我的意思, 我認為就算和國外知名教科書相比, 本書也絕對不居下風, 有一拼的實力。

這本定價是三本當中最便宜的, 價格是 580 (原文版本 69 rmb), 其實不算便宜, 但以書中的內容來說實在是太便宜了。本書使用 nasm 為組譯器, 我參考杨文博的電子書學習 gas at & t syntax 的版本, 將書中範例以 gas 改寫。我還是比較喜歡使用 gnu toolchain。

很巧的是, 這三本書分別是中國、日本、台灣的作者, 真是高興台灣的作者也能出版這樣的書籍, 也很高興台灣的出版社願意出版, 雖然高達 750 的定價 (作業系統開發實戰手冊:以開發一個視窗多工作業系統為例), 但我依然覺得以這樣的知識來說實在值得 ; 日本人寫的 30 天打造 OS!作業系統自作入門則是 780, 在這三本書當中是最貴的, 基本上不知道是不是翻譯的關係, 有點覺得怪怪的, 但還不至於影響理解, 我覺得讀來也算有趣。

首先我很不滿意書名: Orange's 一個作業系統的實現, 台灣用的術語應該是 - Orange's 一個作業系統的實作, 中國在術語應用上實作/實現都是使用實現這詞, 台灣軟體開發人員不會覺得聽起來很奇怪嗎?第一版書名就好多了。

這書上有好多我的筆記, 不過大多不是心得, 而是我得把他的句子稍做改寫, 要不然讀來實在不愉快。20130926 補充: 我後來知道有個成語: 詰屈聱牙可以形容這種慘狀。

明明組合語言對岸是稱為匯編, 真不知道為什麼繁體中文版本變成編譯, 偏偏這又會讓人誤會是要編譯 C 語言的那個意思, 這讓我在書上畫下了不少鉛筆印記。

有些英文註釋還會連在一起, 所有英文單字都連在一起, 不容易看清楚要表達的意思, 這是排版不用心。

還有使用者 / 被使用者這兩個詞, 我看了很久之後才知道這是指 caller/callee, 台灣應該是翻譯成呼叫者 / 被呼叫者, 讓我在權限 stack 切換那邊卡了很久。

訪問以台灣術語來說是存取的意思。例如訪問記憶體指的是存取記憶體, 花了我好多時間才搞懂 ... 按!! 怎麼讀怎麼不爽。

系統使用 (system call) 指的是系統呼叫, 就算是對岸也是稱為系統調用吧!怎麼搞出自己的一套勒!譯者自己念起來不會覺得怪怪的嗎?

想不到第一版原來就很糟糕 (對, 第一版我也有買), 第一版第六章標題名為進程, 台灣應該是用行程, 但重點是整章充斥著處理這東西, 應該是指處理程序的意思。

我大膽猜測, 這位將簡體中文轉為繁體中文的編輯並不懂他現在在編輯的書籍是難得的中文大作, 本書被他做成這個樣子, 要是有一天他突然懂 OS 了, 應該會很後悔自己把這本書搞砸了。

這是我要購得原文本的第二個原因。

書中第三章的保護模式介紹我非常喜愛, 這應該也是入門的門檻之一, 得先過了這關, 後面才有得玩。在 dos 環境下可以寫程式完成一個功能的測試, 從進入保護模式、權限切換、ldt 的使用、分頁表 ... 得把這些程式都看懂, 執行過一遍, 那才能稱上了解了 x86 保護模式。不過我看得異常辛苦, 這章的知識實在是太硬, 我已經挑戰好幾次, 總算有點懂了。

作者將硬體特色做了簡化, 並提供程式碼來測試, 讓讀者有所體會, 不過就算這樣, 我相信要突破這關, 也不容易。

其實在我真的會用 bochs debugger 之後, 我才有所體會, 之前的冥想, 實在是太困難。我愛死 bochs 了。

我遇到的一開始困難點是組合語言, 我不會組合語言, 第三章有關組合語言的程式碼實在讓我大吃苦頭, 但在努力學習之下, 我還是不會組合語言 ... 冏。

不過那沒關係, 只要學習到能夠寫 OS 的部份就夠用, 等建立好 c runtime 環境, 再來使用 C。這邊是我自己的苦工, 很辛苦才搞懂, 所以才有 c runtime 系列文。主要是在談, 寫 os 時通常第一行程式碼是組合語言, 那什麼時候才能用 c 語言呢?要做好什麼準備才能用 c 語言呢?這可讓我吃了不少苦頭, 參考幾本書在加上手動反組譯執行的程式碼, 才讓我了解。書上這段沒有寫得很清楚, 其實 30 天打造 OS!作業系統自作入門也沒寫得很清楚, 當然 c runtime 系列文 也沒寫得很好, 有空再來補上。

大概提一下要做的事情:

  • init bss.
  • init stack.
  • 在 x86 上使用 x86 Protected Mode Flat Memory Model 還要把 %cs, %ds, %ss 設為同一個值。

其他平台會有不同的差異, 例如我在 coretex-m3 上的 c runtime 環境, 就很不同於 x86 的 c runtime。

就算這樣也不輕鬆, 畢竟操作 gdt 切入 x86 保護模式, page tabe, idt, 這些組合語言指令在一般的 os 環境下, 根本不會用到, 要熟悉他們其實是很困難的。還有 x86 其特有的 segment 定址方式, 在記憶體內容的變數, 幾乎都和使用 C 語言宣告變數不同, 每每總是將錯誤的位址填到所執行的組合語言指令, 如何 debug 也是很麻煩的問題, 我試過書上幾種方式, 成效總是不章, 還是靠著很多苦功才找出錯誤。後來學會使用 bochs 的內建除錯器, 總算大幅降低我除錯的痛苦。

堅持使用 gas at&t 語法也讓我的學習之路上佈滿荊棘, 我非常堅持要使用 gas at&t 語法, 偏偏這本書使用的是 nasm intel 語法, 好在有杨文博的版本, 讓我一步一步把本書的程式改成 at&t 語法, 也當作是 gas at&t 的練習, 現在我已經比較習慣 at&t 的語法了。

第三章我應該讀了有超過一年 (陸陸續續, 從第一版讀到第二版), 有連續的時間閱讀比較會有進度, 我總是看了又忘, 忘了又看。

process 一章花了我不少的腦力, 這是第二關, source code 之前沒有秘密, 透過 bochs 一步一步的追蹤組合語言指令, 終於了解 process 切換的秘密。 不過一次要吸收 timer 中斷和 process 複雜的堆疊切換, 實在痛苦, 卡關好久之後才能理解, 要寫好這段程式似乎不容易, 總是有著其他錯誤, 久久無法排除。

基本上能完成 process 切換就可以說自己寫的程式是 os 了, 雖然還沒有 ipc, 檔案處理, 記憶體管理, 但這已經和一般的程式有所不同了。

鍵盤驅動程式比我想的還要複雜, 若螢幕顯示的難度是 1 的話, 鍵盤驅動程式大概是 10 吧!程式碼複雜許多, 會用到類似 finite state machine 的觀念, 不過比起 process 切換, 容易多了。最後會完成一個 tty。

IPC 使用的方式是類似 micro kernel 的方式來實作, 和 linux monolithic kernel 方式不同, 這邊也算好理解。

不過在實作上, assert 和 panic 這兩個 function 就讓我頭大,  花了不少時間, 之前第六章的內容幾乎都忘光了, 重新複習果然很痛苦, 這兩個 function 有些部份和第六章有關聯, 忘記了趕快複習一下。

ref:  Why is Linux called a monolithic kernel?

檔案系統以及 fork 的實作也很精彩, 我終於知道 fork 是怎麼實作的。fork 需要 ipc 的知識, 所以要搞懂該章的訊息傳遞機制, 這可是第三關, 撐住後就一片光明了。不過檔案系統描述的是 ide, 並不是 sata, 這比較可惜。

這本書沒提到:
  • 沒使用 page 來做記憶體管理, 只使用了一對一 mapping。
  • 沒有 semaphore, mutex, 這些 lock 的實作。

閱讀這本書有個問題, 要完全理解書上說的並非只是讀過就好, 還需要跟著實作, 用程式碼來體驗書中的描述, 在配合 gdb single step, 才能清楚的認識這些 os code。這也是雖然我看完卻還是要繼續跟著書中的程式碼, 打造起一個 os, 而且不實作, 實在不能證明自己已經完全理解。

書中知識對於工作上來說可能沒有立即的助益, 我會花時間研究完全只是為了想「知道」 從電腦一開機就執行的 os 程式是什麼樣子, 也認為完全由自己動手完成所有的程式碼很酷, 老是用別人寫好的 library, 總覺得這程式不完全是自己寫的, 成就感不高。想從這本書獲得在工作上的即戰力效應可能不高, 又要花費大量時間學習, 只推薦給有興趣學習的同好或是學生。能在學生時代就知道這些知識是比較好的, 配合作業系統課程, 相信能建立紮實的基礎, 面試能提到這部份的學習, 應該是大大加分。

我很感謝這本書, 讓我得以進入撰寫 os 的大門, 也間接讓我了解程式碼底層, 學生時代有念過程式底層的東西 (系統程式課程), 不過我似乎沒有太多體驗, 透過程式碼的實作, 我親身體驗了這些程式, os 果然是很美的程式。

我跟著這本書, 大約花了一年的時間, 實作了 x86 上的 os (我取名 simple_os),  他是本書的簡單版本, 我只實作功能, 沒有考慮太多錯誤處理。甚至也沒有書中最簡單的記憶體管理, 而是直接切一塊來使用。檔案系統我也不是使用書中範例, 我沒碰 IDE HD, 而是使用 romfs ramdisk 來實作, 由於我已經突破 kernel 只能有 1MB 的限制, 所以我的 ramdisk 可以大一點。

總計實作:
  • process switch
  • system call
  • ipc
  • task process
  • 使用 ring0, ring1, ring3
  • filesystem
  • fork/exec/wait/exit
  • 不使用 bios call, 進入繪圖模式 (這可是我很得意的一點), 秀了幾張圖片和中文, 也可以在繪圖模式和文字模式來回切換。
  • 使用 unreal mode 載入超過 1MB 的檔案
少了什麼呢?
  • lock 機制, 用來保護 critcal section, spinlock, mutex
  • mmu pagine
  • 存取硬碟
  • 還有很多很多 ...
這些都是我要繼續補完的部份。

學習 os 強迫我自己學會了很多底層知識, 在軟體上還有什麼比 os 還底層呢?大概剩下 vm 程式而已。所以若不搞懂很多底層知識, 也無法寫出 os, 需要哪些呢? 太雜了, 自己做就會知道了。

這個 os kernel 學習過程大概花了一年, 不過中間還跑去搞 c++ runtime (我愛 c++ 嘛), jmcce, 而在更久之前就有在摸, 只是功效不大, 還是需要一大段專注的時間才能把 os 學習好。我堅持一人完成這些東西, 我不是在做一個 os, 我是要學習寫一個 os, 自然都要自己來, 和別人合作或是從已有的程式碼開始, 那這樣的學習就不夠完整了。

我知道有人想藉由學習 linux 來搞懂作業系統, 我也有過這樣的經驗, 不過成效不章, 我從 linux kernel 2.0, 2.2, 2.4, 2.6 的書一路買來 (一路賣掉), 甚至還買了 linux 0.11 的學習書籍, 但總是對於 linux/os 沒有突破性的認知。想用這個方法學習的朋友, 你得先定義, 你是要學習 linux, 還是 os, 如果是 linux, 那就硬著頭皮去看吧!如果是 os, 那有更好的方法可以學習, 就是看這本書。

我自己的經驗, 看 linux 0.11 的程式碼都不容易了, 更何況是抽象化更高的新版本, 程式行數更多, 連要找到要看的程式碼都是問題了, 還要面對不熟悉的 cpu 硬體程式碼, 還有 AT & T 語法的組合語言, inline assembly, 這些關卡可都不容易突破。

化繁為簡是我的學習方式, process switch 這一系列文章就是一例。我使用了最少的程式碼, 完成了 process/context switch, 這是我濃縮的菁華, 是我目前很得意的系列作品之一。作業系統之前的程式也是。能寫出這些文章都是因為我靠著本書學習如何完成一個作業系統, 進而讓我建立底層技術的基礎, 站立在這基礎上, 我的學習突飛猛進, 鑽研其他的底層技術似乎也沒那麼困難了。

我沒在玩 shellcode, 不過看到討論區的問題, 憑藉著學習 os 時獲得的基礎, 竟然也勉強可以回答, 這可真是額外的收穫。我得說我學得很辛苦, 但收穫遠遠超過我的辛苦, 還好我撐過來了, 我知道也有人在努力學習 os, 但是最後因為很多原因沒有成功, 那真的很可惜, 還在努力的朋友, 請堅持毅力下去, 像我這樣平凡人的等級都能靠著毅力學到個皮毛, 你也一定可以的。我有多平凡呢? 我的英文不好, 在學習過程中, 我 80% 看中文資料, 20% 是英文資料, 我不是很容易從英文資料獲得資訊的人, 也還好 os 夠古老, 不用最新資訊就可學習。

debugger 的使用很重要, 我幾乎常常在 bochs, qemu/gdb 中使用著 single step, 這又是平凡的證明, 我沒有像霍金的思考能力, 能想出所有執行情形, 只能靠著 debugger 的環境, 慢慢理出有問題的程式碼。

我竟然忘了這本書:《自己動手寫嵌入式操作系統》


這是用 nasm/vc++ 開發的 os, 作者之前是使用 nasm/gcc, 不過因為不熟悉 gcc, 所以改為使用 vc++。對於台灣繁體版本, 我有個疑問:

自己动手写嵌入式操作系统 - hello china
自己動手寫嵌入式操作系統 - hello taiwan
到底書中範例 os 是 hello china 還是 hello taiwan?

我已經確認過了, 是 hello china, 翻譯不應該把人家的 os 名稱也改掉吧!

不過先不管, 裡頭第七章 (7.4/7.5) 提到 semaphore 的實作, 以及如何使用 vc 來開發 os, 這是我覺得對我最有用的部份, 在另外三本都沒提及這主題, 而這需要使用 cpu 提供的 testingand-setting 指令 bts, process switch 需要用這指令來保護 critcal section 的實作。分別說明了單 cpu, 多 cpu 的實作方式。單 cpu 可以藉由關掉中斷來處理這問題。我已經找尋這實作方式很久, 也已經在 cortex-m3 實作出類似的功能, x86 則還沒實作過, xchg 也提供類似的功能, 不過現在似乎都建議使用 bts 來實作, 沒想到這本書提供了我如此重要的資訊。

7.6 則說明在 power pc 下如何使用 lwarx/stwcx 來實作保護 critcal section。

chapter 9 則提供了 pci bus 的實作, 也是非常有用的一章, 另外 3 本都沒有這個議題。




這是 Orange's 一個作業系統的實現 google group 論壇: https://groups.google.com/group/osfromscratch/topics

官網: http://www.osfromscratch.org/homecn

這是百度的討論區:
http://tieba.baidu.com/f?kw=%D7%D4%BC%BA%B6%AF%CA%D6%D0%B4%B2%D9%D7%F7%CF%B5%CD%B3&fr=wwwt

好友 lon 找到難得的繁體中文介紹保護模式的文章: http://www.csie.ntu.edu.tw/~wcchen/asm98/asm/proj/b85506061/table_of_contents.html

這本是 operating systems design and implementation, 本書作者于渊和 linux 作者 Linus 都有參考它來開發他們的 OS。minix 就是 Andrew S. Tanenbaum 在書中的實作, 有簡體中文版本, 看完 Orange's 一個作業系統的實現可進階再看這本。



 也許我應該還要提一下, Programming the 80386, 這也是 Linus 參考過的一本書。

John H. Crawford (Author), Patrick P. Gelsinger (Author) 是 the chief architect of the Intel 80386, 很有說服力的書吧!




保護方式下的80386其編程
(Programming the 80386
簡體中文版本)

80X86保護模式高級程序設計


ref:

6 則留言:

  1. Though a lot of tech terms are quite different in China and TW, at least you can guess...

    After all, please read Simplified version. Much better. Many guys do NOT know how to translate from zh_CN to zh_TW

    回覆刪除
  2. 台灣好的出版社也可以將簡體中文書籍製作的很好, 像碁峰的程式設計師的自我修養:連結、載入、程式庫。或是大話資料結構。

    哪些出版社用心, 讀者們一清二楚, 出版社不要砸了自己的招牌。

    不過看完這本的繁體中文版本, 的確會想買簡體中文版本來看, 只是台灣要買到簡體中文版本來看並不容易, 甚至連中國本地都不好買了。

    回覆刪除
  3. 謝謝大大的說明歷程,又給我一絲的希望

    回覆刪除
  4. Orange 這本書找不到....不知大大是否願意割愛,或借我拷貝??

    回覆刪除
  5. 許博翔你好,
    不好意思, 只能請你到圖書館借閱了。或是到二手圖書試試運氣。

    回覆刪除

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。