关于程序、操作系统、运行
关于这个笔记,要从我开始学习这个课程说起
rCore-Tutorial-Book-v3 3.6.0-alpha.1 文档
这个课程是教人怎么用rust写在RISC-V上跑的操作系统
刚好我又对rust和操作系统比较感兴趣,就学了
概念还是很多的,比如操作系统的系统调用接口:
面向单一编程语言的函数库的编程接口 (API, Application Programming Interface)
和应用程序二进制接口 (ABI, Application Binary Interface)(像dll这种的)
先来说下系统调用接口是什么
系统调用接口
首先,我们在写一个应用程序,也就是软件的时候,一定需要使用到各种具体的硬件资源服务:比如网络连接,文件访问,以及最基础的算力
而访问这些硬件资源自然需要操作系统作为桥梁
那么,我们写的软件到底是怎么从操作系统获取这些资源的呢?
以文件访问作为例子,不管是什么语言,我们通常就是调用了一个库中的一个函数,然后把要访问的文件的地址传入,再调用一些方法,就得到了想要读取的数据
归根到底,我们是通过了一些“神奇的妙妙函数”获取这些资源的
我们使用到的函数往往还都是经过层层封装而得到的,而最底层的访问资源的函数,就是操作系统提供的,比如windows那些各种各样的dll就是ABI
而这些函数就叫做系统调用接口。
那么我们继续深究,调用系统调用接口直接把要求甩给了操作系统,那么操作系统是怎么实现的获取硬件资源呢?(问windows哪些dll是哪里来的,怎么实现的)
同样的,站在硬件的角度,为了让运行在cpu上的指令可以访问到计算机的资源,计算机组成的时候,cpu的指令集也提供了一些“神奇的妙妙指令”用于访问基础的硬件资源,而这些指令集经过高级语言的封装,再编译,就得到了最初的在操作系统上的系统调用接口
不过,即使是使用同一种指令集架构的cpu,访问硬件资源的方式也不见得相同,那么有没有什么统一的方法可以直接让我们在使用高级语言编写操作系统的时候访问到硬件资源呢?
RISC-V 的 SBI (SuperVisor 二进制接口) 就是来解决这个问题,它存在与硬件和操作系统之间,使得操作系统可以通过统一的SBI访问使用RISC-V架构的不同硬件组成的计算机。
接下来说说什么是操作系统
操作系统
我们先来看下电脑开机的过程
第一阶段,首先计算机通电,刻录在计算机上的初始程序直接开始运行,将储存的BIOS程序加载到内存中,然后交给BIOS程序进行执行
第二阶段,BIOS程序读取存储在硬盘上指定区域的操作系统程序加载到内存中,然后进入保护模式,全权交给操作系统程序进行执行
第三阶段,操作系统程序开始执行
所以,我们知道,操作系统实际上就是一个程序
接下来我们来聊聊程序是什么?
程序
被设计好的,可以按照计划的步骤被运行的指令集合就叫做程序
我们知道,操作系统是一个程序
我们平常使用的应用软件也是程序
那这个程序是运行在哪的?
是运行在操作系统上的吗?
这就很奇怪,一个程序怎么能够“运行”程序呢?
接下来我们来说说什么是“运行”?
运行
运行,我的理解是一种“被执行的过程”,也可以说成是一种“解读”的过程
按照这个定义,我们把一份用高级语言写成的代码从编译到运行的全过程分析一下
首先代码,就是我们按照一定语言规范写成的可以被编译链接成为程序的字符串文件
不同语言有不同的代码组成规范,然后各自语言的代码可以被各自语言的编译器/解释器 “解读”
代码需要被编译器“解读”为程序
因此不同语言写成的代码不能使用同一种编译器“解读”
代码被编译和解读,必然需要操作系统提供的系统调用接口
然后编译链接得到的所谓程序(.exe .o)实际上是按照各个操作系统各自编排方式的数据+二进制指令的文件集合
各个操作系统有不同的编排指令文件的方式
程序需要被操作系统“解读”才能运行
因此不同操作系统的程序不能跑在同一个操作系统上
被操作系统“解读”完成的程序文件,会以指令的形式运行在cpu上
不同cpu有不同的指令集架构
指令需要被cpu“解读”才能执行
因此不同指令集架构的指令不能运行在同一个架构的cpu上
理一下上面的过程
我们就能发现从 代码–>程序–>指令–>操作 的过程,每一步都是信息的“解读”的过程
而信息的解读就需要“解码器”,
代码到程序需要编译链接器进行解读
程序到指令需要操作系统进行解读
指令到具体操作的实现需要cpu进行解读(执行)
所以,操作系统是直接在硬件上运行的“程序”,准确说应该叫做指令
而应用程序就真指的是程序
操作系统这个指令 “运行”(解读) 程序,就不奇怪了
💬 评论区
暂无评论,来发表第一条吧。