# 2019q1 Homework4 (smallsys)
contributed by < `grant7163`>
###### tags: `sysprog2019_q1`
## 作業要求
依據 [F08: smallsys](https://hackmd.io/s/BkhVVlHu4)
1. 回答「自我檢查清單」的所有問題,需要附上對應的參考資料和必要的程式碼,以第一手材料 (包含自己設計的實驗) 為佳
2. 透過 [buildroot](https://github.com/buildroot/buildroot) 工具產生針對 AArch64 的 linux kernel image (需要是 5.0 以上版本) 和 root file system,確保滿足以下要求:
* 得以透過 `qemu-system-aarch64` 開機並正確地執行 userspace 套件 (如 Busybox)
* 確認 qemu + gdb 能夠單步執行和設定中斷點
* 確保 VirtIO + 9P 得以運作
* 閱讀 [Embedded Linux size reduction
techniques](http://events17.linuxfoundation.org/sites/events/files/slides/opdenacker-embedded-linux-size-reduction-techniques_0.pdf),嘗試建構出更小但仍可符合上述需求的 Linux 核心
4. 參照 [Linux 核心設計: 透過 eBPF 觀察作業系統行為](https://hackmd.io/s/SJTuuG9a7),在上述 `(2)` 的環境開啟 eBPF 核心設定和準備必要的 userspace 開發工具,做對應的實驗
## 自我檢查清單
- [ ] 你是否詳閱 [手機裡頭的 ARM 處理器:系列講座](http://hackfoldr.org/arm/) 呢?請紀錄學習過程中遇到的問題
- [ ] 請解釋 AArch64 個別通用暫存器的作用,依據 [Linux on AArch64
ARM 64-bit Architecture](https://events.static.linuxfound.org/images/stories/pdf/lcna_co2012_marinas.pdf) 的描述,搭配實際的程式碼說明。提示: 簡報第 19 頁附有參考資訊
- [ ] AArch64 定義四種例外等級: EL0, EL1, EL2, EL3,請找出相關文件 (儘量是 Arm 公司的第一手材料) 並搭配 Linux 核心原始程式碼解說
- [ ] [linux-kernel-module-cheat](https://github.com/cirosantilli/linux-kernel-module-cheat) 提及透過 GDB 對 QEMU 模擬的虛擬硬體之上的 Linux 核心進行追蹤和除錯,請解釋具體原理。提示: 應一併說明 GDB stub 和 [QEMU/Debugging with QEMU](https://en.wikibooks.org/wiki/QEMU/Debugging_with_QEMU) 的運作機制
## 開發紀錄
### 環境建置
先下載 buildroot
```shell
git clone https://github.com/buildroot/buildroot.git
```
進入 menuconfig 作一些設定。
* 在 Target options 中
* Target Architecture : AArch64 little-endian
* Target Architecture Variant : cortex-A57
* 在 toolchain 中
* Kernel Headers : 5.0 version
* Binutils Version : 2.32 version
* GCC compiler Version : 8.x version
* 在 System configuration 中
* Run a getty (login prompt) after boot : ttyAMA0
* 在 Linux Kernel 中
* Kernel version : 5.0 version
* Kernel configuration : Using a custom (def)config file 設定路徑
* `BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64_user/linux.config"`
* 在 /board/qemu/ 建立一個目錄並將加入 linux.config
* 在 Filesystem images 中
* ext2/3/4 root filesystem : ext4
```shell
$ make menuconfig
```
將 config 儲存下來,此時在 /buildroot 目錄下會出現 defconfig 檔案,可將檔名改成 aarch64_user_defconfig 並放到 /configs 目錄中,之後要載入自己的 config 檔就會比較方便了,接著執行 make 。
```shell
$ make savedefconfig
$ make aarch64_user_defconfig
```
### 支援 virtio + 9p
進入 linux-menuconfig 作一些設定。
依據 [VirtFS](https://wiki.qemu.org/Documentation/9psetup) 的說明
* 在 Networking support 中
* Plan 9 Resource Sharing Support (9P2000) : 9P Virtio Transport
* 在 Device Drivers 中的 PCI support
* PCI controller drivers : Generic PCI host controller
* 在 File systems 中的 Network File Systems
* Plan 9 Resource Sharing Support (9P2000) : 9P POSIX Access Control Lists
```shell
$ make linux-menuconfig
```
接著儲存 config 設定並執行 make 。
依據 [9.4. Storing the configuration of other components](https://buildroot.org/downloads/manual/manual.html#customize-store-package-config)
```shell
$ make linux-update-defconfig
```
我們所需要的檔案會產生在 /output/images 目錄下並將 image, rootfs.ext4 複製到根目錄中的 /tmp/output/images 目錄下。
### set up qemu
去 qemu 官網下載模擬器。
```shell
wget https://download.qemu.org/qemu-4.0.0-rc3.tar.xz
tar xvJf qemu-4.0.0-rc3.tar.xz
```
第一次 config 出現如下錯誤訊息。
```shell
$ ./configure --enable-virtfs --target-list=aarch64-softmmu
ERROR: VirtFS requires libcap devel and libattr devel
```
下載對應的套件,在 config 一次,之後在執行 make。
```shell
sudo apt-get install libcap-dev
sudo apt-get install libattr1-dev
```
執行如下命令啟動模擬器。
依據 [9psetup](https://wiki.qemu.org/Documentation/9psetup) 與 ../board/qemu/aarch64_user 目錄下 readme.txt 的描述
*
```shell
qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-nographic \
-smp 1 \
-kernel /output/images/Image \
-append "root=/dev/vda console=ttyAMA0" \
-netdev user,id=eth0 \
-device virtio-net-device,netdev=eth0 \
-drive file=/tmp/output/images/rootfs.ext4,if=none,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-fsdev local,security_model=passthrough,id=fsdev0,path=/tmp/output \
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=share_mnt \
```
使用命令查看 system 資訊,如預期顯示出 linux version : 5.0.7, cpu arch : aarch64。
```shell
...
Welcome to Buildroot
buildroot login: root
# uname -a
Linux buildroot 5.0.7 #2 SMP Mon Apr 15 23:37:26 CST 2019 aarch64 GNU/Linux
```
接著使用 mount(virtio 9p) 將 guest 與 host 目錄共享,如預期在 /mnt 目錄下顯示出 /images。
```shell
# mount -t 9p -o trans=virtio share_mnt /mnt
# cd mnt
# ls
images
```