MIT6.S081 Lab1 Xv6 and Unix utilities(更新ing)

国内的OS课程可能只是在表面上教你操作系统的概念,像是在玩一场模拟器游戏,只是看看别人玩的样子,终究还是在OS的世界里迷失了方向。

本文原载自我的个人博客MIT6.S081 lab1

Q1.sleep (easy)

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.

Some hints:

  • Before you start coding, read Chapter 1 of the xv6 book.

    (1.先看书捏)

  • 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.

    (2.看上面几个文件来你如何获取命令行参数)

  • If the user forgets to pass an argument, sleep should print an error message.

    (3.没传参需要特殊处理)

  • The command-line argument is passed as a string; you can convert it to an integer using atoi (see user/ulib.c).

    (4.命令行输入的参数都是字符串,sleep需要的数字需要用atoi转化成整数)

  • Use the system call sleep.

    (5.使用写好的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.

    (确保程序最后用系统调用exit()退出)

  • 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.

    (MakeFile文件里要把sleep加上,这部分我参考的别人的MakeFile)

  • Look at Kernighan and Ritchie's book The C programming language (second edition) (K&R) to learn about C.

    (C基础薄弱的可以看这本书)

///user/echo.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
  int i;

  for(i = 1; i < argc; i++){
    write(1, argv[i], strlen(argv[i]));
    if(i + 1 < argc){
      write(1, " ", 1);
    } else {
      write(1, "\n", 1);
    }
  }
  exit(0);
}
//user/grep.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
  int fd, i;
  char *pattern;

  if(argc <= 1){
    fprintf(2, "usage: grep pattern [file ...]\n");
    exit(1);
  }
  pattern = argv[1];

  if(argc <= 2){
    grep(pattern, 0);
    exit(0);
  }

  for(i = 2; i < argc; i++){
    if((fd = open(argv[i], 0)) < 0){
      printf("grep: cannot open %s\n", argv[i]);
      exit(1);
    }
    grep(pattern, fd);
    close(fd);
  }
  exit(0);
}
//user/rm.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
  int i;

  if(argc < 2){
    fprintf(2, "Usage: rm files...\n");
    exit(1);
  }

  for(i = 1; i < argc; i++){
    if(unlink(argv[i]) < 0){
      fprintf(2, "rm: %s failed to delete\n", argv[i]);
      break;
    }
  }

  exit(0);
}

参考一下上面的三个.c文件,很明显看出:

1.argc是参数个数,agrv是个二维字符数组,argv[0]是第一个参数,argv[1]是第二个参数, 那么对于我们要实现的sleep,输入sleep xxx,则sleep是作为argv[0],xxx作为argv[1]。

2.没传sleep需要的参数,需要特判。

3.若有参数,则用atoi把字符串转化成整数,最后调用系统调用sleep

以下是我实现的sleep.c,已通测试

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

int main(int argc,char *argv[]){
    int time;
    if(argc < 2){
        printf("You forget to pass an argument, so I print an error message.");
        exit(1);
    }
    time = atoi(argv[1]);
    sleep(time);
    exit(0);
}

Q2.pingpong (easy)

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 "<pid>: received ping", where <pid> 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 "<pid>: received pong", and exit. Your solution should be in the file user/pingpong.c.

Some hints:

  • Use pipe to create a pipe.

    (使用pipe系统调用来创建管道,这个博主讲的很好,易于理解linux管道pipe详解_linux pipe-CSDN博客)

  • Use fork to create a child.

    (使用fork创建子进程,父子通信嘛)

  • Use read to read from the pipe, and write to write to the pipe.

    (使用read系统调用来从管道读写)

  • Use getpid to find the process ID of the calling process.

    (使用getpid调用获得当前进程id,answer要输出)

  • 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.

    (用user.h下提供的调用)

Run the program from the xv6 shell and it should produce the following output:

    $ make qemu
    ...
    init: starting sh
    $ pingpong
    4: received ping
    3: received pong
    $
  

我的代码如下,已满分:

(想了大半天,知道用两个管道那就很容易了,一锤定easy)

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
 
int main(int argc,char * argv[]){
    int p[2];
    int p2[2];
    char buf[1024];
    pipe(p);
    pipe(p2);
    char *a = "hello mychild";
    char *b = "hello myparent";
    if(fork() == 0){
        close(p[1]);
        int len = read(p[0],buf,sizeof(buf));
        if(len > 0)
            printf("%d: received ping\n",getpid());
        close(p[0]);
        close(p2[0]);
        write(p2[1],b,strlen(b));
        
        close(p2[1]);
    }else{
        close(p[0]);
        write(p[1],a,strlen(a));
        wait((int*)0);
        int len = read(p2[0],buf,sizeof(buf));
        if(len > 0)
            printf("%d: received pong\n",getpid());
        close(p[0]);
        close(p[1]);
        close(p2[0]);
        close(p2[1]);

    }

    exit(0);
}

最近主要在忙别的,后面的题也会好好做,慢慢更~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: xv6是一个基于Unix的操作系统,它是由麻省理工学院开发的一个教学用途的操作系统。它的设计和实现都非常简单,因此非常适合用于操作系统的教学和学习。Unix utilitiesUnix操作系统中的一些常用工具,例如ls、grep、awk、sed等,它们可以帮助用户完成各种任务,例如查看文件、搜索文本、处理数据等。这些工具也被移植到了其他操作系统中,成为了广泛使用的工具。 ### 回答2: xv6是一个教学目的的操作系统内核,它是根据Unix第六版(Version 6 Unix)设计而成的。Unix utilities是指Unix操作系统中提供的一系列实用工具程序。 xv6的设计灵感来自于Unix,因此它具有类似于Unix的文件系统、进程管理、内存管理等特性。它采用C语言编写,具有简洁的结构和易于理解的代码,这使得学生可以更好地理解操作系统的内部工作原理。xv6内核为学生提供了一个可用于学习和实验的平台,帮助他们深入了解操作系统和计算机系统的工作方式。 与此同时,Unix utilities是一些用于完成特定任务的Unix命令行工具程序。这些工具程序通常被用于处理文件、管理进程、网络通信、文本处理等方面。常见的Unix utilities包括ls(列出目录内容)、grep(查找指定模式)、cp(复制文件)、rm(删除文件)等等。这些工具程序非常强大且灵活,可以通过简单的命令行参数来满足各种不同需求。 xv6和Unix utilities有着密切的关系。学习和理解xv6可以帮助我们深入理解Unix操作系统的设计和实现原理。而掌握Unix utilities可以使我们更加高效地处理各种系统管理任务和编程工作。通过学习和使用这些工具,我们可以更好地理解和应用操作系统的概念和原则,提高我们的计算机系统操作和编程技能。总之,xv6和Unix utilities都为我们提供了学习和实践操作系统的机会,帮助我们更好地掌握计算机系统的核心知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Silver Vortex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值