首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MIT 6.S081 Lab Four -- Trap

你的backtrace应当使用这些帧指针来遍历栈,并在每个栈帧中打印保存的返回地址。...注意返回地址位于栈帧帧指针的固定偏移(-8)位置,并且保存的帧指针位于帧指针的固定偏移(-16)位置 XV6在内核中以页面对齐的地址为每个栈分配一个页面。...先使用r_fp()读取当前的帧指针,然后读出返回地址并打印,再将fp定位到前一个帧指针的位置继续读取即可。 根据提示:XV6在内核中以页面对齐的地址为每个栈分配一个页面。...---- Alarm(Hard) YOUR JOB 在这个练习中你将向XV6添加一个特性,在进程使用CPU的时间内,XV6定期向进程发出警报。...如果您告诉qemu只使用一个CPU,那么使用gdb查看陷阱会更容易,这可以通过运行 make CPUS=1 qemu-gdb 如果alarmtest打印“alarm!”,则您已成功。

21230

xv6(18) 控制台输入输出

为什么 $write$ 系统调用使用文件描述符 $1$ 就会将消息打印到屏幕?$printf$ 函数又是如何实现的?看完本文相信你会找到答案。...$ 函数 $printf$ 函数有两个,一个是内核使用,一个是用户态使用。...,这里就直接来看用户态如何实现 $printf$ 函数,首先打印单个字符的函数: static void putc(int fd, char c) { write(fd, &c, 1); } $putc...$xv6$ 的 $printf$ 函数,注释十分详细,过一遍基本能懂,稍稍注意两个点就行,一是处理 %s 时,二级指针要正确使用,另外如果 字符串指针指向 0,并没有做错误处理,而是打印字符串 (null...为什么 $write$ 系统调用使用文件描述符 $1$ 就会将消息打印到屏幕?$printf$ 函数又是如何实现的?对这几个问题都有相应的流程图,私以为把这几条线捋得还是很清楚得。

23610
您找到你想要的搜索结果了吗?
是的
没有找到

Mit6.S081-实验1-Xv6 and Unix utilities

在shell输入命令行,shell程序读取输入内容,通过调用fork(system call)开启一个shell的子进程, shell进程利用wait(system call),等待子进程执行完后继续执行...unix system calls在两个进程间”ping-pong“一个字节,使用一对pipe,一个pipe对应一个方向,另外一个pipe对应另外一个方向。...; exit(1); } //打印读取到的字符数组 printf("%d: received ping\n", getpid()); //子进程向pipe2的写端,写入字符数组 if(write(p2[...; exit(1); } //打印读取的字符数组 printf("%d: received pong\n", getpid()); //等待进程子退出 wait(0); exit(0); } 3,辅助图...发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

66810

MIT 6.S081 Lab Three -- 页表

中,这样你就可以在exec.c中调用它了 在你的printf调用中使用%p来打印像上面示例中的完成的64比特的十六进制PTE和地址 QUESTION 根据文本中的图3-4解释vmprint的输出。...因此,当内核需要使用在系统调用中传递的用户指针(例如,传递给write()的缓冲区指针)时,内核必须首先将指针转换为物理地址。本节和下一节的目标是允许内核直接解引用用户指针。...(在内核模式,无法访问设置了PTE_U的页面) 别忘了上面提到的PLIC限制 Linux使用的技术与您已经实现的技术类似。...然而,这种设置允许边信道攻击,Meltdown和Spectre。...修改xv6来为内核使用超级页面。 修改xv6,这样当用户程序解引用空指针时会收到一个异常。也就是说,修改xv6使得虚拟地址0不被用户程序映射。

25040

MIT_6.s081_Lab

如果用户忘记传递参数, sleep 应该打印错误消息。 命令行参数作为字符串传递;您可以使用atoi将其转换为整数(请参阅 user/ulib.c)。 使用系统调用sleep。...● 在printf调用中使用%p输出完整的64位十六进制PTE和地址,示例所示。...它使用get()从哈希表中获取密钥。 它打印由于puts而应在哈希表中但丢失的数字键(在这种情况下为零),并打印每秒获得的获取次数。...如果一切顺利,nettests 将打印 testing ping: OK,并且 make server 将打印一条来自 xv6! 的消息。...对于本实验,您必须使用具有多核的专用机器。如果您使用一台正在做其他事情的机器,那么 kalloctest 打印的计数将是无稽之谈。

1.1K10

MIT 6.S081 Lab Seven -- 多线程

您将在用户级线程包中实现线程之间的切换,使用多个线程来加速程序,并实现一个屏障。 在编写代码之前,您应该确保已经阅读了xv6手册中的“第7章: 调度”,并研究了相应的代码。...您应该在具有多个内核的真实Linux或MacOS计算机(不是xv6,不是qemu)上执行此任务。最新的笔记本电脑都有多核处理器。 这个作业使用UNIX的pthread线程库。...首先,它通过调用put()将许多键添加到哈希表中,并以每秒为单位打印puts的接收速率。之后它使用get()从哈希表中获取键。...它打印由于puts而应该在哈希表中但丢失的键的数量(在本例中为0),并以每秒为单位打印gets的接收数量。 通过给ph一个大于1的参数,可以告诉它同时从多个线程使用其哈希表。试试ph 2: $ ....您将使用pthread条件变量,这是一种序列协调技术,类似于xv6的sleep和wakeup。 您应该在真正的计算机(不是xv6,不是qemu)上完成此任务。

