点击上方“五分钟学算法”,选择“星标”公众号
重磅干货,第一时间送达
不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统。我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识。不论是为了满足程序员们自带的成就感,还是为了面试找工作时能更深入地和面试官探讨(装逼)。
那写一个操作系统究竟有多难呢?我结合自己的经历给大家讲一讲。
写一个操作系统有多难
先说一句废话:会者不难,难者不会。
冷启动
对于零基础的人,甚至是计算机知识零基础的人来说,难。难点并不在于操作系统的代码量本身,而在于任何一个事物发展初期都会遇到的困境,冷启动。
我不知道应该看哪本书作为入门书籍,甚至不知道应该看书还是看网络上的文章,还是找一个领路者带你入门,甚至还在被一些讨论自己做一个操作系统到底有没有意义这个问题纠结着。
好多人在这个冷启动时期,就被弄得没脾气了。
你可能比较幸运,找到了一本入门书籍,刚好作者的文笔和思路比较对你的胃口,于是度过了冷启动时期。
但你也可能不太幸运,找了一本难读的书籍,或者是优秀的作品但刚好不对你的胃口,于是就从入门到放弃了。
我当时的第一本启蒙书籍,是《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、设置中断、设置分段分页、进入保护模式这些步骤是串行的,每一步都不能出一丁点错误,否则后面的步骤会被前面的步骤卡住,遇到问题没法跳过,就像你做一张数学试卷,必须从第一题开始顺序做到最后一题,而且前面的正确了才能往后继续做一样。
虚拟机崩了...
中期
千辛万苦来到中期,这里的人可能已经不多了,但到了这里你会认识一大批和你一样在挣扎的人,新世界的大门可能就此打开,所以对你来说,其实你会觉得自己做操作系统的人好多啊,而且高手如云。
因为虽然你可以按照自己的意志对写好的操作系统有一些微调,也对操作系统的各个部分有了一个模糊的认识,但总是甩不开你所看的书的影子,简单说就是没见识。
我当时呢,就被《操作系统真相还原》里的操作系统的思路舒服着,总是认为就应该把内核映射到内存高端的空间上,要用很取巧的办法设计页表。总之就是见识少,因为只知道一种实现方式,所以觉得天下的操作系统都是这个鬼样。
因为好歹是有点知识量在了,这个阶段一些操作系统领域的大牛(反正是比你厉害很多的人啦),会稍稍理一理你了,可能语气会从原来的拉黑,变成“哦”,再到现在的“嗯嗯”。
xbook操作系统开发者 b站我叫小骨头
你也会加入到一些群或者一些社区当中,认识更多的大佬。你会发现,你眼中的这个操作系统,在他们眼里就是个其中一种很常规的或者说很过时的方式而已。于是乎你在慢慢的影响下,也打开了思路,决定了解更多的操作系统。
我呢,当时的选择是阅读 linux 源码,并尝试仿写一个(最后仿写这一步放弃了)。
linux0.11源码
这我感觉,只要这一步你的选择是了解一款经典的操作系统,那还能选什么呢,只能是 linux 吧哈哈。
这一时期的书籍呢,也比较多,我的话是通过《linux 内核设计的艺术》来简单了解 linux 的整个流程和脉络,再通过《linux 内核完全注释》配合着 linux 的源码进行重点源码逐行了解,还通过和一款开源操作系统 bookos 的作者进行交流,进一步了解一个成熟操作系统需要考虑的问题。
bookos - xbook2 运行截图(来自该作者的官网)
linux 有些了解后,便通过仿写的形式来进一步加深理解。但仿写最终放弃了,因为即便是 linux0.11 的源代码,里面都非常复杂,完全仿写还是很费时间的。于是便将自己认为纯苦力的工作简化,比如 linux 会根据内存大小来划分内存区域,我就直接写死了 32M 内存。再比如 linux 支持的硬盘数是动态变化的,我就直接只支持一块硬盘,这样里面好多数组,for 循环,就都展开了,我觉得对理解一个操作系统,这些工作无关紧要。
这里说个小插曲,读 linux 源码,有时候差点没把我气死。linus 这个人太调皮了,好多地方的注释写的大概是这种风格。/*_ emm,这里我也不知道有啥用,不过先写上吧,我乐意,嘿嘿 _/ 对于正在苦苦理解源码的我,简直不友好
奉上一段 linux 的源码,来自 main.c
/*
* Yeah, yeah, it's ugly, but I cannot find how to do this correctly
* and this seems to work. I anybody has more info on the real-time
* clock I'd be interested. Most of this was trial and error, and some
* bios-listing reading. Urghh.
*/
#define CMOS_READ(addr) ({ \
outb_p(0x80|addr,0x70); \
inb_p(0x71); \
})
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
static void time_init(void)
{
struct tm time;
do {
time.tm_sec = CMOS_READ(0);
...
...
插曲结束,回到正题。
这时候找书便不再是你的难题了,你会自发的去找自己需要的书籍,并且每个人想关注的点不同,也会找不同的侧重点去深入了解。比如 linux 早期版本中是没有网络模块的,所以如果侧重点在网络编程,那就专门找如《linux 内核网络模型》这种书。有时候一些驱动程序,和一些比较好的操作系统变编程习惯,我也会通过如《一个 64 位操作系统的实现》这类书的部分章节来强化。
而且这个阶段你不在寂寞,会有很多同行者和你一起,也会有很多小白请教你问题。
后期
此时,一个操作系统的框架,你应该已经摸清楚了,但你不可能深入每一个细节。此时,也不是坚不坚持的问题了,而是选择的问题。你要你的操作系统不但支持 x86 还支持 arm 么?你要把各种驱动程序都完善么?你要做优美的图形化界面么?你要深入学习显卡方面的编程么?你要加入制作国产操作系统的大军么?
我的选择是不,所以我止步于此了,因为我是
因为我当初决定入坑的时候,是为了对我现在所做的工作有更深入的理解。我是个软件工程师,是 Java 程序员,并不是专门做嵌入式,专门做内核开发的从业者。所以我认为再往后继续深入可以,但已经没必要向前中期那样集中火力搞了,而是利用闲散时间能多了解就多了解,按需学习。
当然你也可以选择继续,我觉得不论是止步于此,还是继续往下走,都是有好处的。
我的经历小结
冷启动:《30 天自制操作系统》
初期:《操作系统真相还原》
中期:《linux 内核设计的艺术》《linux 内核完全注释》+ linux0.11 源码
后期:止步
这个系列要写什么
要写一个极简的操作系统教程,带你入坑
如果说属于上述哪个阶段的教程的话,我觉得处于冷冷启动阶段,因为无论是冷启动、初期还是中期,都有让人放弃的点,而这个冷冷启动阶段的极简教程,会让你在上面的各个阶段,都不那么容易放弃。
我曾经写过这样的系列,但一开始总是定很大的目标,期待读者除了我的系列文章外,不需要读任何资料就可以完全按照我的教程完成一个操作系统的制作,但往往很不现实,也没有必要,完全不是一个系列文章该做的事。下面是我在博客园折腾的系列们...
系列文章无法做到足够细致,只有大部头的书籍才能做到这一点。但上面的每一本书,部头真的都非常大,很容易让人放弃,从而错失一本好书和一个入坑的机会,我在每本书上都放弃过两三次。而网上,简单的自制操作系统的文章,又过于简单,完全无法让人达到入坑的标准。
所以为了解决这个痛点,我决定根据自己的经历,结合书本上的知识,反思之前写过的教程中的一些缺点,出这样一个极简教程的系列,其知识密度介于大部头书籍和网上的文章之间。
该教程的核心目标是,让读者对制作一个操作系统的核心流程,应该掌握的知识,需要经历的过程,和需要克服的心理障碍,做到心中有数,不再畏惧,做好入坑自制操作系统的正确姿势。并且在深入学习的过程中,不断的会有“哦,原来这个系列说的 xxx 就是这个意思呀”的正向反馈,这一点是非常重要的。因为技术的学习过程中之所以会放弃,一个原因是兴趣不够,另一个原因就是“我理解了”这种正向反馈不够。那本系列,我希望会在你后续深入学习的过程中,这个系列的影子会一直陪伴你,给你这种正向反馈和继续下去的动力,当然,最好还能让你提升兴趣,甚至让本不想亲手制作操作系统的人,也打开这个新世界的大门。
本来还想写个目录,后来想想算了,中途的思路很可能要根据实际情况来调整,就当作给大家的期待吧。
先送你一份入坑礼物
这可能是 全网最简单的操作系统 demo,啥也不能干,就做到了能接受键盘参数往屏幕上打印。最诱人的一点就是,如果你是 Windows 操作系统,你直接源码下载下来,点击 run.bat,不用安装任何环境,直接就可以运行。这可能是好多入坑小伙伴梦寐以求的一个 demo 吧,地址奉上:
https://gitee.com/sunym1993/flash-4th-os.git
flash-4th-os 运行截图
为什么是 flash-4th-os 呢?因为我英文名叫 Flash,然后我写的前三次都放弃了,这是我写的第四个,哈哈哈。
推荐阅读
• 吴师兄实名吐槽 LeetCode 上的一道题目。。。• 面试字节跳动时,我竟然遇到了原题……• 计算机专业的学生怎样练习编程才能把编程学精通?• 为什么 MySQL 使用 B+ 树• 一道简简单单的字节跳动算法面试题
欢迎关注我的公众号“五分钟学算法”,如果喜欢,麻烦点一下“在看”,点击左下方阅读原文,获取谷歌师兄的算法刷题笔记。
![](https://i-blog.csdnimg.cn/blog_migrate/e8d41f30e7162a70528abab077e4dd75.png)