寫一個操作系統內核有多難?大概的內容、步驟是什麼?

Linus Torvalds以為他自己如何如何了? 鏈接中人有說到

「一個好一點兒的計算機碩士畢業的學生。
寫一個操作系統的內核絕對是應該辦到而且肯定可以辦到的事兒。」

是這樣的嗎?如果真的要去寫一個操作系統的內核,大概可以分成幾個任務?大概是怎麼做的呢?

(可以請用只懂計算機基本原理,懂一點點硬體和一點點軟體的人能看懂的水平解釋)


2015.12.3 更新

更新下第二版的代碼地址:

hurley25/Hurlex-II · GitHub


第二版在硬體機制上沒有增加多少東西(簡單的忙等待的IDE驅動,簡單的鍵盤驅動),主要是策略上和代碼上做了一點點優化,參考了Linux內核的一些命名和代碼(比如2.6內核的夥伴演算法簡化後添加進來)。


--------------------------------------------

厚臉皮推薦自己基於《JamesM"s kernel development tutorials》寫的中文文檔,如果你只有基本的C語言和彙編基礎以及一點點操作系統理論的話,這是起點很低的入門讀物了。

項目地址:Hurlex-doc by hurley25


PDF 文檔以及對應的 Latex 源文件(那會只是剛開始學著用Latex,不規範的地方請見諒)也在git倉庫里一併提供(可以免費複製傳播,請不要用於商業用途)。git倉庫里甚至按照章節的形式提供了每章節結束後代碼的樣子(文檔里不是全部代碼都貼),以供參考。


懶得下載可以看在線版: x86架構操作系統內核的實現


在線版是markdown格式轉換的,遺憾的是markdown格式的源文件被我搞丟了。。


補充一下文檔目錄:

  1. 項目概述和開發環境配置
  2. 計算機啟動過程、GRUB 以及 multiboot 標準
  3. 裸機上運行的 Hello OS Kernel
  4. 字元模式下的顯卡驅動
  5. 相關庫函數和調試列印函數
  6. 添加全局段描述符表
  7. 添加中斷描述符表
  8. 完成中斷請求和定時器中斷
  9. 物理內存管理的實現
  10. 虛擬內存管理的實現
  11. 內核堆管理的實現
  12. 內核線程的創建與切換
  13. 接下來如何繼續學習

------------------------------------------

這個東西很難被稱為「內核」,甚至說它是「玩具內核」都是繆贊了。這只是一個看起來能運行的原理示範性質的小程序。不過不可否認,按照文檔來,你可以寫出一個看起來挺好玩的東西並學到一些基礎知識。

雖然一個真正的內核很難很複雜,但是一個簡單的Demo並不是遙不可及。即使有興趣,學習的過程中也需要樂趣和不斷獲得的成就感,不是嗎?

祝你玩的愉快~


不是太難,關鍵還是需要興趣,如果你真的想刨根問底,沒什麼能擋住你。


最基本的有幾個部分:
1 bootloader, 你是用個現成的grub還是自己寫,很多人就倒在這一步了。
2 內存管理
3 進程管理
4 中斷和系統調用
5 文件系統

當然可以折騰的很多,但最好還是先把這些弄出來,才可稱之為一個操作系統。
資料都有,你可以參考:
Expanded Main Page JamesM"s kernel development tutorials

xv6的代碼也不錯,文檔齊全,Xv6, a simple Unix-like teaching operating system

Orange"S:一個操作系統的實現 (豆瓣) 可以參考,只是有很多部分其實可以不用彙編寫了。
James的那個教程還是入門最好的。

在Github無數個人在折騰自己的Hobby OS:Open Source Operating Systems

SamyPesse/How-to-Make-a-Computer-Operating-System。

比如我當年的小項目: chenyukang/Panda,

有的完成度還是比較高的,比如klange/toaruos總共花了六年時間才做出一個基本可用的有圖形界面和網路的 OS。redox-os/redox是一個 Rust 寫的微內核的 OS。

你要做的就是準備好時間,做,看,做,看...

我的建議是可以自己花些時間做一個簡單的 OS,哪怕是拼湊出來也好,就是為了體會一下編程的石器時代,而後還是選擇自己感興趣的模塊,看看成熟的操作系統是如何做的,畢竟人的精力和時間是有限的。


