免费解析网站制作,163注册企业邮箱,wordpress网站重做,网站核验单怎么下载xv6源码分析 001
我们先看看xv6这个项目的基本结构#xff08;只看代码部分#xff09;
主要就是两个目录kernel 和 user。 user是一些用户程序#xff0c;也就是我们平时在shell上面执行的命令#xff0c;每执行一个命令就会创建一个新的用户进程来执行这个命令 在user目…xv6源码分析 001
我们先看看xv6这个项目的基本结构只看代码部分
主要就是两个目录kernel 和 user。 user是一些用户程序也就是我们平时在shell上面执行的命令每执行一个命令就会创建一个新的用户进程来执行这个命令 在user目录下有两个文件需要我们注意一下usys.pl 和 initcode.S usys.pl主要是输出一段汇编指令并通过重定向输入到指定的文件中下面我们就来看看这段汇编 print # generated by usys.pl - do not edit\n;print #include \kernel/syscall.h\\n; # 引入定义对应系统调用号的宏常量的头文件sub entry {my $name shift;print .global $name\n;print ${name}:\n;print li a7, SYS_${name}\n;print ecall\n;print ret\n;
}很明显这是系统调用的trap过程但是这个是什么语言我还不清楚 .global $name类似C语言中的声明global声明这个过程在这个目录内可见${name}:过程的名称在c代码中通过一个向量extren char name[];可以引入这个汇编过程 li a7, SYS_${name}li指令的作用将任意的立即数加载到指定的寄存器中这里是将SYS_{name}这个宏常量加载到寄存器a7中为什么这么做呢明天我们将会看到在进行系统调用的时候发起系统调用的进程将会将CPU的执行权交给内核线程内核线程如何知道进程调用的是那个系统调用呢这是就可以从寄存器a7中取出先前存放进去的SYS_{name}系统调用号来执行相应的系统调用。注意这是涉及的是线程切换由用户态线程切换到了内核线程因为每个进程都都一个内核线程这样能够大大减少系统调用的开销。ecall陷入指令trap使进程从用户态切换到内核态即用户线程切换到内核线程ret调用返回返回的内核线程的上下文 我们再来看看initcode.S 主要作用是系统调用exec和start的过程我就直接在源码上注释了 # Initial process that execs /init.
# This code runs in user space.#include syscall.h# exec(init, argv)
.globl start # 声明start过程为整个目录可见
start: # 过程的开始标签la a0, init # 将init这个字符串的地址加载到寄存器a0la a1, argv # 将argc字符串的地址加载到寄存器a1li a7, SYS_exec # 将exec的系统调用号加载到寄存器a7ecall # 陷入内核执行系统调用# for(;;) exit();
exit: li a7, SYS_exitecalljal exit # jal指令是跳转到对应的标签相当于c语言的goto# char init[] /init\0;
init: # 定义一个字符串表示加载的可执行程序映像的名称.string /init\0# char *argv[] { init, 0 }; # 定义了一个argv 数组
.p2align 2
argv:.long init # init字符串的地址.long 0 # 一个空指针
ok今晚就先到这里了我们明晚再继续吧。
字符串的地址 .long 0 # 一个空指针
ok今晚就先到这里了我们明晚再继续吧。