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

今天我们来进行Mit6.S081实验一的内容。

实验任务

一、启动xv6(难度:Easy)

获取实验室的xv6源代码并切换到util分支。

$ git clone git://g.csail.mit.edu/xv6-labs-2020
Cloning into 'xv6-labs-2020'...
...
$ cd xv6-labs-2020
$ git checkout util
Branch 'util' set up to track remote branch 'util' from 'origin'.
Switched to a new branch 'util'

1.构建并运行xv6

make qemu

2.测试xv6

        这些是mkfs在初始文件系统中包含的文件;大多数是可以运行的程序。刚刚跑了其中的:ls、cat

3.退出qemu

查看xv6中的进程:Ctrl+p(xv6没有实现ps程序),
退出qemu启动的xv6:Ctrl+a x

4.分析

        xv6通过qemu启动完成后,启动了shell进程。通过shell,启动子进程ls、cat,显示了xv6目录下的文件。

参考:Lab1: Xv6 and Unix utilities · 6.S081 All-In-One (dgs.zone)

 二、sleep(难度:Easy)

1.需求

        实现xv6的UNIX程序sleep:您的sleep应该暂停到用户指定的计时数。一个滴答(tick)是由xv6内核定义的时间概念,即来自定时器芯片的两个中断之间的时间。您的解决方案应该在文件user/sleep.c

2.提示

第一章 操作系统接口 · 6.S081 All-In-One (dgs.zone)(参考)

  • 在你开始编码之前,请阅读《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的声明以便其他程序调用,用汇编程序编写的user/usys.S可以帮助sleep从用户区跳转到内核区。

  • 确保main函数调用exit()以退出程序。

  • 将你的sleep程序添加到Makefile中的UPROGS中;完成之后,make qemu将编译您的程序,并且您可以从xv6的shell运行它。

参考以下代码(查看如何获取传递给程序的命令行参数)

types.h

typedef unsigned int   uint;
typedef unsigned short ushort;
typedef unsigned char  uchar;

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int  uint32;
typedef unsigned long uint64;

typedef uint64 pde_t;

/*
这段代码是在 C 语言中使用 typedef 关键字定义了一些新的数据类型:

uint:无符号整数,通常是 unsigned int 类型。
ushort:无符号短整数,通常是 unsigned short 类型。
uchar:无符号字符,通常是 unsigned char 类型。
然后定义了一些更具体的无符号整数类型:

uint8:8 位无符号整数,通常是 unsigned char 类型。
uint16:16 位无符号整数,通常是 unsigned short 类型。
uint32:32 位无符号整数,通常是 unsigned int 类型。
uint64:64 位无符号整数,通常是 unsigned long 类型。
最后,定义了一个名为 pde_t 的类型,它被定义为 uint64 类型,通常用于表示页表项(Page Directory Entry)中的地址或者数据。
*/

start.h

#define T_DIR     1   // Directory
#define T_FILE    2   // File
#define T_DEVICE  3   // Device

struct stat {
  int dev;     // File system's disk device
  uint ino;    // Inode number
  short type;  // Type of file
  short nlink; // Number of links to file
  uint64 size; // Size of file in bytes
};

/*
这段代码定义了一些常量以及一个结构体 struct stat,用于描述文件系统中文件的状态信息。

常量定义:
T_DIR:表示目录类型,其值为 1。
T_FILE:表示文件类型,其值为 2。
T_DEVICE:表示设备类型,其值为 3。
结构体 struct stat 包含以下成员:
int dev:表示文件所在的文件系统的磁盘设备。
uint ino:表示文件的 inode 号码。
short type:表示文件的类型,可以是 T_DIR、T_FILE 或者 T_DEVICE。
short nlink:表示指向该文件的硬链接数目。
uint64 size:表示文件的大小,以字节为单位。
这个结构体用于保存文件的各种属性信息,比如文件类型、大小、所在设备等。在实际的文件系统中,通过这些信息可以对文件进行管理和操作。
*/

user.h

struct stat;
struct rtcdate;

// system calls
int fork(void);
int exit(int) __attribute__((noreturn));
int wait(int*);
int pipe(int*);
int write(int, const void*, int);
int read(int, void*, int);
int close(int);
int kill(int);
int exec(char*, char**);
int open(const char*, int);
int mknod(const char*, short, short);
int unlink(const char*);
int fstat(int fd, struct stat*);
int link(const char*, const char*);
int mkdir(const char*);
int chdir(const char*);
int dup(int);
int getpid(void);
char* sbrk(int);
int sleep(int);
int uptime(void);