一般計算機的本科生(大一的會點C語言,有點耐心,3個月)就可以了。。。
有一本日本人寫的書叫《30天自製操作系統》一步一步帶你寫出一個操作系統內核(可以寫到光碟上,從光碟啟動,第一節就叫你如何實現一個「hello,world」),一般計算機的本科生(就是會一點點C語言的那種理工科生),有點耐心的話,每天2~3小時,三個月基本能夠看完,跟著擼出一個操作系統內核。根本不需要什麼碩士水平。不需要前面說的各種文檔。事實上作者的目標甚至是中學生也能看得懂,感覺基本做到了(最後也就幾十k的代碼)。寫完之後會很有成就感
我的第一本計算機厚書就是《30天自製操作系統》。寫出來有什麼滑鼠鍵盤輸入,漢字顯示(書中是日文顯示,由於日文中有漢字,所以其實可以算漢字顯示),多進程(多任務),段頁式內存管理,各種驅動,定時器,文件系統(讀硬碟,文件目錄和內容讀取等),窗口,音樂播放,內核保護,api,小遊戲,圖片播放,應有盡有。。。如果大學能夠跟著寫完,絕對,畢業面試的時候能吹噓一下。。。當然裡面的c語言編譯器不是自己寫的(編譯器工作量真不小)。。。
我當初就是看不慣國內那些書在那裡裝比,沒有真正的拿得出手的科研成果,然後在那裡裝比的各種著作。然後人家這本,哈哈,真的就能夠跟著擼出一個操作系統內核,而且,絕對是效率不錯,結構可以的東西。。。而且人家通俗易懂,很有誠意,比起那些複製粘貼強行裝B的書不知道要強多少倍。。。跟著做完內核保護和api的話,還能加深理解。
我的意思是,你完全可以自己快樂地把一個操作系統內核給讀懂,在半參與的狀態下做出來,玩一玩,不用一開始就想的那麼高深和神聖。。最後跟著一起寫api,玩遊戲,理論+實踐,輕鬆+愉快。。以後如果有興趣可以去讀linux的東西,去搞點其他的。。。愉快的成長
而不是一本厚書接著一本厚書地啃,啃了半年也看不到一個hello,world和桌面,最後感嘆一句放棄。那樣很無趣,很苦逼。

----------------------------------------------------補充分割線------------------------------------------------------
本書的某些代碼的確不算完美,有些地方甚至比較幼稚,作者為了照顧初學者,會故意不用某些高級的成熟的開發技巧。。。這是本書的缺點,也是本書的優點。因為本書的定位就是那些沒啥基礎卻又好學的新手。
最後如果你在讀那本書,請一定要看第18頁,不要去買軟盤(我當初就TM沒細看,去買了軟盤還有軟盤讀盤的那種古董級別的東西,結果看到第18頁吐血了,葵花寶典:第一頁:「欲練此功 必先自宮」,某人狠下心,咔,第二頁「若不自宮,也能成功」,連想艹都不能)。。。
----------------------------------------------------補充分割線------------------------------------------------------
我的文章受眾是普普通通的計算機專業的本科生(我也是計算機本科生畢業)(各位研究生大大們,見諒)。。。希望哪怕有一個人能夠通過這本書,開始寫一點代碼。我讀大學的時候見過太多人,張口閉口比爾蓋茨,扎克伯格,卻不知他們的偶像還寫過不少代碼。。。他們沒事情會去看「燙燙燙,屯屯屯」的由來,也不願意去寫幾行C語言代碼。他們會去看各種Linux的花邊故事,也不願意自己看看操作系統的基本結構。。。學校里也是,你還沒弄個網站就有一堆教授跟你說:三大框架,並發優化,彷彿一開始弄,就要弄到標準,弄到一個水平。。。
我只希望,有人能夠去踏踏實實地去看點書,去寫點代碼,而不是看了知乎的「寫一個操作系統內核有多難」之後,記住幾個名詞然後回去吹牛,我希望,他們能夠自己開始動手去看,去跟著寫,去發現,去收穫。


寫個玩具內核不難,固然學習與理解需要花費比較長的時間,但總體而言本科碩士的知識面已經足夠了。關於內容和大體步驟,當時寫了一點東西,如果感興趣可以作為參考:基於 Bochs 的操作系統內核實現

寫個玩玩還是挺超值的,對得起上學沒處打發的時間。

ps: Linus 可比一般的噴子腦殘之流憑他們可憐的想像力所沾到的影子牛逼多了。


