原网页:http://rcore-os.cn/rCore-Tutorial-Book-v3/chapter0/2os-interface.html
ABI 即,应用程序和系统软件之间的约定
年代和操作系统的演化
寒武纪 1946 ----- 打孔纸带,计算机一次只执行一个程序
泥盆纪 鱼类 和 二叠纪 两栖动物 1950~60 ----- 批处理系统
-----
补充,批处理系统:
批处理是指把一批作业(古老的术语,可理解为现在的程序)以脱机方式输入到磁带上,并使这批作业能一个接一个地连续处理,流程如下:
-
将磁带上的一个作业装入内存;
-
操作系统把运行控制权交给该作业;
-
当该作业处理完成后,控制权被交还给操作系统;
-
重复 1-3 的步骤处理下一个作业直到所有作业处理完毕。
这样能充分地利用计算机系统:即尽量使该系统连续运行,减少 CPU 的空闲时间。批处理操作系统分为单道批处理系统和多道批处理系统。单道批处理操作系统只能管理内存中的一个(道)作业,无法充分利用大型计算机系统中的所有资源,致使系统整体性能较差。这就像泥盆纪 2 的史前鱼类–邓氏鱼,有着坚硬的头部铠甲,很强壮,但运动缓慢,灵敏度低,离不开水。
1964 年, IBM 公司开发了面向 System/360 系列大型计算机的统一可兼容的操作系统—— OS/360 12 ,它是一种多道批处理操作系统。多道批处理操作系统能管理内存中的多个(道)作业,可比较充分地利用计算机系统中的所有资源,提升系统整体性能。这里的“多道”是指允许同时把多个程序放入内存,并允许它们交替在 CPU 中运行,它们共享系统中的各种硬、软件资源。当一道程序因 I/O 请求而暂停运行时, CPU 便立即转去运行另一道程序。这就像二叠纪 3 的两栖动物,当水中暂时有危险或食物不多的时候,可以离开水面到陆地上来,并享用陆地上的动植物资源。
然而,处理器共享产生了程序间隔离的需求,以限制一个程序中的运行错误使其他程序崩溃或损坏。为此计算机中进一步添加了硬件级的内存保护机制,限制了一个程序在运行时能访问的地址空间,提高了故障隔离的能力,并减少了隔离的开销。另外,虽然批处理操作系统提高了系统的执行效率,但其缺点是人机交互性差,比如,批处理计算的一个实际挑战是如何调试应用程序和操作系统本身。如果程序员的代码出现错误,必须重新编码,上传内存,再执行。这需要花费以小时和天为单位的时间开销,使得程序员修改和调试程序很不方便。实质上是将计算机重新变成单用户系统。
-----
侏罗纪和白垩纪 恐龙 1961 ----- 分时系统
-----
补充,分时系统:
分时是指多个用户和多个程序以很小的时间间隔来共享使用同一台计算机上的 CPU 和其他硬件资源。1961 年,麻省理工学院的 Fernando Corbató 带领团队成功研发了在 IBM 709 计算机上的 CTSS(Compatible Time-Sharing System, 兼容时间共享系统)操作系统 9 ,它拥有分时系统必须有的特征:支持多个用户分享使用同一台计算机,即宏观上的同一时间段内能完成多个人机交互工作。
-----
古近纪 哺乳动物 20世纪80年代 ----- DOS, 初代Windows
第四纪 智人时代 21世纪初
|
-
二十一世纪 神人时代 今天
-----
API 和 ABI
操作系统的接口形式就是上一节提到的应用程序二进制接口 (ABI, Application Binary Interface)。
操作系统不能只提供面向单一编程语言的函数库的编程接口 (API, Application Programming Interface) ,它的接口需要考虑对基于各种编程语言的应用支持,以及访问安全等因素,使得应用软件不能像访问函数库一样的直接访问操作系统内部函数,更不能直接读写操作系统内部的地址空间。为此,操作系统设计了一套安全可靠的接口,我们称为系统调用接口 (System Call Interface)。系统调用接口通常面向应用程序提供了 API 的描述,但在具体实现上,还需要提供 ABI 的接口描述规范。
API 与 ABI 的区别
应用程序二进制接口 ABI 是 "不同二进制代码片段" 的连接纽带。ABI 定义了二进制机器代码级别的规则,主要包括基本数据类型、通用寄存器的使用、参数的传递规则、以及堆栈的使用等等。ABI 与处理器和内存地址等硬件架构相关,是用来约束链接器 (Linker) 和汇编器 (Assembler) 的。在同一处理器下,基于不同高级语言编写的应用程序、库和操作系统,如果遵循同样的 ABI 定义,那么它们就能正确链接和执行。
应用程序编程接口 API 是 "不同源代码片段" 的连接纽带。API 定义了一个源码级(如 C 语言)函数的参数,参数的类型,函数的返回值等。因此 API 是用来约束编译器 (Compiler) 的:一个 API 是给编译器的一些指令,它规定了源代码可以做以及不可以做哪些事。API 与编程语言相关,如 libc 是基于 C 语言编写的标准库,那么基于 C 的应用程序就可以通过编译器建立与 libc 的联系,并能在运行中正确访问 libc 中的函数。
值得注意的是,我们设计的各种操作系统总共只用到三十个左右系统调用功能接口(如下表所示),就可以支持应用需要的上述功能。而且这些调用与最初的 UNIX 的系统调用接口类似,几乎没有变化。尽管UNIX 的系统调用最早是在 1970 年左右设计和实现的,但这些调用中的大多数仍然在今天的系统中广泛使用。
编号 |
系统调用 |
所在章节 |
功能描述 |
---|---|---|---|
1 |
exit |
2 |
结束执行 |
2 |
write |
2/6 |
(2)输出字符串/(6)写文件 |
3 |
yield |
3 |
暂时放弃执行 |
4 |
get_time |
3 |
获取当前时间 |
5 |
getpid |
5 |
获取进程id |
6 |
fork |
5 |
创建子进程 |
7 |
exec |
5 |
执行新程序 |
8 |
waitpid |
5 |
等待子进程结束 |
9 |
read |
5/6 |
(5)读取字符串/(6)读文件 |
10 |
open |
6 |
打开/创建文件 |
11 |
close |
6 |
关闭文件 |
12 |
dup |
7 |
复制文件描述符 |
13 |
pipe |
7 |
创建管道 |
14 |
kill |
7 |
发送信号给某进程 |
15 |
sigaction |
7 |
设立信号处理例程 |
16 |
sigprocmask |
7 |
设置要阻止的信号 |
17 |
sigreturn |
7 |
从信号处理例程返回 |
18 |
sleep |
8 |
进程休眠一段时间 |
19 |
thread_create |
8 |
创建线程 |
20 |
gettid |
8 |
获取线程id |
21 |
waittid |
8 |
等待线程结束 |
22 |
mutex_create |
8 |
创建锁 |
23 |
mutex_lock |
8 |
获取锁 |
24 |
mutex_unlock |
8 |
释放锁 |
25 |
semaphore_create |
8 |
创建信号量 |
26 |
semaphore_up |
8 |
减少信号量的计数 |
27 |
semaphore_down |
8 |
增加信号量的计数 |
28 |
condvar_create |
8 |
创建条件变量 |
29 |
condvar_signal |
8 |
唤醒阻塞在条件变量上的线程 |
30 |
condvar_wait |
8 |
阻塞与此条件变量关联的当前线程 |
<--- 没看完,我觉得,理论的东西还是等具体的实践做完了再来看
配置实验环境:
1. 安装 Rust
标签:操作系统,rcore,批处理,ABI,接口,第零,API,-----,阅读 From: https://www.cnblogs.com/yinhuachen/p/17004190.html