// ulib.c
int stat(const char*, struct stat*);
char* strcpy(char*, const char*);
void *memmove(void*, const void*, int);
char* strchr(const char*, char c);
int strcmp(const char*, const char*);
void fprintf(int, const char*, ...);
void printf(const char*, ...);
char* gets(char*, int max);
uint strlen(const char*);
void* memset(void*, int, uint);
void* malloc(uint);
void free(void*);
int atoi(const char*);
int memcmp(const void *, const void *, uint);
void *memcpy(void *, const void *, uint);

/*
这段代码展示了一些结构体和系统调用函数的声明,以及一些在 ulib.c 文件中实现的库函数声明。这些声明通常用于操作系统的实现中,特别是在 Unix/Linux 系统中。

struct stat; 和 struct rtcdate;:这些是结构体声明,但是具体的结构体定义并没有在这段代码中给出。这样的声明表明这些结构体在其他地方有定义,可能是在其他文件或者系统头文件中。
系统调用函数声明:
这些函数声明了一些常见的系统调用函数,如 fork、exit、wait、pipe 等,用于操作进程、文件和系统状态等。
每个函数声明描述了函数的参数和返回类型,有些函数使用了 __attribute__((noreturn)) 指示函数不会返回(如 exit)。
ulib.c 文件中的库函数声明:
这些函数声明了一些在 ulib.c 文件中实现的库函数,如字符串操作函数 strcpy、strcmp、内存操作函数 memmove、memset 等,以及输出函数 fprintf、printf 和内存分配函数 malloc、free 等。
这些声明描述了操作系统的核心功能,包括进程管理、文件操作、内存管理等。
*/

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);
}
/*
#include "kernel/types.h"、#include "kernel/stat.h"、#include "user/user.h":这些是头文件包含语句,用于包含所需的系统头文件,以便在程序中使用相关的函数和数据结构。
main 函数:这是程序的入口函数,它接收命令行参数 argc 和 argv[],其中 argc 表示参数的个数,argv[] 是一个指向参数字符串数组的指针。
for 循环:遍历命令行参数数组 argv[],从索引 1 开始(跳过程序名称本身),将每个参数字符串使用 write 函数写入到标准输出(文件描述符 1)。
write 函数:用于向文件描述符写入数据,第一个参数是文件描述符(1 表示标准输出),第二个参数是要写入的数据,第三个参数是要写入的数据长度。
在循环中,如果不是最后一个参数,则在参数之间插入空格;如果是最后一个参数,则在参数后面插入换行符 \n。
exit(0):正常退出程序,参数 0 表示程序正常结束。
*/

grep.c

// Simple grep.  Only supports ^ . * $ operators.

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

char buf[1024];
int match(char*, char*);

void
grep(char *pattern, int fd)
{
  int n, m;
  char *p, *q;

  m = 0;
  while((n = read(fd, buf+m, sizeof(buf)-m-1)) > 0){
    m += n;
    buf[m] = '\0';
    p = buf;
    while((q = strchr(p, '\n')) != 0){
      *q = 0;
      if(match(pattern, p)){
        *q = '\n';
        write(1, p, q+1 - p);
      }
      p = q+1;
    }
    if(m > 0){
      m -= p - buf;
      memmove(buf, p, m);
    }
  }
}

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);
}

// Regexp matcher from Kernighan & Pike,
// The Practice of Programming, Chapter 9.

int matchhere(char*, char*);
int matchstar(int, char*, char*);

int
match(char *re, char *text)
{
  if(re[0] == '^')
    return matchhere(re+1, text);
  do{  // must look at empty string
    if(matchhere(re, text))
      return 1;
  }while(*text++ != '\0');
  return 0;
}

// matchhere: search for re at beginning of text
int matchhere(char *re, char *text)
{
  if(re[0] == '\0')
    return 1;
  if(re[1] == '*')
    return matchstar(re[0], re+2, text);
  if(re[0] == '$' && re[1] == '\0')
    return *text == '\0';
  if(*text!='\0' && (re[0]=='.' || re[0]==*text))
    return matchhere(re+1, text+1);
  return 0;
}

// matchstar: search for c*re at beginning of text
int matchstar(int c, char *re, char *text)
{
  do{  // a * matches zero or more instances
    if(matchhere(re, text))
      return 1;
  }while(*text!='\0' && (*text++==c || c=='.'));
  return 0;
}

/*
这段代码实现了一个简单的 grep 命令,可以在文本中搜索指定的模式(pattern)。它支持基本的正则表达式操作符 ^、.、* 和 $。

以下是代码中主要部分的解释:

grep 函数:
接收一个模式 pattern 和一个文件描述符 fd(如果为 0,则表示从标准输入读取)。
使用 read 函数从文件描述符中读取数据到缓冲区 buf 中。
使用 match 函数匹配模式并输出匹配的行。
main 函数:
解析命令行参数,如果参数个数不符合要求则打印用法信息并退出。
提取模式 pattern 和需要搜索的文件。
对每个文件,打开文件并调用 grep 函数进行搜索,最后关闭文件。
match、matchhere 和 matchstar 函数:
这些函数实现了简单的正则表达式匹配逻辑。
match 函数用于在文本中查找模式。
matchhere 函数用于在文本开头匹配模式。
matchstar 函数用于处理 * 操作符。
这个程序的核心逻辑在于 match 函数和相关的匹配函数,它们用于实现基本的正则表达式匹配功能。
*/

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);
}

