Loading... # 站在用户和应用程序的角度看操作系统 操作系统内核是一个需要提供各种服务的软件,其服务对象是应用程序,而用户(这里可以理解为一般使用计算机的人)是通过应用程序的服务间接获得操作系统的服务的,因此操作系统内核藏在一般用户看不到的地方。但应用程序需要访问操作系统获得操作系统的服务,这就需要通过操作系统的接口才能完成。操作系统的接口形式就是应用程序二进制接口 (ABI, Application Binary Interface)。 操作系统不能只提供面向单一编程语言的函数库的编程接口 (API, Application Programming Interface) ,它的接口需要考虑对基于各种编程语言的应用支持,以及访问安全等因素,使得应用软件不能像访问函数库一样的直接访问操作系统内部函数,更不能直接读写操作系统内部的地址空间。为此,操作系统设计了一套安全可靠的接口,我们称为系统调用接口 (System Call Interface)。 系统调用接口通常面向应用程序提供了API的描述,但在具体实现上,还需要提供ABI的接口描述规范。 <div class="tip inlineBlock info"> 一些思考:提供ABI规范是便于底层开发人员进行驱动程序的开发,以及进行汇编级别的优化和高级编程语言运行库的开发等操作 </div> 在现代处理器的安全支持(特权级隔离,内存空间隔离等)下,应用程序就不能直接以函数调用的方式访问操作系统的函数,以及直接读写操作系统的数据变量。 <div class="tip inlineBlock error"> 这里的不能直接以函数调用的方式访问操作系统的函数,我认为指的是操作系统内部使用的函数而非暴露出来的系统调用接口 </div> 不同类型的应用程序可以通过符合操作系统规定的ABI规范的系统调用接口,发出系统调用请求,来获得操作系统的服务。操作系统提供完服务后,返回应用程序继续执行。 <div class="tip inlineBlock share"> **API 与 ABI 的区别** 应用程序二进制接口 ABI 是不同二进制代码片段的连接纽带。ABI 定义了二进制机器代码级别的规则,主要包括基本数据类型、通用寄存器的使用、参数的传递规则、以及堆栈的使用等等。ABI 与处理器和内存地址等硬件架构相关,是用来约束链接器 (Linker) 和汇编器 (Assembler) 的。在同一处理器下,基于不同高级语言编写的应用程序、库和操作系统,如果遵循同样的 ABI 定义,那么它们就能正确链接和执行。 应用程序编程接口 API 是不同源代码片段的连接纽带。API 定义了一个源码级(如 C 语言)函数的参数,参数的类型,函数的返回值等。因此 API 是用来约束编译器 (Compiler) 的:一个 API 是给编译器的一些指令,它规定了源代码可以做以及不可以做哪些事。API 与编程语言相关,如 libc 是基于 C 语言编写的标准库,那么基于 C 的应用程序就可以通过编译器建立与 libc 的联系,并能在运行中正确访问 libc 中的函数。 简单来说,API是编译器级别的,ABI是汇编级别的。 </div> # 系统调用接口的一些比较重要的功能与相应的抽象 对于系统调用接口提供的功能,下面列出了一些值得了解的功能: - 一个运行的程序可以创建另一个程序的实例吗?需要等待另外一个程序执行完成吗?操作系统能停止或恢复另一个正在运行的程序吗? - 一个运行的程序如何与连接到计算机的设备通信并通过它们与物理世界通信? - 多个运行的程序如何同步互斥地对共享资源进行访问? - 一个运行的程序可以要求更多(或更少)的内存空间吗? - 一个运行的程序如何持久地存储用户数据? - 一个运行的程序如何能输出字符信息?如何能获得输入字符信息? 下面列出了一些相对比较重要的操作系统接口或抽象: - 进程(即程序运行过程)管理:复制创建进程 fork 、退出进程 exit 、执行进程 exec 等。 - 线程管理:线程(即程序的一个执行流)的创建、执行、调度切换等。 - 线程同步互斥的并发控制:互斥锁 mutex 、信号量 semaphore 、管程 monitor 、条件变量 condition variable 等。 - 进程间通信:管道 pipe 、信号 signal 、事件 event 等。 - 虚存管理:内存空间映射 mmap 、改变数据段地址空间大小 sbrk 、共享内存 shm 等。 - 文件I/O操作:对存储设备中的文件进行读 read 、写 write 、打开 open 、关闭 close 等操作。 - 外设I/O操作:外设包括键盘、显示器、串口、磁盘、时钟 … 但接口均采用了文件 I/O 操作的通用系统调用接口。 <div class="tip inlineBlock share"> 上述表述在某种程度上说明了操作系统对计算机硬件重要组成的抽象和虚拟化,使得应用程序只需基于对简单的抽象概念的访问来达到对计算机系统资源的使用: - 文件 (File) 是外设的一种抽象和虚拟化。特别对于存储外设而言,文件是持久存储的抽象。 - 地址空间 (Address Space) 是对内存的抽象和虚拟化。 - 进程 (Process) 是对计算机资源的抽象和虚拟化。而其中最核心的部分是对CPU的抽象与虚拟化。 </div> ![][1] 有了这些系统调用接口,简单的应用程序就不用考虑底层硬件细节,可以在操作系统的服务支持和管理下简洁地完成其应用功能了。 [1]: https://www.onesnowwarrior.cn/usr/uploads/2022/03/2885797050.png Last modification:March 24, 2022 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 如果觉得我的文章对你有用,请随意赞赏