邀請 @於仲智 來回答。

折騰了半個學期 + 4個人能搞出來,還帶了一個基本的 GUI。

光在 GUI 里顯示滑鼠就直播 coding 了 7 個小時……
Rendering mouse ...
GitHub - TakefiveInteractive/TedkOS: Operating System


現在不少人都在通過自己寫內核來學習操作系統,網上還有專門的課程(6.828 / Fall 2011

/ Schedule),按照這個課程,幾個月就可以完成一個功能還算完備的內核.

但是這些人可以自己用幾個月的時間寫個內核,建立在當下相關資料特別豐富,而且虛擬機調試特別方便的基礎上的.用bochs(雖然我自己從來都沒有整好過),qemu,可以輕鬆進行彙編級調試,qemu還可以利用gdb remote debug來進行源碼級調試.

但是倒退到Linus那個時代,一個人寫內核的,絕對是絕頂高手,因為當初沒有什麼相關資料,大概就幾本書可以參考,MINIX那本,UNIX內核設計與實現等.而且調試非常不便,只能靠自己把代碼寫對,非常非常的不容易.


最新回復

當時我感冒了,回家呆了半天,然後寫了這些東西。
當時2013、2014年完成了一些技術攻關,2014、2015年一直到廣東省科技創新大賽前基本都還在做,省賽意外失利後就沒繼續做了,所以到寫這些東西的時候,已經過去了將近一年,每個功能具體入微的實現、當時對其他系統的研究、一些設備的支持啥的這些細節都已經忘得差不多了,只剩下那個時候開發的整體印象。所以這篇文章沒有給大家帶來更多的知識真是不好意思。
我的博客http://hwj.me我其實蠻少用的,最近才想再次去使用它,所以那裡也沒有太多的東西給大家。
有人說PS的,我也表示理解,畢竟就一個圖放在這,喜歡搞大新聞的人也蠻多。這裡就放一個視頻表示真實性吧。
鬼鳥操作系統的簡單演示(for 知乎)
視頻封面鬼鳥操作系統的簡單演示(for 知乎)—在線播放—優酷網,視頻高清在線觀看視頻

至於有人說那個按鈕的單詞打錯了,這個好像當時也有人說過,忘記改了……當時我的英語水平剛剛從不及格到及格,這種錯誤犯了不止一次,包括在一些函數中。

有人還說這些東西不牛x,我說真心話這的確不牛x,這篇文章也並非炫耀。只是解答上面這個人的問題罷了。希望更多人能夠到達自己要到達的山峰。

目前高考結束了,我最近在試圖去研究AI,這個操作系統(包括內核)也會進行不斷的更新。

-------------------------------------------歷史分割-------------------------------------
我很想回答這個問題。 我是一個高中生,自初中開始就想做一個操作系統,並付諸於行動。 我們製作的操作系統 鬼鳥操作系統,使用自己實現的 探索者操作系統內核,已經完成了基本的功能,外加一個不錯的圖形用戶界面。

上面這個圖就是我們操作系統在VMware虛擬機裡面的運行截圖。 其實說來做操作系統,你需要首先掌握一些基本功,我在初中的時候已經學習了x86的彙編語言,在高中的時候,在正式做系統內核前,我完成了兩三次每次2-3000行的彙編技術驗證代碼,對彙編語言,函數思維,很多設備的特性和諸如參數傳遞這類眾多小技術細節都有了較為詳細的理解。

上面這個圖就是我們操作系統在VMware虛擬機裡面的運行截圖。 其實說來做操作系統,你需要首先掌握一些基本功,我在初中的時候已經學習了x86的彙編語言,在高中的時候,在正式做系統內核前,我完成了兩三次每次2-3000行的彙編技術驗證代碼,對彙編語言,函數思維,很多設備的特性和諸如參數傳遞這類眾多小技術細節都有了較為詳細的理解。

類似這樣的基本功必不可少,我可以用彙編實現整套操作系統,但是考慮到可移植性,後續維護,我們到後期還是用了彙編和C混編的方案。除此之外,因為操作系統運行環境和應用程序運行環境著實不同,這些基本功對於我們進行操作系統設計,調試都是極其重要的。

