# 2019q1 Homework4 (riscv)
contributed by < `bauuuu1021` >
* [作業要求](https://hackmd.io/s/ryHaBkrOE)
## 操作練習
* risc-emu 及將 `temu` 指令加入環境變數
```shell
bauuuu1021@x555:~/riscv-emu$ ./temu
temu version 2019-02-10, Copyright (c) 2016-2018 Fabrice Bellard
usage: riscvemu [options] config_file
options are:
-m ram_size set the RAM size in MB
-rw allow write access to the disk image (default=snapshot)
-ctrlc the C-c key stops the emulator instead of being sent to the
emulated software
-append cmdline append cmdline to the kernel command line
Console keys:
Press C-a x to exit the emulator, C-a h to get some help.
bauuuu1021@x555:~/riscv-emu$ export PATH=`pwd`:$PATH
```
* 啟動模擬器
* ==必須在 `/tmp` 目錄執行!==
* 下載&解壓縮
```shell
$ wget https://bellard.org/tinyemu/diskimage-linux-riscv-2018-09-23.tar.gz
$ tar zxvf diskimage-linux-riscv-2018-09-23.tar.gz
```
* 啟動
```shell
$ cd diskimage-linux-riscv-2018-09-23/
$ temu root-riscv64.cfg
```
* Buildtool
* 在 `/tmp` 中
```shell
$ wget https://bellard.org/tinyemu/buildroot-riscv-2018-10-20.tar.gz
$ tar zxvf buildroot-riscv-2018-10-20.tar.gz
$ cd buildroot-riscv-2018-10-20
$ cp configs/riscv64_defconfig .config
```
* 將 `package/e2fsprogs/e2fsprogs.mk` 中 E2FSPROGS_VERSION = 後面的字串從 1.43.1 到 1.44.5
* 將 `package/e2fsprogs/e2fsprogs.hash` 中新增以下 sha256 ba5eb3069d69160d96818bb9700de9ab5a8458d9add1fd85d427c0000d34c5b9 e2fsprogs-1.44.5.tar.xz
* 刪去檔案 `package/e2fsprogs/0002-fuse2fs-might-need-librt.patch`
* 建構 (大約需 20-30 min)
```shell
$ make
```
* cross compile
* 指令
```cmd
./output/host/usr/bin/riscv64-buildroot-linux-gnu-gcc -o hello hello.c -static
```
* 結果
```cmd
~ # cd /mnt/buildroot-riscv-2018-10-20/
/mnt/buildroot-riscv-2018-10-20 # ls
CHANGES README docs package
COPYING arch fs support
Config.in board hello system
Config.in.legacy boot hello.c toolchain
Makefile configs linux
Makefile.legacy dl output
/mnt/buildroot-riscv-2018-10-20 # ./hello
hello
```
* busybox
* 在 `output/images` ,用 file 檢查:
```shell
bauuuu1021@x555:/tmp/buildroot-riscv-2018-10-20/output/images$ file rootfs.ext2
rootfs.ext2: Linux rev 1.0 ext2 filesystem data, UUID=306a3bb1-212c-4f17-b43e-ded88a847394
```
* 回到 `diskimage-linux-riscv-2018-09-23` 目錄,建立 `test.cfg`:
```config
{
version: 1,
machine: "riscv64",
memory_size: 128,
bios: "bbl64.bin",
kernel: "kernel-riscv64.bin",
cmdline: "console=hvc0 root=/dev/vda rw",
drive0: { file: "/tmp/buildroot-riscv-2018-10-20/output/images/rootfs.ext2" },
fs0: { tag: "/dev/root", file: "/tmp" },
eth0: { driver: "user" },
}
```
* 執行
```shell
$ temu test.cfg
```
* 以 `root` 為 login name,不用密碼即可登入系統。
* 可以觀察到更改時間
```shell
[root@localhost ~]# busybox --help | head
BusyBox v1.24.2 (2019-04-06 21:49:37 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
```
## 自我檢查事項
### virtio 的作用
> [riscv-emu](https://github.com/sysprog21/riscv-emu) 原始程式碼中多次出現 [virtio](https://www.linux-kvm.org/page/Virtio),這樣的機制對於 host 和 guest 兩端有何作用?在閱讀 [Virtio: An I/O virtualization framework for Linux](https://www.ibm.com/developerworks/library/l-virtio/index.html) 一文後,對照原始程式碼,你發現什麼?
* 節錄 [Virtio: An I/O virtualization framework for Linux](https://www.ibm.com/developerworks/library/l-virtio/index.html) 如下
>Linux is the [hypervisor](https://en.wikipedia.org/wiki/Hypervisor) playground. As my article on Linux as a hypervisor showed, Linux offers a variety of hypervisor solutions with different attributes and advantages. Examples include the Kernel-based Virtual Machine (KVM), lguest, and User-mode Linux. Having these different hypervisor solutions on Linux can tax the operating system based on their independent needs. One of the taxes is virtualization of devices. **Rather than have a variety of device emulation mechanisms (for network, block, and other drivers), virtio provides a common front end for these device emulations to standardize the interface and increase the reuse of code across the platforms.**
>
* virtio 是一個通用的介面,給不同的 device 使用,允許這些不同 device 只要使用特定共用 API 就能在 linux 平台上運作
* 因此省去了每個 device 都需要各自實作 host(linux)/guest(device) 對應的介面的麻煩
### 9P2000 與 VirtFS 關係
>在 Guest 端透過 `$ dmesg | grep 9pnet` 命令,我們可發現 9P2000 字樣,這和上述 VirtFS 有何關聯?請解釋運作原理並設計實驗
* 指令
* `dmesg` 用來印出開機訊息
* `grep` 可以從特定範圍中抓取指定字串,例如 `$ dmesg | grep 9pnet` 就是從 `dmesg` 印出的內容中尋找關鍵字 `9pnet`
* 輸入指令後結果如下
```shell
~ # dmesg | grep 9p2000
[ 0.090474] 9p: Installing v9fs 9p2000 file system support
```
* [Plan 9](https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs)
>Plan 9 is a distributed operating system, designed to **make a network of heterogeneous and geographically separated computers function as a single system.**
>
Plan 9 可用來建構一個異質、甚至是分散的系統;其中一個核心的概念是 **"Everything is File"**,其中包括網路介面、檔案系統介面等
> ... ==The client process's input/output on virtual files, that appear in other processes' namespace, becomes inter-process communication between the two processes.== This way, Plan 9 generalizes the Unix notion of the filesystem as the central point of access to computing resources. It carries over Unix's idea of device files to provide access to peripheral devices (mice, removable media, etc.) and the possibility to mount filesystems residing on physically distinct filesystems into a hierarchical namespace, but adds the possibility to mount a connection to a server program that speaks a standardized protocol and treat its services as part of the namespace.
>
process 間的通訊可以藉由對這樣的 virtual file 進行 I/O 來達成,因此從檔案系統可以輕易的存取週邊 device,也能 mount 特定協定(9P)的 server program
>All programs that wish to provide services-as-files to other programs speak a unified protocol, called ==**9P**==.
* [9P (Plan 9 Filesystem Protocol)](https://en.wikipedia.org/wiki/9P_(protocol))
>9P is a network protocol developed for the Plan 9 from Bell Labs distributed operating system as the means of connecting the components of a Plan 9 system. Files are key objects in Plan 9.
>...
>==9P was revised for the 4th edition of Plan 9 under the name 9P2000==
...
A kernel client driver implementing 9p with some extensions for Linux is part of the v9fs project. 9P and its derivatives have also found application in embedded environments, such as the Styx on a Brick project.
9P2000 其實就是 4th Plan 9 後對於 9P 這種協定的稱呼
* [v9fs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/filesystems/9p.txt)
* v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol.
* 結論
```shell
[ 0.090474] 9p: Installing v9fs 9p2000 file system support
```
藉由安裝 v9fs 使模擬器內可以運行 Plan 9 的核心功能
### ?
>在 `root-riscv64.cfg` 設定檔中,有 `bios: "bbl64.bin"` 描述,這用意為何?提示:參閱 [Booting a RISC-V Linux Kernel](https://www.sifive.com/blog/all-aboard-part-6-booting-a-risc-v-linux-kernel)
## kilo 編輯器
>編譯 [kilo](https://github.com/sysprog21/kilo) 編輯器,允許在 RISC-V/Linux 模擬環境中運作
>
* 完成 操作練習->buildtool 建置及 cross compile 練習後,在 ==/tmp== 目錄中進行以下操作
```shell
$ git clone https://github.com/sysprog21/kilo
$ cd buildroot-riscv-2018-10-20/
$ ./output/host/usr/bin/riscv64-buildroot-linux-gnu-gcc -o ../kilo/kilo ../kilo/kilo.c -static
```
* 啟動模擬器 `root_9p-riscv64.cfg`,執行
```shell
mount -t 9p /dev/root /mnt
```
>[補充]
>在 `root_9p-risc64.cfg` 中,可以看到
>```config
> /* Also access to the /tmp directory. Use
> mount -t 9p /dev/root /mnt
> to access it. */
> fs0: { tag: "/dev/root", file: "/tmp"},
>```
>因此如果在 `root-riscv64.cfg` 中加入此行,即可使用 mount 功能[color=#0abab5]
* 在 `/mnt/kilo` 中可看到編譯成功的執行檔,將 `kilo` 加入環境變數(方便在各層目錄使用,optional)
```shell
$ export PATH=`pwd`:$PATH
```
* 按照格式即可使用
```shell
Usage: kilo <filename>
```
![](https://i.imgur.com/2Fxl8nR.png)
* 到 `buildtool` 目錄 cross compile,再到模擬器執行
```shell
/mnt/kilo # ./test
testing...
```
## 精簡化 ext2 image
>調整 buildroot 設定,讓原本輸出的 ext2 image 佔用約 14 MB 空間,變得更精簡
>* 移除套件,但確保仍可開機並提供必要的服務及工具
>* Busybox 裡頭的 vi 也不需要存在,改用 [kilo](https://github.com/sysprog21/kilo)
>
* 接續 `操作練習->busybox` ,輸入 `~# busybox` 會出現
```shell
~ # busybox
BusyBox v1.21.1 (2017-05-23 22:05:40 CEST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
...(skip)...
Currently defined functions:
[, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash,
...(skip)...
unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, users,
usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch,
watchdog, wc, wget, which, who, whoami, whois, xargs, xz, xzcat, yes,
zcat, zcip
```
倒數第 3 行有出現 vi,且簡單測試可以正常使用
```shell
~ # vi test.c
~ # cat test.c
#include <stdio.h>
int main () {
printf("test\n");
}
```
* 在 `$ make menuconfig` 出現的設定視窗中的 `Target packages` 可看到關於 `busybox` 的設定,第一行出現 `BusyBox configuration file` 的路徑,進入選項後可看到 default 為 `package/busybox/busybox.config`
* 按照路徑進入該檔案後,在 379 行開始有關於 editors 的設定
```config=379
#
# Editors
#
CONFIG_AWK=y
# CONFIG_FEATURE_AWK_LIBM is not set
CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y
CONFIG_CMP=y
CONFIG_DIFF=y
# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
CONFIG_FEATURE_DIFF_DIR=y
# CONFIG_ED is not set
CONFIG_PATCH=y
CONFIG_SED=y
CONFIG_VI=y
CONFIG_FEATURE_VI_MAX_LEN=4096
...(skip)...
```
將
```config=392
CONFIG_VI=y
```
改為
```config=392
CONFIG_VI=n
```
* 回到 `buildroot-riscv-2018-10-20` 目錄,`$ make`;到 `output/images` 執行 `$ ls -lh`
```shell
-rw-r--r-- 1 bauuuu1021 bauuuu1021 13M 4月 12 17:35 rootfs.ext2
```
檔案從 14M 縮小為 13M
* 再到 `diskimage-linux-riscv-2018-09-23` 執行 `$ temu test.cfg` 進入虛擬器,執行 `~# busybox | grep vi` 會發現沒有顯示任何 package(function),且嘗試使用 `~# vi` 也無法使用
* 使用 ==kilo 編譯器== 中提及的方法編譯並加入環境變數
>TODO:
>加入 kilo 改成使用 script?(system configuration->Custom scripts to run after creating filesystem images)
>
>[color=#0abab5]
>
## 參考資料
* [QEMU wiki](https://zh.wikipedia.org/wiki/QEMU)
* [2019q1 Homework4 (作業區)](https://hackmd.io/s/r1bJyiauV)
* [Quit from text editor](http://www.climagic.org/txt/how-to-quit-vi-emacs-nano-pico-joe-jed-etc.dyn)
###### tags:`bauuuu1021`,`sysprog`,`2019spring`