首页 > 其他分享 >MIT 6.S081 操作系统组织架构

MIT 6.S081 操作系统组织架构

时间:2023-07-03 20:45:57浏览次数:34  
标签:ECALL sys 调用 操作系统 kernel exec SYS S081 MIT

进程概述

64 位的 RISC-V 的 VAS 是 39 位的,即 VA 只有 39 位,而 Xv6 则只有 38 位,最大虚拟地址为 #define MAXVA 0x3fffffffff

VAS 的顶端,即最高位存放了两个 page,一个是用于 trampoline,一个用于 mapping the process's trapframe。 Xv6 使用这两个 page 来切换到内核以及返回。

进程的状态被定义在 kernel/proc.h 的结构体 struct proc 所描述,进程在内核中最重要的信息就是它的 page table、 kernel stack 以及运行状态(run state)。

A process can make a system call by executing the RISC-V ecall instruction. This instruction raises the hardware privilege level and changes the program counter to a kernel-defined entry point.

The code at the entry point switches to a kernel stack and executes the kernel instructions that implement the system call. When the system call completes, the kernel switches back to the user stack and returns to user space by calling the sret instruction. (x64 架构似乎是 iret?)

tNX75y3sYmVHobl

User/Kernel mode 切换

我们是如何从 user mode 进入到 kernel mode 的?

例如,当 ls 程序运行时,会调用 read/write 系统调用;shell 程序会调用 fork 或者 exec 系统调用,所以必须要有一张方式可以使得用户的应用程序能够将控制权以一种协同工作的方式转移到内核,这样内核才能提供相应的服务。

在 RISC-V 中,有一个专门的指令用于实现这一功能,叫做 ECALL(指令而非函数?),ECALL 接收一个数字参数,当一个用户程序想要将程序的执行控制权转移到内核,它只需要执行 ECALL 指令,并且传入一个数字。这里的数字参数代表了应用程序想要调用的 System CallSystem Call 表如下所示:

static uint64 (*syscalls[])(void) = {
    [SYS_fork] sys_fork,
    [SYS_exit] sys_exit,
    [SYS_wait] sys_wait,
    [SYS_pipe] sys_pipe,
    [SYS_read] sys_read,
    [SYS_kill] sys_kill,
    [SYS_exec] sys_exec,
    [SYS_fstat] sys_fstat,
    [SYS_chdir] sys_chdir,
    [SYS_dup] sys_dup,
    [SYS_getpid] sys_getpid,
    [SYS_sbrk] sys_sbrk,
    [SYS_sleep] sys_sleep,
    [SYS_uptime] sys_uptime,
    [SYS_open] sys_open,
    [SYS_write] sys_write,
    [SYS_mknod] sys_mknod,
    [SYS_unlink] sys_unlink,
    [SYS_link] sys_link,
    [SYS_mkdir] sys_mkdir,
    [SYS_close] sys_close,
    [SYS_trace] sys_trace,
};

ECALL 会跳转到内核中一个特定的、由内核控制的位置,在 Xv6 中存在一个唯一的系统调用接入点,每一次应用程序执行 ECALL 指令,应用程序都会通过这个接入点进入到内核中。例如,不论是 shell 还是其他的应用程序,当它在用户空间执行 fork 时,它并不是直接调用操作系统中对应的函数,而是调用 ECALL 指令,并将 fork 对应的数字 SYS_fork 作为参数传给 ECALL,之后再通过 ECALL 跳转到内核中。

在内核侧,有一个位于 syscall.c 的函数 syscall,每一个从用户程序发起的系统调用都会调用到这个 syscall 函数,syscall 函数会检查 ECALL 的参数,通过这个参数,内核可以知道要调用的是 fork

假设现在要执行另外一个系统调用 exec,两个参数,用户代码会将 exec 需要的参数存放在寄存器 a0a1 中,事实上这里的两个参数都是地址,并将系统调用号存放在寄存器 a7 中。

用户态中执行的 exec 系统调用并不能直接执行内核中的 exec 代码,而是要由封装好的系统调用函数执行 ECALL 指令,所以 exec 函数实际上调用的是 ECALL 指令,指令的参数代表了 exec 系统调用的索引数字,之后控制权到了 syscall 函数,syscall 函数才实际调用 exec 系统调用。

Xv6 启动流程

RISC-V 启动时,先运行一个存储于 ROM 中的 bootloader 程序 kernel.ld 来加载 xv6 kernel 到内存中,然后在 machine 模式下从 _entry 开始运行 Xv6。bootloader 将 xv6 kernel 加载到 0x80000000 的物理地址中,因为前面的地址中有 I/O 设备

_entry 中设置了一个初始 stack,stack0 来让 Xv6 执行 kernel/start.c。在 start 函数先在 machine 模式下做一些配置,然后通过 RISC-V 提供的 mret 指令切换到 supervisor mode,使 program counter 切换到 kernel/main.c

