• 关于《自己动手写操作系统》的总结

    关于《自己动手写操作系统》的总结

    昨天晚上终于完成了《自己动手写操作系统》的最后一部分功能,看着三个控制台上的进程各自运行着,终于舒了一口气。查看了最早的程序,是8月18号的,到现在整整30天。原本以为用10天可以搞定,没想到会用这么久。这本书读起来非常累,尤其是要照着书上写的东西把所有程序自己敲一遍,然后调试,运行,周而复始。虽然只是实现了一个最最最简陋的操作系统,没有文件系统,没有内存管理,没有命令,没有好多,不能像正常系统一样工作,但对于我这样的初学者,即使是完全照抄,还是费了很大的劲,当然,也收获了很多。所以,要总结一下,为这段日子画一个句号。

    首先,评论一下这本书。《自己动手写操作系统》的作者于渊,没有查到他更多的信息,只是根据《程序员》杂志主编孟岩在序中的介绍,于渊是一位非常年轻的程序员,有着广泛的技术视野和上佳的文笔。年轻是一种资本,从书中也可以看到作者的活力与激情。当年Linus写出Linux的内核时也不过是大学二年级的学生。这就是年轻的好处,有着不断的激情与梦想,有着无限的精力,除旧布新,开天辟地。年轻就是要不断探索,所以整个学习过程,我深受感染。但是年轻的劣势就在于沉淀的太少,所以书中很多问题,作者并没有交代清楚,整个思路也没有那么清晰,精要。经典的书籍,一定有一种道在里面。当然,这种评论首先出于我自身的理解和悟性,并不是书本来就是这样的。于渊自己也说,这本书是他学习过程的记录和总结,他也是以一个学习者的态度来写书的。所以,这一切都不是问题,万事都有开始,Linus当初为访问学校文件系统而编写磁盘驱动时,恐怕也没有想到他会开辟Linux世界的大好河山。

    在学完整个学期的操作系统课程后,如果你想自己写一个小的操作系统,一定会发现无从下手,因为传统的操作系统课程过于关注理论,不会告诉你要用什么工具,什么语言,如何写代码这些。当然,这并不是说理论不重要,在你对事物有了一个感性认识后,会发现理论有非常重要的作用,因为理论基础不行,会在很大程度上制约你的理解和进步。比如我现在很头疼的一点就是自己的数学基础太差了。既然要动手写,就有一个开发环境,这本书给我很大的一个收获就是在各种工具的使用方面。所以就从这儿说起。

    三种操作系统:学习这本书的过程,我使用了三个操作系统,主机用的是windows,然后虚拟了DOS和linux。在开始阶段用Windows写程序,然后共享到DOS下面运行(因为那些程序要在实模式下运行)。中间阶段以及后期把程序所在文件夹共享到三个系统里。在linux下写程序,编译,然后把程序写到虚拟软盘映像,然后在DOS下加载虚拟软盘映像观察效果,如果有问题,在linux或windows下调试。其实整个过程都可以在linux下进行,并且在这本书的第二版里,作者已经把工作环境完全 放在了linux下,并对此作出了说明。linux命令行的工作方式,会很大程序上提高工作效率,这一点我已经深有体会,不仅如此,那些神奇的命令单兵作战或者协同作战会起到你在windows下想做而做不了的事。也许在windows下可以通过各种软件实现那种功能,但是在linux下,那些命令从发明到今天,20多年了,大家还在使用,不论时代怎么改变,人们都有共有的需求,所以那些命令永远不过时,并且越来越强大。我说上面这些,并不是想让你用linux,我觉得不论什么操作系统,它的存在必然有他的理由以及生命力所在,只有适合不适合,没有高下之分,这正如各种编程语言一样。人是不能被说服的,只能自己觉悟。如果不主动探索,永远不知道原来外面有一个大大的世界。

    三种虚拟机:因为需要不同的操作系统,所以有人发明了虚拟机这种东西,可以虚拟出不同的操作系统,以便人们不用再买一台机器,不用多系统,也能在各种操作系统之间自由切换。这就是操作系统课上老师说的一台物理设备抽象出了多个逻辑设备吧。学习这本书的过程,我使用了三种虚拟机:VMWare,Virtual PC,Bochs.VMware功能强大,也挺消耗资源,我用来虚拟linux,然后直接在上面写程序。Virtual PC小巧,占用资源少,我用来虚拟DOS,Bochs是一款开源软件,在windows和linux下都有对应的版本,因为它是用软件模拟了硬件,所以很慢,但是它的一个很大的优势也在于此,Bochs可以用来方便的调试操作系统,你可以用它看看一台计算机从加电开始,都执行了哪些指令,各种寄存器的值怎么改变的,例如你怀疑自己的内核有问题,那么可以在内核的入口处设置一个断点,虚拟的计算机启动后,到内核的入口用就停住,你可以看看各个值是否正确。并且三种虚拟机应该都有专门的机制和主机共享,VMWare Virtual PC 的共享我用过,bochs不经常用,就不知道了。

    三种编译工具:nasm,gcc和make。nasm是开源的汇编语言编译器,windows和linux下都有相应的版本,gcc就不用说了,linux下经典的编译工具,对这两种编译工具,整个过程也只使用了它们最基本的功能。make是我第一次接触,下面说一下make的作用。因为要编写一个操作系统,即使它十分简陋,但是还是要有许多文件需要编译,这些文件分布于不同的文件夹,需要的头文件也在不同的文件夹,难道每次都要一个一个地重新编译吗?出于这样的需求,出现了make,使用make,只要第一次用一种格式化的语言写一个make file,定义好make 命令的作用,然后每次更新完文件,只要简单修改一个Makefile,然后输入 make **,所有文件就会自动全部编译完成,并且如果文件没有更新,就不会被重新编译。

    三种编辑器:edit,notepad,vim。因为受之前学的《汇编语言》的影响,开始的时候,使用的是DOS下的edit编辑程序,后来感觉实在不好用,就干脆直接用记事本了。学习过程到了中后期,改用了vim。用过linux或者unix的人一定不会不知道vi。vim是vi的一个升级版。vi是许多unix,linux系统默认的编辑器。vim和emacs,分别被称为编辑器之神和神的编辑器,它们的地位可想而知。这次学习操作系统的过程,vim的使用给了我很大的感触,这真的是无比强大的编辑器!每次当我想到,如果有这么一个功能多好,然后google vim+想要的功能,居然每次都可以找到。原因就在于你想要的功能,前人都想到了,所以,利器在手,就看你能不能玩转了。而且因为是开源,vim有着很好的扩展性,需要一个功能时,加入对应的插件就可以了,根据需要定制,非常方便。另一个感触是,学习一个工具,一定要用它,这样才能不断进步。之前我也学习过vim,可是只是为学而学,不是为用而学,所以学到的东西很快就忘了。包括整个Linux系统也是这样,一定要去用它,不要为了学而学。并且vim的学习曲线陡峭,开时时候非常不适应,但是过了适应期,你会发现vim是无往不利,真正的编辑器之神!

    N种小工具:学习的整个过程,还用到了N种工具,这里一起说一下。windows下用到了Turbo Debugger,一款古老的调试器,用来调试汇编程序。winimage,用来建立虚拟软盘,同时可以向软盘里写入文件。Unltra Edit,这本来是一个著名的编辑器,被我用来当16进制查看器查看虚拟软盘的16进制值了。。。linux下我最常用的工具是grep。这是个非常有用的小命令,当你想要知道一个变量都出现在了哪一个文件的哪一行时,你难道像在windows里一样一个文件一个文件的点开看吗?有了grep,只要一个命令就可以把他们全部找到了。如果你想对所有文件中的一个变量作出改变时,就用到了另一个命令,sed。这个命令可以批量的替换,删除你指定的一个或者一批文件中的某个变量。非常方便。有一次,我想在每一个#include "global.h",前面加一个#include "tty.h",并且换行时,就用到了这个命令。还有一个最常用的工具是ctags,这个工具配合vim使用,给我阅读代码带来了很大的方便。ctags的使用是这样的,先用ctags -R *,生成一个tags文件,里面记录了你所有代码中用到的变量,函数等等。这样当你想从一个函数的调用处跳到它的定义处时,只要Ctrl+],主可以直接跳过去了,然后Ctrl+O又跳回来,或者你面对那么多文件,忘记了main函数在哪里时,只要vim -t main,就直接进入了main函数,非常好用。

    工具就像兵器一样,好的工具可以让工作变得非常有效率,关于工具,说的不少了,就说到这里。

    因为学习的是操作系统,下一个话题就说一下在操作系统方面的收获。

    在操作系统上,这本书和课上学的操作系统课不一样的地方在于,它首先给了我一个感性的认识,让你觉得操作系统是可以看的到,摸的着的,而不是课堂上抽象出的一些概念。比如进程一章,就真正在操作系统中编写了进程并让它们运行起来。我觉得感性的认识加上理论上的思考才是最有效的学习方式。实践,然后知道不足,去学习理论,然后再实践,然后觉得知识又不够用,然后再学习,这样一个螺旋式上升的过程我觉得应该是有效的。这是在方法上给我的启示。在具体的知识上,主要实现了从CPU加电初始化BIOS,加载引导扇区开始,到加载loader,loader加载kernel,然后kernel设置中断,键盘驱动,初始化进程,然后由进程调度程序调动整个进程运行这一系列的流程。其中还学习了保护模式,GDT,LDT,IDT,8259A等等概念及其运用。但是没有涉及处理机管理,内存管理,文件系统这些东西,在这本书的第二版《Orange's 一个操作系统的实现》,已经有了这部分功能。

      说了也不少了,没有想说的了,就作一个下一步的计划吧,下面要重新学习一下C语言和汇编,感觉基础还是不行,然后散着看一点操作系统方面的东西,跟着课学一下理论,好好看看 Operating system concept,理论了解了,可能会看《操作系统:设计与实现》以及Linux的源代码。未来的变数还很大,只能有一个初步的打算了。

    Read More ...