mirror of
https://github.com/duguosheng/6.S081-All-in-one.git
synced 2026-02-02 18:39:38 +08:00
1170 lines
63 KiB
HTML
1170 lines
63 KiB
HTML
|
||
<!DOCTYPE HTML>
|
||
<html lang="" >
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||
<title>Lab1: Xv6 and Unix utilities · 6.S081 All-In-One</title>
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||
<meta name="description" content="">
|
||
<meta name="generator" content="GitBook 3.2.3">
|
||
<meta name="author" content="DuGuoSheng">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/style.css">
|
||
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-search-pro/search.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-chapter-fold/chapter-fold.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-code-optimize/plugin.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-splitter/splitter.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-pageview-count/plugin.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-donate/plugin.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-tbfed-pagefooter/footer.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-flexible-alerts/style.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-ancre-navigation/style/plugin.css">
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../gitbook/gitbook-plugin-fontsettings/website.css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta name="HandheldFriendly" content="true"/>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="../../gitbook/images/apple-touch-icon-precomposed-152.png">
|
||
<link rel="shortcut icon" href="../../gitbook/images/favicon.ico" type="image/x-icon">
|
||
|
||
|
||
|
||
<link rel="prev" href="summary.html" />
|
||
|
||
|
||
</head>
|
||
<body>
|
||
|
||
<div class="book">
|
||
<div class="book-summary">
|
||
|
||
|
||
<div id="book-search-input" role="search">
|
||
<input type="text" placeholder="Type to search" />
|
||
</div>
|
||
|
||
|
||
<nav role="navigation">
|
||
|
||
|
||
|
||
<ul class="summary">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="header">概述</li>
|
||
|
||
|
||
|
||
<li class="chapter " data-level="1.1" data-path="../../">
|
||
|
||
<a href="../../">
|
||
|
||
|
||
课程介绍
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
<li class="header">文档翻译</li>
|
||
|
||
|
||
|
||
<li class="chapter " data-level="2.1" data-path="../../tranlate_books/book-riscv-rev1/summary.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/summary.html">
|
||
|
||
|
||
book-riscv-rev1
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<ul class="articles">
|
||
|
||
|
||
<li class="chapter " data-level="2.1.1" data-path="../../tranlate_books/book-riscv-rev1/c1/s0.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s0.html">
|
||
|
||
|
||
第一章 操作系统接口
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<ul class="articles">
|
||
|
||
|
||
<li class="chapter " data-level="2.1.1.1" data-path="../../tranlate_books/book-riscv-rev1/c1/s1.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s1.html">
|
||
|
||
|
||
1.1 进程和内存
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.1.2" data-path="../../tranlate_books/book-riscv-rev1/c1/s2.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s2.html">
|
||
|
||
|
||
1.2 I/O和文件描述符
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.1.3" data-path="../../tranlate_books/book-riscv-rev1/c1/s3.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s3.html">
|
||
|
||
|
||
1.3 管道
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.1.4" data-path="../../tranlate_books/book-riscv-rev1/c1/s4.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s4.html">
|
||
|
||
|
||
1.4 文件系统
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.1.5" data-path="../../tranlate_books/book-riscv-rev1/c1/s5.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s5.html">
|
||
|
||
|
||
1.5 真实世界
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.1.6" data-path="../../tranlate_books/book-riscv-rev1/c1/s6.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c1/s6.html">
|
||
|
||
|
||
1.6 练习
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
</ul>
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2" data-path="../../tranlate_books/book-riscv-rev1/c2/s0.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s0.html">
|
||
|
||
|
||
第二章 操作系统架构
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<ul class="articles">
|
||
|
||
|
||
<li class="chapter " data-level="2.1.2.1" data-path="../../tranlate_books/book-riscv-rev1/c2/s1.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s1.html">
|
||
|
||
|
||
2.1 抽象系统资源
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.2" data-path="../../tranlate_books/book-riscv-rev1/c2/s2.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s2.html">
|
||
|
||
|
||
2.2 用户态,核心态,以及系统调用
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.3" data-path="../../tranlate_books/book-riscv-rev1/c2/s3.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s3.html">
|
||
|
||
|
||
2.3 内核组织
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.4" data-path="../../tranlate_books/book-riscv-rev1/c2/s4.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s4.html">
|
||
|
||
|
||
2.4 代码:XV6架构篇
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.5" data-path="../../tranlate_books/book-riscv-rev1/c2/s5.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s5.html">
|
||
|
||
|
||
2.5 进程概述
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.6" data-path="../../tranlate_books/book-riscv-rev1/c2/s6.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s6.html">
|
||
|
||
|
||
2.6 代码:启动XV6和第一个进程
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.7" data-path="../../tranlate_books/book-riscv-rev1/c2/s7.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s7.html">
|
||
|
||
|
||
2.7 真实世界
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.2.8" data-path="../../tranlate_books/book-riscv-rev1/c2/s8.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c2/s8.html">
|
||
|
||
|
||
2.8 练习
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
</ul>
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3" data-path="../../tranlate_books/book-riscv-rev1/c3/s0.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s0.html">
|
||
|
||
|
||
第三章 页表
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<ul class="articles">
|
||
|
||
|
||
<li class="chapter " data-level="2.1.3.1" data-path="../../tranlate_books/book-riscv-rev1/c3/s1.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s1.html">
|
||
|
||
|
||
3.1 页式硬件
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.2" data-path="../../tranlate_books/book-riscv-rev1/c3/s2.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s2.html">
|
||
|
||
|
||
3.2 内核地址空间
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.3" data-path="../../tranlate_books/book-riscv-rev1/c3/s3.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s3.html">
|
||
|
||
|
||
3.3 代码:创建一个地址空间
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.4" data-path="../../tranlate_books/book-riscv-rev1/c3/s4.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s4.html">
|
||
|
||
|
||
3.4 物理内存分配
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.5" data-path="../../tranlate_books/book-riscv-rev1/c3/s5.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s5.html">
|
||
|
||
|
||
3.5 代码:物理内存分配
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.6" data-path="../../tranlate_books/book-riscv-rev1/c3/s6.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s6.html">
|
||
|
||
|
||
3.6 进程地址空间
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.7" data-path="../../tranlate_books/book-riscv-rev1/c3/s7.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s7.html">
|
||
|
||
|
||
3.7 代码:sbrk
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.8" data-path="../../tranlate_books/book-riscv-rev1/c3/s8.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s8.html">
|
||
|
||
|
||
3.8 代码:exec
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.9" data-path="../../tranlate_books/book-riscv-rev1/c3/s9.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s9.html">
|
||
|
||
|
||
3.9 真实世界
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.3.10" data-path="../../tranlate_books/book-riscv-rev1/c3/s10.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c3/s10.html">
|
||
|
||
|
||
3.10 练习
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
</ul>
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4" data-path="../../tranlate_books/book-riscv-rev1/c4/s0.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s0.html">
|
||
|
||
|
||
第四章 陷阱指令和系统调用
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<ul class="articles">
|
||
|
||
|
||
<li class="chapter " data-level="2.1.4.1" data-path="../../tranlate_books/book-riscv-rev1/c4/s1.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s1.html">
|
||
|
||
|
||
4.1 RISC-V陷入机制
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.2" data-path="../../tranlate_books/book-riscv-rev1/c4/s2.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s2.html">
|
||
|
||
|
||
4.2 从用户空间陷入
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.3" data-path="../../tranlate_books/book-riscv-rev1/c4/s3.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s3.html">
|
||
|
||
|
||
4.3 代码:调用系统调用
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.4" data-path="../../tranlate_books/book-riscv-rev1/c4/s4.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s4.html">
|
||
|
||
|
||
4.4 系统调用参数
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.5" data-path="../../tranlate_books/book-riscv-rev1/c4/s5.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s5.html">
|
||
|
||
|
||
4.5 从内核空间陷入
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.6" data-path="../../tranlate_books/book-riscv-rev1/c4/s6.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s6.html">
|
||
|
||
|
||
4.6 页面错误异常
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.7" data-path="../../tranlate_books/book-riscv-rev1/c4/s7.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s7.html">
|
||
|
||
|
||
4.7 真实世界
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="2.1.4.8" data-path="../../tranlate_books/book-riscv-rev1/c4/s8.html">
|
||
|
||
<a href="../../tranlate_books/book-riscv-rev1/c4/s8.html">
|
||
|
||
|
||
4.8 练习
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
</ul>
|
||
|
||
</li>
|
||
|
||
|
||
</ul>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
<li class="header">实验记录</li>
|
||
|
||
|
||
|
||
<li class="chapter " data-level="3.1" data-path="../use_git/git1.html">
|
||
|
||
<a href="../use_git/git1.html">
|
||
|
||
|
||
版本控制
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
<li class="chapter " data-level="3.2" data-path="summary.html">
|
||
|
||
<a href="summary.html">
|
||
|
||
|
||
实验内容
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<ul class="articles">
|
||
|
||
|
||
<li class="chapter active" data-level="3.2.1" data-path="lab1.html">
|
||
|
||
<a href="lab1.html">
|
||
|
||
|
||
Lab1: Xv6 and Unix utilities
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
</ul>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
<li class="divider"></li>
|
||
|
||
<li>
|
||
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
|
||
Published with GitBook
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
</nav>
|
||
|
||
|
||
</div>
|
||
|
||
<div class="book-body">
|
||
|
||
<div class="body-inner">
|
||
|
||
|
||
|
||
<div class="book-header" role="navigation">
|
||
|
||
|
||
<!-- Title -->
|
||
<h1>
|
||
<i class="fa fa-circle-o-notch fa-spin"></i>
|
||
<a href="../.." >Lab1: Xv6 and Unix utilities</a>
|
||
</h1>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div class="page-wrapper" tabindex="-1" role="main">
|
||
<div class="page-inner">
|
||
|
||
<div id="book-search-results">
|
||
<div class="search-noresults">
|
||
|
||
<section class="normal markdown-section">
|
||
|
||
<div id="anchor-navigation-ex-navbar"><i class="fa fa-anchor"></i><ul><li><span class="title-icon "></span><a href="#lab1-xv6-and-unix-utilities"><b></b>Lab1: Xv6 and Unix utilities</a></li><li><span class="title-icon "></span><a href="#实验任务"><b></b>实验任务</a></li><ul><li><span class="title-icon "></span><a href="#启动xv6难度:easy"><b></b>启动xv6(难度:Easy)</a></li><li><span class="title-icon "></span><a href="#sleep难度:easy"><b></b>sleep(难度:Easy)</a></li><li><span class="title-icon "></span><a href="#pingpong(难度:easy)"><b></b>pingpong(难度:Easy)</a></li><li><span class="title-icon "></span><a href="#primes素数,难度:moderatehard"><b></b>Primes(素数,难度:Moderate/Hard)</a></li><li><span class="title-icon "></span><a href="#find(难度:moderate)"><b></b>find(难度:Moderate)</a></li><li><span class="title-icon "></span><a href="#xargs(难度:moderate)"><b></b>xargs(难度:Moderate)</a></li></ul><li><span class="title-icon "></span><a href="#提交实验"><b></b>提交实验</a></li><li><span class="title-icon "></span><a href="#可选的挑战练习"><b></b>可选的挑战练习</a></li></ul></div><a href="#lab1-xv6-and-unix-utilities" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a><h1 id="lab1-xv6-and-unix-utilities"><a name="lab1-xv6-and-unix-utilities" class="anchor-navigation-ex-anchor" href="#lab1-xv6-and-unix-utilities"><i class="fa fa-link" aria-hidden="true"></i></a>Lab1: Xv6 and Unix utilities</h1>
|
||
<h1 id="实验任务"><a name="实验任务" class="anchor-navigation-ex-anchor" href="#实验任务"><i class="fa fa-link" aria-hidden="true"></i></a>实验任务</h1>
|
||
<h2 id="启动xv6难度:easy"><a name="启动xv6难度:easy" class="anchor-navigation-ex-anchor" href="#启动xv6难度:easy"><i class="fa fa-link" aria-hidden="true"></i></a>启动xv6(难度:Easy)</h2>
|
||
<p>获取实验室的xv6源代码并切换到util分支</p>
|
||
<pre><code class="lang-bash">$ 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'
|
||
</code></pre>
|
||
<p>Xv6-labs-2020存储库与本书的xv6-riscv稍有不同;它主要添加一些文件。如果你好奇的话,可以执行<code>git log</code>:</p>
|
||
<pre><code class="lang-bash">$ git log
|
||
</code></pre>
|
||
<p>您将需要使用Git版本控制系统管理和提交文件以及后续的实验室作业。接下来,切换到一个分支(执行<code>git checkout util</code>),其中包含针对该实验室定制的xv6版本。要了解关于Git的更多信息,请查看Git用户手册。Git允许您跟踪对代码所做的更改。例如,如果你完成了其中一个练习,并且想检查你的进度,你可以通过运行以下命令来提交你的变化:</p>
|
||
<pre><code class="lang-bash">$ git commit -am 'my solution for util lab exercise 1'
|
||
Created commit 60d2135: my solution for util lab exercise 1
|
||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||
$
|
||
</code></pre>
|
||
<p>您可以使用<code>git diff</code>命令跟踪您的更改。运行<code>git diff</code>将显示自上次提交以来对代码的更改,<code>git diff origin/util</code>将显示相对于初始xv6-labs-2020代码的更改。这里,<strong><em>origin/xv6-labs-2020</em></strong>是git分支的名称,它是包含您下载的初始代码分支。</p>
|
||
<ul>
|
||
<li><strong>构建并运行xv6</strong></li>
|
||
</ul>
|
||
<pre><code class="lang-bash">$ make qemu
|
||
riscv64-unknown-elf-gcc -c -o kernel/entry.o kernel/entry.S
|
||
riscv64-unknown-elf-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -DSOL_UTIL -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie -c -o kernel/start.o kernel/start.c
|
||
...
|
||
riscv64-unknown-elf-ld -z max-page-size=4096 -N -e main -Ttext 0 -o user/_zombie user/zombie.o user/ulib.o user/usys.o user/printf.o user/umalloc.o
|
||
riscv64-unknown-elf-objdump -S user/_zombie > user/zombie.asm
|
||
riscv64-unknown-elf-objdump -t user/_zombie | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > user/zombie.sym
|
||
mkfs/mkfs fs.img README user/xargstest.sh user/_cat user/_echo user/_forktest user/_grep user/_init user/_kill user/_ln user/_ls user/_mkdir user/_rm user/_sh user/_stressfs user/_usertests user/_grind user/_wc user/_zombie
|
||
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 954 total 1000
|
||
balloc: first 591 blocks have been allocated
|
||
balloc: write bitmap block at sector 45
|
||
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
|
||
|
||
xv6 kernel is booting
|
||
|
||
hart 2 starting
|
||
hart 1 starting
|
||
init: starting sh
|
||
$
|
||
</code></pre>
|
||
<p>如果你在提示符下输入 <code>ls</code>,你会看到类似如下的输出:</p>
|
||
<pre><code class="lang-bash">$ ls
|
||
. 1 1 1024
|
||
.. 1 1 1024
|
||
README 2 2 2059
|
||
xargstest.sh 2 3 93
|
||
cat 2 4 24256
|
||
echo 2 5 23080
|
||
forktest 2 6 13272
|
||
grep 2 7 27560
|
||
init 2 8 23816
|
||
kill 2 9 23024
|
||
ln 2 10 22880
|
||
ls 2 11 26448
|
||
mkdir 2 12 23176
|
||
rm 2 13 23160
|
||
sh 2 14 41976
|
||
stressfs 2 15 24016
|
||
usertests 2 16 148456
|
||
grind 2 17 38144
|
||
wc 2 18 25344
|
||
zombie 2 19 22408
|
||
console 3 20 0
|
||
</code></pre>
|
||
<p>这些是<code>mkfs</code>在初始文件系统中包含的文件;大多数是可以运行的程序。你刚刚跑了其中一个:<code>ls</code>。</p>
|
||
<p>xv6没有<code>ps</code>命令,但是如果您键入Ctrl-p,内核将打印每个进程的信息。如果现在尝试,您将看到两行:一行用于init,另一行用于sh。</p>
|
||
<p>退出 qemu : <code>Ctrl-a x</code>。</p>
|
||
<h2 id="sleep难度:easy"><a name="sleep难度:easy" class="anchor-navigation-ex-anchor" href="#sleep难度:easy"><i class="fa fa-link" aria-hidden="true"></i></a>sleep(难度:Easy)</h2>
|
||
<blockquote>
|
||
<p>[!TIP|label:YOUR JOB]
|
||
<strong>实现xv6的UNIX程序</strong><code>sleep</code><strong>:您的</strong><code>sleep</code><strong>应该暂停到用户指定的计时数。一个滴答(tick)是由xv6内核定义的时间概念,即来自定时器芯片的两个中断之间的时间。您的解决方案应该在文件<em>user/sleep.c</em>中</strong></p>
|
||
</blockquote>
|
||
<p><strong>提示:</strong></p>
|
||
<ul>
|
||
<li><p>在你开始编码之前,请阅读《book-riscv-rev1》的第一章</p>
|
||
</li>
|
||
<li><p>看看其他的一些程序(如<strong><em>/user/echo.c, /user/grep.c, /user/rm.c</em></strong>)查看如何获取传递给程序的命令行参数</p>
|
||
</li>
|
||
<li><p>如果用户忘记传递参数,<code>sleep</code>应该打印一条错误信息</p>
|
||
</li>
|
||
<li><p>命令行参数作为字符串传递; 您可以使用<code>atoi</code>将其转换为数字(详见<strong><em>/user/ulib.c</em></strong>)</p>
|
||
</li>
|
||
<li><p>使用系统调用<code>sleep</code></p>
|
||
</li>
|
||
<li><p>请参阅<strong><em>kernel/sysproc.c</em></strong>以获取实现<code>sleep</code>系统调用的xv6内核代码(查找<code>sys_sleep</code>),<strong><em>user/user.h</em></strong>提供了<code>sleep</code>的声明以便其他程序调用,用汇编程序编写的<strong><em>user/usys.S</em></strong>可以帮助<code>sleep</code>从用户区跳转到内核区。</p>
|
||
</li>
|
||
<li><p>确保<code>main</code>函数调用<code>exit()</code>以退出程序。</p>
|
||
</li>
|
||
<li><p>将你的<code>sleep</code>程序添加到<strong><em>Makefile</em></strong>中的<code>UPROGS</code>中;完成之后,<code>make qemu</code>将编译您的程序,并且您可以从xv6的shell运行它。</p>
|
||
</li>
|
||
<li><p>看看Kernighan和Ritchie编著的《C程序设计语言》(第二版)来了解C语言。</p>
|
||
</li>
|
||
</ul>
|
||
<p>从xv6 shell运行程序:</p>
|
||
<pre><code class="lang-bash">$ make qemu
|
||
...
|
||
init: starting sh
|
||
$ sleep 10
|
||
(nothing happens for a little while)
|
||
$
|
||
</code></pre>
|
||
<p>如果程序在如上所示运行时暂停,则解决方案是正确的。运行<code>make grade</code>看看你是否真的通过了睡眠测试。</p>
|
||
<p>请注意,<code>make grade</code>运行所有测试,包括下面作业的测试。如果要对一项作业运行成绩测试,请键入(不要启动XV6,在外部终端下使用):</p>
|
||
<pre><code class="lang-bash">$ ./grade-lab-util sleep
|
||
</code></pre>
|
||
<p>这将运行与<code>sleep</code>匹配的成绩测试。或者,您可以键入:</p>
|
||
<pre><code class="lang-bash">$ make GRADEFLAGS=sleep grade
|
||
</code></pre>
|
||
<p>效果是一样的。</p>
|
||
<h2 id="pingpong(难度:easy)"><a name="pingpong(难度:easy)" class="anchor-navigation-ex-anchor" href="#pingpong(难度:easy)"><i class="fa fa-link" aria-hidden="true"></i></a>pingpong(难度:Easy)</h2>
|
||
<blockquote>
|
||
<p>[!TIP|label:YOUR JOB]
|
||
<strong>编写一个使用UNIX系统调用的程序来在两个进程之间“ping-pong”一个字节,请使用两个管道,每个方向一个。父进程应该向子进程发送一个字节;子进程应该打印“<code><pid>: received ping</pid></code>”,其中<code><pid></pid></code>是进程ID,并在管道中写入字节发送给父进程,然后退出;父级应该从读取从子进程而来的字节,打印“<code><pid>: received pong</pid></code>”,然后退出。您的解决方案应该在文件<em>user/pingpong.c</em>中。</strong></p>
|
||
</blockquote>
|
||
<p><strong>提示:</strong></p>
|
||
<ul>
|
||
<li><p>使用<code>pipe</code>来创造管道</p>
|
||
</li>
|
||
<li><p>使用<code>fork</code>创建子进程</p>
|
||
</li>
|
||
<li><p>使用<code>read</code>从管道中读取数据,并且使用<code>write</code>向管道中写入数据</p>
|
||
</li>
|
||
<li><p>使用<code>getpid</code>获取调用进程的pid</p>
|
||
</li>
|
||
<li><p>将程序加入到<strong><em>Makefile</em></strong>的<code>UPROGS</code></p>
|
||
</li>
|
||
<li><p>xv6上的用户程序有一组有限的可用库函数。您可以在<strong><em>user/user.h</em></strong>中看到可调用的程序列表;源代码(系统调用除外)位于<strong><em>user/ulib.c</em></strong>、<strong><em>user/printf.c</em></strong>和<strong><em>user/umalloc.c</em></strong>中。</p>
|
||
</li>
|
||
</ul>
|
||
<p>运行程序应得到下面的输出</p>
|
||
<pre><code class="lang-bash">$ make qemu
|
||
...
|
||
init: starting sh
|
||
$ pingpong
|
||
4: received ping
|
||
3: received pong
|
||
$
|
||
</code></pre>
|
||
<p>如果您的程序在两个进程之间交换一个字节并产生如上所示的输出,那么您的解决方案是正确的。</p>
|
||
<h2 id="primes素数,难度:moderatehard"><a name="primes素数,难度:moderatehard" class="anchor-navigation-ex-anchor" href="#primes素数,难度:moderatehard"><i class="fa fa-link" aria-hidden="true"></i></a>Primes(素数,难度:Moderate/Hard)</h2>
|
||
<blockquote>
|
||
<p>[!TIP|label:YOUR JOB]
|
||
<strong>使用管道编写</strong><code>prime sieve</code><strong>(筛选素数)的并发版本。这个想法是由Unix管道的发明者Doug McIlroy提出的。请查看<a href="http://swtch.com/~rsc/thread/" target="_blank">这个网站</a>(翻译在下面),该网页中间的图片和周围的文字解释了如何做到这一点。您的解决方案应该在<em>user/primes.c</em>文件中。</strong></p>
|
||
</blockquote>
|
||
<p>您的目标是使用<code>pipe</code>和<code>fork</code>来设置管道。第一个进程将数字2到35输入管道。对于每个素数,您将安排创建一个进程,该进程通过一个管道从其左邻居读取数据,并通过另一个管道向其右邻居写入数据。由于xv6的文件描述符和进程数量有限,因此第一个进程可以在35处停止。</p>
|
||
<p><strong>提示:</strong></p>
|
||
<ul>
|
||
<li><p>请仔细关闭进程不需要的文件描述符,否则您的程序将在第一个进程达到35之前就会导致xv6系统资源不足。</p>
|
||
</li>
|
||
<li><p>一旦第一个进程达到35,它应该使用<code>wait</code>等待整个管道终止,包括所有子孙进程等等。因此,主<code>primes</code>进程应该只在打印完所有输出之后,并且在所有其他<code>primes</code>进程退出之后退出。</p>
|
||
</li>
|
||
<li><p>提示:当管道的<code>write</code>端关闭时,<code>read</code>返回零。</p>
|
||
</li>
|
||
<li><p>最简单的方法是直接将32位(4字节)int写入管道,而不是使用格式化的ASCII I/O。</p>
|
||
</li>
|
||
<li><p>您应该仅在需要时在管线中创建进程。</p>
|
||
</li>
|
||
<li><p>将程序添加到<strong><em>Makefile</em></strong>中的<code>UPROGS</code></p>
|
||
</li>
|
||
</ul>
|
||
<p>如果您的解决方案实现了基于管道的筛选并产生以下输出,则是正确的:</p>
|
||
<pre><code class="lang-bash">$ make qemu
|
||
...
|
||
init: starting sh
|
||
$ primes
|
||
prime 2
|
||
prime 3
|
||
prime 5
|
||
prime 7
|
||
prime 11
|
||
prime 13
|
||
prime 17
|
||
prime 19
|
||
prime 23
|
||
prime 29
|
||
prime 31
|
||
$
|
||
</code></pre>
|
||
<p><strong>参考资料翻译:</strong></p>
|
||
<blockquote>
|
||
<p>考虑所有小于1000的素数的生成。Eratosthenes的筛选法可以通过执行以下伪代码的进程管线来模拟:</p>
|
||
</blockquote>
|
||
<pre><code class="lang-c">p = get a number from left neighbor
|
||
print p
|
||
=loop:
|
||
n = get a number from left neighbor
|
||
if (p does not divide n)
|
||
send n to right neighbor
|
||
p = 从左邻居中获取一个数
|
||
print p
|
||
loop:
|
||
n = 从左邻居中获取一个数
|
||
if (n不能被p整除)
|
||
将n发送给右邻居
|
||
</code></pre>
|
||
<p><img src="images/p1.png" alt="img"></p>
|
||
<blockquote>
|
||
<p>生成进程可以将数字2、3、4、…、1000输入管道的左端:行中的第一个进程消除2的倍数,第二个进程消除3的倍数,第三个进程消除5的倍数,依此类推。</p>
|
||
</blockquote>
|
||
<h2 id="find(难度:moderate)"><a name="find(难度:moderate)" class="anchor-navigation-ex-anchor" href="#find(难度:moderate)"><i class="fa fa-link" aria-hidden="true"></i></a>find(难度:Moderate)</h2>
|
||
<blockquote>
|
||
<p>[!TIP|label:YOUR JOB]
|
||
<strong>写一个简化版本的UNIX的<code>find</code>程序:查找目录树中具有特定名称的所有文件,你的解决方案应该放在<em>user/find.c</em></strong></p>
|
||
</blockquote>
|
||
<p>提示:</p>
|
||
<ul>
|
||
<li>查看<strong><em>user/ls.c</em></strong>文件学习如何读取目录</li>
|
||
<li>使用递归允许<code>find</code>下降到子目录中</li>
|
||
<li>不要在“<code>.</code>”和“<code>..</code>”目录中递归</li>
|
||
<li>对文件系统的更改会在qemu的运行过程中一直保持;要获得一个干净的文件系统,请运行<code>make clean</code>,然后<code>make qemu</code></li>
|
||
<li>你将会使用到C语言的字符串,要学习它请看《C程序设计语言》(K&R),例如第5.5节</li>
|
||
<li>注意在C语言中不能像python一样使用“<code>==</code>”对字符串进行比较,而应当使用<code>strcmp()</code></li>
|
||
<li>将程序加入到Makefile的<code>UPROGS</code></li>
|
||
</ul>
|
||
<p>如果你的程序输出下面的内容,那么它是正确的(当文件系统中包含文件<strong><em>b</em></strong>和<strong><em>a/b</em></strong>的时候)</p>
|
||
<pre><code class="lang-bash">$ make qemu
|
||
...
|
||
init: starting sh
|
||
$ echo > b
|
||
$ mkdir a
|
||
$ echo > a/b
|
||
$ find . b
|
||
./b
|
||
./a/b
|
||
$
|
||
</code></pre>
|
||
<h2 id="xargs(难度:moderate)"><a name="xargs(难度:moderate)" class="anchor-navigation-ex-anchor" href="#xargs(难度:moderate)"><i class="fa fa-link" aria-hidden="true"></i></a>xargs(难度:Moderate)</h2>
|
||
<blockquote>
|
||
<p>[!TIP|label:YOUR JOB]
|
||
编写一个简化版UNIX的<code>xargs</code>程序:它从标准输入中按行读取,并且为每一行执行一个命令,将行作为参数提供给命令。你的解决方案应该在<strong><em>user/xargs.c</em></strong></p>
|
||
</blockquote>
|
||
<p>下面的例子解释了<code>xargs</code>的行为</p>
|
||
<pre><code class="lang-bash">$ echo hello too | xargs echo bye
|
||
bye hello too
|
||
$
|
||
</code></pre>
|
||
<p>注意,这里的命令是<code>echo bye</code>,额外的参数是<code>hello too</code>,这样就组成了命令<code>echo bye hello too</code>,此命令输出<code>bye hello too</code></p>
|
||
<p>请注意,UNIX上的<code>xargs</code>进行了优化,一次可以向该命令提供更多的参数。 我们不需要您进行此优化。 要使UNIX上的<code>xargs</code>表现出本实验所实现的方式,请将<code>-n</code>选项设置为1。例如</p>
|
||
<pre><code class="lang-bash">$ echo "1\n2" | xargs -n 1 echo line
|
||
line 1
|
||
line 2
|
||
$
|
||
</code></pre>
|
||
<p><strong>提示:</strong></p>
|
||
<ul>
|
||
<li>使用<code>fork</code>和<code>exec</code>对每行输入调用命令,在父进程中使用<code>wait</code>等待子进程完成命令。</li>
|
||
<li>要读取单个输入行,请一次读取一个字符,直到出现换行符('\n')。</li>
|
||
<li><strong><em>kernel/param.h</em></strong>声明<code>MAXARG</code>,如果需要声明<code>argv</code>数组,这可能很有用。</li>
|
||
<li>将程序添加到<strong><em>Makefile</em></strong>中的<code>UPROGS</code>。</li>
|
||
<li>对文件系统的更改会在qemu的运行过程中保持不变;要获得一个干净的文件系统,请运行<code>make clean</code>,然后<code>make qemu</code></li>
|
||
</ul>
|
||
<p><code>xargs</code>、<code>find</code>和<code>grep</code>结合得很好</p>
|
||
<pre><code class="lang-bash">$ find . b | xargs grep hello
|
||
</code></pre>
|
||
<p>将对“<code>.</code>”下面的目录中名为<strong><em>b</em></strong>的每个文件运行<code>grep hello</code>。</p>
|
||
<p>要测试您的<code>xargs</code>方案是否正确,请运行shell脚本<strong><em>xargstest.sh</em></strong>。如果您的解决方案产生以下输出,则是正确的:</p>
|
||
<pre><code class="lang-bash">$ make qemu
|
||
...
|
||
init: starting sh
|
||
$ sh < xargstest.sh
|
||
$ $ $ $ $ $ hello
|
||
hello
|
||
hello
|
||
$ $
|
||
</code></pre>
|
||
<p>你可能不得不回去修复你的<code>find</code>程序中的bug。输出有许多<code>$</code>,因为xv6 shell没有意识到它正在处理来自文件而不是控制台的命令,并为文件中的每个命令打印<code>$</code>。</p>
|
||
<h1 id="提交实验"><a name="提交实验" class="anchor-navigation-ex-anchor" href="#提交实验"><i class="fa fa-link" aria-hidden="true"></i></a>提交实验</h1>
|
||
<p><strong>这就完成了实验</strong>。确保你通过了所有的成绩测试。如果这个实验有问题,别忘了把你的答案写在<strong><em>answers-lab-name.txt</em></strong>中<strong><em>。</em></strong>提交你的更改(包括<strong><em>answers-lab-name.txt</em></strong>),然后在实验目录中键入<code>make handin</code>以提交实验。</p>
|
||
<p><strong>花费的时间</strong></p>
|
||
<p>创建一个命名为<strong><em>time.txt</em></strong>的新文件,并在其中输入一个整数,即您在实验室花费的小时数。不要忘记<code>git add</code>和<code>git commit</code>文件。</p>
|
||
<p><strong>提交</strong></p>
|
||
<p>你将使用<strong><a href="https://6828.scripts.mit.edu/2020/handin.py/" target="_blank">提交网站</a></strong>提交作业。您需要从提交网站请求一次API密钥,然后才能提交任何作业或实验。</p>
|
||
<p>将最终更改提交到实验后,键入<code>make handin</code>以提交实验。</p>
|
||
<pre><code class="lang-bash">$ git commit -am "ready to submit my lab"
|
||
[util c2e3c8b] ready to submit my lab
|
||
2 files changed, 18 insertions(+), 2 deletions(-)
|
||
|
||
$ make handin
|
||
tar: Removing leading `/' from member names
|
||
Get an API key for yourself by visiting https://6828.scripts.mit.edu/2020/handin.py/
|
||
Please enter your API key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||
Dload Upload Total Spent Left Speed
|
||
100 79258 100 239 100 79019 853 275k --:--:-- --:--:-- --:--:-- 276k
|
||
$
|
||
</code></pre>
|
||
<p><code>make handin</code>将把你的API密钥存储在<strong><em>myapi.key</em></strong>中。如果需要更改API密钥,只需删除此文件并让<code>make handin</code>再次生成它(<strong><em>myapi.key</em></strong>不得包含换行符)。</p>
|
||
<p>如果你运行了<code>make handin</code>,并且你有未提交的更改或未跟踪的文件,则会看到类似于以下内容的输出:</p>
|
||
<pre><code> M hello.c
|
||
?? bar.c
|
||
?? foo.pyc
|
||
Untracked files will not be handed in. Continue? [y/N]
|
||
</code></pre><p>检查上述行,确保跟踪了您的实验解决方案所需的所有文件,即以??开头的行中所显示的文件。您可以使用<code>git add filename</code>命令使git追踪创建的新文件。</p>
|
||
<p>如果<code>make handin</code>无法正常工作,请尝试使用curl或Git命令修复该问题。或者你可以运行<code>make tarball</code>。这将为您制作一个tar文件,然后您可以通过我们的web界面上传。</p>
|
||
<ul>
|
||
<li>请运行“<code>make grade</code>”以确保您的代码通过所有测试</li>
|
||
<li>在运行“<code>make handin</code>”之前提交任何修改过的源代码`</li>
|
||
<li>您可以检查提交的状态,并在以下位置下载提交的代码:<a href="https://6828.scripts.mit.edu/2020/handin.py/" target="_blank">https://6828.scripts.mit.edu/2020/handin.py/</a></li>
|
||
</ul>
|
||
<h1 id="可选的挑战练习"><a name="可选的挑战练习" class="anchor-navigation-ex-anchor" href="#可选的挑战练习"><i class="fa fa-link" aria-hidden="true"></i></a>可选的挑战练习</h1>
|
||
<ul>
|
||
<li><p>编写一个<code>uptime</code>程序,使用<code>uptime</code>系统调用以滴答为单位打印计算机正常运行时间。(easy)</p>
|
||
</li>
|
||
<li><p>在<code>find</code>程序的名称匹配中支持正则表达式。<strong><em>grep.c</em></strong>对正则表达式有一些基本的支持。(easy)</p>
|
||
</li>
|
||
<li><p>xv6 shell(<strong><em>user/sh.c</em></strong>)只是另一个用户程序,您可以对其进行改进。它是一个最小的shell,缺少建立在真实shell中的许多特性。例如,</p>
|
||
<ul>
|
||
<li>在处理<strong>文件中的</strong>shell命令时,将shell修改为不打印$(moderate)</li>
|
||
<li>将shell修改为支持<code>wait</code>(easy)</li>
|
||
<li>将shell修改为支持用“<code>;</code>”分隔的命令列表(moderate)</li>
|
||
<li>通过实现左括号“<code>(</code>” 以及右括号“<code>)</code>”来修改shell以支持子shell(moderate)</li>
|
||
<li>将shell修改为支持<code>tab</code>键补全(easy)</li>
|
||
<li>修改shell使其支持命令历史记录(moderate)</li>
|
||
<li>或者您希望shell执行的任何其他操作。</li>
|
||
</ul>
|
||
</li>
|
||
<li><p>如果您非常雄心勃勃,可能需要修改内核以支持所需的内核特性;xv6支持的并不多。 </p>
|
||
</li>
|
||
</ul>
|
||
<footer class="page-footer"><span class="copyright">copyright by duguosheng all right reserved,powered by Gitbook</span><span class="footer-modification">该文件修订时间:
|
||
2021-08-19 12:03:03
|
||
</span></footer>
|
||
|
||
</section>
|
||
|
||
</div>
|
||
<div class="search-results">
|
||
<div class="has-results">
|
||
|
||
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
|
||
<ul class="search-results-list"></ul>
|
||
|
||
</div>
|
||
<div class="no-results">
|
||
|
||
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<a href="summary.html" class="navigation navigation-prev navigation-unique" aria-label="Previous page: 实验内容">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
<script>
|
||
var gitbook = gitbook || [];
|
||
gitbook.push(function() {
|
||
gitbook.page.hasChanged({"page":{"title":"Lab1: Xv6 and Unix utilities","level":"3.2.1","depth":2,"previous":{"title":"实验内容","level":"3.2","depth":1,"path":"labs/requirements/summary.md","ref":"labs/requirements/summary.md","articles":[{"title":"Lab1: Xv6 and Unix utilities","level":"3.2.1","depth":2,"path":"labs/requirements/lab1.md","ref":"labs/requirements/lab1.md","articles":[]}]},"dir":"ltr"},"config":{"plugins":["-lunr","-search","-highlight","code-highlighter","search-pro","github","chapter-fold","code-optimize","splitter","pageview-count","donate","tbfed-pagefooter","flexible-alerts","ancre-navigation","custom-favicon"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"tbfed-pagefooter":{"copyright":"copyright by duguosheng","modify_label":"该文件修订时间:","modify_format":"YYYY-MM-DD HH:mm:ss"},"code-highlighter":{},"chapter-fold":{},"github":{"url":"https://github.com/duguosheng"},"splitter":{},"search-pro":{},"donate":{"alipay":"https://raw.githubusercontent.com/duguosheng/6.S081-All-in-one/main/images/alipay.png","alipayText":"支付宝","button":"打赏","title":"","wechat":"https://raw.githubusercontent.com/duguosheng/6.S081-All-in-one/main/images/wechatpay.png","wechatText":"微信"},"fontsettings":{"theme":"white","family":"sans","size":2},"favicon":"images/book.ico","pageview-count":{},"custom-favicon":{},"ancre-navigation":{"associatedWithSummary":true,"float":{"level1Icon":"","level2Icon":"","level3Icon":"","showLevelIcon":false},"mode":"float","multipleH1":true,"pageTop":{"level1Icon":"","level2Icon":"","level3Icon":"","showLevelIcon":false},"printLog":false,"showLevel":true},"flexible-alerts":{"danger":{"className":"danger","icon":"fa fa-ban","label":"Attention"},"note":{"className":"info","icon":"fa fa-info-circle","label":"Note"},"style":"flat","tip":{"className":"tip","icon":"fa fa-lightbulb-o","label":"Tip"},"warning":{"className":"warning","icon":"fa fa-exclamation-triangle","label":"Warning"}},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false},"code-optimize":{"copyButtons":true,"showLines":true}},"theme":"default","author":"DuGuoSheng","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"6.S081 All-In-One","gitbook":"*"},"file":{"path":"labs/requirements/lab1.md","mtime":"2021-08-19T04:03:03.495Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2021-08-19T05:21:12.980Z"},"basePath":"../..","book":{"language":""}});
|
||
});
|
||
</script>
|
||
</div>
|
||
|
||
|
||
<script src="../../gitbook/gitbook.js"></script>
|
||
<script src="../../gitbook/theme.js"></script>
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-search-pro/jquery.mark.min.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-search-pro/search.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-github/plugin.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-chapter-fold/chapter-fold.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-code-optimize/plugin.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-splitter/splitter.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-pageview-count/plugin.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-donate/plugin.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-flexible-alerts/plugin.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-sharing/buttons.js"></script>
|
||
|
||
|
||
|
||
<script src="../../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|
||
|