book-riscv-rev1.pdf 翻译(自用)第一章 操作系统接口

news2024/11/17 9:45:29

Job of operating system:

操作系统使得多个程序分享一台计算机,提供一系列仅靠硬件无法支持的服务。

  1. 管理与抽象低级别硬件(如:文件处理程序不需要关注使用哪种硬盘)
  2. 使得多个程序分享硬件(programs that can run at the same time)
  3. 为程序提供可控的相互交流(分享数据或工作)的方式。

操作系统是通过interface为用户程序提供服务,然而设计良好的接口并不容易:

一方面,希望接口简单且应用场景单一,以实现起来更简单;

一方面,希望提供复杂的feature给应用。

So,设计依赖机制较少,但可结合起来以提供更具通用性的接口。

        本书使用一个操作系统作为例子来诠释操作系统的概念。xv6 系统提供了一些由 Ken Thompson 与 Dennis Ritchie 的 Unix系统引入的基本接口,同时也模仿了Unix 系统的内部设计。Unix 系统提供的狭窄接口能很好底结合起来,以实现令人惊喜的通用性。此接口是如此的成功,以至于现代操作系统,BSD,Linux,Mac OS X, Solaris, 甚至Microsoft Windows 都具有类 Unix 的接口。理解 xv6 是理解这些操作系统的不错的开端。

        正如 图1.1所示,xv6 采用了传统的kernel形式,内核是向用户程序提供服务的特定程序。每个运行的程序称之为进程(process),都具有其对应的内存空间(memory),内存中包含指令、数据与栈(instructions, data, and a stack)。

 

  1. 指令 (instructions) 实现程序的计算 (computation)
  2. 计算基于变量 (data)
  3. 栈组织程序的过程调用 (procedure calls)

一台计算机通常有很多进程,但仅一个内核。

        当进程需要 invoke 内核服务时,程序 invoke 系统调用 (system call),系统调用进入内核,内核服务并返回,所以进程在用户空间 user space 与内核空间 kernel space 之间交替执行。

        内核使用CPU的硬件保护机制 (hardware protection mechanisms) 以保证每个执行在用户空间的程序只能访问自己的内存。内核拥有实现此硬件保护机制所需的硬件特权 (hardware privileges) ,用户程序 (user program) 无此特权。当用户程序 invokes 一个系统调用时,硬件会提高特权级别并开始执行内核中的 pre-arranged 函数。

        内核提供的系统调用集是用户程序可见的 interface。Xv6内核提供的服务与系统调用,是传统 UNIX内核提供的子集。

        本章的剩余部分将提到 xv6 系统的服务:进程,内存,文件描述符,管道以及一个文件系统,通过代码段与讨论shell使用这些服务的方法,来详述xv6服务。shell(Unix的命令行用户接口)对系统调用的使用显示了这些系统调用设计的精巧。

        shell 读取用户输入并执行,其作为一个用户程序,而非内核的一部分,也体现了 system call interface 的强大之处。shell 并不特殊,易被取代, 现代UNIX系统有一系列shell可供选择。The xv6 shell is a simple implementation of the essence of the Unix Bourne shell.

1.1 进程与内存

        一个 xv6 进程包含用户空间的内存(指令,数据与栈),以及仅内核可见的各进程状态。xv6 为等待执行的进程间分配CPU秒。当一个进程不在执行时,xv6 保存其CPU寄存器,下次执行时恢复。内核为每个进程关联一个进程标识符(PID)。

        一个进程(父进程)可以通过 fork 系统调用创建新进程。fork 创建的新进程称之为子进程,子进程拥有内存的内容与父进程相同。fork 在子进程与父进程都返回,具体而言,父进程中返回子进程的 PID,子进程中返回 0。例如,下面代码段

int pid = fork();
if(pid > 0){
    printf("parent: child=%d\n", pid); //1
    pid = wait((int *) 0);
    printf("child %d is done\n", pid);
} else if(pid == 0){
    printf("child: exiting\n");//2
    exit(0);
} else {
    printf("fork error\n");
}

        exit 系统调用终止调用进程的执行,释放资源,如内存及打开的文件。Exit 接受一个整型数,一般 0 表示成功,1 表示失败。wait 系统调用返回当前进程的某个退出/终止的子进程的PID,拷贝子进程的退出状态,并传递给 wait 的地址参数,如果调用进程无子进程退出,wait 等待某个子进程退出;若调用进程无子进程,wait 立刻返回 -1。当然,如果调用进程不在乎子进程的退出状态,完全可以给 wait 传递一个 0 地址。

(注意1,2 处的打印顺序不一定)

        尽管,开始子进程的内存内容与父进程相同,但是,二者通过不同的内存与寄存器执行,改变某个进程中的某个变量不会影响另一个进程中该变量的值。如,wait 返回值存在父进程的 pid 中,这不会改变子进程的pid 变量,其值依然为0。

        exec 系统调用使用加载自文件的新 memory image取代调用进程的内存。使用的文件必须为特定格式,以指明文件的哪个部分为指令、数据,以及从哪个指令开始执行等。xv6 使用 ELF 格式,第三章将讨论更多细节。当 exec 成功执行时,不会返回到调用进程,加载自文件的指令从ELF header 中声明的入口点开始执行。exec 有两个参数:文件名,字符串数组。