/*
这段代码实现了一个简单的 rm(删除文件)命令,可以删除指定的文件。让我们来看一下代码的主要部分:

#include "kernel/types.h"、#include "kernel/stat.h"、#include "user/user.h":这些是头文件包含语句,用于包含所需的系统头文件和声明相关的函数和数据结构。
main 函数:这是程序的入口函数,它接收命令行参数 argc 和 argv[],其中 argc 表示参数的个数,argv[] 是一个指向参数字符串数组的指针。
参数检查:程序首先检查参数个数是否符合要求,如果小于 2,则打印用法信息并退出程序。
循环删除文件:程序使用 unlink 函数删除每个指定的文件。如果删除失败(unlink 返回值小于 0),则打印错误信息,并退出循环。
exit:正常退出程序,参数 0 表示程序正常结束。
*/

3.sleep代码(写在user/sleep.c)

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h" // 必须以这个顺序 include,由于三个头文件有依赖关系

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

/*
代码实现了一个简单的 sleep 命令,用于让当前进程睡眠指定的时钟 tick 数量。以下是代码的一些说明:

错误处理: 如果参数个数小于 2,即用户未提供睡眠时间参数,程序会打印用法信息并退出。
参数转换: 通过 atoi 函数将字符串形式的睡眠时间参数转换为整数。
睡眠功能: 使用 sleep 系统调用使当前进程睡眠指定的时钟 tick 数量。
退出码: 程序成功执行后,返回退出码 0,表示正常结束。
*/

4.编译配置

在Makefile下添加配置。

5.测试sleep程序

xv6通过qemu启动完成后,启动了shell进程。通过shell,启动子进程sleep。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/566039.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

xshell的基本命令

1. 创建虚拟环境: conda create -n 虚拟环境名称 python3.7 2. 激活进入虚拟环境 conda activate 虚拟环境名称 3. 退出虚拟环境 conda deactivate 4. 查看所有虚拟环境 conda env list 5. 卸载环境 conda remove -n 虚拟环境名称 --all 6. 执行py文件: python3.py文…

微软刚开源就删库的WizardLM-2:MT-Bench 榜单评测超越GPT-4,7B追平Qwen1.5-32B

前言 微软最近发布的WizardLM-2大型语言模型因其先进的技术规格和短暂的开源后突然撤回&#xff0c;引起了科技界的广泛关注。WizardLM-2包括三个不同规模的模型&#xff0c;分别是8x22B、70B和7B&#xff0c;均展现了在多语言处理、复杂对话、推理和代理任务上的卓越能力。 H…

如何用PHP语言实现远程语音播报

如何用PHP语言实现远程语音播报呢&#xff1f; 本文描述了使用PHP语言调用HTTP接口&#xff0c;实现语音播报。通过发送文本信息&#xff0c;来实现远程语音播报、语音提醒、语音警报等。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称1…

IDEA代码重构

重构 重构的目的&#xff1a; 提高代码的可读性、可维护性、可扩展性和性能。 重命名元素 重命名类 当我们进行重命名操作的时候可以看到第六行存在一个R(rename)&#xff0c;点击后就会弹出所偶有引用&#xff0c;这样可以避免我们在修改后存在遗漏引用处未修改。 我们可以通过…

操作系统安全:Windows与Linux的安全标识符,身份鉴别和访问控制

「作者简介」&#xff1a;2022年北京冬奥会中国代表队&#xff0c;CSDN Top100&#xff0c;学习更多干货&#xff0c;请关注专栏《网络安全自学教程》 操作系统有4个安全目标&#xff0c;也就是说想要保证操作系统的安全&#xff0c;就必须实现这4个需求&#xff1a; 标识系统…

YoloV9改进策略:下采样改进|自研下采样模块(独家改进)|疯狂涨点|附结构图

文章目录 摘要自研下采样模块及其变种第一种改进方法 YoloV9官方测试结果改进方法测试结果总结 摘要 本文介绍我自研的下采样模块。本次改进的下采样模块是一种通用的改进方法&#xff0c;你可以用分类任务的主干网络中&#xff0c;也可以用在分割和超分的任务中。已经有粉丝用…

单细胞+RIP-seq项目文章| Cell ReportshnRNPU蛋白在小鼠精原干细胞池建立的关键作用

