内核之路:稳扎稳打,直指操作系统
操作系统内核学习的重要性不言而喻。大到研发具有自主知识产权可信操作系统这一国家战略,小到程序员内功的自我修炼,内核学习都是绕不开的关键环节之一。另一方面,操作系统内核是多种技术知识的交汇处,比如体系结构、编译链接、数据结构与算法、网络技术、存储技术等等。因此,内核的学习既是对前期所学知识的检验,又是帮助我们将这些知识融会贯通的好机会。
下面仅以Linux操作系统为例,分析、讨论内核的学习方法。在内核的学习过程中,我们除了面临内核本身技术复杂度的挑战,还不得不应对内核版本变化快、各种技术书籍资料相对滞后等不利因素。因此,内核的学习不能囿于某个或某些技术点的掌握,而应将重点放在内核技术学习的方法上。总体而言,内核技术的学习方法,就是不停地应用程序员技术手段(编写调试内核模块,阅读、修改、调试内核源码,阅读内核技术文档),以探索内核技术的原理,并在此过程中,遵循“问题-猜想-实证-构建”的学习方式。下面仅以一例说明如何在内核学习中应用上述方法。
在学习Linux内核地址分段管理机制的过程中,特别是结合《微机原理》、《汇编语言》、《计算机操作系统》等课程,很自然会产生一个疑惑,指针变量到底存储的是什么。这就是提出了“问题”。通过阅读有关x86地址转换机制的技术文档,可以大胆“猜想”指针变量中存储的其实是偏移量。而这又带来新的疑惑:为什么平时编程时没有感知到指针实质是偏移量,但却并没有带来什么不利影响。接下来,就需要通过我们应用程序员技术手段,分析并解决这一疑惑。通过编写内核模块访问GDTR寄存器,进而获取全局段描述符表信息;并结合x86技术手册,分析段描述符中的内容,从而发现常见段的范围是整个线性地址空间,即偏移量数值上等于线性地址。这一过程,就是利用程序员手段进行“实证”。“实证”之后,事情并没有结束,还需要应用学到的知识。比如,分段机制看似没有多大用处了,但是还可用于线程局部存储的构建。使用学到的分段管理机制,“构建”一个线程局部存储,而这又是内核学习的进一步深化。
从上面可以看出,内核学习的关键就是程序员技术手段,而线索就是“问题-猜想-实证-构建”。下面从学习路线角度,分析Linux内核的具体学习步骤。
第一步,学习Linux内核之前,需要满足如下要求:
-
会Linux的基本操作。推荐书籍《鸟哥的linux私房菜》。
-
使用过Linux系统API进行程序开发。推荐书籍《Unix环境高级编程》。
-
学习过《汇编语言》一课,特别是学习过保护模式下的汇编,更有助于理解现代操作系统的一些底层细节。
第二步,有了前面的基础,就可以着手开始内核的学习,但绝不是从学习内核源码开始,而应从内核使用者的角度入手,即学习编写内核模块。这一步中,将会通过各种编程练习,掌握字符设备驱动程序、内核态同步、中断、内核与内核模块跟踪和调试等关键技术。推荐的书籍是《Linux设备驱动程序》。
第三步,有了内核模块的编写经验,自然而然就会对内核有一定的感性认识。在此基础之上,可以根据自己的兴趣或需要,选择一个内核子系统进行学习,比如地址空间与内存管理、存储I/O栈、进程调度等等。切忌内核学习没有方向性,特别是直接从内核启动代码入手。下面以地址空间与内存管理、存储I/O栈这两个在实际开发中经常碰到的子系统为例,说明学习路线。
对于地址空间与内存管理而言,可以按照如下路线进行:
-
学习内核中分段管理机制,可配以per cpu变量使用、TLS构建等练习。
-
学习内核中分页管理机制,可配以保留物理内存,自行构建页表映射等练习。
-
学习内核页框管理机制。在构建练习中,可实现不同的页框分配算法。
-
学习内核内存池管理机制。在构建练习中,可实现多种内存池管理机制。
-
学习内核地址空间管理机制。在学习过程中,弄清内核地址空间共享的原理,并配以针对野指针的页面保护等练习。
-
学习进程地址空间管理机制,可配以自行实现共享内存机制等练习。
-
学习用户态堆管理机制。在研究各种malloc实现的同时,配以自行实现一个高并发、可垃圾回收、空间碎片小的堆的练习。
对于存储I/O栈而言,可以按照如下路线进行:
-
学习块设备驱动程序。需要理解块设备层的结构、熟悉块设备的基本接口,及各类I/O调度器原理,配以实现基于内存的简单块设备的练习。
-
学习VFS(Virtual File System)。需要理解VFS中各种数据结构的组织方式;从read、write这两个API开始,阅读源码,一直追踪到与page cache的交互为止。
-
学习从VFS到块设备的处理过程。可以先了解一两个简单的fs实现,如proc fs,然后再编写一个简单的文件系统demo。在此基础之上,深入理解page cache的数据write back流程、文件系统设计要点等。最后,学习一个经典文件系统,如ext4、btrfs,并配以构建一个面向非易失内存的文件系统的练习。