char *argv[3];
argv[0] = "echo";
argv[1] = "hello";
argv[2] = 0;
exec("/bin/echo", argv);
printf("exec error\n");

        此代码段用 参数列表为 “echo hello” 的/bin/echo 程序实例取代调用进程。大多数程序忽略参数数组的首元素(一般为程序名)。

        

        xv6 shell 使用以上的系统调用代替用户执行程序。shell 的主要结构很简单,参考 user/sh.c 内的main函数。主循环使用 getcmd 读取用户的一行输入。然后调用 fork 拷贝 shell 进程。父进程调用 wait,而子进程执行命令。例如,如果用户向 shell 输入 “echo hello”,runcmd 被调用的同时被传递了参数 "echo hello",runcmd 实际执行命令。对于 "echo hello",exec 将被调用。若 exec 成功,子进程将执行来自 echo 而非 runcmd 的指令。某个点,echo 调用 exit ,这将使得父进程从 wait 返回。

        为什么 fork 与 exec 不作为一个调用整体实现呢?之后我们将发现这种分隔在shell 实现 IO重定向时大有用处。立即替换(exec)一个刚刚被创建的复制进程是一种浪费,为了避免这种浪费,通过虚拟内存技术,如写时复制,内核优化了 fork 的实现。

        xv6 大多数时候分配内存是显式的:fork 分配子进程所需用来拷贝父进程内存的内存,exec 分配存储可执行文件的内存。一个进程在运行时若需要更多空间,可调用 sbrk 实现增长 n 字节的数据内存。sbrk 返回新内存的位置。

1.2 I/O 与 文件描述符

        文件描述符是小的整型,指代一个进程可读写的,受内核管理的对象。一个进程可以通过打开一个文件、目录、设备或创建一个管道,或复制一个已存的描述符来获得一个文件描述符。为了简要起见,我们通常将一个文件描述符指向的对象视为一个 “文件”,文件描述符接口通过抽象,消除了文件、管道、设备之间的差异性,使之都可被视为字节流。输入输出将被视为 I/O

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/486264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【代码练习】旋转矩阵题解思路记录分析