除此之外,畢竟操作系統是個大工程,在做這個東西的時候,我們力量小,這時就需要我們有聰明的開發策略。打個比方,現在商業級操作系統的文件系統部分所佔代碼量可能就已經超越眾多小型操作系統總代碼量了,個人或者小團體開發的操作系統,真的不能過多關注單一的功能,人家的東西是按商業化考慮的,你就按照實現的角度考慮就行了,哪怕你的一些做法功能不會像人家那麼好,一些優化演算法不如人家那麼有效,但是到真正的需要你考慮其效能問題的時候,你們的操作系統已經非常大了,那時候進行商業性的設計,比現在的更方便。

做操作系統,最關鍵的是,要在大的功能上均有所實現,在人少力量弱的情況下,小功能不要追求完整。只要能夠支撐下個功能的實現就行了。例如,實現內核模塊動態鏈接功能,至少需要在文件系統方面實現文件讀取,能讀取文件才能支持後面對elf格式分析,重定位等一堆功能實現。但是這並不意味著你需要在百忙中追求文件系統中長文件名的讀取這類只有用戶才介意的功能。

操作系統包含的功能面多,對於我們而言,不可能一開始就學完所需要的各個知識,各種標準規範協議,實際上大多數情況下,你需要邊學習,邊借鑒,邊設計,邊研發。在這個情況下,你需要清晰的知道自己需要完成哪些功能,對於這些功能,你要有清晰的了解,然後以這些功能實現為主線,博覽群書,看看民間的方案,linux和Windows的方案,然後再設計自己的方案。我接觸過的很多人,邊看30天自製操作系統邊做,或者Orangs 一個操作系統的實現 ,哪怕是一些更加專業的書籍,也會有一些不足和局限,如果對自己做的功能不了解,只能深陷於這些書的坑。

就說這麼多吧,我的qq 2322869088,個人網站胡文傑的小站,時間不早了,還有80多天就高考了,希望這篇文章能給大家說明一些事情。還有,對於985 211院校,憑著操作系統參加自主招生容不容易一本線錄取?

稍後這個文章會被複制到知乎其他文章中。


儘管上面很多人說寫一個操作系統內核是比較簡單地事情,但是,如果你只有一點點軟體和一點點硬體基礎,那麼我可以放心地告訴你,這絕對不是一件很簡單的事。除非你指的操作系統就是一個稍微能控制一下資源或者稍微能運行幾個進程的簡單東西而已。

在寫操作系統之前,你就清晰地明白操作系統是要幹什麼用的。操作系統對應用程序提供了硬體層面的抽象;負責管理包括CPU,內存,磁碟,IO等硬體資源,以及進程表,文件打開表,頁表等軟體資源;負責提供應用程序可用的API和系統調用;負責保護硬體資源和軟體資源的訪問安全和隔離性;以及提供多用戶支持等等功能。那麼在寫一個操作系統之前,你就得保證你所寫的操作系統滿足必須滿足的要求:魯棒性,可擴展性,高效性,豐富性,安全性。先不說後幾條要求,僅僅魯棒性一點要求,都能把一個程序員折騰很久(呃,我這個菜鳥程序猿就被折騰了很久)。

當你明白了理論上的代碼要求,你可以開始琢磨寫一個簡單的操作系統內核。至於你說要分為那幾步。我的拙見是,在你動手寫之前,你又必須給自己一個規劃,這個規劃就是:從實模式到保護模式一步一步的推進,從微內核到單內核的推進,從實驗到簡易實用的推進…

當你開始寫實模式的操作系統內核時,你得要會一下這些必須知道的知識:(哪怕一點點)

  1. 操作系統啟動原理,也就是bootloader的作用,包括魔數,MBR等等
  2. Intel 彙編或者ATT 彙編或者嵌入彙編。這裡面需要使用到int中斷,簡單的算術操作指令,跳轉指令,開關中斷指令(你只需要知道一點點,完全不用看intel手稿)
  3. DS,ES,SS,BS,SI,DI,AX,BX等等寄存器的使用和工作原理,這是實模式下唯一需要了解的一點點微機原理知識。
  4. 信號量,消息同步以及中斷屏蔽的知識。這一部分會讓你更加清楚地了解到Linux單內核的NB之處。
  5. 系統調用,進程切換,內存分配,磁碟訪問布局,文件系統。系統調用包括read,write,fork,exec,wait,exit這些最基本的系統調用(甚至不用去看dup,dup2,wait2等等暫時無用的),進程切換了解pcb管理,內存就了解最簡單的分配方式,文件系統就是inode節點結構(甚至不需要考慮超級塊等等)。

