基本术语
操作系统
负责完成最基本功能和系统管理的部分,一般包括内核、驱动、引导、文件管理程序等。
系统
包括操作系统和所有运行在他之上的应用程序。
内核
操作系统的核心,管理硬件设备,分配系统资源。
内核态
由此我们可以看出,内核的重要性远远大于应用程序,因此内核在运行时独立于应用程序,我们一般称之为系统态(内核态),拥有受保护的内存空间以及访问硬件设备的所有权限。系统态以及被保护的内存空间,统称为内核空间。
用户态
相对地,应用程序运行在用户态,无法擅自进入内核空间(你去银行取钱进入不了金库),受到一系列的限制,这时候就需要银行职员帮你办理业务,我们称之为系统调用。
执行流程
假设你的应用程序调用了c语言库函数,库函数就会通过系统调用,让内核完成任务。库函数与系统调用存在三种关系:
-
关系一:复杂封装(如
printf)-
printf("Hello, %s", name) 是一个非常强大的库函数。它的工作远不止“输出文字”。 -
它的工作流程:首先,它会帮你格式化字符串(比如把
name变量值替换到%s的位置);其次,它可能会将数据放入缓存以提高效率;最后,在适当的时机,它才会去调用write()这个真正的系统调用,让内核把数据最终写到控制台。 -
结论:在这里,系统调用(
write)只是整个复杂工作(printf)中的一个步骤。
-
-
关系二:简单映射(如
open)-
open() 库函数的功能非常单一:打开一个文件。 -
这个操作几乎完全需要内核的权限(访问文件系统),所以
open库函数几乎不做任何额外工作,只是简单地将参数传递给同名的open系统调用。 -
结论:这是一种近乎一对一的映射关系。
-
-
关系三:无关(如
strcpy)-
strcpy(字符串复制)函数的功能完全在用户空间内就可以完成(就是在内存里拷贝数据),它不涉及任何硬件或特权操作。 -
结论:这类库函数完全不需要使用系统调用
-
当应用程序执行一条系统调用,我们说内核正在代其执行
当应用程序需要做一些它自己没权限做的事(比如读写文件、从网络接收数据),它不能自己动手,而是必须“呼叫”操作系统帮忙。这个过程就是执行一条系统调用。此时,实际完成这个敏感操作的是内核,而不是应用程序本身。
应用程序被称为通过系统调用在内核空间运行
当内核“代其执行”时,CPU 的执行权限会从低权限的“用户态”提升到高权限的“内核态”。此时,CPU 执行的代码是内核的代码(在内核空间)。虽然执行的是内核代码,但这些代码是为了响应当前应用程序的请求而运行的。所以,我们可以看作是应用程序的请求正在内核空间里得到处理。
内核被称为运行于进程上下文中
虽然内核在处理请求,但它并没有忘记这个请求是为谁服务的。内核会保存当前应用程序(即“进程”)的所有状态信息(比如是谁发起的调用、它的数据在哪等),这个环境就是“进程上下文”,这确保了内核处理完事情后,能把结果准确地返回给正确的应用程序,并恢复该应用程序的执行。
这种交互关系——应用程序通过系统调用界面陷入内核——是应用程序完成其工作的基本行为方式
应用程序几乎所有有意义的、需要与外部世界(硬件、网络、文件)交互的工作,最终都必须通过“系统调用”这个唯一的、安全的门户来请求内核完成。这是应用程序能够“做事”的根本方式。没有这个机制,应用程序就只能在自己狭小的内存空间里做数学计算,无法实现任何实际功能。
《linux内核设计与实现》

6638

被折叠的 条评论
为什么被折叠?



