首页 > 其他分享 >MIT 6.S081 Isolation & System call entry/exit

MIT 6.S081 Isolation & System call entry/exit

时间:2023-07-12 10:36:48浏览次数:45  
标签:内核 Isolation System exit mode 寄存器 table page trap

Trap 机制

程序运行往往需要完成用户空间和内核空间的切换,每当:

  • 程序执行系统调用(system call);
  • 程序出现了 page fault 等错误;
  • 一个设备触发了中断;

都会发生这样的切换。

这里用户空间切换到内核空间通常被称为 trap,因此有时候我们会说程序“陷入”到内核态。trap 机制需要尽可能的简单。

trap 的工作,可以说是让硬件从适合运行用户程序的状态,切换到适合运行内核代码的状态。

这里说的状态中,我们最关心的状态可能是 $32$ 个用户寄存器,我们尤其需要关注以下硬件寄存器的内容:

  • 堆栈寄存器(stack register,又称 stack pointer);
  • 程序计数器(Program Counter Register);
  • 表明当前 mode 的标志位的寄存器,表明当前是 supervisor mode 还是 user mode;
  • 控制 CPU 工作方式的寄存器,例如 SATP(Supervisor Address Translation and Protection)寄存器,它包含了指向 page table 的物理内存地址;
  • STVEC(Supervisor Trap Vector Base Address Register)寄存器,它指向了内核中处理 trap 的指令的起始地址;
  • SEPC(Supervisor Exception Program Counter)寄存器,在 trap 的过程中保存程序计数器的值;
  • SSRATCH(Supervisor Scratch Register)寄存器

在 trap 的最开始,CPU 所有的状态肯定还是在运行用户代码而不是内核代码,在 trap 处理的过程中,我们会逐渐更改状态,或者对状态做一些操作,我们可以设想一下我们需要做哪些操作:

  • 保存 $32$ 个用户寄存器的状态,例如,当响应中断完成后,我们会希望能恢复用户程序的执行,而这些寄存器需要被内核代码所使用,因此,在 trap 之前,我们需要保存这 $32$ 个用户寄存器的内容;
  • 保存 PC 的内容,原因类似于保存 $32$ 个用户寄存器;
  • 将 mode 修改为 supervisor mode;
  • 运行内核代码前,将 SATP 由指向 user page table 修改为指向 kernel page table;

trap 机制不会依赖于 $32$ 个用户寄存器;

supervisor mode 可以实现什么 user mode 不能实现的事情?(其实不多)

  • 读写 SATP、STVEC、SEPC、SSCRATCH 等寄存器;
  • 使用 PTE_U 标志位为 0 的 PTE;

supervisor mode 并不能读写任意物理地址,在 supervisor mode 中,也需要通过 page table 来访问内存,如果一个物理地址映射的虚拟地址并不在当前 SATP 指向的 page table 中,又或者 SATP 指向的 page table 中,PTE_U = 1,那么 supervisor mode 不能使用那个地址。

Trap 代码执行流程

2020 版的课程以 Xv6 的 sh.cgetcmd 中执行的 write 系统调用来说明这个例子(2021 版中,getcmd 转而使用了 fprintf),我这里其实是调试的 echo.c

执行 make CPUS=1 qemu-gdb 以及 gdb-multiarch(注意要配置好 .gdbinit),然后 gdb 中执行 file user/echo.o 以及 b main,将断点打在 user/echo.cmain 函数处,多执行几次 continue,直到 qemu 中的 shell 加载完成,可以执行命令了,输入 echo zwyyy,再在 gdb 的窗口中执行 layout split 以及 continue,函数将停在 main 函数处,从 echo.asm 中我们可以看到 write 系统调用对应的 ECALL 指令所在的地址,为 $\text{0x31c}$,因此我们执行 b *0x31c,然后执行 continue

然后我们打印 PC 的值,正好在 $\text{0x31c}$ 处:

a0,a1,a2 寄存器中的内容是 shell 传递给 write 系统调用的参数,a0 是文件描述符,a1 是 shell 想要写入的字符串的指针,a2 是想要写入的字符数:

在 QEMU 中输入 ctrl + a,再输入 c 可以进入到 QEMU 的 console 中,之后输入 info mem,QEMU 会打印完整的 page table

可以看到最后两个 pte 的 vaddr 非常大,接近虚拟地址的顶端,这两个 page 分别是 trapframe page 和 trampoline page。

之后的实例还是按照 2020 的课程视频来讲,(我自己停在 ecall 执行 si 之后会直接到 ret,进入内核的流程没有显示出来。。。)

