6.S081-Lab Util report

本文介绍了在 xv6 操作系统中实现 sleep 系统调用、并发 ping-pong 程序、并发 primes 素数筛选、find 文件查找以及 xargs 命令行工具的过程。通过阅读 xv6 代码,理解系统调用、管道、进程创建和同步等概念,加深了对操作系统内核和并发编程的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lab Util report

Boot Xv6 (easy)

没啥复杂的,按照教程来就可以了,基本没踩坑。

Sleep

描述:Implement the UNIX program sleep for xv6; your sleep should pause for a user-specified number of ticks. A tick is a notion of time defined by the xv6 kernel, namely the time between two interrupts from the timer chip. Your solution should be in the file user/sleep.c.

指导(可以称得上是保姆级了。。。):

  • Before you start coding, read Chapter 1 of the xv6 book.
    *Look at some of the other programs in user/ (e.g., user/echo.c, user/grep.c, and user/rm.c) to see how you can obtain the command-line arguments passed to a program.
  • If the user forgets to pass an argument, sleep should print an error message.
  • The command-line argument is passed as a string; you can convert it to an integer using atoi (see user/ulib.c).
  • Use the system call sleep.
  • See kernel/sysproc.c for the xv6 kernel code that implements the sleep system call (look for sys_sleep), user/user.h for the C definition of sleep callable from a user program, and user/usys.S for the assembler code that jumps from user code into the kernel for sleep.
  • Make sure main calls exit() in order to exit your program.
  • Add your sleep program to UPROGS in Makefile; once you’ve done that, make qemu will compile your program and you’ll be able to run it from the xv6 shell.
  • Look at Kernighan and Ritchie’s book The C programming language (second edition) (K&R) to learn about C.

按照教程即可。代码如下:

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int main(int argc, char *argv[])
{
   
   
    int t;
	if (argc <= 1 || argc > 2) {
   
   
		fprintf(2, "usage: sleep <seconds>\n");
        exit(1);
	}
    t = atoi(argv[1]);
    sleep(t);
	exit(0);
}

实现sleep命令没啥好讲的,实际上好玩的是sleep syscall的实现,即如何从用户态陷入内核空间,进而完成sleep命令的。

首先在user.h中声明了sleep这个函数,在usys.S中看到,首先.global sleep在全局符号表中注册函数名sleep,之后调用sleep这个系统调用时就会执行以下这段riscv汇编代码:

.global sleep
sleep:
 li a7, SYS_sleep
 ecall
 ret

这段汇编的意思也很明确,就是把SYS_sleep的值放入a7寄存器中,记录系统调用的类型,之后的ecall指令产生一个异常,此时陷入内核态,然后查看kernel/syscall.c可知SYS_sleepsys_sleep存在映射关系,syscall函数可以根据SYS_<name>值的不同执行不同的sys_<name>函数(kernel/syscall.c:140)。

void
syscall(void)
{
   
   
  int num;
  struct proc *p = myproc();

  num = p->trapframe->a7;
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
   
   
    p->trapframe->a0 = syscalls[num]();
  } else {
   
   
    printf("%d %s: unknown sys call %d\n",
            p->pid, p->name, num);
    p->trapframe->a0 = -1;
  }
}

反正目前看kernel/syscall.c里的syscall实现,是通过中断实现的(trapframe),具体的实现会等到后面的实验再详细解释。

以上是一个基本的理解,更详细的了解估计在后面的课程中会涉及。

参考:

PingPong

描述:Write a program that uses UNIX system calls to ‘‘ping-pong’’ a byte between two processes over a pair of pipes, one for each direction. The parent should send a byte to the child; the child should print “: received ping”, where is its process ID, write the byte on the pipe to the parent, and exit; the parent should read the byte from the child, print “: received pong”, and exit. Your solution should be in the file user/pingpong.c.

指导:

  • Use pipe to create a pipe.
  • Use fork to create a child.
  • Use read to read from the pipe, and write to write to the pipe.
  • Use getpid to find the process ID of the calling process.
  • Add the program to UPROGS in Makefile.
  • User programs on xv6 have a limited set of library functions available to them. You can see the list in user/user.h; the source (other than for system calls) is in user/ulib.c, user/printf.c, and user/umalloc.c.

之前实现过unix的版本,直接把代码copy稍作改动即可。

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"


int main()
{
   
   
    int p[2], q[2];
    pipe(p), pipe(q);
    if (fork() > 0) {
   
   
        close(p[0]);
        close(q[1]);
        char x[1];
        write(p[1], "0", 1);
        read
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值