當你進步到保護模式的時候,你就得額外學習其他的知識了,這些知識包括但不限於:

  1. 地址轉換的概念,段頁的概念,頁表訪問,MMU,TLB等原理。
  2. 什麼是內核模式,什麼是用戶模式,ring0~3是怎麼具體保證的的
  3. EAX,EBX,ECX等等通用寄存器以及控制寄存器,GDT,LDT的概念
  4. 更高級的內存分配模式,例如slab或者懶惰夥伴分配等等。
  5. 更高級文件系統,ext3,ext4等等。

當你又從微內核進步到單內核的時候,你需要考慮:

  1. 微內核中一些模塊如進程分配服務,內存分配服務,文件管理服務,設備驅動服務如何集成到內核,哪些可以集成到內核,哪些不能。
  2. 自旋鎖,信號量,消息同步的有什麼區別,如何避免死鎖。
  3. 單內核的系統調用和微內核系統調用的區別等等。

當你從實驗進步到簡易實用(只是簡易而已,暫時還不包括網路資源管理,這一部分涉及到TCP/IP協議棧,更加複雜)的時候,你需要考慮:

  1. 操作系統效率以及安全性問題,這裡面涉及到進程調度,內存管理演算法,磁碟調度演算法等等方面。
  2. 系統調用的豐富性問題,是不是支持大部分的系統調用。
  3. 基本應用程序的支持性問題,例如shell,cat,wc,cd,ls這些簡單的總要支持。
  4. POSIX標準的支持問題,能不能支持編譯運行一些原始版本的程序。

總而言之,對我這樣一個剛剛研一的不是研究系統架構的人來說,寫一個操作系統內核也並不是一個非常簡單的事情(儘管我們在大二的時候就已經寫過了)。我仍然需要花很多的時間查資料,看文章,向我的一直奮戰在一線的參與Linux以及KVM內核維護的可愛的bash老師(他在我們的學校bbs上的ID叫bash)請教,我仍然能夠從中學習到很多很多以前沒有學習到的知識。

所以,寫一個操作系統並沒有很多人說的那麼簡單,當然這樣的說法有點冒犯了上面一些說比較簡單的大神們^-^,還請包涵,畢竟我代表的是平均智商,哈哈。當然如果我自己的一點點粗淺的理解能夠幫助到lz,那就比較好啦…


這個不難。寫個小內核的,僅有有限的任務調度功能的操作系統,讀完CS專業大學三年級的課程即可。目標平台可以是真實的,也可以運行在Windows Console下。這種操作系統有很多,比如ucOS,rex,FREERTOS,等等。


最初程序員們都是紙帶機啥的上面寫點0和1。後來寫寫彙編,都是針對硬體直接編程。也不區分什麼內核應用什麼的,都是一個線串下來。

硬體遵循摩爾定律發展了一陣兒之後一根筋的程序裡面就得弄一大堆中斷響應。也就是說程序執行的過程中,需要讓CPU停下來干別的更重要的事兒的情況多了起來。慢慢的程序結構複雜了起來,人們覺得需要做點基礎工作讓寫代碼的時候不必關注多中斷調度啥的。還有就是一次要乾的事兒多了,幾個事兒不能光靠外部中斷進行切換,得讓它們有個內在的秩序。於是就有了任務調度。


再後來大家覺得光有任務調度的代碼還不夠。最好內存管理也能簡單點。還有存儲設備,一個勁兒的對一個塊讀完了擦,擦完了寫,特定的塊會掛掉。諸如此類的需求不斷出現。於是就有了內存管理和設備驅動。


慢慢的發展下來大家覺得這部分代碼是非常重要的。要區別於它們所服務的代碼。就有了內核和應用的區分。早期的應用和內核是在一起編譯的,後來有了可執行文件這樣的設計,就可以分開了。


上面的例子可能不夠準確。大家輕拍。


回到正題。操作系統是為了解決計算機科學技術發展中遇到的實際問題。分幾個步驟,要看題主想解決幾個問題,也就是有什麼樣的目標。


