xv6的作业翻译——作业1 - shell和系统调用

时间:2022-02-02 23:10:58

Xv6的lecture

LEC 1 Operating systems

 

L1: O/S overview

L1:O/S概述

 
* 6.828 goals 
6.828的目标
 
Understand operating systems in detail by designing and implementing a small O/S
通过设计并实现一个小型的系统在细节上理解操作系统。
 
Hands-on experience with building systems("Applying 6.033")
构建系统来完成练习。
 
* What do applications want from an O/S?
从程序角度看操作系统需要提供什么?
 
* Abstract the hardware for convenience and portability
对硬件进行抽象使其方便使用和移植
 
* Multiplex the hardware among multiple applications
在多个程序间复用硬件资源
 
* Isolate applications to contain bugs
隔离程序阻止错误蔓延
 
* Allow sharing among applications
允许程序间共享资源
 
 
* What is an OS?
什么是操作系统?
 
* e.g. OSX, Windows, Linux
例如OSX、Windows和linux
 
* the small view: a h/w management library
狭义:硬件的管理库
 
* the big view: physical machine -> abstract one w/ better properties
广义:物理机器  -> 具有更好特性的抽象机器
 
* Organization: layered picture
结构:分层图像
 
h/w: CPU, mem, disk
硬件:CPU、内存、磁盘
 
kernel: [various services]
内核:多种服务
 
user: applications, e.g. vi and gcc
用户:应用程序,如vi和gcc
 
we care a lot about the interfaces and internel kernel structure
我们更关心接口和内核的内部结构
 
* What services does an O/S kernel typically provide?
一个典型的操作系统内核需要提供什么服务?
 
* processes
进程
* memory
内存管理
* file contents
文件内容
* directories and file names
目录和文件名称
* security
安全
* many others: users, IPC, network, time, terminals
其他:用户、IPC、网络、时间和终端
 
* What does an O/S abstraction look like?
操作系统的抽象看来什么样?
 
* Applications only see them via system calls
应用程序仅能通过系统调用看到它们。
* Examples, from UNIX / Linux:
例如:在UNIX或Linux中:
 
```
  fd = open("out", 1);
  write(fd, "hello\n", 6);
  pid = fork();
```
 
* Why is O/S design/implementation hard/interesting?
为什么操作系统的设计和实现是如此难又是有趣的?
 
* the environment is unforgiving: weird h/w, no debugger
实验环境不好:古怪的硬件、没有调试器
 
* it must be efficient (thus low-level?)
它必须是高效的(那么就是低层次的?)
        ...but abstract/portable (thus high-level?)
        …但是抽象/可移植(这是高层次的?)
* powerful (thus many features?)
功能强大(更多特性?)
        ...but simple (thus a few composable building blocks?)
        …但是简单(较少的可组合的构建模块?)
* features interact: `fd = open(); ...; fork()`
内部特性: fd = open(); …; fork()
* behaviors interact: CPU priority vs memory allocator.
内部行为:CPU特权对比内存分配
* open problems: security, multi-core
开放的问题:安全、多核心
 
* You'll be glad you learned about operating systems if you...
学习操作系统后你可能会愿意做以下事情…
* want to work on the above problems
想要解决上面的问题
* care about what's going on under the hood
关心那层布下面发生了什么
* have to build high-performance systems
愿意去构建一个高效的系统
* need to diagnose bugs or security problems
愿意去分析错误或是安全问题
 

Class structure

课程结构

 
* See web site: http://pdos.lcs.mit.edu/6.828
 
* Lectures
课程
 
* basic O/S ideas
基本的操作系统概念
* extended inspection of xv6, a traditional O/S
Xv6,一个传统的操作系统的扩展的分析 
* several more recent topics
几个较新的话题
* xv6 programming to re-inforce xv6 understanding
从xv6的编码到对重新加强的xv6的理解
 
* Lab: JOS, a small O/S for x86 in an exokernel style
实验:JOS,为x86平台所写的一个小型的微内核操作系统
 
