系列文章 : simulation / emulation 學習筆記
這一篇是基於另外幾篇文章
這一篇來嘗試使用 checkpoint 來加速 linux kernel 開機
想要把檔案放到 root filesystem 裡面的話,可以把檔案放在 buildroot/output/target 裡面,然後重新下 make 就可以了。
例如我把一個 test.txt 放在 output/target/ 目錄底下,重新用 make 來 build buildroot,用 gem5 開機之後,就可以看到根目錄出現 test.txt
# cat /test.txt
aabb
#
把編譯好的檔案放到 output/target/ 裡面,然後重新在 buildroot 裡面下 make
# 用 buildroot 的 toolchain 來 build 一個簡單的 source file
../buildroot/output/host/bin/aarch64-buildroot-linux-gnu-gcc ./hi.c -o ./hi
cp ./hi ../buildroot/output/target/
# 回到 buildroot 的目錄,並重新 build buildroot
# 記得要把重新 build 好的 filesystem 放到 resource 目錄
cd ../buildroot
make
cp output/images/rootfs.ext4 gem5-resources/disks/rootfs.ext4
# 回到 gem5 目錄,並啟動 gem5,然後進入 shell
> /hi
hello!
# 成功執行 hi,並成功 print 出訊息 !!
目前 gem5 的網路好像有點問題,導致開機會拖更久。
這邊先把網路初始化的一部分關掉,bypass 這個問題。
cd buildroot
vim output/target/etc/network/interfaces
# auto eth0
#iface eth0 inet dhcp
# pre-up /etc/network/nfs_check
# wait-delay 15
# hostname $(hostname)
cd buildroot
make -j16
cp output/images/rootfs.ext4 ../gem5-resources/disks/rootfs.ext4
我們可以寫一個簡單的 source file ( chkpt.c )
#include <stdio.h>
// M5Ops number : https://github.com/gem5/gem5/blob/stable/include/gem5/asm/generic/m5ops.h#L60
void dump_reset_stats() {
__asm__ __volatile__ (
"mov x0, #0\n\t"
"mov x1, #0\n\t"
".inst 0xFF000110 | (0x41 << 16)\n\t" // Encodes m5_dump_reset_stats
::: "x0", "x1"
);
}
void chkpt() {
__asm__ __volatile__ (
"mov x0, #0\n\t"
"mov x1, #0\n\t"
".inst 0xFF000110 | (0x43 << 16)\n\t" // Encodes M5OP_CHECKPOINT
::: "x0", "x1"
);
}
int main() {
printf("m5 ops chkpt!\n");
chkpt();
}
而這個特殊的 instruction .inst 0xFF000110 | (0x43 << 16) 會被 gem5 的 isa-parser 辨識為 m5Ops。這個 instruction 並不是 ARM 的 instruction,而是 gem5 為了讓模擬器可以取得控制權,而額外設計的 instruction。
gem5 有許多 m5Ops,而這邊我們想要使用的 m5Ops 是 checkpoint : https://github.com/gem5/gem5/blob/v25.0.0.0/src/sim/pseudo_inst.cc#L357
我們可以將 chkpt.c 編譯成 chkpt 後,用上面的方式放到 buildroot 產生的 root filesystem。
當我們使用 configs/example/arm/starter_fs.py 想要創建一個 checkpoint 的時候,需要增加 --checkpoint 這個 option。
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu=atomic --num-cores=4 --root-device=/dev/vda --checkpoint
我們可以在 gem5 的 guest OS 的 shell 去執行 chkpt,便可以觸發 checkpoint。
/chkpt
我們可以在 m5out 資料夾裡面,看到一個類似 cpt.7035321774750 的資料夾。
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu=atomic --num-cores=4 --root-device=/dev/vda --checkpoint
> /chkpt
產生的 checkpoint 會在 m5out/cpt.7035321774750。每次 checkpoint 所產生的資料夾的後綴 ( “cpt.*” ) 應該都會不一樣。
嘗試從 checkpoint restore 回原本的狀態
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu="atomic" --num-cores=4 --root-device=/dev/vda --restore ./m5out/cpt.7035321774750
我們可以再次進入 gem5 guest OS 的 shell,看看有沒有成功回到 prompt
./util/term/gem5term 3456
==== m5 terminal: Terminal 0 ====
# ls -al /
total 38
drwxr-xr-x 18 root root 1024 Jan 1 00:00 .
drwxr-xr-x 18 root root 1024 Jan 1 00:00 ..
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu=”minor" --num-cores=4 --root-device=/dev/vda --restore ./m5out/cpt.7035321774750
有看到回到 prompt 的話,表示我們從快速的 model ( atomic ) 進行 checkpoint,然後在慢速的 model ( minor ) restore 回來!!!
雖然在比較慢的 model 上做 checkpoint 比較沒有意義,不過這邊也來嘗試看看...
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu=minor --num-cores=4 --root-device=/dev/vda --checkpoint
> /chkpt
這一次產生的 checkpoint 在 cpt.1331995838000。
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu="atomic" --num-cores=4 --root-device=/dev/vda --restore ./m5out/cpt.1331995838000
成功 restore 到 prompt 了 !
./build/ARM/gem5.opt configs/example/arm/starter_fs.py --kernel=vmlinux --disk-image=rootfs.ext4 --cpu="atomic" --num-cores=4 --root-device=/dev/vda --restore ./m5out/cpt.1331995838000
這邊也成功了 !
[--] 可以嘗試看看,restore 的時候,使用不同的 root filesystem 看看。這一招在 debug kernel driver 的時候,可能會有點效果 ( restore 時,載入新的 root filesystem,裡面包含新的 linux kernel driver ) 雖然實際上也可以用網路把檔案傳到 guest OS ... XD。 restore 到 prompt 之後,再把檔案傳進去就可以了。