XV6学习(2)Lab syscall】的更多相关文章

XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接下来就可以从main.c的init函数开始 这里会和JOS做一个对比 首先看一下在执行main.c之前的物理内存分布 0x0000-0x7c00 引导程序的栈 0x7c00-0x7d00 引导程序的代码(512字节) 0x10000-0x11000 内核ELF文件头(4096字节) 0xA0000-…
xv6学习笔记(3):中断处理和系统调用 1. tvinit函数 这个函数位于main函数内 表明了就是设置idt表 void tvinit(void) { int i; for(i = 0; i < 256; i++) SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0); SETGATE(idt[T_SYSCALL], 1, SEG_KCODE<<3, vectors[T_SYSCALL], DPL_USER); initlock…
xv6学习笔记(4) : 进程 xv6所有程序都是单进程.单线程程序.要明白这个概念才好继续往下看 1. XV6中进程相关的数据结构 在XV6中,与进程有关的数据结构如下 // Per-process state struct proc { uint sz; // Size of process memory (bytes) pde_t* pgdir; // Page table char *kstack; // Bottom of kernel stack for this process e…
xv6学习笔记(5) : 锁与管道与多cpu 1. xv6锁结构 1. xv6操作系统要求在内核临界区操作时中断必须关闭. 如果此时中断开启,那么可能会出现以下死锁情况: 进程A在内核态运行并拿下了p锁时,触发中断进入中断处理程序. 中断处理程序也在内核态中请求p锁,由于锁在A进程手里,且只有A进程执行时才能释放p锁,因此中断处理程序必须返回,p锁才能被释放. 那么此时中断处理程序会永远拿不到锁,陷入无限循环,进入死锁. 2. xv6中的自旋锁 Xv6中实现了自旋锁(Spinlock)用于内核临…
XV6学习笔记(1) 1. 启动与加载 首先我们先来分析pc的启动.其实这个都是老生常谈了,但是还是很重要的(也不知道面试官考不考这玩意), 1. 启动的第一件事-bios 首先启动的第一件事就是运行bios,这个时候我们的机器位于实模式,也就是16位地址.这个时候能访问的空间只有1mb 就是设置cs寄存器的值为0xFFFF, ip的值为0x0000 这个就是bios的地址,然后我们会去运行bios执行各种对硬件的检查 但是xv6和之前的jos(也就是828)中都没有这样做,作为一个精简的os系…
实验的代码放在了Github上. 第二个实验是Lab: system calls. 这个实验主要就是自己实现几个简单的系统调用并添加到XV6中. XV6系统调用 添加系统调用主要有以下几步: 在user/user.h中添加系统调用函数的定义. 在user/usys.pl中添加入口,这个文件将会在make后生成user/usys.S文件,在该汇编文件中,每个函数就只有三行,将系统调用号通过li(load imm)存入a7寄存器,之后使用ecall进入内核态,最后返回. fork: li a7, S…
正在学习MIT的6.S081,把做的实验写一写吧. 实验的代码放在了Github上. 第一个实验是Lab util,算是一个热身的实验,没有涉及到系统的底层,就是使用系统调用来完成几个用户模式的小程序. Boot xv6 (easy) 启动XV6,按照文档执行就ok了. $ git clone git://g.csail.mit.edu/xv6-labs-2020 $ cd xv6-labs-2020 $ git checkout util $ make qemu 在XV6中没有ps命令,而是使…
最后一个实验了,代码在Github上. 这一个实验其实挺简单的,就是要实现网卡的e1000_transmit和e1000_recv函数.不过看以前的实验好像还要实现上层socket相关的代码,今年就只有网卡驱动了. 虽然实验文档里面给了一本400多页的网卡文档,但其实也不需要怎么读这本厚厚的文档,实验的hints里面就讲的挺清楚了. 实验 首先是e1000_transmit函数,按照hints一步步来就行了,唯一一个要查文档的就是cmd域,但其实这个域的宏定义里面就只给了E1000_TXD_CM…
代码在github上.总体来说如果理解了COW机制的话,这个实验的完成也没有很复杂. 这一个实验是要完成COW(copy on write)fork.在原始的XV6中,fork函数是通过直接对进程的地址空间完整地复制一份来实现的.但是,拷贝整个地址空间是十分耗时的,并且在很多情况下,程序立即调用exec函数来替换掉地址空间,导致fork做了很多无用功.即使不调用exec函数,父进程和子进程的代码段等只读段也是可以共享的,从而达到节省内存空间的目的.同时COW也可以将地址空间拷贝的耗时进行延迟分散…
代码放在github上. 这一次实验感觉挺简单的,特别是后面两个小实验.主要就是对多线程和锁进行一个学习. Uthread: switching between threads 这一个实验是要实现一个简单的用户级线程,写完之后发现原来用户级线程的简单实现也没有想象的那么复杂. 首先定义一个context结构体保存线程上下文,并加入到thread结构体中.在上下文中只需要保存被调用者保存的寄存器,即sp和s0-s11,ra用来保存线程的返回地址,类似于进程中的pc. struct thread_c…