不難,會C語言,學過操作系統原理,自己慢慢摸索,總能寫出來的……表示大二下的時候,旁聽計算機的嵌入式操作系統課,然後寫過一個基於優先順序調度的RTOS,跑在STM32上,沒發現了什麼bug,但是問題在於並沒什麼卵用,只是為了好玩而已。當時如果真的深入進去,花大時間去寫個跑在x86上的,估計也是行的,但是還是沒什麼卵用……這些寫操作系統的也僅僅是為了練練手,熟悉熟悉理論而已,花的時間多,還沒意義。你要知道,嵌入式RTOS到處都有,freeRTOS,ucos等等,完善的一比,要你寫的幹嘛?像linux這樣強大的,還要你寫的系統?有時間去學學java,web,找份互聯網的工作比在那花時間寫操作系統這類扯淡的事實在有意義的多……


借這個問題,正好把自己以前走過的總結下。

zero to one
大學的時候,一心熱血,想著寫個自己的簡單操作系統,剛開始也是一臉茫然,首先接觸的也是這份文檔《JamesM"s kernel development tutorials》JamesM"s kernel development tutorials,對著作者的blog,特別有意思,很多概念都不是很清楚,慢慢查,在學習完之後,對操作系統簡單的有了輪廓,bootload, GDT IDT, 內存管理,文件系統等等。

microkernel vs monolithic
隨後認識了有一種更新的理念(當然現在不新了,對當時對我),微內核,發現內核OS,原來還能有另一種(非Linux宏內核的)設計,我們看的很多教程,多少天寫操作系統,包括前面的JamesM"s kernel development tutorials,都是類unix實現,本質上設計的思路和框架都類似。微內核則是把很多原來集成到kernel的模塊,通過IPC的方式,變成一個個services跑在用戶模式下面,這樣大大增強了可擴展性和內核的穩定性。

這塊精妙的設計,當我後來看到 erlang中的actor 模型的時候,想到就是microkernel的設計,如此相似。

這塊精妙的設計,當我後來看到 erlang中的actor 模型的時候,想到就是microkernel的設計,如此相似。

在接觸Linux的時候,曾經看到的有關Linus和Minix作者關於微內核和宏內核的爭論,讓我首先接觸到Minix,但是水平不夠,讀起來比較吃力。

後來發現了FreeNOS,用C++寫的基於微內核的操作系統,通過學習這個項目,又對操作系統,軟體設計,設計模式等等大開腦洞。

FreeNOS
lordsergioinspa/FreeNOS · GitHub
這是一個用C++實現的微內核的操作系統,各種宏內核中的服務作為一個獨立的services在微內核中,基於消息的通信方式,這點其實跟Mac內核中的mach那部分機制相似。
除了是一個操作系統的實現,另外從中也能很好的學習到OOP的設計方式,整個代碼風格特別好,完全基於面相對象,還有一些常見的設計模式,在接觸了這個開源項目之後,才了解,代碼風格,注釋,doxygen,scons,設計模式。
不僅涵蓋了所有的操作系統的設計,學習,更接地氣的包括了各種優美設計。

Exokernel微內核
http://pdos.csail.mit.edu/6.828/2005/readings/engler95exokernel.pdf

新一代的微內核,MIT出品。

Exokernel微內核的核心觀點是:只要內核還提供對系統資源的抽象,就不能實現性能的最大優化 -- 內核應該支持一個最小的、高度優化的原語集,而不是提供對系統資源的抽象。從這個觀點上來說,IPC也是一個太高級的抽象因而不能達到最高的性能。Exokernel微內核的核心是支持一個高度優化的原語名叫保護控制轉移(protected control transfer, PCT)。PCT是一個不帶參數的跨地址空間的過程調用,其功能類似於一個硬體中斷。在PCT的基礎上,可以實現高級的IPC抽象如RPC。在MIPS R3000處理器上,一個基於PCT的RPC實現了僅10μs的開銷,而在同一硬體上運行的Mach RPC為95μs。

對磁碟的處理,跟微內核的比較

堅持成長,更多的不在於結果,關乎過程。共勉~


我來寫一個如何在15天內完成一個嵌入式實時操作系統,並移植到stm32單片機的攻略吧。第一次看到這個問題是在大概兩個月之前,從那時候開始決定自己也寫一個操作系統,於是開始看os的基本概念,進程切換,任務調度,內存管理,任務通信,文件系統等等。

我來寫一個如何在15天內完成一個嵌入式實時操作系統,並移植到stm32單片機的攻略吧。第一次看到這個問題是在大概兩個月之前,從那時候開始決定自己也寫一個操作系統,於是開始看os的基本概念,進程切換,任務調度,內存管理,任務通信,文件系統等等。