25820

MIT 6.S081 教材第六章内容 -- 锁 --

除了共享的数据,在一些其他场合也需要锁,例如对于printf,如果我们将一个字符串传递给它,XV6会尝试原子性的将整个字符串输出,而不是与其他进程的printf交织输出。...所以现在有了一个缓存,一个写指针和一个读指针: 读指针的内容需要被显示 写指针接收来自例如printf的数据 我们前面已经了解到了锁有多个角色。...UART的缓存中,读指针是不是总是会落后于写指针? 从读指针到写指针之间的字符是要显示的字符,UART会逐次的将读指针指向的字符在显示器上显示,同时printf可能又会将新的字符写入到缓存。...---- 接下来我们看一如何使用这条指令来实现自旋锁。让我们来看一XV6中的acquire和release的实现。...以上就是对锁的介绍,我们之后还会介绍很多锁的内容,在这门课程的最后我们还会介绍lock free program,并看一何在内核中实现它。

15640

6.S0816.828: 2 Lab system calls

一、trace1 问题分析实现一个trace,能够追踪某个进程(包括子进程)指定系统调用执行情况,打印它的状态,如下图所示。...打印进程及其子进程运行某个系统调用的日志,所以mask应该添加在进程结构体中,并且fork内核函数也需要copy mask字段。主要步骤如下:kernel/proc.h添加tracemask字段。...%d: %s %s %s %d\n",p->pid,"syscall",syscallnames[num],"->",p->trapframe->a0); } } else { printf...xv6的物理内存是用空闲链表管理的,统计这条链表上的页数就行。xv6的进程分配是采用一个进程数组来维护,直接遍历这个数组上非UNUSED状态的进程即可。...内核中有argint、argaddr、argfd,支持读取整数、指针、文件描述符,都是argraw的封装。内核态和用户态不会直接读写同一份数据,而是会拷贝,copyout是将数据拷贝到用户地址中。

52860

MIT 6.S081 Lab Two -- 系统调用

在本实验室中,您将向xv6添加一些新的系统调用,这将帮助您了解它们是如何工作的,并使您了解xv6内核的一些内部结构。您将在以后的实验室中添加更多系统调用。...如果在掩码中设置了系统调用的编号,则必须修改xv6内核,以便在每个系统调用即将返回时打印出一行。 该行应该包含进程id、系统调用的名称和返回值; 您不需要打印系统调用参数。...uint64 dstaddr; argaddr(0, &dstaddr); // 使用 copyout,结合当前进程的页表,获得进程传进来的指针(逻辑地址)对应的物理地址 // 然后将...&sinfo 中的数据复制到该指针所指位置,供用户进程使用。...测试运行结果: 可选的挑战 感兴趣的小伙伴可以去做一可选的挑战: 打印所跟踪的系统调用的参数(easy)。 计算平均负载并通过sysinfo导出(moderate)。

38840

MIT_6.s081_Lab1:Xv6 and Unix utilities

如果用户忘记传递参数, sleep 应该打印错误消息。 命令行参数作为字符串传递;您可以使用atoi将其转换为整数(请参阅 user/ulib.c)。 使用系统调用sleep。...父母应该向孩子发送一个字节; 子进程应该打印“: received ping”,其中 是它的进程 ID,将管道上的字节写入父进程,然后退出; 父母应该从孩子那里读取字节,打印“: received pong...一些提示: 使用管道创建管道。 使用 fork 创建一个孩子。 使用 read 从管道读取,并使用 write 写入管道。 使用 getpid 查找调用进程的进程 ID。...xv6 上的用户程序有一组有限的库函数可供它们使用。...因此,主素数进程应该只在所有输出都被打印出来,并且在所有其他素数进程都退出之后才退出。 当管道的写端关闭时,read 返回零。

73220

MIT_6.s081_Lab4:Xv6 and Trap

Lab4_2 BackTrace 添加一个新的功能,打印函数调用栈.在这个机器中,我们知道有一个结构叫做栈帧,可以保存当前函数调用某个函数之前的一些寄存器,返回地址和一些局部变量的信息,比如说C语言的main...输出应如下: 1) 在def.h添加backtrace()函数的声明. 2) GCC 编译器将当前执行的函数的帧指针存储在寄存器s0中,s0就对应上面的fp指针. static inline uint64...,所以说我们可以循环一,每一次循环就取上一个函数的栈帧最高地址,输出返回地址即可. void backtrace(void){ uint64 fp = r_fp(), top = PGROUNDUP...-8))); } } Lab4_3 Alarm 在本练习中,您将向xv6添加一项功能,该功能会在使用CPU时间的情况下定期向进程发出警报。...这意味着您可以将代码添加到usertrap和sys_sigreturn中,它们会协同工作以使用户进程在处理完警报后正确恢复。 10.确保正确地保存和恢复寄存器。

