软件环境:ubuntu20.04,qemu,aosp
硬件环境:x86 pC
目标:测试虚拟机与Host之间共享内存ivshmem
1. ivshmem说明
以Acrn Hypervisor为例,ivshmem(inter-vm share memory)框架如上图所示,ivshmem就是虚拟机<->虚拟机,虚拟机<->Host之间共享内存。
参考Intel ACRN Hypervisor介绍:https://projectacrn.github.io/latest/tutorials/inter-vm_communication.html#inter-vm-vuart
2. ivshmem测试
目前qemu支持ivshmem,虚拟机内核需要编译vsoc驱动,以谷歌cuttlefish虚拟机为例进行测试
2.1 编译VM内核
由于android kernel 5.10将vsoc驱动删除了,需要自行添加
#1. 将老版本vsoc.c uapi/vsoc_shm.h拷贝到目录
#2. 将vsoc编译到内核image
common/drivers/staging/android/Makefile
+obj-y += vsoc.o
#3. 编译android内核bzImage和initramfs.img
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
2.2 编译cuttlefish
cuttlefish选择使用qemu进行启动,crosvm还不支持ivshmem,修改cuttlefish代码
#1. cf支持ivshmem. device/google/cuttlefish/qemu_manager.c增加如下修改
//ivshmem test
qemu_cmd.AddParameter("-object");
qemu_cmd.AddParameter("memory-backend-file,size=1M,share,mem-path=/dev/shm/ivshmem,id=hostmem");
qemu_cmd.AddParameter("-device");
qemu_cmd.AddParameter("ivshmem-plain,memdev=hostmem");
#2. 重新编译aosp cuttlefish
2.3 ivshmem测试
Android Vm侧用于测试ivshmem代码ivshmem-reader_x86.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <assert.h>
#define SHM_SIZE (1*1024*1024)
int main(int argc, char **argv) {
char *p;
int fd;
int i;
void* tmp;
fd = open("/sys/bus/pci/devices/0000:00:02.0/resource2", O_RDWR);
// assert(fd != -1);
if (fd < 0) {
printf("open pci device failed\n");
return 0;
}
tmp = mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// assert(p != NULL);
if (tmp == (void*)-1) {
printf("mmap failed.\n");
return 0;
}
p = (char*)tmp;
for (i = 0; i < 8; i++) {
printf("%c", p[i]);
}
printf("%s\n", p);
munmap(p, SHM_SIZE);
close(fd);
return 0;
}
使用qemu启动android虚拟机,测试ivshmem.
#1. 使用前文编译的bzImage和initramfs.img启动虚拟机,再次启动前删除host侧/dev/shm/ivshmem节点
launch_cvd -daemon -vm_manager=qemu_cli -display0=width=1080,height=600,dpi=160 -kernel_path bzImage -initramfs_path initramfs.img -use_overlay=false
#2. host向ivshmem写数据
echo "hello" > /dev/shm/ivshmem
#3. Android Vm从ivshmem读数据
adb push ivshmem-reader /data/tmp/ivshmem-reader_x86
adb shell /data/tmp/ivshmem-reader_x86
测试结果