l 内核将应用程序和硬件分离开来。
l 部分内核是体系结构和硬件特有的,而部分内核则是可移植的。
虽然这通常并不能够使得内核本身更清楚,但是源程序代码的体系结构无关部分通常定义了与低层,也就是体系结构相关部分(或假定)的接口。作为一个简单的例子,内存管理代码中的体系结构无关部分假定只要包含特定的头文件就可以获得合适的PAGE_SIZE 宏(参看10791行)的定义,该宏定义了系统的内存管理硬件用于分割系统地址空间的内存块的大小(参看第8章)。体系结构无关代码并不关心宏的确切定义,而把这些问题都留给体系结构相关代码去处理。(顺便一提,这比到处使用#ifdef/#endif程序块来定义平台相关代码要清晰易懂得多。)
这样,内核向新的体系结构的移植就转变成为确认这些特性以及在新内核上实现它们的问题。
另外,用户应用程序的可移植性还可以通过它和内核的中间层次――标准C库(libc)――的协助来实现。应用程序实际上从不和内核直接通讯,而只通过libc来实现。图3.1中显示应用程序和内核直接通讯的唯一原因在于它们能够和内核通讯。虽然在实际上应用程序并不同内核直接通讯――这样做是毫无意义的。通过直接和内核通讯所能处理的问题都可以通过使用libc实现,而且更容易。
Libc和内核通讯的方式是体系结构相关的(这和图中有一点矛盾),libc负责将用户代码从实现细节中解放出来。有趣的是,甚至大部分libc都不了解这些细节。大部分的libc,例如atoi和rand的实现,都根本不需要和内核进行通讯。剩余部分的大部分libc,例如printf函数,在涉及到内核之前或之后就已经处理大量的工作。(printf必需首先解释格式化字符串,分析相应参数,设定打印方法,在临时内部缓冲器中记录预期输出。直到此时它才调用底层系统调用write来实际打印该缓冲区。)其它部分的libc 则只是相应系统调用的简单代理。因而一旦发生函数调用时,它们会立即调用内核相应函数以完成主要工作。在最低层次上,大部分libc通过单通道同内核进行交流,而它们所使用的机制将第5章中进行详细介绍。
由于这种设计,所有的用户应用程序,甚至大部分的C库,都是通过体系结构无关的方式和内核通讯的。
文章评论(0条评论)
登录后参与讨论