作业系统(Operating System)的研究,我们以Linux kernel的探讨来说明一些应有的正确观念。
对于Linux kernel的研究,最经常听到有人提起「kernel source code」的研读与分析,并且最常看到的研究方式为「寻找kernel进入点,并依照程式流程(flow)做循序研究」,不过,这却是一种「大部份情况下都错误」的研究方式。
由于电脑系统是一种foreground-background system,并且Linux kernel是在此系统上的作业系统,因此整体的kernel行为是「control patch」,也就是「控制权的转移」与「系统状态的改变」,并不是「程式(函数)流程(flow)」,或是「程式结构(structure)」的问题;最近有朋友问起这方面的议题,正好也在进行Linux device driver的training,因此特别整理这则日记,来与大家分享,若有任何论述上的失误,或是有不同的观点,欢迎在这里留言分享。
许多人对于「作业系统」的观念可能真的有点薄弱;具体来说,对于kernel内部原理的研究,其方法应该是:
1. kernel的开机阶段,是以「流程(flow)」的角度来做讨论。
2. kernel完成开机后,会执行init process,由此正式切换到F/B system的观念,也就是整个系统是一个偌大的状态机,整个系统内部是一连串复杂的控制权转移动作。
最近朋友希望我能针对「kernel的执行流程」做简单介绍,但是这个问题在命题上应当有修正或是观念澄清的空间。由于电脑本身是一种foreground-background system,因此foreground的工作会影响CPU将控制权移交到background的哪一个部份;如果把user-space当成foreground,kernel-space当成background,那么整体系统便能以下图表示。
Background受到foreground行为的影响,拿以下二个process为例,虽然执行结果相同,但因为foreground内部的行为不同,因此control path也会。
此时,仍是以「流程图」逻辑来思考的话,当然无法领会?中奥妙。简单二个不同的process,CPU将控制权移转到作业系统的路径(也就是kernel执行了哪些程式码),居然有这么大的差异。如果再把排程器(scheduler)加入,那么整个控制路径很可能「不同时间执行同一程式」也会不同。 Tricky!
以研究方法来说,命题时观念的失误,终将无法得到正确且完善的结论,因此「希望就kernel的执行流程」做讨论的命题,应当做修正,并且给定一个更明确的题目;再者,若无法体认kernel是一个大型的状态机,而仍以「流程与程式结构」的观念来思考,除了在问题的描述会有相当大的误差外,可能也会对「如何了解kernel source code」的方法摸不着头绪。
由此可知,整体系统在kernel开完机并执行init process后,就必须针对其「行为」做分析与研究,而不是徘徊在「结构化C程式」的圈圈里;这个观念证明了「逐行看code」并不是研究kernel原理的正确方法。
Kernel本身的行为是一连串复杂的状态改变与控制权转移,因此是状态机的观念。至于,研究方法是采用流程或是控制路径的观念进行,就看我们想要读的是哪一个部份的source code。前面提到研究kernel的二个阶段与方式,当中的转捩点为init process,接续init process,建议可先由program execution(process creation)的观念开始切入,以了解整个作业系统的行为。
所以,kernel的研究,是以其动态(run-time)时期行为(behavior)的分析与观察为主。

