From fa75ac970cc33a18622b4c75a21e29a4eecdea91 Mon Sep 17 00:00:00 2001 From: shzhxh Date: Mon, 13 Jan 2020 21:55:29 +0800 Subject: [PATCH] update analysis of xv6 --- OS/XV6/专题分析/xv6的系统调用.md | 78 ++++++++++++++++++++++- OS/XV6/专题分析/xv6的组织.md | 23 +++++++ 2 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 OS/XV6/专题分析/xv6的组织.md diff --git a/OS/XV6/专题分析/xv6的系统调用.md b/OS/XV6/专题分析/xv6的系统调用.md index ed09d67..a718318 100644 --- a/OS/XV6/专题分析/xv6的系统调用.md +++ b/OS/XV6/专题分析/xv6的系统调用.md @@ -1,3 +1,77 @@ -在user/user.h定义了可用的系统调用。 +#### 从内核态到用户态 + +在xv6启动的过程中,0号核在main函数里会执行userinit函数,标记initcode处的数据会复制到第一个用户进程的内存空间。标记initcode的数字是一段代码,它对应的内容在user/initcode.S,是要把文件init的内容放到内存里以用户态去执行。文件init编译自user/init.c。 + +user/init.c把文件sh放到内存里执行。文件sh编译自user/sh.c,把用户输入的命令调入内存中执行,它就是xv6的shell。shell就是不断地使用getcmd函数读取命令行的输入,然后使用runcmd函数来执行命令行的输入。 + +#### 从用户态到内核态 + +系统调用怎么从用户态到的内核态呢?文件user/usys.pl生成user/usys.S,usys.S就是用来完成从用户态到内核态的代码。从代码可见,它是通过ecall产生一个异常来进入内核态。只要把usys.S生成的二进制文件链接进用户程序里,就可以使用系统调用了。 + +#### 进程和内存 + +相关系统调用的实现请看kernel/sysproc.c。 + +##### fork + +文件位置:kernel/proc.c。作用:创建一个进程。 + +fork函数一次调用两次返回,这很怪异,因为一般的调用都是只返回一次的。fork从父进程返回很正常,但为什么会从子进程返回呢?这是因为子进程继承了父进程的所有资源,这一句`*(np->tf) = *(p->tf)`相当于子进程复制了父进程运行的“快照”,子进程里也相当于进行了一个fork函数且从下一句开始执行。 + +1. p为当前进程,np为子进程。 +2. uvmcopy把父进程的内存复制给子进程。 +3. `np->tf->a0 = 0`保证了子进程返回0,因为寄存器a0保存了函数的返回值。 +4. `return pid`对于子进程来说,在汇编层面应该实际执行的返回寄存器a0的值。 + +##### exit + +文件位置:kernel/proc.c。作用:让调用它的进程停止运行。 + +##### wait + +文件位置:kernel/proc.c。作用:等待当前进程的某个子进程退出。 + +##### exec + +文件位置:kernel/exec.c。作用:把硬盘上的程序加载到内存里并执行之。 + +##### sbrk + +文件位置:kernel/sysproc.c。作用:为进程分配内存。 + +#### 文件系统 + +相关系统调用的实现请看kernel/sysfile.c。 + +##### read + +文件位置kernel/file.c。作用:从文件描述符所指向的文件读取n个字节。 + +##### write + +文件位置kernel/file.c。作用:从文件描述符所指向的文件写入n个字节。 + +##### close + +##### open + +##### pipe + +##### dup + +##### chdir + +##### mkdir + +##### mknod + +##### fstat + +##### link + +##### unlink + +##### I/O重定向 + + -在kernel/syscall.h定义系统调用号。 \ No newline at end of file diff --git a/OS/XV6/专题分析/xv6的组织.md b/OS/XV6/专题分析/xv6的组织.md new file mode 100644 index 0000000..d4b3609 --- /dev/null +++ b/OS/XV6/专题分析/xv6的组织.md @@ -0,0 +1,23 @@ +操作系统有三个需求:多路复用、隔离和交互。本章概述了操作系统如何实现如上三个需求,本章还概述了xv6的进程。xv6-riscv在低层的实现很多是特定于riscv的,比如进程。 + +#### 抽象物理资源 + +把物理资源抽象成系统调用接口,可以简化应用程序的编写,并使应用程序相互隔离,实践证明是个比较好的硬件抽象方法。 + +#### 特权模式和系统调用 + +应用程序处于用户模式,以被强制隔离。内核处于管理模式,以执行特权指令。CPU从机器模式开始执行,主要是配置计算机。 + +应用程序通过ecall指令调用内核的功能。应用程序不应知道调用内核功能的内存地址,因为恶意程序可借此威胁系统安全。 + +#### 内核的组织 + +操作系统的哪一部分放在管理模式下是设计的一个核心问题,宏内核的设计是把整个操作系统都放在内核里。这样的内核组织方式使得操作系统拥有完整的硬件权限,这有利于操作系统的不同部分间相互协同。但这也使操作系统的不同部分之间的接口变得复杂,从而出容易出现错误。为了减少内核产生错误的风险,仅让少量的操作系统代码运行在管理模式,而让大部分的操作系统都运行在用户模式,这样的内核组织方式叫微内核。 + +在微内核里,操作系统的大量功能都以服务的形式运行于用户态,其它程序以进程间通信的方式使用操作系统提供的服务。这样内核接口就仅包含少量的低级别的功能,诸如启动程序、发送消息、访问硬件等。 + +#### xv6的组织 + +#### 进程概述 + +#### 第一个进程 \ No newline at end of file