ECALL 指令其实只会做三件事:

  • 将代码从 user mode 切换到 supervisor mode;
  • 将 PC 的值保存在 SEPC 寄存器中;
  • 跳转到 STVEC 寄存器指向的指令;

执行 ECALL 之后,程序会位于 trampoline page 的起始位置,即 0xffffff000 这个位置。由于 gdb 的一些奇怪行为,trampoline page 中的第一条执行(即 csrrw 指令已经被执行了:

到目前位置,用户寄存器的值还没有被改变。

标签:内核,Isolation,System,exit,mode,寄存器,table,page,trap
From: https://www.cnblogs.com/zwyyy456/p/17546849.html

相关文章

  • SystemVerilog Dynamic Array Randomization
    https://verificationguide.com/systemverilog/systemverilog-dynamic-array-randomization/DynamicArrayRandomizeForadynamicarray,itispossibletorandomizebotharraysizeandarrayelements.randomizedynamicarraysizeInbelowexample,dynamicarr......
  • laraveladmin 上传图片通过filesystems到其他网站提供的接口
    要通过Laravel的Filesystems将图片上传到其他网站提供的接口,可以按照以下步骤进行操作:首先,确保你已经在Laravel中配置好了Filesystems。你可以在config/filesystems.php文件中定义一个新的磁盘配置,用于上传图片到其他网站的接口。'disks'=>[//其他磁盘配置.........
  • 1845D - Rating System
    Problem-1845D-CodeforcesRatingSystem-洛谷|计算机科学教育新生态(luogu.com.cn)题意可以去洛谷看一下。没带苏菲狗,鼠标手画。属实抱歉我们可以看到这个最后的等级是这样计算的,直到它第一次到k只是一个前缀和,在达到k之后,出现一次<0的连续区间等级就回归k,在某处回......
  • [Linux][报错解决] linux发行版无法运行systemctl和cron
    报错信息运行cron时显示了"newcrontabisinstalling",然而事实是根本没有运行crontab里的命令*/1****date>>/tmp/mydate查找解决方法时发现有两个可能的原因1.未添加必要的环境变量cron跑指令和在shell里直接写是不一样的,cron并不知道哪个路径是他需要用来跑指令的......
  • system函数的风险和解决
    system函数的风险和解决源码摘录/*ExecuteLINEasashellcommand,returningitsstatus.*/staticintdo_system(constchar*line){intstatus=-1;intret;pid_tpid;structsigactionsa;#ifndef_LIBC_REENTRANTstructsigactionintr,quit;#e......
  • Anolis 8.8 (CentOS 8) install snapper to support system snapshot.
    Anolis8.8(CentOS8)installsnappertosupportsystemsnapshot.cd/etc/yum.repos.d/wgethttps://download.opensuse.org/repositories/filesystems:snapper/CentOS_8/filesystems:snapper.repoyuminstallsnappersudoyuminstallpython3python3-setuptools......
  • Educational Codeforces Round 151 (Rated for Div. 2) D. Rating System
    贪心由题可得,对于k的选择一定是单调递增的,对于前面选定的k后面选的k必须大于之前选的才会发生新的变化,因此k的选择其实是一个单调栈,由前缀和组成我们要想最后的结果最大,则k值一定要尽可能的高,例如当选中i为k值时,如果从i后面某个原本的前缀和要大于选k之后所得到的前缀和的话,说明......
  • Python中os.system()、subprocess.run()、call()、check_output()的用法
    1.os.system()os.system()是对C语言中system()系统函数的封装,允许执行一条命令,并返回退出码(exitcode),命令输出的内容会直接打印到屏幕上,无法直接获取。示例:#test.pyimportosos.system("ls-l|greptest")#允许管道符#测试执行$ll<=======......
  • C#winform软件移植上linux的秘密,用GTK开发System.Windows.Forms
    国产系统大势所趋,如果你公司的winform界面软件需要在linux上运行,如果软件是用C#开发的,现在我有一个好的快速解决方案。世界第一的微软的MicrosoftVisualStudio,确实好用,C#开发起来确实效率高,不过微软的开发语言开发的软件的界面都是跟windows系统绑定的,现在.netcore已......
  • SystemVerilog编码技巧
    工程组织可以将一些公用的变量定义成package,放到同一个sv文件中,然后在需要用到公用变量的文件中通过import来引用变量,创建filelist时,需要通过+incdir+(包含package的sv文件的路径)来指示,并将这些package的sv列在其他sv前面packagerv_param_pkg; parameterWITDH=8;endpacka......