前言:
大約在兩個周不到前動手,平均每天7個小時,從完全不知道怎麼下手(真的快哭了),到現在完成了一個----基於優先順序時間片調度,具有信號量,消息隊列,內存管理的嵌入式系統並命名為--LarryOS,並且移植到stm32(Cortex-M3架構)上,還在stm32上實現了一個malloc和free函數,受益匪淺。現在還正在完善。我是用自己命名的,當然,大家寫好了也可以用自己命名,圖個開心么 ,想想是不是很激動啊。

對於這個問題下的回答的看法:
大神真的好多,幾乎都是x86型的,難度真的要比我的大,不得不承認。不過,我覺得對於新手,寫那樣一個系統真的是太艱辛了,比如我這種入ee坑的在校大三學生,課真的太多了,周內最少三節課,而且和cs沒有一毛錢關係,課餘時間太少,如果花費一個學期或者三個月的時間來寫,可能有些得不償失。因為許多想寫os的朋友,和我一樣,一是覺得寫os很酷,二是想通過寫來理解os,畢竟看書看了就忘,也沒有衡量自己學的好壞的標準。因此,選擇寫嵌入式系統,是一個非常好的選擇 。

知識儲備:
這個問題想必是很多同學顧慮的,到底寫一個嵌入式系統需要什麼知識儲備?我從自己的經歷出發,並加以簡化,大家可以參考一下。

自身版:
1c語言要求:我自己在大學裡幾乎沒學過c語言,上機幾乎10道題會2道,期末全靠背。後來開始自學了c,看了c語言程序設計現代方法,c和指針 c專家編程 第一本書的課後題,做了3分之2吧,就這樣,沒了
2彙編要求:會基本的x86指令,僅僅是基本,看了王爽的彙編語言,程序寫的很少,僅僅上機課寫過
3微機原理或者計算機組成原理:老師上課太坑了實在,我自己看了csapp的前四章大概,豁然開朗,推薦這個。
4操作系統:看了三個禮拜os的基本概念,僅僅是了解概念,沒辦法深入,也沒地方。。。。
5數據結構:看過浙大的數據結構公開課的3分之2,會寫基本的鏈表,隊列,最基本的樹和樹的基本的遍歷辦法,圖完全不會
6單片機基礎:大約兩年的單片機基礎
7新手看到這裡,可能已經慌亂了。。。。不要怕,我說的很多東西,寫嵌入式系統用不到啊 ,繼續,發一個精簡版

精簡版
1:c語言 能把我推薦的c書的第一本或者c primer之類的書看個一半,或者自己本身知道指針的概念,知道結構體指針,函數指針,二級指針的用法,僅僅是概念和寫法就行了,不用深入,用不了多久。
2彙編:知道有幾條常用指令,用法和功能是什麼就可以了
3組成原理:知道中斷是什麼,入棧和出,寄存器,知道彙編對應的計算機大概動作就可以了,用不了一個周
4操作系統:找個公開課或者書,看看大概的os概念,一個周就夠了,我現在很多概念還是不知道,後面可以慢慢學
5數據結構:會寫鏈表,隊列就行了,我們不寫文件系統,不用樹
6單片機基礎:用過單片機,不用自己寫驅動代碼,僅僅可以在別人的驅動下,編寫一些簡單的邏輯代碼就行,完全沒學過的人,兩個禮拜就可以用stm32來編程了,如果之前學過51,一個禮拜不到即可,因為我們只是藉助一下單片機,避免使用虛擬機,方便操作系統的調試。因為我們可以用單片機,輸出某些信息在串口或者液晶屏,讓我們直接看到代碼的錯誤點,方便我們調試。

正文:如何開始寫一個嵌入式系統?
因為我觀察這個問題已經是兩年前的問題了,不知道我發了這麼多,大家還能看到沒,看不到我打了這麼多字就白打了。。。。。所以我先寫到這裡,確認大家能看到,還想看,我就開始寫後文吧,因為是最近的項目,所以記得很清楚,寫起來很快的,希望能看到的,想看的朋友說一聲,提醒一下我更新,謝謝了

更新:更新放在了知乎另外一個問題的回答
http://www.zhihu.com/question/25628124/answer/133388181


僅用有無獨創的內核,這個標準來評價一個程序員,是比較片面的。