题目 给你一幅由 N N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。 不占用额外内存空间能否做到? 示例 1: 给定 matrix [ [1,2,3], [4,5,6], [7,8,9] ], 原地旋转输入矩阵,使其变为: [ [7…

【C语言】学习

文章目录 前言1. warm up1.1 输出helloworld1.2 示例1.3 C语言程序结构 前言 以后要学习操作系统深度学习了&#xff0c;所以C语言就不可缺少了。 1. warm up 1.1 输出helloworld #include<stdio.h> void main() {printf("Hello World!!"); }std 标准 io输…

JS案例分析-某国际音x-tt-params参数分析

今天我们要分析的网站是&#xff1a;https://www.tiktok.com/selenagomez?langen&#xff0c;参数名字叫x-tt-params。 先来抓个包 这个接口是用户视频列表url&#xff0c;参数叫x-tt-params&#xff0c;该接口中还有其他参数像msToken&#xff0c;X-Bogus&#xff0c; _sig…

Cartesi 2023 年 4 月回顾

查看你不想错过的更新 2023年5月1日&#xff0c;感谢Cartesi生态系统中所有了不起的构建者&#xff01; 在一个激动人心的旅程之后&#xff0c;我们的首届全球线上黑客马拉松正式结束了&#xff01;有超过200名注册建造者参加&#xff0c;见证了所有参与者展示的巨大才华和奉献…

【Android】串口通信的理论与使用教程

Android系统诞生这十几年以来&#xff0c;Android开发工程师岗位经历了由盛转衰的过程&#xff0c;目前纯UI的Android APP已经鲜有公司愿意花费巨资去开发&#xff0c;Android APP开发的业务也仅剩游戏、物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;等…

springcloud:新一代分布式定时任务框架——PowerJob

0. 引言 之前我们讲解过主流的分布式定时任务框架xxl-job&#xff0c;随着技术的迭代更新&#xff0c;更多的定时任务框架也开始出现&#xff0c;今天我们来看一看新一代的定时任务框架PowerJob 1. PowerJob简介 PowerJob是基于java开发的企业级的分布式任务调度平台&#x…

Java设计原则之单一职责原则、开闭原则、里氏代换原则

文章目录 面向对象设计原则概述 单一职责原则 开闭原则 里氏代换原则 面向对象设计原则概述 软件的可维护性&#xff08;Maintainability&#xff09;和可复用性&#xff08;Reusability&#xff09;是两个非常重要的用于衡量软件质量的属性&#xff0c;软件的可维护性是指软…

Ubuntu常用命令总结

目录 1&#xff09;安装包命令及下载包命令 2&#xff09;阅读协议内容 3&#xff09;执行sh文件&#xff1a; 4&#xff09;创建虚拟环境 5&#xff09;激活虚拟环境 6&#xff09;虚拟环境中安装包 7&#xff09;安装上传代码工具 8&#xff09;代码上传 9&#xff09…

传输控制协议(TCP)知识点总结

文章目录 传输控制协议&#xff08;TCP)知识点总结介绍数据包格式TCP连接的建立和关闭三次握手四次挥手一张图展示这些过程 其他知识 传输控制协议&#xff08;TCP)知识点总结 维基百科: 传输控制协议&#xff08;TCP&#xff09;是Internet协议套件中的主要协议之一。它起源于…

五种最危险的新兴网络攻击技术

SANS研究所的网络专家揭示了包括网络罪犯和民族国家行为者在内的网络攻击者正在使用的五种最危险的新兴网络攻击技术。在旧金山举行的RSA网络安全会议上&#xff0c;由SANS研究所的几位分析师组成的讨论组讨论了新兴的网络攻击战术、技术和程序&#xff0c;并提供了如何为企业做…

使用GLSL来实现实时滤镜的效果

1. 先来明确几个概念 1.1 OpenGL OpenGL 全称为 Open Graphics Library&#xff08;开放图形库&#xff09;。 是用于渲染 2D 或 3D 图像的跨语言跨平台的应用程序编程接口&#xff0c;用于CPU控制GPU做图像渲染&#xff0c;是一套API。 提供设计人员一个共同的硬件驱动标准…

虚函数、静态绑定和动态绑定

静态绑定 class Base { public:Base(int data) :ma(data) {}void show() { cout << "Base::show()" << endl; }void show(int) { cout << "Base::show(int)" << endl; }protected:int ma; };class Derive : public Base { public…

Go | 一分钟掌握Go | 10 - 反射

作者&#xff1a;Mars酱 声明&#xff1a;本文章由Mars酱编写&#xff0c;部分内容来源于网络&#xff0c;如有疑问请联系本人。 转载&#xff1a;欢迎转载&#xff0c;转载前先请联系我&#xff01; 前言 反射你以为只在Java中有吗&#xff1f;Go也有反射机制&#xff0c;很多…

【JavaEE】应用层自定义协议及UDP协议

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 本篇文章将为大家介绍应用层中UDP协议~~ 在应用层这里&#xff0c;虽然存在一些现有的协议&#xff08;HTTP&#xff09;&#xff0c;但是也有很多情况&#xff0c;需要程序猿自定制协议&a…

OJ 功能介绍 使用手册

目录 服务器配置 OJ界面展示 用户管理 一、批量导入&#xff08;从方便管理角度建议以 学生姓名 作为 用户名 &#xff09; 二、批量生成临时用户 后期修改成需要的用户名和密码 &#xff08;学生登录后修改密码&#xff09; 三、用户自行注册&#xff08;填写邮箱获取验证码…

Nmap入门到高级【第九章】

预计更新Nmap基础知识 1.1 Nmap简介和历史 1.2 Nmap安装和使用方法 1.3 Nmap扫描技术和扫描选项 Nmap扫描技术 2.1 端口扫描技术 2.2 操作系统检测技术 2.3 服务和应用程序检测技术 2.4 漏洞检测技术 Nmap扫描选项 3.1 扫描类型选项 3.2 过滤器选项 3.3 探测选项 3.4 输出选项…

【致敬未来的攻城狮计划】— 连续打卡第二十天:RA2E1_UART —— 串口通信例程

系列文章目录 1.连续打卡第一天&#xff1a;提前对CPK_RA2E1是瑞萨RA系列开发板的初体验&#xff0c;了解一下 2.开发环境的选择和调试&#xff08;从零开始&#xff0c;加油&#xff09; 3.欲速则不达&#xff0c;今天是对RA2E1 基础知识的补充学习。 4.e2 studio 使用教程 5.…

Docker consul服务注册与发现

目录 一、服务注册与发现 1、什么是服务注册与发现 2、什么是consul 3、consul提供的一些关键特性 4、容器更新与发现 二、基于nginx与consul构建自动发现即高可用的Docker服务架构 consul服务器部署 1、建立consul 2、查看集群信息 3、通过http获取集群信息 regist…

SpringBoot+vue文件上传下载预览分片上传

学习链接 Blob & File 上传文件 前台 整个过程&#xff0c;就是在使用FormData 添加 上File&#xff08;这个Blob&#xff09;&#xff0c;并且key要和后台的名字对应上在点击上传按钮开始上传之前&#xff0c;使用了URL.createObjectURL(File)创建blobUrl&#xff0c;…

MySQL数据库之库表管理

一、常用的数据类型&#xff1a; 类型含义tinyint(n)1个字节&#xff0c;范围(-128~127)smallint(n)2个字节&#xff0c;范围(-32768~32767)mediumint(n)3个字节&#xff0c;范围(-8388608~8388607)int(n)4个字节(32个比特位)&#xff0c;整数型&#xff0c;范围(-2147483648~…