大家好,我是轩辕。
今天跟大家深度聊一下,操作系统这门课,怎么学,才能更牛逼?
一、做好前置功课
千万不要一上来就啃书,学任何课程之前,都需要做好功课:
这是一门什么课程?讲什么东西的?
位于整个计算机技术知识体系的哪个位置,有哪些相关联的课程?
学了这门课有什么用?如果一上来直接就啃书,一不小心就会掉入枯燥的技术名词海洋中,什么也学不进去。
首先来了解一下,操作系统到底是个啥?为什么会有操作系统这个东西出现?
在二十世纪中叶,计算机刚刚诞生之初的那二三十年里,是没有操作系统这个东西的。程序员编写的程序是直接放到计算机上去运行。
所以那时候的程序员,必须对计算机的硬件设备(CPU、存储设备、输入设备、输出设备)非常熟悉,才能编写出可以运行的程序,那时候的程序员可不像现在,随便培训一下就能上的,是个技术含量很高的活。
直接把程序放到计算机上执行,是通过人工来操作,执行完一个,再放另一个。但随着计算机速度的提高,人工操作的性能瓶颈开始出现,这就是著名的“人机矛盾”。这时候计算机科学家们开始思考:能不能提前把所有程序都录入进去,然后让计算机自动切换多个程序呢?
于是,计算机科学家们捣鼓出了一个管理程序,专门来负责控制切换其他程序的运行。
批处理系统、多道批处理系统相继诞生,操作系统的概念开始兴起。
计算机硬件发展越来越快,可以同时运行多个程序了,这个管理程序逐渐演化成操作系统,功能也越来越强大,不但负责调度管理其他程序的运行,还负责管理计算机所有的硬件资源(CPU、内存、外存、网卡、输入输出设备),作为一个二道贩子中间商,提供简单的接口给其他程序,程序员们编写的程序不再需要直接与计算机硬件打交道了,与操作系统打交道就好了。
所以,话说回来, 操作系统这门课程,讲的就是这个计算机的大管家,是如何管理程序的运行,以及如何管理计算机硬件资源并提供接口给程序使用的一门计算机基础课程!
因此,操作系统的核心,就是由下面这些东西构成的:
管理程序运行:线程管理、进程管理
管理内存资源:内存管理
管理硬盘资源:文件系统
管理网卡资源:网络协议栈
管理输入输出:中断管理、同步与异步
为应用程序提供接口:系统调用
看到了吗,操作系统书上每一部分东西都不是凭空而来的,大家在学习到操作系统每一个章节的时候,都要清楚的知道,学的这一部分东西是做啥的?只有清楚自己在操作系统学习海洋中的位置,才不会迷失方向。
二、选择几本好书
准备工作做好了,接下来就是要选择几本好的学习教材。
在这里我一定要说几句了!!!
大家一定要区分好一个概念:操作系统理论和具体的操作系统实现,这是两码事情!
同一个操作系统机制,不同的操作系统实现可能完全不同,一定要弄清楚书上写的那些东西是操作系统的理论,还是某个操作系统(比如UNIX)中的实现,不要以为UNIX是这么做的,所有操作系统就都是这样,这就走入误区了!
我推荐,操作系统学习一定要准备三本书:
1、写操作系统理论的书 2、写Linux操作系统实现的书 3、写Windows操作系统实现的书 首先,建议从理论书籍看起走,它会告诉你操作系统的发展历史,以及各个操作系统概念的作用。这类书籍偏重计算机科学性质,也就是有点学院派的意思。
光看理论还是虚的,犹如空中楼阁,你只能想象它的存在,却看不见摸不着。所以学了理论书籍,也要来看一下现代主流操作系统的具体实现,才能进一步加深你对这个知识点和技术的理解深度。
操作系统理论书籍中也会捎带介绍一些操作系统具体的实现,但是只是蜻蜓点水式的,不会太深入。想要真正了解某一个系统,最好是深入学习这个操作系统的实现。
如果是偏后端开发的,建议以Linux为重点,重点研究Linux下的实现,可顺便看一些Windows。
如果是网络安全(尤其是二进制方向)、客户端开发的,重点研究下Windows的实现,可顺便看一些Linux。
比如同样是线程,Linux和Windows的实现有着巨大的差异,比较posix线程和win32线程的实现差异,从内核数据结构到应用编程接口,学习原理和使用的差异,理解线程这个东西在操作系统中到底是一个什么样的存在。
比如内存管理,同样是基于x86下的段页式内存管理机制,对比Linux和Windows的管理实现差异,缺页异常处理、写时拷贝机制有哪些异同之处。
又比如系统调用,线程调度、中断处理、异常处理、锁等等,通过对比学习二者的差异,你会对这些操作系统概念了解的更加深刻,也会更加体会,理论与实际的差异所在。
在书的选择上,理论书籍毫无疑问首推黑皮书:《现代操作系统》
讲Linux的推荐:《Linux内核设计与实现》
讲Windows的推荐:《Windows内核原理与实现》
看书的时候,不一定非要从第一页看到最后一页,不要这么死脑筋,学会灵活应对。如果进程管理看不下去,可以先看内存管理,同步与异步看不下去就先放着,等其他方面的知识储备够了,再回头来看,可能就会事半功倍。
如果确实觉得看书很枯燥,看不进去,也可以尝试看看我之前写过的系列故事文章,通过第一人称视角的方式,用有趣的故事形式讲解这些底层知识。
比如,讲中断技术:
CPU明明8个核,网卡为啥拼命折腾一号核?
讲内存管理:
一个故事看懂内存管理
讲DMA技术:
一个故事看懂DMA技术
三、学习阅读源码
除了看书,另外一项非常重要不可或缺的工作就是阅读源码!
一边看书,一边对照着源码学习,这是最直接最高效的学习方式。
不要觉得看操作系统源码是个很庞大的工程,自己可能看不下去。首先克服自己心里的恐惧,操作系统也是人写的,又不是让你一口气看完,你学哪一部分,就看那一部分的,没有那么遥不可及,等你通过阅读源码get到了书上写的某个知识点,那种感觉是非常舒适的。而一旦你习惯了这种舒适,就会形成正向反馈,推动你不断学习更多知识,也会养成通过源码学习和解决问题的良好习惯。
Linux是开源的这地球人都知道,去下载一份源码到自己电脑上,然后用sourceinsight这个工具打开,这个工具便于查看定位各种数据结构、函数的定义。
比如我用它来查看Windows XP的源代码:
阅读源码一定要带着目的性,毕竟,操作系统源码的规模是几千万行级别。
比如最近在学习系统调用,就先看书,把系统调用的概念、原理弄清楚,再找到源码中讲系统调用的部分,结合源代码进行分析,和书上讲的内容进行结合对照,把这一块源码好好琢磨琢磨,加深对其理解。
(PS:顺便说一下,书的出版有一定的时效性,要注意手里的操作系统源码版本是不是和书上的一致,有可能会出现不一样的情况,从而产生疑惑)
四、一定要动手实践
纸上得来终觉浅,绝知此事要躬行!
对于大部分人来说,能做到结合看书+源码分析,就已经足够了,对于操作系统的理解就已经达到一定的深度。
但如果你想有更进深一步的学习,这还不够!
毕竟,看书也好,看源码也好,都是看来的,操作系统真的就如书上和源码中描述的那样吗?
我学习一个东西,绝不听信书上所言,一定要亲自验证才为真,这样留下的印象想忘也忘不了。
那什么叫亲自验证?
可以通过ARK级别工具,观察内核中的数据结构,如系统调用表、内存管理中的全局描述符表GDT、中断管理中的IDT。去看一下里面到底装了什么东西,然后尝试用书上讲解的知识,去解读这些数据结构,看看是不是书上写的那样。
还通过内核级调试工具,跟踪操作系统系统调用流程、文件创建过程、数据包处理流程···
再然后,自己编写内核驱动程序,加载到内核空间,去遍历所有的进程,去自己翻译虚拟地址,去劫持线程执行流···
能做到这个程度,操作系统就是你的玩具了。
五、几个好东西
最后,收藏党的福利时间,推荐几个学习操作系统的好东西:
1、Linux源码在线查看网站,墙裂推荐,函数、数据结构可以关联检索,各种Linux版本应有尽有:
https://elixir.bootlin.com/linux/latest/source
2、Windows源码(包含开源的WRK、泄露的Windows NT、Windows XP、还有逆向工程版本的ReactOS全家桶打包合辑)
3、操作系统学习书籍资料免费送给大家:
觉得有用,记得点个赞哦~