You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pke-doc/chapter2_installation.md

347 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 第二章.实验环境配置与实验构成
### 目录
- [2.1 实验环境安装](#environments)
- [2.1.1 头歌平台](#subsec_educoder)
- [2.1.2 Windows环境WSL](#subsec_windows)
- [2.1.3 Ubuntu操作系统环境](#subsec_ubuntu)
- [2.1.4 openEuler操作系统环境](#subsec_openeuler)
- [2.2 riscv-pke实验代码的获取](#preparecode)
- [2.3 PKE实验构成](#pke_experiemnts)
<a name="environments"></a>
## 2.1 实验环境安装
<a name="subsec_educoder"></a>
### 2.1.1 头歌平台
为支撑《操作系统原理》课程的教学PKE系列实验在[头歌平台educoder.net](https://www.educoder.net/)上进行了部署。
<img src="pictures/educoder_1.png" alt="educoder_step1" style="zoom:80%;" />
读者可以在头歌平台的主页上通过选择左上角的“实践课程”入口然后在搜索框中输入“基于RISCV的操作系统实验”找到PKE实验对应的实践课程
<img src="pictures/educoder_2.png" alt="educoder_step2" style="zoom:80%;" />
进入课程后,可以先阅读课程实验说明,翻到课程下的实验后就可以通过点击“开始实战”来进入实验了。
<img src="pictures/educoder_3.png" alt="educoder_step3" style="zoom:80%;" />
进入实战后,会看到如下的界面:
<img src="pictures/educoder_4.png" alt="educoder_step4" style="zoom:80%;" />
以上界面中,左侧显示的是实验的任务描述以及参考文献链接。右侧是做实验要用到(修改)的源代码文件,在右侧界面的顶端,有一个“命令行”标签,点击进入后可进入命令行模式;顶端的右侧的文件夹图标点击后会出现整个文件目录树,读者可以通过目录树选择要阅读的文件;最后,在右下角有个“评测”按钮,读者可以在完成实验后点击该按钮对自己的实验结果进行评测。
**实际上读者看到的这个界面背后是一个Linux docker虚拟机在该虚拟机中已经安装好了实验所需要的环境**。包括各种开发工具包、RISC-V交叉编译器等而评测按钮按下后会触发虚拟机中的构建build脚本该脚本会自动对代码树进行构建、执行给定的用户程序如lab1_1中的user/app_helloworld、最后根据输出的内容对实验结果的正确性进行判断。
**然而,由于在头歌平台上的课程,每个实验都对应了一个独立的代码仓库,所以从一个实验到另一个实验的切换无法通过`git merge`命令实现对上一个实验的实验结果的继承**。学生在进行实验切换时需要将之前实验的代码手动地贴入下一个实验的对应文件中。这一点我们在课程的“课程须知”中做了说明。一个比较好的方法是采用类似Notepad++这样类型的软件,记录每个实验的答案(包括答案所在的文件),并在切换到下一个实验时,将答案拷贝粘贴到对应文件。
考虑到头歌平台的用户身份(主要有老师和学生)的不同,以及老师开课和学生选课的过程的不同,头歌平台给出了[教师使用手册](pictures/EduCoder平台教师使用手册v5.0.0_20200924.pdf)和[学生使用手册](pictures/EduCoder平台学生使用手册v5.0.0_20200924.pdf)。**简单来说为了将头歌平台上的PKE实验课程应用到《操作系统原理》课程教学教师需要在头歌平台上建立一个教学课堂并在该教学课堂中选用“基于RISCV的操作系统实验”课程将该实验课程中的实验有选择性的导入到所建立的教学课堂中并最后吧所建立的教学课堂的邀请码发给学生**。对于学生而言,只需要用老师所给的邀请码在头歌平台上加入教学课堂即可。以上过程都可以通过头歌主页右上侧的“+”符号(将鼠标移动到该符号上)对应的弹出菜单中选择即可。
“基于RISCV的操作系统实验”课程的设计充分考虑到了实验的模块化以及学制安排的问题。课程共设计了15个实验其中包含9个基础实验和6个挑战实验随着时间推移这个列表可能会进一步增加实验间的关联见[PKE实验的组成](#pke_experiemnts)。**教师开设教学课堂的时候,可以根据学生的水平、教学预期按需选择不同的实验内容,分期分批地给学生安排实验任务**。
<a name="subsec_windows"></a>
### 2.1.2 Windows环境WSL
如果读者的工作环境是Windows10的专业版可采用WSLWindows Subversion Linux+MobaXterm的组合来搭建PKE的实验环境。在Windows10专业版上配置该环境的说明可以参考[这里](https://zhuanlan.zhihu.com/p/81769058)。
需要说明的是PKE实验并不需要中文字体、图形界面或者JAVA的支持所以读者在安装WSL的过程中无须安装于汉化相关的包也无需安装xfce、JDK等。只需要安装WSL的基础环境后再按照[下一节](#subsec_ubuntu)的说明继续完成PKE开发环境的安装。
<a name="subsec_ubuntu"></a>
### 2.1.3 Ubuntu操作系统环境
实验环境我们推荐采用Ubuntu 16.04LTS或18.04LTSx86_64操作系统以及WSL中的相应版本。我们未在其他系统如archRHEL等上做过测试但理论上只要将实验中所涉及到的安装包替换成其他系统中的等效软件包就可完成同样效果。另外我们在EduCoder实验平台网址https://www.educoder.net 上创建了本书的同步课程课程的终端环境中已完成实验所需软件工具的安装所以如果读者是在EduCoder平台上选择的本课程则可跳过本节的实验环境搭建过程直接进入通过终端命令行进入实验环境。
PKE实验涉及到的工具软件有
- RISC-V交叉编译器及附带的主机编译器、构造工具等
- spike模拟器
以下分别介绍这两个部分的安装过程。对于新安装的Ubuntu操作系统**我们强烈建议读者在新装环境中完整构建buildRISC-V交叉编译器以及spike模拟器**。对于熟练用户为了避免耗时且耗资源的构建build过程一个可能的方案是从https://toolchains.bootlin.com 下载,**但是要注意一些依赖包如GCC的版本号**。如果强调环境的可移植性,可以考虑在虚拟机中安装完整系统和环境,之后将虚拟机进行克隆和迁移。
#### RISC-V交叉编译器
RISC-V交叉编译器是与Linux自带的GCC编译器类似的一套工具软件集合不同的是x86_64平台上Linux自带的GCC编译器会将源代码编译、链接成为适合在x86_64平台上运行的二进制代码称为native code而RISC-V交叉编译器则会将源代码编译、链接成为在RISC-V平台上运行的代码。后者RISC-V交叉编译器生成的二进制代码是无法在x86_64平台即x86_64架构的Ubuntu环境下直接运行的它的运行需要模拟器我们采用的spike的支持。
一般情况下我们称x86_64架构的Ubuntu环境为host而在host上执行spike后所虚拟出来的RISC-V环境则被称为target。RISC-V交叉编译器的构建build、安装过程如下
● 第一步,安装依赖库
RISC-V交叉编译器的构建需要一些本地支撑软件包可使用以下命令安装
`$ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev device-tree-compiler`
● 第二步获取RISC-V交叉编译器的源代码
有两种方式获得RISC-V交叉编译器的源代码一种是通过源代码仓库获取使用以下命令
`$ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain.git`
但由于RISC-V交叉编译器的仓库包含了Qemu模拟器的代码下载后的目录占用的磁盘空间大小约为4.8GB,(从国内下载)整体下载所需的时间较长。为了方便国内用户,我们提供了另一种方式就是通过百度云盘获取源代码压缩包,链接和提取码如下:
`链接: https://pan.baidu.com/s/1cMGt0zWhRidnw7vNUGcZhg 提取码: qbjh`
从百度云盘下载RISCV-packages/riscv-gnu-toolchain-clean.tar.gz文件大小为2.7GB再在Ubuntu环境下解压这个.tar.gz文件采用如下命令行
`$ tar xf riscv-gnu-toolchain-clean.tar.gz`
之后就能够看到和进入当前目录下的riscv-gnu-toolchain文件夹了。
● 第三步构建buildRISC-V交叉编译器
`$ cd riscv-gnu-toolchain`
`$ ./configure --prefix=[your.RISCV.install.path]`
`$ make`
以上命令中,[your.RISCV.install.path]指向的是你的RISC-V交叉编译器安装目录。如果安装是你home目录下的一个子目录如~/riscv-install-dir则最后的make install无需sudoer权限。但如果安装目录是系统目录如/opt/riscv-install-dir则需要sudoer权限即在make install命令前加上sudo
● 第四步,设置环境变量
`$ export RISCV=[your.RISCV.install.path]`
`$ export PATH=$PATH:$RISCV/bin`
以上命令设置了RISCV环境变量指向在第三步中的安装目录并且将交叉编译器的可执行文件所在的目录加入到了系统路径中。这样我们就可以在PKE的工作目录调用RISC-V交叉编译器所包含的工具软件了。
**建议读者将以上两个export命令加入到`~/.bashrc``~/.profile`或 `/etc/profile`文件的末尾。**这样,每次重新启动(并打开终端程序)后,系统会自动设置这两个环境变量,而不用每次都要手动输入以上命令。
#### spike模拟器
接下来安装spkie模拟器。首先取得spike的源代码有两个途径一个是从github代码仓库中获取
`$ git clone https://github.com/riscv/riscv-isa-sim.git`
也可以从百度云盘中下载spike-riscv-isa-sim.tar.gz文件约4.2MB然后用tar命令解压缩。百度云盘的地址以及tar命令解压缩可以参考2.1.1节RISC-V交叉编译器的安装过程。获得spike源代码或解压后将在本地目录看到一个riscv-isa-sim目录。
接下来构建buildspike并安装
`$ cd riscv-isa-sim`
`$ ./configure --prefix=$RISCV`
`$ make`
`$ make install`
在以上命令中我们假设RISCV环境变量已经指向了RISC-V交叉编译器的安装目录即[your.RISCV.install.path]。
<a name="subsec_openeuler"></a>
### 2.1.4 openEuler操作系统
PKE实验将提供基于华为openEuler操作系统的开发方法*具体的华为云使用方法待续*但在openEuler操作系统环境中的交叉编译器安装方法以及其他环节都可参考[2.1.3 Ubuntu环境](#subsec_ubuntu)的命令进行。
<a name="preparecode"></a>
## 2.2 riscv-pke实验代码的获取
以下讨论我们假设读者是使用的Ubuntu/openEuler操作系统且已按照[2.1.2](#subsec_ubuntu)的说明安装了需要的工具软件。对于头歌平台而言,代码已经部署到实验环境,读者可以通过头歌网站界面或者界面上的“命令行”选项看到实验代码,所以头歌平台用户无须考虑代码获取环节。
#### 代码获取
在Ubuntu/WSL/openEuler操作系统可以通过以下命令下载riscv-pke的实验代码
(克隆代码仓库)
```bash
`$ git clone https://gitee.com/hustos/riscv-pke.git
Cloning into 'riscv-pke-prerelease'...
remote: Enumerating objects: 195, done.
remote: Counting objects: 100% (195/195), done.
remote: Compressing objects: 100% (195/195), done.
remote: Total 227 (delta 107), reused 1 (delta 0), pack-reused 32
Receiving objects: 100% (227/227), 64.49 KiB | 335.00 KiB/s, done.
Resolving deltas: 100% (107/107), done.`
```
克隆完成后将在当前目录应该能看到riscv-pke-prerelease目录。这时可以到riscv-pke目录下查看文件结构例如
`$ cd riscv-pke`
切换到lab1_1_syscall分支因为lab1_1_syscall是默认分支这里也可以不切换
`$ git checkout lab1_1_syscall`
`$ tree -L 3`
(将看到如下输出)
```
.
├── LICENSE.txt
├── Makefile
├── README.md
├── kernel
│   ├── config.h
│   ├── elf.c
│   ├── elf.h
│   ├── kernel.c
│   ├── kernel.lds
│   ├── machine
│   │   ├── mentry.S
│   │   └── minit.c
│   ├── process.c
│   ├── process.h
│   ├── riscv.h
│   ├── strap.c
│   ├── strap.h
│   ├── strap_vector.S
│   ├── syscall.c
│   └── syscall.h
├── spike_interface
│   ├── atomic.h
│   ├── dts_parse.c
│   ├── dts_parse.h
│   ├── spike_file.c
│   ├── spike_file.h
│   ├── spike_htif.c
│   ├── spike_htif.h
│   ├── spike_memory.c
│   ├── spike_memory.h
│   ├── spike_utils.c
│   └── spike_utils.h
├── user
│   ├── app_helloworld.c
│   ├── user.lds
│   ├── user_lib.c
│   └── user_lib.h
└── util
├── functions.h
├── load_store.S
├── snprintf.c
├── snprintf.h
├── string.c
├── string.h
└── types.h
```
在代码的根目录有以下文件:
- Makefile文件它是make命令即将使用的“自动化编译”脚本
- LICENSE.txt文件即riscv-pke的版权文件里面包含了所有参与开发的人员信息。riscv-pke是开源软件你可以以任意方式自由地使用前提是使用时包含LICENSE.txt文件即可
- README.md文件一个简要的英文版代码说明。
另外是一些子目录,其中:
- kernel目录包含了riscv-pke的内核部分代码
- spike_interface目录是riscv-pke内核与spike模拟器的接口代码如设备树DTB、主机设备接口HTIF等用于接口的初始化和调用
- user目录包含了实验给定应用如lab1_1中的app_helloworld.c以及用户态的程序库文件如lab1_1中的user_lib.c
- util目录包含了一些内核和用户程序公用的代码如字符串处理string.c类型定义types.h等。
#### 环境验证
对于Ubuntu/WSL/openEuler用户对于头歌用户可以通过选择“命令行”标签进入shell环境、进入提示的代码路径开始构造过程可以在代码的根目录进入riscv-pke-prerelease子目录后输入以下构造命令应看到如下输出
```bash
$ make
compiling util/snprintf.c
compiling util/string.c
linking obj/util.a ...
Util lib has been build into "obj/util.a"
compiling spike_interface/dts_parse.c
compiling spike_interface/spike_htif.c
compiling spike_interface/spike_utils.c
compiling spike_interface/spike_file.c
compiling spike_interface/spike_memory.c
linking obj/spike_interface.a ...
Spike lib has been build into "obj/spike_interface.a"
compiling kernel/syscall.c
compiling kernel/elf.c
compiling kernel/process.c
compiling kernel/strap.c
compiling kernel/kernel.c
compiling kernel/machine/minit.c
compiling kernel/strap_vector.S
compiling kernel/machine/mentry.S
linking obj/riscv-pke ...
PKE core has been built into "obj/riscv-pke"
compiling user/app_helloworld.c
compiling user/user_lib.c
linking obj/app_helloworld ...
User app has been built into "obj/app_helloworld"
```
如果环境安装不对(如缺少必要的支撑软件包),以上构造过程可能会在中间报错,如果碰到报错情况,请回到[2.2](#environments)的环境安装过程检查实验环境的正确性。
构造完成后在代码根目录会出现一个obj子目录该子目录包含了构造过程中所生成的所有对象文件.o、编译依赖文件.d、静态库.a文件和最终目标ELF文件如./obj/riscv-pke和./obj/app_helloworld
这时我们可以尝试借助riscv-pke内核运行app_helloworld的“Hello world!”程序:
```bash
$ spike ./obj/riscv-pke ./obj/app_helloworld
In m_start, hartid:0
HTIF is available!
(Emulated) memory size: 2048 MB
Enter supervisor mode...
Application: ./obj/app_helloworld
Application program entry point (virtual address): 0x0000000081000000
Switching to user mode...
call do_syscall to accomplish the syscall and lab1_1 here.
System is shutting down with exit code -1.
```
如果能看到以上输出riscv-pke的代码获取和验证就已经完成可以开始实验了。
<a name="pke_experiemnts"></a>
## 2.3 PKE实验的组成
对于《操作系统原理》课堂来说PKE实验由3组基础实验以及基础试验后的挑战实验组成见图1.2
- **对于基础实验而言**,第一组基础实验重点涉及系统调用、异常和外部中断的知识;第二组基础实验重点涉及主存管理方面的知识;第三组实验重点涉及进程管理方面的知识。基础实验部分实验指导文档较为详细,学生(读者)需要填写的代码量很小,可以看作是“阅读理解+填空”题,涉及的知识也非常基础。
- **对于挑战实验而言**,每一组实验的挑战实验都可以理解为在该组实验上的挑战性内容,只给出题目(应用程序)和预期的效果(需要做到的目标)。这一部分实验指导文档只给出大的方向,需要学生(读者)查阅和理解较多课外内容,为实现预期的效果需要填写的代码量也较大,可以看作是“作文题”。
如图1.2所示,**基础实验部分存在继承性**即学生读者需要按照实线箭头的顺序依次完成实验是不可跳跃的这是因为PKE的实验设计后一个实验依赖前一个实验的答案在开始后一个实验前需要先将之前的答案继承下来通过git commit/git merge命令
**而挑战部分的实验只依赖于每组实验的最后一个实验**例如如果学生读者完成了实验1的3个基础试验后就可以开始做实验1的挑战实验了不需要等到完成所有基础实验再开始。
<img src="pictures/experiment_organization_withlab4.png" alt="experiment_organization" style="zoom:100%;" />
图1.2 PKE实验的组织结构
**PKE实验即可用于自学目的也可以用于教学目的**。对于自学的读者,可以完全按照[PKE文档](https://gitee.com/hustos/pke-doc)以及在gitee的代码仓库中所获得的代码进行出于教学目的所有的PKE实验我们都在[头歌平台](https://www.educoder.net/)进行了部署,实验结果的检测全部在头歌平台上进行,实验完成后头歌平台会生成实验情况的简报。教师可以根据简报,对学生的实验完成情况给出具体的分数。
考虑到《操作系统原理》课堂的实验安排很多学校例如华中科技大学计算机学院是将实验分成了两部分课内实验和课程设计。如果采纳PKE实验根据学生的水平我们给出两个方案
**方案一(学生其他课程负担较重,或不希望实验太难的情况):**
- 课内实验包括所有的基础实验;
- 课程设计学生可在每组实验中,选择(学生自选)一个挑战实验。
这种情况,对于课内实验我们的建议是:每个基础实验=30分每组实验总分90分3组实验取平均分总分仍然是90总分加上实验报告的10分等于课内实验的总分数对于课程设计我们的建议是每个挑战实验=30分3个挑战实验总分求和总分90最后加上实验报告的10分等于课程设计的总分数。
**方案二(学生平均能力较强,且希望实验分数有区分度的情况):**
- 课内实验包括所有的基础实验外加基础实验的1个学生自选挑战实验
- 课程设计学生可在每组实验中,选择之前未完成的一个挑战实验。
这种情况,对于课内实验我们的建议是:每个基础实验=20分外加一个挑战实验每组实验总分是3*20+30=90分3组实验取平均分总分仍然是90总分加上实验报告的10分等于课内实验的总分数对于课程设计我们的建议是每个挑战实验=30分3个挑战实验总分求和总分90最后加上实验报告的10分等于课程设计的总分数。