xv6-六
前言这篇博客研究xv6的Copy-on-Write机制的实现
Lab Copy-on-Write Fork for xv6本次lab用来实现xv6的Copy-on-Write机制
Copy-on-Write要求
Your task is to implement copy-on-write fork in the xv6 kernel. You are done if your modified kernel executes both the cowtest and usertests programs successfully.
分析Copy-on-Write和lazy allocation非常类似,都是为了节省直接分配导致的性能损失,从而推迟实际的physical page的分配和映射,仅仅完成virtual page的分配。
其中,Copy-on-Write是在进程fork时,仅仅复制父进程的pd(页表),而共享实际的physical page,从而节省了physical page的分配和内容的复制。而实际的页框(physical page)分配,延迟到父进程或子进程执行 ...
xv6-五
前言这篇博客研究lazy page allocation机制
lazy page allocation一个操作系统中可以包含多个进程,进程的地址空间所占用的虚拟地址空间之和一般远远大于实际的物理内存之和。
因此,一般操作系统通过通过如下几种方法,将进程的超大的虚拟地址空间映射到有限的物理地址空间中
不同虚拟内存映射相同物理内存实际上,不同进程或相同进程的不同虚拟内存有很大一部分包含相同的数据(linux的glibc库, 内核的stack0数据)。因此,完全可以将这些虚拟内存指向相同的物理地址
延迟分配往往进程会申请超过实际需要的内存,并且申请后不会立即使用。因此,当进程申请内存时,仅仅分配虚拟内存并记录在描述符中,但是并不实际分配物理内存并映射。也就是此时并不消耗物理内存。当进程真正访问该虚拟内存时,会产生page fault,从而在异常处理时完成实际的映射即可
Lab lazy allocation本次lab帮助熟悉xv6的lazy allocation机制
Lazy allocation要求
Modify the code in trap.c to respond to a p ...
xv6-四
前言这篇博客探索一下xv6从U-mode地址空间trap(陷入)到S-mode地址空间的机制(前面xv6-二已经介绍的非常详细了)
Lab traps本次lab帮助熟悉xv6的trap(陷入)机制
Backtrace要求
Implement a backtrace() function in kernel/printf.c. Insert a call to this function in sys_sleep, and then run bttest, which calls sys_sleep. Your output should be as follows:
1234backtrace:0x0000000080002cda0x0000000080002bb60x0000000080002898
After bttest exit qemu. In your terminal: the addresses may be slightly different but if you run addr2line -e kernel/kernel (or riscv64-unknown- ...
xv6-三
前言这篇博客探索一下xv6内核的虚拟内存机制
xv6的页表机制page table(页表)是典型的软、硬件结合的机制,即硬件提供相关的电路实现和接口,操作系统根据硬件的接口,实现相关的服务
页表硬件对于riscv指令来说(无论在S-mode还是U-mode),其操作的是virtual address(虚拟地址)。但是对于机器的RAM来说,其操作的是physical address(物理地址)
而page table的硬件部分,则是连接两个地址的组件——其将virtual address(虚拟地址)映射为physical address(物理地址)
page table工作的基本逻辑如下图所示
直白的说,其将虚拟地址空间和物理地址空间以页(4096字节)为单位切分,并以页为单位进行映射(即通过page table记录页号之间的映射关系)
当然,riscv支持多种page table机制,但是这些机制的大体思路和上面的图所展示的是一致的
xv6采用了Sv39方案的page table,即support a 39-bit virtual address space。该方案中,64bit的vi ...
xv6-二
前言这篇博客探索一下xv6内核的系统调用过程
xv6启动流程参考xv6-book,可以对xv6的启动过程有非常清晰的认识,这对于理解linux内核的启动大有裨益
首先,写在ROM中的boot loader,将内核装载入内存中,并将执行流跳转到固定的入口点(代码写死在ROM中,自然跳转的入口点也是固定的)
因此,编译内核时,需要将内核的入口函数_entry(kernel/entry.S:6)编译到boot loader指定的地址处(xv6是0x80000000)
而为了让生活更美好,_entry函数使用汇编指令初始化栈后,跳转到使用C语言编写的start(kernel/start.c:20)。start函数的主要工作就是设置CSRs(control and state registers),从而切换到S-mode(supervisor mode),并将执行流设置成main(kernel/main.c:10)。start函数实现的非常巧妙,其通过设置CSRs,伪造一个异常处理保存的上下文,其上下文的特权级是S-mode,PC是main。执行mret指令后,通过恢复上下文,完成特权级和执行流 ...
xv6
前言大名鼎鼎的MIT的6.828课程看了课程提供的视频,瞬间心潮澎湃希望可以通过这门课程,加深对于操作系统方面的理解
Lab Utilities本次lab帮助熟悉xv6操作系统
Boot xv6在Linux的终端中,执行如下命令,安装相关依赖1sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu
执行如下命令,拉取xv6仓库1git clone git@gitee.com:jiaweihawk/mit-6.S081.git
执行如下命令,拉取gdb并编译1234567sudo apt-get install libgmp-dev libncurses5-dev \ && wget http://mirrors.aliyun.com/gnu/gdb/gdb-12.1.tar.gz\ && tar -zxvf gdb-12.1.tar.gz\ && ...