精原干细胞&#xff08;SSCs&#xff09;是负责精子发生的干细胞&#xff0c;具有自我更新和分化产生功能性精子的能力。SSCs的持续再生对于维持雄性生育力至关重要。然而&#xff0c;SSC池的发育起源尚不清楚。在哺乳动物中&#xff0c;SSCs源自名为 prospermatogonia&#xf…

端口被占用的解决方案汇总

端口被占用的解决方案汇总 【一】windows系统端口被占用【二】Linux系统端口被占用【三】Linux的ps命令查找&#xff08;1&#xff09;ps命令常用的方式有三种&#xff08;2&#xff09;ps -ef |grep 8080 【一】windows系统端口被占用 &#xff08;1&#xff09;键盘上按住Wi…

Ubuntu-18.04本地化部署Rustdesk服务器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、配置防火墙二、安装三大件1.下载三大件2.安装三大件 三、安装客户端1.下载客户端1.Windows2.Linux 四、配置客户端连接服务器五、总结 前言 如果你是想数据…

JS-47-Node.js06-fs模块-读写文件

Node.js内置的fs模块就是文件系统模块&#xff0c;负责读写文件。 和所有其它JavaScript模块不同的是&#xff0c;fs模块同时提供了异步和同步的方法。 一、回顾&#xff1a;异步方法VS同步方法 1-1、异步方法 因为JavaScript的单线程模型&#xff0c;执行IO操作时&#xff…

.gitignore语法及配置问题

语法及配置 前言.gitignore语法Git 忽略规则优先级gitignore规则不生效Java项目中常用的.gitignore文件c项目中常用的.gitignore注意事项 前言 在工程中&#xff0c;并不是所有文件都需要保存到版本库中&#xff0c;例如“target”目录及目录下的文件就可以忽略。在Git工作区的…

AI视频分析技术的常用开源模型及TSINGSEE青犀AI视频识别分析能力介绍

AI视频分析技术是指利用人工智能技术来对视频数据进行分析和处理的技术。开源模型是指可以免费获取和使用的代码模型&#xff0c;可以帮助开发人员快速构建和部署AI视频分析应用程序。 以下是一些业内常用的用于AI视频分析技术的开源模型&#xff1a; OpenCV&#xff1a;Open…

MySQL—一条查询SQL语句的完整执行流程

MySQL—一条查询SQL语句的完整执行流程 表结构和数据如下&#xff1a; 我们分析的sql语句如下&#xff1a; select tb_id,tb_name,tb_address from tb_user where tb_id 66;大体来说&#xff0c;MySQL可以分为Server层和存储引擎层两部分: Server层 包括:连接器、查询缓存、…

OpenCV-基于阴影勾勒的图纸清晰度增强算法

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 实现原理 大家在工作和学习中&#xff0c;无论是写报告还是论文&#xff0c;经常有截图的需求&#xff0c;比如图表、图纸等&…

【PCL】教程global_hypothesis_verification 通过验证模型假设来实现 3D 对象识别与位姿估计...

测试程序1 milk.pcd milk_cartoon_all_small_clorox.pcd 终端输出1&#xff1a; Model total points: 12575; Selected Keypoints: 193 Scene total points: 307200; Selected Keypoints: 7739 [pcl::SHOTEstimation::computeFeature] The local reference frame is not valid!…

若依集成mybatisplus报错找不到xml

引用&#xff1a;https://blog.csdn.net/qq_65080131/article/details/136677276 MybatisPlusAutoConfiguration中可以知道&#xff0c;系统会自动配置SqlSessionFactory&#xff0c;&#xff0c;但是&#xff0c;当你有自定义的SqlSessionFactory&#xff0c;&#xff0c;就会…

Spark-机器学习(4)回归学习之逻辑回归

在之前的文章中&#xff0c;我们来学习我们回归中的线性回归&#xff0c;了解了它的算法&#xff0c;知道了它的用法&#xff0c;并带来了简单案例。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请…

NCH WavePad for Mac:功能全面的音频编辑利器

NCH WavePad for Mac是一款功能全面的音频编辑软件&#xff0c;专为Mac用户设计。它集音频录制、编辑、处理和效果添加于一体&#xff0c;为用户提供一站式的音频解决方案。 NCH WavePad for Mac v19.16注册版下载 作为一款专业的音频编辑器&#xff0c;WavePad支持对音频文件进…

软件测试之【合理的利用GPT来辅助软件测试一】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言GPT的原理及技巧GPT辅助接口自动化测试 前言 在编程基础栏目中&#xff…

OSI七层模型、TCP/IP五层模型理解(个人解读,如何理解网络模型)

OSI七层模型 七层模型&#xff0c;亦称OSI&#xff08;Open System Interconnection&#xff09;。参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为OSI参考模型或七层模型。它是一个七层的、抽象的模…