54830

MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 --Trap -- 中

之后内核就可以任意的使用a0寄存器了。 关键在于CSR寄存器不能直接使用存储器访问指令(sd和ld)进行读取和写入,CSR寄存器的访问需要使用特定的指令进行读取和写入操作。...所以你可以这样想,尽管XV6并没有使用这里提供的灵活性,但是一些其他的操作系统用到了。...之后内核就可以任意的使用a0寄存器了。 关键在于CSR寄存器不能直接使用存储器访问指令(sd和ld)进行读取和写入,CSR寄存器的访问需要使用特定的指令进行读取和写入操作。...指向完这条指令之后,我们打印当前的Stack Pointer寄存器, 这是这个进程的kernel stack。...这里写入的是我们将要执行的第一个C函数的指针,也就是函数usertrap的指针。我们在后面会使用这个指针。 下一条指令是向t1寄存器写入数据。

27040

MIT 6.S081 Lab One -- Util

您的解决方案应该在文件user/sleep.c中 Tips: 在你开始编码之前,请阅读《book-riscv-rev1》的第一章 看看其他的一些程序(: /user/echo.c, /user/grep.c..., /user/rm.c)查看如何获取传递给程序的命令行参数 如果用户忘记传递参数,sleep应该打印一条错误信息 命令行参数作为字符串传递; 您可以使用atoi将其转换为数字(详见/user/ulib.c...) 使用系统调用sleep 请参阅kernel/sysproc.c以获取实现sleep系统调用的xv6内核代码(查找sys_sleep),user/user.h提供了sleep的声明以便其他程序调用,用汇编程序编写的...如果要对一项作业运行成绩测试,请键入(不要启动XV6,在外部终端下使用): $ ./grade-lab-util sleep 这将运行与sleep匹配的成绩测试。...父进程应该向子进程发送一个字节; 子进程应该打印“: received ping”,其中是进程ID,并在管道中写入字节发送给父进程,然后退出; 父级应该读取从子进程而来的字节,打印

27710

笔记 Lab3: Page tables | 页表

添加一个打印页表的内核函数,以如下格式打印出传进的页表,用于后面两个实验调试用: page table 0x0000000087f6e000 ..0: pte 0x0000000021fda801 pa...,而 xv6 已经有一个递归释放页表的函数 freewalk(),将其复制一份,并将释放部分代码改为打印即可: // kernel/vm.c int pgtblprint(pagetable_t pagetable...vmprint(p->pagetable); // 按照实验要求,在 exec 返回之前打印页表。...You pass this part of the lab if usertests runs correctly. xv6 原本的设计是,用户进程在用户态使用各自的用户态页表,但是一旦进入内核态(例如使用了系统调用...查阅 xv6 book 的 Chapter 5 以及 start.c 可以知道 CLINT 仅在内核启动的时候需要使用到,而用户进程在内核态中的操作并不需要使用到该映射。

1.6K20

MIT_6.s081_Lab7:Xv6 and Networking

全局变量 regs 持有指向 E1000 的第一个控制寄存器的指针;您的驱动程序可以通过将 regs 索引为数组来获取其他寄存器。您需要特别使用索引 E1000_RDT 和 E1000_TDT。...如果一切顺利,nettests 将打印 testing ping: OK,并且 make server 将打印一条来自 xv6! 的消息。...提示 首先将打印语句添加到 e1000_transmit() 和 e1000_recv(),然后运行 ​​make server 和(在 xv6 中)nettests。...使用 net_rx() 将 mbuf 传送到网络堆栈。 然后使用 mbufalloc() 分配一个新的 mbuf 来替换刚刚给 net_rx() 的那个。将其数据指针(m->head)编程到描述符中。...您将需要锁来应对 xv6 可能从多个进程使用 E1000 的可能性,或者当中断到达时可能在内核线程中使用 E1000。

65120

xv6(13) 文件系统:文件描述符&系统调用

这里简单的再过一系统调用,$xv6$ 的系统调用使用 INT 64 指令来实现的,触发一个 $64$ 号中断陷入内核,根据向量号 $64$ 去获取执行中断服务程序。...,为什么使用二级指针同样看前文。...而 $Linux$ 更为严格,不能使用 $unlink$ 一个目录,空目录也不行,经测试, $xv6$ 中是可以使用 $unlink$ 来删除一个空目录的,而 $Linux$ 中不行,$Linux$...对此表示怀疑,在 $Linux$ 新目录的链接数为 2,而 $xv6$ 只为 1。...$ 使用的是直接赋值而不是递增递减来操作,$xv6$ 可能为了简化统一吧,只使用 $unlink$ 和 $iput$ 两函数实现对文件的删除,只是这样的话对于 $xv6$ 来说链接数就与目录项个数不是一一对应的了

29110
领券