* you build it, 5 labs + final lab of your choice
你要完成5个实验和一个最终的选做实验
* kernel interface: expose hardware, but protect -- no abstractions!
内核接口:暴露硬件,但要在没有抽象的前提下进行保护!
* unprivileged library: fork, exec, pipe, ...
非特权库:fork,exec,pipe,…
* applications: file system, shell, ..
应用:文件系统,shell,…
* development environment: gcc, qemu
开发环境:gcc,qemu
* lab 1 is out
实验1已经不合适了
* make grade
升级吧
 

Code review

代码概述
 
* Two quizzes: one in class hours, one in final's week
两个小测验:一个是随堂测验,另一个在本周结束
 
 
## Shell and system calls
Shell和系统调用
 
* 6.828 is largely about design and implementation of system call interface. let's start by looking at how programs use that interface. 
6.828大部分内容都是设计和实现系统调用接口。让我们从一个程序如何使用接口开始看。
 
example:
例如:
 
the Unix shell.
Unix的shell。
 
* the shell is the Unix command UI
Shell是unix的命令接口
* typically handles login session, runs other processes
典型的场合是处理登录和运行其他进程
* you saw it in 6.033: http://web.mit.edu/6.033/www/assignments/handson-unix.html
你能在6.033上看到:
 
* the shell is also a programming/scripting language
Shell也是一个可编程或脚本语言
 
