站在用户和应用程序的角度看操作系统操作系统内核是一个需要提供各种服务的软件，其服务对象是应用程序，而用户（这里可以理解为一般使用计算机的人）是通过应用程序的服务间接获得操作系统的服务的，因此操作系统内核藏在一般用户看不到的地方。但应用程序需要访问操作系统获得操作系统的服务，这就需要通过操作系统的接口才能完成。操作系统的接口形式就是应用程序二进制接口 (ABI, Application Binary Interface)。操作系统不能只提供面向单一编程语言的函数库的编程接口 (API, Application Programming Interface) ，它的接口需要考虑对基于各种编程语言的应用支持，以及访问安全等因素，使得应用软件不能像访问函数库一样的直接访问操作系统内部函数，更不能直接读写操作系统内部的地址空间。为此，操作系统设计了一套安全可靠的接口，我们称为系统调用接口 (System Call Interface)。系统调用接口通常面向应用程序提供了API的描述，但在具体实现上，还需要提供ABI的接口描述规范。[scode type="blue"]一些思考：提供ABI规范是便于底层开发人员进行驱动程序的开发，以及进行汇编级别的优化和高级编程语言运行库的开发等操作[/scode]在现代处理器的安全支持（特权级隔离，内存空间隔离等）下，应用程序就不能直接以函数调用的方式访问操作系统的函数，以及直接读写操作系统的数据变量。[scode type="red"]这里的不能直接以函数调用的方式访问操作系统的函数，我认为指的是操作系统内部使用的函数而非暴露出来的系统调用接口[/scode]不同类型的应用程序可以通过符合操作系统规定的ABI规范的系统调用接口，发出系统调用请求，来获得操作系统的服务。操作系统提供完服务后，返回应用程序继续执行。[scode type="share"]API 与 ABI 的区别应用程序二进制接口 ABI 是不同二进制代码片段的连接纽带。ABI 定义了二进制机器代码级别的规则，主要包括基本数据类型、通用寄存器的使用、参数的传递规则、以及堆栈的使用等等。ABI 与处理器和内存地址等硬件架构相关，是用来约束链接器 (Linker) 和汇编器 (Assembler) 的。在同一处理器下，基于不同高级语言编写的应用程序、库和操作系统，如果遵循同样的 ABI 定义，那么它们就能正确链接和执行。应用程序编程接口 API 是不同源代码片段的连接纽带。API 定义了一个源码级（如 C 语言）函数的参数，参数的类型，函数的返回值等。因此 API 是用来约束编译器 (Compiler) 的：一个 API 是给编译器的一些指令，它规定了源代码可以做以及不可以做哪些事。API 与编程语言相关，如 libc 是基于 C 语言编写的标准库，那么基于 C 的应用程序就可以通过编译器建立与 libc 的联系，并能在运行中正确访问 libc 中的函数。简单来说，API是编译器级别的，ABI是汇编级别的。[/scode]系统调用接口的一些比较重要的功能与相应的抽象对于系统调用接口提供的功能，下面列出了一些值得了解的功能：一个运行的程序可以创建另一个程序的实例吗？需要等待另外一个程序执行完成吗？操作系统能停止或恢复另一个正在运行的程序吗？一个运行的程序如何与连接到计算机的设备通信并通过它们与物理世界通信？多个运行的程序如何同步互斥地对共享资源进行访问？一个运行的程序可以要求更多（或更少）的内存空间吗？一个运行的程序如何持久地存储用户数据？一个运行的程序如何能输出字符信息？如何能获得输入字符信息？下面列出了一些相对比较重要的操作系统接口或抽象：进程（即程序运行过程）管理：复制创建进程 fork 、退出进程 exit 、执行进程 exec 等。线程管理：线程（即程序的一个执行流）的创建、执行、调度切换等。线程同步互斥的并发控制：互斥锁 mutex 、信号量 semaphore 、管程 monitor 、条件变量 condition variable 等。进程间通信：管道 pipe 、信号 signal 、事件 event 等。虚存管理：内存空间映射 mmap 、改变数据段地址空间大小 sbrk 、共享内存 shm 等。文件I/O操作：对存储设备中的文件进行读 read 、写 write 、打开 open 、关闭 close 等操作。外设I/O操作：外设包括键盘、显示器、串口、磁盘、时钟 … 但接口均采用了文件 I/O 操作的通用系统调用接口。[scode type="share"]上述表述在某种程度上说明了操作系统对计算机硬件重要组成的抽象和虚拟化，使得应用程序只需基于对简单的抽象概念的访问来达到对计算机系统资源的使用：文件 (File) 是外设的一种抽象和虚拟化。特别对于存储外设而言，文件是持久存储的抽象。地址空间 (Address Space) 是对内存的抽象和虚拟化。进程 (Process) 是对计算机资源的抽象和虚拟化。而其中最核心的部分是对CPU的抽象与虚拟化。[/scode]有了这些系统调用接口，简单的应用程序就不用考虑底层硬件细节，可以在操作系统的服务支持和管理下简洁地完成其应用功能了。
操作系统学习笔记（1）——什么是操作系统
前言最近找到一个好文档，关于如何用Rust编写一个操作系统，里面系统的讲述了操作系统的相关知识和源代码等等，所以就打算跟着这个文档开始学习操作系统相关的知识(之后就可以去读CSAPP了从认识来看一个操作系统（OS）是一个软件，它帮助用户和应用程序使用和管理计算机的资源。操作系统可能对最终用户不可见，但控制着嵌入式设备、更通用的系统（如智能手机、台式计算机和服务器）以及巨型机等各种计算机系统。从功能开始操作系统主要做的事情就只有两件：一是向下管理计算机硬件和各种外设，二是向上给应用软件提供各种服务帮助。进一步描述操作系统是一个可以管理CPU、内存和各种外设，并管理和服务应用软件的系统软件。[scode type="share"]系统软件是在一个计算机系统范围内使用的软件，可涉及到整个计算机系统。文本编辑器这样的软件只涉及到对文本文件的编辑，并不能被叫做系统软件。而在计算机中安装的 C 标准库 libc（类似的有 Rust 标准库 等）可以算是一个，因为它提供了与OS交互的系统调用接口，其功能覆盖了整个计算机系统，会被许多不同的软件访问。[/scode]为了完成这些工作，操作系统需要知道如何与硬件打交道，如何更好地给应用软件提供服务，这就有一系列操作系统相关的理论、抽象、设计等来支持如何做和做得好的需求。[scode type="blue"]在不同的应用场景下，操作系统的边界也是不同的，我们可以把运行时库、图形界面支持库等这些可支持不同应用的系统软件 (System Software) 也看成是操作系统的一部分。比如说嵌入式环境，一般操作系统以运行时库的形式与应用程序紧密结合在一起，形成一个可在嵌入式硬件上单一执行的嵌入式应用。而 Android 应用运行在 ARM 处理器上 Android 操作系统的执行环境中。[/scode]简化描述站在应用程序的角度来看，我们可以发现常见的应用程序其实是运行在由硬件、操作系统内核、运行时库、图形界面支持库等所包起来的一个 执行环境 (Execution Environment) 中，应用程序只需根据与系统软件约定好的应用程序二进制接口 (ABI, Application Binary Interface) 来请求执行环境提供的各种服务或功能，从而完成应用程序自己的功能。于是我们可以将操作系统的定义简化成：应用程序的软件执行环境。一直在变化的定义操作系统的内涵和外延随着历史的发展也一直在变化，并没有类似于“1+1=2”这样的明确定义。如今在二十一世纪初期的大众眼中，操作系统就是他们的手机/终端上的软件系统，包括各种应用程序集合，图形界面和网络浏览器是其中重要的组成部分。但无论操作系统的内在实现和具体目标如何变化，其管理计算机硬件，给应用提供服务的核心定位没有变化。