Bao Hypervisor
Bao 是一个轻量级 Type-I hypervisor(虚拟机管理器),基于静态分区架构。
同样是静态分区架构的还有 Jailhouse,但Jailhouse需要通过Linux完成一些设备初始化的操作。
Bao 适合嵌入式场景,适用于MCS(混合关键系统)。
一、bao 的构建
1. 依赖
sudo apt install build-essential bison flex git libssl-dev ninja-build \
u-boot-tools pandoc libslirp-dev pkg-config libglib2.0-dev libpixman-1-dev \
gettext-base curl xterm cmake python3-pip xilinx-bootgen
pip3 install pykwalify packaging pyelftools
2. 安装 qemu
# 安装ARM qemu
sudo apt-get install qemu-system-arm
3. 安装ARM交叉编译工具
安装x86_64 Linux hosted的ARM交叉编译工具(aarch64 ELF裸金属):gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz
下载地址:gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf
下载后解压文件。可输入aarch64-none-elf-gcc -v验证是否配置成功。
4. 下载 bao-demos 源码
git clone https://github.com/bao-project/bao-demos
cd bao-demos
5. 配置构建信息
我这里选择平台 qemu-aarch64-virt
,运行的Guest OS是linux和freertos,交叉编译器的路径是刚刚解压后的文件的bin的路径+前缀。但注意不是所有平台都支持已有的Guest OS,具体看 bao-demos 的 readme。
export PLATFORM=qemu-aarch64-virt
export DEMO=linux+freertos
export CROSS_COMPILE=/home/clara/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-
6. make
make -j$(nproc)
备注:
这里会编译很一会儿,建议先去干其它事情。然后在freertos这里遇到一个找不到寄存器的报错,解决办法如下。
报错:未知或缺少系统寄存器icc_sre_el2
参考解决办法:GNU Toolchain - Unknown or missing system register (GIC register - Cortex-A53) - Compilers and Libraries forum - Support forums - Arm Community
因此,我这里将 bao-demos/wrkdir/srcs/freertos/src/baremetal-runtime/src/arch/armv8/aarch64/start.S
中第57行icc_sre_el2修改为s3_4_c12_c9_5:
msr icc_sre_el2, x1 修改为:
msr s3_4_c12_c9_5, x1
make 成功之后可以看到如下内容:
To start qemu execute "make PLATFORM=qemu-aarch64-virt DEMO=linux+freertos run"
7. make run
运行bao的话输入 make run。
make PLATFORM=qemu-aarch64-virt DEMO=linux+freertos run
可看到打印出如下内容:
--------------------------------------------------------------------------------
5) Setup connections and jump to Bao
Qemu will let you know in which pseudo-terminals it placed the virtio serial.
For example:
char device redirected to /dev/pts/4 (label serial3)
If you are running more than one guest, open a new terminal and connect to it.
For example:
screen /dev/pts/4
If you are running a Linux guest you can also connect via ssh to it by opening
a new terminal and running:
ssh root@localhost -p 5555
Finally, make u-boot jump to where the bao image was loaded:
go 0x50000000
When you want to leave QEMU press Ctrl-a then x.
二、运行 bao
这里要参考 bao-demos 里的说明 linux+freertos。
u-boot 跳至 bao image 加载的地方
make run 之后按照它给出的指示,输入 go 0x50000000
使u-boot跳转至bao image。
BOOTP broadcast 1
DHCP client bound to address 192.168.42.15 (1 ms)
Using virtio-net#31 device
TFTP from server 192.168.42.2; our IP address is 192.168.42.15
Filename 'boot.scr.uimg'.
Load address: 0x40400000
Loading: *
TFTP error: 'Access violation' (2)
Not retrying...
=> go 0x50000000
## Starting application at 0x50000000 ...
Bao Hypervisor
Bao FreeRTOS guest
Task1: 0
Task2: 0
Task1: 1
Task2: 1
Task1: 2
Task2: 2
Task1: 3
应该这里就是运行的FreeRTOS。
虚拟终端连接Linux
Qemu会让你知道它把virtio serial放置在哪个虚拟终端 (pseudo-terminals, pts)中。
例如,我这里qemu是它是 /dev/pts/2
。
char device redirected to /dev/pts/2 (label serial3)
那么我通过下面这个命令连接到虚拟终端。(使用 Ctrl-A
,k
退出。)
sudo apt install screen # 安装 screen
screen /dev/pts/2
在虚拟终端中,需要输入Buildroot,名称和密码都是root。
Welcome to Buildroot
buildroot login: root
Password:
# 输入 root
Linux和Freertos通信
一个 core 是分配给FreeRTOS的,其余的core分配给Linux。
平台的第一个可用的UART分配给FreeRTOS,其余可用的都分配给了Linux。
Linux客户机这里我是通过 screen /dev/pts/2
进入的。应该也可通过ssh,对应的静态地址是192.168.42.15,但我还没有尝试成功。
按照说明,可以通过写/dev/baoipc0向FreeRTOS发送消息。例如,在Linux处输入如下命令:
echo "Hello, Bao!" > /dev/baoipc0
则可以在FreeRTOS这边看到:
Task1: 224
Task2: 224
Task1: 225
Task2: 225
message from linux: Hello, Bao!
Task1: 226
Task2: 226
Task1: 227
Task2: 227
这时候FreeRTOS客户机会向Linux发送消息。但Linux这边不是同步的,要查看FreeRTOS发来的消息需要读取/dev/baoipc0。
cat /dev/baoipc0
可看到如下内容:
# echo "Hello, Bao!" > /dev/baoipc0
# cat /dev/baoipc0
freertos has received 0 uart interrupts!
#