* look at some simple examples of shell operations, how they use different O/S abstractions, and how those abstractions fit together.  See     [Unix paper](../readings/ritchie78unix.pdf) if you are unfamiliar with the shell.
查看一些shell操作的简单例子,了解他们如何使用不同的O/S抽象,这些抽象如何一些工作。如果你不熟悉这些shell,请看[Unix文件](https://pdos.csail.mit.edu/6.828/2014/readings/ritchie78unix.pdf)
 
* [Simplified xv6 sh.c](../homework/sh.c)
简单的xv6中的shell源文件sh.c
* See [chapter 0 of xv6 book](../xv6/book-rev8.pdf)
读xv6课本的第0章
* Basic organization: parsing and executing commands (e.g., ls, ls | wc, ls > out)
基本结构:解释并执行命令(如:ls,ls | wc, ls > out)
* Shell implemented using system calls (e.g., read, write, fork, exec, wait) conventions: -1 return value signals error, error code stored in errno, perror prints out a descriptive error message based on errno.
Shell通过系统调用(如:read,write,fork,exec和wait)来实现功能:返回-1表明出错,错误码保存在errno中,perror可以打印errno代表的错误描述。
* Many systems calls are encapsulated in libc calls (e.g., fgets vs read)
很多系统调用被封装在libc库的函数调用中(如:fgets封装了read)
 
  Demo:
  - open sh.c in emacs
  - look at main()
  - look at runcmd()
  - look at fgets()
  - man 3 fgets()
  
* Trace system calls $ls
跟踪系统调用 ls
* On OSX: sudo dtruss ./a.out  (where a.out is the compiled sh.c)
在OSX中:sudo dtruss ./a.out (这里a.out是sh.c编译后的文件)
* On Linux: strace ./a.out
在Linux中:strace ./a.out
 
- compile sh.c
编译sh.c
- run ./a.out
运行./a.out
- strace ./a.out
跟踪./a.out
 
* what does fork() do?
Fork()都做了什么?
 
copies user memory
拷贝用户内存
copies process kernel state (e.g. user id)
拷贝进程的内核状态(如:用户id)
child gets a different PID
子进程获得一个不同的PID
child state contains parent PID
子进程的状态信息中包含父进程的PID
returns twice, with different values
以不同的返回值返回两次
  * parent and child may run concurrently (e.g., on different processors).
  你进程和子进程可能会同步运行(比如:在不同的处理器上)
 
 
* what does wait() do?
Wait()都做了什么?
 
waits for any child to exit
等待任何子进程退出
what if child exits before parent calls wait?
如果子进程在父进程调用wait之前结束会发生什么?
 
    - strace /bin/sh
    - study output:
    read()
    write()
    stat()
    etc.
 
* what are file descriptors? (0, 1, 2, etc. in read/write)
文件描述符是什么?(0、1、2文件描述符,比如在读写中)
 
[echo.c](l-overview/echo.c)
 
* what is i/o redirection?
什么是i/o重定向?
How would you implement ">"  in sh.c
在sh.c中你如何实现“>”?
* what are pipes?  (ls | wc )
什么是管道?( ls | wc)
[pipe1.c](l-overview/pipe1.c)
[pipe2.c](l-overview/pipe2.c)
How would you implement them in sh.c?
在sh.c中你是怎么实现它们的?
 
* Homework assignment for [shell](../homework/xv6-shell.html)
关于shell的课后作业安排(https://pdos.csail.mit.edu/6.828/2014//homework/xv6-shell.html
 

Homework: shell

作业:shell

This assignment will make you more familiar with the Unix system call interface and the shell by implementing several features in a small shell, which we will refer to as the 6.828 shell. You can do this assignment on any operating system that supports the Unix API (a Linux Athena machine, your laptop with Linux or MacOS, etc.). Submit your 6.828 shell to the submission web site as a text file with the name "hwN.c", where N is the homework number as listed on the schedule.

这个安排能让你更熟悉unix的系统调用接口和shell(通过在一个6.828版本中使用的小型shell中实现几个功能特性)。你可以在任何支持unix API(linux的雅典娜机器、你的装有linux或MacOS的笔记本等等)的操作系统上完成它。将你的6.828 shell以文本文件格式并且命名为”hwN.c”发送到提交网址,这里N是进度表中的作业序号。

Read Chapter 0 of the xv6 book.

阅读xv6课本的第0章

If you are not familiar with what a shell does, do the Unix hands-on from 6.033.

如果你不熟悉shell的功能,请查看6.033的Unix手册。

Download the 6.828 shell, and look it over. The 6.828 shell contains two main parts: parsing shell commands and implementing them. The parser recognizes only simple shell commands such as the following:

下载6.828shell[https://pdos.csail.mit.edu/6.828/2014/homework/sh.c]。它包含两个主要部分:解析shell命令和实现它们。解析器仅能识别简单的shell命令,有下面所示:

ls > y

cat < y | sort | uniq | wc > y1

cat y1

rm y1

ls |  sort | uniq | wc

rm y

Cut and paste these commands into a file t.sh

剪切并粘贴这些到文件t.sh。

To compile sh.c, you need a C compiler, such as gcc. On Athena, you can type:

为了编译sh.c,你需要一个C编译器,比如gcc。在雅典娜机器上,你可以输入以下命令:

$ add gnu

to make gcc available. If you are using your own computer, you may have to install gcc.

确保gcc可用。如果你使用自己的机器,你可能需要安装gcc。

Once you have a gcc, you can compile the skeleton shell as follows:

一旦你安装了gcc,你就可以用如下的命令来编译这个简单的shell:

$ gcc sh.c

which produce an a.out file, which you can run:

这会产生一个叫a.out的可执行文件。

$ ./a.out < t.sh

This execution will print error messages because you have not implemented several features. In the rest of this assignment you will implement those features.

由于你没有实现那几个功能特性,所以上面的执行会显示出错信息。在作业的剩余部分,你将实现那些功能特性。

Executing simple commands

执行简单命令

Implement simple commands, such as:

实现简单的命令,例如:

$ ls

The parser already builds an execcmd for you, so the only code you have to write is for the ' ' case in runcmd. You might find it useful to look at the manual page for exec; type "man 3 exec", and read about execv. Print an error message when exec fails.

解析器已经帮你完成了execmd函数,你要做的就是写runcmd部分中的那空白case。你可以在exec的手册上找到有用的信息;键入”man 3 exec”命令,阅读关于execv的内容。当exec失败时要打印一条错误信息。

To test your program, compile and run the resulting a.out:

测试你的程序,编译并运行生成的a.out文件:

6.828$./a.out

This prints a prompt and waits for input. sh.c prints as prompt 6.828$ so that you don't get confused with your computer's shell. Now type to your shell:

这会显示一个提示符并等待输入。Sh.c显示一个6.828$的提示符,这样你就不会和你机器上的shell混淆。现在为你的shell输入命令:

6.828$ ls

Your shell should print an error message (unless there is a program named ls in your working directory). Now type to your shell:

你的shell将会显示一条错误信息(除非在你的工作目录中有一个名叫ls的程序)。现在为你的shell输入命令:

6.828$ /bin/ls

This should execute the program /bin/ls, which should print out the file names in your working directory. You can stop the 6.828 shell by tying ctrl-d, which should put you back in your computer's shell.

这会执行/bin/ls的程序,它会显示你工作目录下的文件名称。你可以通过按ctrl-d组合键来终止6.828 shell的执行,这会返回到你机器中的shell。

You may want to change the 6.828 shell to always try /bin, if the program doesn't exist in the current working directory, so that below you don't have to type "/bin" for each program. If you are ambitious you can implement support for a PATH variable.

如果程序不在你当前的工作目录,你可能想改变6.828 shell让它总是试图在/bin目录下寻找,而不需要你为每个程序都键入”/bin”。

I/O redirection

I/O重定向

Implement I/O redirection commands so that you can run:

实现I/O重定向命令,以便你可象下面这样使用命令:

echo "6.828 is cool" > x.txt

cat < x.txt

The parser already recognizes ">" and "<", and builds a redircmd for you, so your job is just filling out the missing code in runcmd for those symbols. You might find the man pages for open and close useful。

解析器已经可以辨识”>”和”<”符号,并且替你完成了redircmd函数,所以你的工作仅仅是将runcmd中缺少的已做了符号标识的代码补全。你可以在关于open和close的手册部分找到有用的信息。

Make sure you print an error message if one of the system calls you are using fails.

要确保当你使用的一个系统调用失败后显示一条错误信息。

Make sure your implementation runs correctly with the above test input. A common error is to forget to specify the permission with which the file must be created (i.e., the 3rd argument to open).

使用上面的测试输入来确保你实现在部分正确运行。一个觉的错误是忘记为一个必须创建的文件指定权限(比如,open的第三个参数)。

Implement pipes

实现管道

Implement pipes so that you can run command pipelines such as:

实现管道功能以便你可以象下面的命令一样使用命令管道:

$ ls | sort | uniq | wc

The parser already recognizes "|", and builds a pipecmd for you, so the only code you must write is for the '|' case in runcmd. You might find the man pages for pipe, fork, close, and dup useful.

解析器已经可以辨识”|”符号,并且替你完成了pipecmd部分,所以你必须编写runcmd函数中”|”分支部分的代码。你能在手册中关于pipe、fork、close和dup部分找到用有信息。

Test that you can run the above pipeline. The sort program may be in the directory /usr/bin/ and in that case you can type the absolute pathname /usr/bin/sort to run sort. (In your computer's shell you can type which sort to find out which directory in the shell's search path has an executable named "sort".)

运行上面的管道命令来测试。Sort程序可能位于/usr/bin/目录,在这种情况下你可键入一个绝对路径/usr/bin/sort来运行它(在计算机的shell中,你可以键入sort,是因为在shell的可执行文件的搜索路径中可以找到它)。

Now you should be able the following command correctly:

现在可以正确使用下面的命令:

6.828$ a.out < t.sh

Make sure you use the right absolute pathnames for the programs.

确保你为程序使用了正确的路径名称。

Don't forget to submit your solution to the submission web site, with or without challenge solutions.

别忘了向提交网站[https://ccutler.scripts.mit.edu/6.828/handin.py/]提交你的解决方案,带不带挑战练习解决方案都可以。

Challenge exercises

挑战练习

You can add any feature of your choice to your shell. But, you may want consider the following as a start:

你可以向你的shell中添加任何你想要的功能特性。但你可以考虑从下面的开如:

Implement lists of commands, separated by ";"

实现命令列表,它以”;”分隔。

Implement sub shells by implementing "(" and ")"

实现子shell通过”(“和”)”符号支持的实现

Implement running commands in the background by supporting "&" and "wait"

通过支持”&”符号和”wait”命令来支持后台运行命令。

All of these require making changing to the parser and the runcmd function.

所有的这些需求都要修改解析器和runcmd函数。