![](https://img-blog.csdnimg.cn/e8d5df143c554a60a4ca37a5b1902654.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
MIT6.081操作系统
文章平均质量分 90
主要介绍该课程的学习过程
自信的小睫毛
菜鸟成长日记
展开
-
MIT6S.081 Lab1:Unix utilities
This lab will familiarize you with xv6 and its system calls.实现几个unix实用工具,熟悉系统调用。主要考虑如何把管道符 | 前面的指令得到的标准输入(可能有多行)放到xargs后的命令参数argv[1]所代表文件的参数数组中;原创 2023-07-13 20:26:44 · 111 阅读 · 0 评论 -
MIT6.S081 Lab2:System calls
3.有了系统调用号后,就可以根据系统调用函数指针数组uint64 (*syscall[])(void) (kernel/syscall.c中),查找到系统调用的实现函数sys_trace() (kernel/sysproc.c) ,到这里系统调用一般完成。内核的系统调用实现需要找到用户代码传递的参数,因为用户代码调用系统调用,实际上是调用它的包装函数,参数首先会存放在寄存器中,这是C语言存放参数的惯例位置。通过用户调用exec系统调用的例子,理解系统调用的过程很重要!)内核实现,主要内容获取调用参数。原创 2023-07-13 20:26:09 · 119 阅读 · 1 评论 -
MIT6.S081 Lab3:Page tables
Xv6对于用户地址空间使用从零开始的虚拟地址,幸运的是,内核的内存从较高的地址开始。在上一个实验中,已经使得每一个进程都拥有独立的内核态页表了,这个实验的目标是,在进程的内核态页表中维护一个用户态页表映射的副本,这样使得内核态也可以对用户态传进来的指针(逻辑地址)进行解引用。这样做相比原来 copyin 的实现的优势是,原来的 copyin 是通过软件模拟访问页表的过程获取物理地址的,而在内核页表内维护映射副本的话,可以利用 CPU 的硬件寻址功能进行寻址,效率更高并且可以受快表加速。原创 2023-07-13 20:24:53 · 118 阅读 · 1 评论 -
MIT6.S081 Lab4:traps
打印各级函数调用的返回地址,编译器用栈帧指针指向一个栈帧,栈帧中保存着caller func的栈帧指针。%x是打印十六进制,0x00646c72小端存储为72-6c-64-00,对照ASCII码表,72:r 6c:l 64:d 00:充当字符串结尾标识。倒数到小于等于 0 的时候,如果没有正在处理的时钟,则尝试触发时钟,将原本的程序流保存起来(在 xv6 中,使用一个页来存储栈,如果 fp 已经到达栈页的上界,则说明已经到达栈底。这样,在每次时钟中断的时候,如果进程有已经设置的时钟(原创 2023-07-13 20:25:38 · 94 阅读 · 1 评论 -
MIT6.S081 Lab5:Xv6 lazy page allocation
在sbrk()的具体实现函数sys_sbrk()中只增加(或者减少)进程内存大小,但不实际分配内存(不调用growproc()),下面的代码考虑到了sbrk参数为负的情况。3.由于懒分配的页,在刚分配的时候是没有对应的映射的,所以要把一些原本在遇到无映射地址时会 panic 的函数的行为改为直接忽略这样的地址。在访问到这一部分内存的时候才进行实际的物理内存分配。由于这里可能会访问到懒分配但是还没实际分配的页,所以要加一个检测,确保 copy 之前,用户态地址对应的页都有被实际分配和映射。原创 2023-07-13 20:24:05 · 159 阅读 · 1 评论 -
MIT6.S081 Lab7:Multithreading
实现在用户态线程库切换线程;用多线程来为程序提速;实现一个同步屏障。原创 2023-07-13 20:23:04 · 85 阅读 · 1 评论 -
MIT6.S081:Lab9 File system
参考上图,原xv6inode 结构中,用于索引数据块的包括直接块(addrs[]数组前NDIRECT的数直接就是数据块地址)和间接块(只是一级索引,addrs[NDIRECT]一项记录间接块的地址,间接块中才直接存储着数据块的地址),由于没有用到更高级索引,所以这限制了能索引的数据块个数,所以现在考虑增加二级索引,来扩大能够支持的文件大小。2.修改bmap()函数(用来获取inode中第bn个块的块号addr),和itruc()函数(释放该inode所使用的所有数据块)。让其能够识别二级索引。原创 2023-07-13 20:21:32 · 202 阅读 · 1 评论 -
MIT6.S081 Lab11:Networking
e1000_recv()函数必须扫描rx ring并且将新的packet的mbuf递交到网络栈(调用net_rx())。然后需要分配一个新mbuf并且将它的信息记录在描述数组(rx_ring)项中,因此当E1000到达rx ring中的该点时,它将会找到一个未填充的buffer,用来DMA 一个新的packet。1.对于发送函数,当网络栈需要发送packet,它调用e1000_transmit(),使用mbuf(该函数的参数)中持有的待发送的packet。原创 2023-07-13 20:19:58 · 83 阅读 · 1 评论