main 先对一些设备和子系统进行初始化,然后调用 kernel/proc.c 中定义的 userinit 来创建第一个用户进程。这个进程执行了一个 initcode.S 的汇编程序,这个汇编程序调用了 exec 这个 system call 来执行 /init,重新进入 kernel。exec 将当前进程的内存和寄存器替换为一个新的程序(/init),当kernel执行完毕exec指定的程序后,回到 /init 进程。/inituser/init.c)创建了一个新的 console device 以文件描述符 0, 1, 2 打开,然后在 console device 中开启了一个 shell 进程,至此整个系统启动了。

标签:ECALL,sys,调用,操作系统,kernel,exec,SYS,S081,MIT
From: https://www.cnblogs.com/zwyyy456/p/17523954.html

相关文章

  • MIT 6.S081 页表
    Paginghardware总的来说,Xv6的虚拟内存到物理内存的映射方式与x64是一致的,都是使用页表来进行映射。区别在于,Xv6只使用了三级页表,而x64则是使用四级页表,另外,二者的页表层级的命名也有区别,对Xv6来说,最高级的页表是L3(其地址存放于寄存器satp中)。每个pagetable含有5......
  • 统信UOS国产服务器操作系统(UOS Server 20-1060e)安装使用体验
    总体来说,UOS系统的安装还是很简明的。需要注意的是后期的驱动安装和其他各方面的使用细节。以下是具体安装过程:(感谢统信软件河北团队的大力支持。)特别感谢统信的郭赞、喵喵喵、Zero等各位大神的帮助。一、安装部分1、进入安装界面后,您自己很明确的请根据自己需求修改。2、“......
  • MIT6.5840 lab2,3 记录
    参考链接课程地址如何Debug:没有它可怎么活,几万行的日志怎么看Students'GuidetoRaftraft算法可视化:直观展示raft可视化简单入门raft讲解视频:强烈推荐感想感觉理论+实践来学一个东西才学的深刻,特别是对于我这样对抽象理解不太行的,每次见识了一个算法或系统真正如何运行......
  • OutOfMemoryError: Java heap space/GC overhead limit exceeded 内存溢出问题排查
    一、背景我开发的给产线使用的工具时不时就无法登录,查看日志基本上都是内存溢出,查看实际内存基本上都占满了JVM设置的内存大小导致的现象就是SpringBoot项目无法登录,导致系统不可用。下面是我的java启动设置。javaw-Xmx6G-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPat......
  • x64 架构,也称作AMD64或Intel 64,是指一种64位的处理器架构,是对x86架构的扩展和升级。x6
    x64架构,也称作AMD64或Intel64,是指一种64位的处理器架构,是对x86架构的扩展和升级。x64架构支持更大的内存寻址范围和更高的性能,适用于运行64位操作系统和应用程序。x64架构最早由AMD引入,并在2003年取得了广泛的市场认可。随后,Intel也推出了兼容x64架构的处理器。目前,绝大多数......
  • 多个commit合并为一个
    在进行多个commit合并成一个博客编写的过程中,你可以使用以下代码示例作为参考:#合并多个commitgitrebase-iHEAD~N#N代表需要合并的commit数目,例如合并最近3个commit,N为3,也可以选择任意commit信息gitrebase-istartCommit[endCommit],默认endCommit是最新的commit,com......
  • Debian是一种流行的自由操作系统,它基于Linux内核,采用自由软件的方式进行开发和发布 De
    Debian是一种流行的自由操作系统,它基于Linux内核,采用自由软件的方式进行开发和发布。以下是关于Debian起源和其开发者的信息:Debian的起源:Debian的起源可以追溯到1993年,最初由IanMurdock(IanAshleyMurdock,1970-2015)创建。他希望构建一个自由、开放和稳定的操作系统发行版,以及一......
  • 使用Redis时的vm.overcommit_memory内存分配控制
    最近在使用Redis的时候遇到了linux系统中的vm.overcommit_memory参数设置,对此不是很了解,于是研究了一下,有了本文。 ===================================== 一个尝试,如何在内存中申请空间:>>>100000*400000*8/1024/1024/1024298.0232238769531 实际代码:importnumpyas......
  • MIT 6.s081 实验环境搭建
    准备工作Linux系统,我是在实验室配的主机上装了DebianBookworm,然后mac通过ssh连接上去进行操作,宿舍里则是使用的wsl2,里面的发行版也是DebianBookworm。开始配置clone源码在~/Documents/code/mit目录下执行gitclonegit://g.csail.mit.edu/xv6-labs-2021,将源码cl......
  • Xv6 操作系统组织架构
    进程概述64位的RISC-V的VAS是39位的,即VA只有39位,而Xv6则只有38位,最大虚拟地址为#defineMAXVA0x3fffffffff。VAS的顶端,即最高位存放了两个page,一个是用于trampoline,一个用于mappingtheprocess'strapframe。Xv6使用这两个page来切换到内核以及返回。......