前言
ACRN作为Intel为工控领域推出的一个小型化的虚拟机,它的特点主要有这么几个:
1.针对Intel的芯片做了非常强的优化
2.RT-VM实时虚拟机的实时性很好
3.CACHE缓存技术发挥的好
4.TCC技术 / 当然不是所有intel的芯片都支持,,,得带e的芯片才行
编译机器的环境
编译环境就没有ACRN这么严格了,相对还是轻松的,我们可以用虚拟机Ubuntu22.04去搭建环境,根据给出的文档操作就可以了Getting Started Guide — Project ACRN™ 3.2-unstable documentation
mkdir -p ~/acrn-work
sudo apt install -y gcc git make vim libssl-dev libpciaccess-dev uuid-dev \
libsystemd-dev libevent-dev libxml2-dev libxml2-utils libusb-1.0-0-dev \
python3 python3-pip libblkid-dev e2fslibs-dev \
pkg-config libnuma-dev libcjson-dev liblz4-tool flex bison \
xsltproc clang-format bc libpixman-1-dev libsdl2-dev libegl-dev \
libgles-dev libdrm-dev gnu-efi libelf-dev \
build-essential git-buildpackage devscripts dpkg-dev equivs lintian \
apt-utils pristine-tar dh-python python3-lxml python3-defusedxml \
python3-tqdm python3-xmlschema python3-elementpath acpica-tools
cd ~/acrn-work
git clone https://github.com/projectacrn/acrn-hypervisor.git
cd acrn-hypervisor
git checkout release_3.2
cd ..
git clone https://github.com/projectacrn/acrn-kernel.git
cd acrn-kernel
git checkout release_3.2
目标机器Step1
其实ACRN对硬件芯片还是有限制的,可以去对应的查看一下,这里我还是用intel i7-12700来做示范。系统可以使用ECI或者ACRN教程上面的Ubuntu 22.04。对RT_VM虚拟机的实时性不会有很大影响
BIOS设置
Hyper-Threading | Disabled | Intel Advanced Menu ⟶ CPU Configuration |
---|---|---|
Intel (VMX) Virtualization | Enabled | Intel Advanced Menu ⟶ CPU Configuration |
Intel(R) SpeedStep | Disabled | Intel Advanced Menu ⟶ Power & Performance ⟶ CPU - Power Management Control |
Turbo Mode | Disabled | Intel Advanced Menu ⟶ Power & Performance ⟶ CPU - Power Management Control |
C States | Disabled | Intel Advanced Menu ⟶ Power & Performance ⟶ CPU - Power Management Control |
RC6 (Render Standby) | Disabled | Intel Advanced Menu ⟶ Power & Performance ⟶ GT - Power Management Control |
VT-d | Enabled | Intel Advanced Menu ⟶ System Agent (SA) Configuration |
Above 4GB MMIO BIOS assignment | Disabled | Intel Advanced Menu ⟶ System Agent (SA) Configuration |
PM Support | Enabled | Intel Advanced Menu ⟶ System Agent (SA) Configuration ⟶ Graphics Configuration(没找到) |
DVMT Pre-Allocated | 64M | Intel Advanced Menu ⟶ System Agent (SA) Configuration ⟶ Graphics Configuration |
生成配置文件
这里需要注意一点,ACRN建议我们在生成配置文件的时候,就插上所有需要用的到设备,比如hdmi、pcie设备、usb键鼠等等,因为这个配置是一次性的,如果后期再增加,那在虚拟机里可能识别不到。
编译机器Step1
编译机器主要是把这个my_board文件拷过来,可以结合这个链接,我们在这里大概的说一下过程。Getting Started Guide — Project ACRN™ 3.2-unstable documentation
在这里我们主要去搭建一个实时的RT_VM,当然也有标准的STD_VM,只要按官方的教程就可以了。在终端里输入 acrn-configuration之后,按照链接里选好my_board.xml,在界面里按下面的方式去设置,因为ACRN会用串口去调试打印数据,如果等级设置的太低,它会什么都打印,严重影响实时性。
然后对应设置RT_VM的参数
接着按照官网的方式去编译,会获得一堆deb的安装文件,这些文件需要拷贝到目标平台上
目标机器Step2
安装上面所有的deb文件,然后我们修改GRUB的菜单,在进入系统的时候选择带有acrn-service-vm的选项进入即可。
设置网络
sudo cp /usr/share/doc/acrnd/examples/* /etc/systemd/network
sudo systemctl enable --now systemd-networkd
VM镜像的选择
在目标机器Step1的过程中啊,我们其实是随便填写了一个镜像目录,教程里用的是Ubuntu的Ubutnu22.04.iso这种iso的镜像文件。这个会有问题,我们可以进系统,但是任何的操作都没有办法保存,这是因为iso这种镜像烧录方式决定的,无法修改内部的数据。所以我们可以通过Run Ubuntu as the User VM OS — Project ACRN™ 3.2-unstable documentation这个链接里面提到的,将Ubuntu通过KVM去打包成一个xxx.img的镜像,替换我们原来的Ubuntu.iso镜像,比如下面所示
当然啊,其实我们可以用之前的ECI镜像,实时性的效果会更好,可以参考前面的ECI Core-jammy编程。
然后我们直接运行launch_user_vm_id1.sh这个脚本,稍等一会就可以进入VM虚拟机中。
联网问题
按上面的所有操作,我们在虚拟机里是没有办法联网的。根据Virtio-Net — Project ACRN™ 3.2-unstable documentation这个链接中提到的,我们需要在脚本里指定联网的设备(ACRN里叫Tap)
在目标机器上使用ifconfig命令,可以看到存在acrn-br0和tap0 我们要指定tap0作为网络的接口
acrn@acrn:~/acrn-work$ ifconfig
acrn-br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.36 netmask 255.255.255.0 broadcast 192.168.8.255
inet6 240e:478:e58:4560:822e:1577:8b6d:3 prefixlen 128 scopeid 0x0<global>
inet6 240e:478:e58:4560:689a:7bff:fe5c:2038 prefixlen 64 scopeid 0x0<global>
inet6 fd82:2e15:778b:6d00:689a:7bff:fe5c:2038 prefixlen 64 scopeid 0x0<global>
inet6 fe80::689a:7bff:fe5c:2038 prefixlen 64 scopeid 0x20<link>
ether 6a:9a:7b:5c:20:38 txqueuelen 1000 (Ethernet)
RX packets 7159 bytes 775567 (775.5 KB)
RX errors 0 dropped 55 overruns 0 frame 0
TX packets 2527 bytes 380381 (380.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 34:df:20:03:00:82 txqueuelen 1000 (Ethernet)
RX packets 14282 bytes 9998415 (9.9 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6609 bytes 783568 (783.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0x50500000-505fffff
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 296 bytes 24997 (24.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 296 bytes 24997 (24.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 62:f9:46:52:c4:1e txqueuelen 1000 (Ethernet)
RX packets 4078 bytes 403446 (403.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7241 bytes 9084469 (9.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
我们继续修改launch脚本,把这个tap0挂载上,这样就可以访问网络了。
加载磁盘的问题
生成一个test.img的磁盘块,大小为2048M 也就是2G
dd if=/dev/zero of=test.img bs=1M count=2048
mkfs.ext4 test.img
修改launch脚本。它每一行命令前置的序列是不能重复的,比如这里在添加磁盘前已经有0 3 4 5 ,我们可以选择7、8、9等等,比如这里我选择了9
进入RT VM1以后,挂载它
mkdir /home/xxx/test
sudo mount /dev/vdb /home/xxx/test
sudo chmod 755 /home/xxx/test
扩充img
# 用qemu-img将eore-jammy.img扩大到20G
qemu-img resize eore-jammy.img 20G
# 进入VM1,
fdisk /dev/vda
# 然后
wq
# 最后
resize2fs /dev/vda2
优化RT VM
使用debug调试线,用putty进入后更改Loglevel等级(串口 115200波特率),当然这个在设置VM的时候可以选择,改成2 2 2,如果之前没有改的话,我们就要用这个debug调试线的方式去修改。
loglevel 2 2 2
在VM1中调整grub, /etc/default中找到grub,修改成以下内容 (我这里VM1用了俩核,所以我可以去把一个核隔离了用来做实时任务)
GRUB_CMDLINE_LINUX DEFAULT="quiet splash isolcpus=nohz.domain,1 idle=poll rcu_nocb_poll rcu_nocbs=1 mce=off"
Real Time测试结果
在VM1里面,我们进行Cyclictest的实时性测试(宿主机用的是Ubuntu 22.04,VM1用的镜像是ECI Core-jammy),48h的结果是15us,已经很不错了,跟裸机的ECI基本没有区别