如果題主的目的是為了興趣,那麼有不少教程可以讀一讀,例如於淵的《自己動手編寫操作系統》就是我入門時看的…然而大部分書只能帶你入門,之後要學東西靠得是實驗和讀手冊(例如Intel IA-32 Software Developer Manual)

如果題主更多的是為了積攢經驗方便以後工作,則只需要稍微了解系統原理,多注重如何使用現有API。因為人們對這類經驗看中的是你學沒學會一種思想,能不能知道商用系統中怎麼利用,很少有需要你自己重造輪子的。

要記住的是,一般沒人會只因為你做了一個操作系統就給你工作。這也是我忘了操作系統只是興趣後,才體驗到的教訓…希望能幫上一些人的忙…

感謝@Suji Yan邀請


我認為,某些專業的合格碩士生建造一個 Karl Benz 時代的汽車也並不難。但是我不知道這麼做有什麼實際意義。我還看到有人說:「初學者千萬不要看 Linux 代碼」「可能一輩子都看不完」。這是最最誤導初學者的言論。學汽車難道不去看真正的發動機,去看 Karl Benz 的古董?去看標準模型做的玩具?

一個 Audi 的 TFSI 發動機的細節,研究十年不一定能窮盡。但是那不意味著這台發動機的知識是不分層次的。組織合理的話,你在這台發動機上花的實踐可以和得到的知識成正比。

另一件值得注意的事情是,軟體在構建過程中的樣子,未必就是最終 deliver 的樣子。和建築一樣,軟體在構建過程中也要搭腳手架。很多代碼是構建過程中不得不用但是 deliver 之前又不得不刪除或者 disable 的。剛剛開始寫程序,甚至寫過幾年 app 的人,都不見得知道如何去運用這種 scaffold code。OS 內核恰恰是需要 scaffold code 非常多的領域。我認為,隨著軟體系統越來越複雜,真的沒有必要每一代人都重複體驗如何構建某個領域的 scaffold code。初學者更應該從成型的軟體中學習知識。

題外話:拿 Linus 開涮的人我都繞著走 —— 當經理的肯定不是好鳥,做技術的早晚摔跟頭。


嚴格來講,我們上OS課的每個人都寫過。不知道你有沒有做過jos lab,那個就是要自己寫一個內核(雖然是在既定框架下)。

要是急於寫出來的話,去看《30天自製操作系統》,跟著敲代碼就好。


內核不難,但要讓大廠商為你的內核寫驅動比登天還難。
寫文章不難,但要讓大網站把你放首頁很難。


我覺得李納斯的牛逼之處在於,他在他當時的時代能寫出來牛逼的內核。
好比,你問說,現在製造噴氣式飛機很牛逼么?現在不牛逼,但在螺旋槳時代出現噴氣式就是很牛逼!
李寫內核0.1是在90年代初,那時還沒有win95吧?你在那時寫出一個win nt內核你就也牛逼了!


一兩句說不清!
說到可操作性,去看於淵的書《自己動手寫操作系統》《Orange"S:一個操作系統的實現》。


有人推薦《自己動手編寫操作系統》,不過我還是喜歡趙炯的《Linux內核完全注釋》,用的是linux-0.11的源碼。


如果只是個玩具操作系統,那麼可能不會太難,就好比一些教學操作系統,但是如果需要考慮

支持不同的硬體架構(x86, MIPS, PPC, ARM)?

支持多處理器。

高性能(高效的內存管理,進程調度,中斷處理,文件系統,IO)。

穩定性(進程地址空間隔離,保護)

靈活可擴展的驅動框架。

那還是蠻難的。

甚至有些人說操作系統裡邊沒啥演算法,如果是玩具操作系統,那麼可能的確不需要什麼演算法,因為演算法本來就是為了滿足性能,效率等需求而產生的。但是,商業的操作系統裡邊,肯定是有很多演算法的,別說內存分配,進程調度,或者文件系統了。就算是最基本的自旋鎖,都有好幾種演算法。


推薦閱讀:

iPhone 5s 配備的 A7 處理器是 64 位,意味著什麼?
CPU 的摩爾定律是不是因為 10 納米的限制已經失效了?10 納米之後怎麼辦?
為什麼計算機能讀懂 1 和 0 ?
《黑客帝國》中的先知是人還是程序?
如何看待這篇關於人工智慧的譯文?

TAG:操作系統 | 計算機 | 計算機科學 | Linux 內核 | 操作系統內核 |