简介
本文通过了在ubuntu使用了多种方式创建和运行qnx800 vm(Virtual Machine, 虚拟机) ,并比较了这几种方式的差异点。
方式1:通过mkqnximage
快速创建并使用qemu-system_x84_64
运行该qnx800 vm
方式2:通过Generic x86_64
BSP编译出image,并使用qemu-system_x84_64
运行该qnx800 vm
方式3:通过BSP_aarch64_qemu_virt
BSP编译出image,并使用qemu-system-aarch64
运行qnx800 vm
方式 | 工具 | 优势 | 劣势 |
---|---|---|---|
1 | mkqnximage | 不用配置,快速编译出相关功能的qnx800 vm,可以进行快速验证 | buildfile文件不方便自定义 |
2 | Generic x86_64 BSP | 可以根据自己的需求配置buildfile文件和启动程序 | 有一定的门槛,需要对BISO启动,QNX启动和buildfile机制熟悉 |
3 | BSP_aarch64_qemu_virt | 同上 | 同上 |
试验环境
Host
: Ubuntu 22.04.3 LTSQNX Version
: SDP800, 8.0 Build141 - November 27.2023BSP for Generic x86_64
: 8.0 Build 50 - November 20, 2023,BSP_x86_64_br-hw-rel_be-800_SVN989189_JBN50.zipBSP for Raspberry Pi BCM2711 R-PI4
: 8.0 Build 198 - June 18, 2024,BSP_raspberrypi-bcm2711-rpi4_br-hw-rel_be-800_SVN999745_JBN198.zipqemu-system-x86_64
:qemu-system-aarch64
:
mkqnximage创建并运行qnx800 vm
QNX提供了一个mkqnximage
的工具用于创建运行与X86平台的qnx vm image,该image支持在Vmware
, VirtualBox
, qemu
等虚拟机工具上运行。
1.创建qnx800 vm image
使用以下方式在ubuntu下快速生成一个可用qemu运行的qnx800 vm image。
1 | mkdir qnx800_qemu_base_x86 |
2.运行qnx800 vm
之后可以使用mkqnximage --run
运行qnx800 vm。
1 | mkqnximage --run |
这个命令相当于启动了qemu-system-x86_64
程序,并指定相关的一些配置,这些配置来源于mkqnximage
创建QNX VM image时候传入的options
参数,实际运行的命令如下:
1 | qemu-system-x86_64 -smp 2 --cpu max -m 1G -drive file=output/disk-qemu.vmdk,if=ide,id=drv0 -netdev bridge,br=br0,id=net0 -device virtio-net-pci,netdev=net0,mac=52:54:00:50:16:3c -pidfile output/qemu.pid -nographic -kernel output/ifs.bin -serial mon:stdio -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 -nographic |
各个参数的定义如下:(注意,在启动qnx800 VM需要加上--cpu max
的参数,但是启动qnx710 VM就不需要)
○ -smp 2 --cpu max
§ Specifies 2 CPU cores for the guest.
§ The –cpu max enables the most feature-rich virtual CPU supported by QEMU on the host.
○ -m 1G
§ Allocates 1 GB of memory for the guest.
○ -drive file=output/disk-qemu.vmdk,if=ide,id=drv0
§ Attaches a disk image (output/disk-qemu.vmdk) using the IDE interface.
§ id=drv0 assigns an identifier to the drive.
○ -netdev bridge,br=br0,id=net0
§ Connects the guest’s networking through the host bridge br0.
§ id=net0 assigns an identifier to this network device.
○ -device virtio-net-pci,netdev=net0,mac=52:54:00:50:16:3c
§ Adds a VirtIO network device connected to net0.
§ Assigns the specified MAC address to the guest’s network interface.
○ -pidfile output/qemu.pid
§ Stores the QEMU process ID in output/qemu.pid.
○ -nographic
§ Disables graphical output. The guest runs entirely in the terminal.
○ -kernel output/ifs.bin
§ Specifies the kernel image (output/ifs.bin) to boot the guest.
○ -serial mon:stdio
§ Configures the serial port to be accessible via the terminal for debugging.
○ -object rng-random,filename=/dev/urandom,id=rng0
§ Adds an entropy source (/dev/urandom) for the guest.
§ id=rng0 assigns an identifier to the RNG object.
○ -device virtio-rng-pci,rng=rng0
§ Adds a VirtIO RNG device, linked to the rng0 entropy source.
qnx800 VM启动的过程如下:
3.修改配置
上述创建的vm image使用的默认配置,可以通过修改local/options
的文件来修改配置,然后执行重新生成vm image就可以了。
1 | mkqnximage --clean |
4.Host通过ssh访问qnx800 vm
在启动qnx800 vm的时候,qemu-system-x86_64
会在host端创建一个br0
的网卡给qnx800 vm,只要保证这两个网卡在同一个网段即可。
Host端br0网卡:
qnx800 vm网卡:
5.单独编译ifs.bin
当使用创建好的qnx800 vm image后,如果有需要对其中的某些配置做一个简单的修改而不想要重新创建整个vm image,那么可以单独修改output/build/
目录中的.build
或者启动相关的脚本。
之后重新执行mkifs -o output output/build/ifs.build output/ifs.bin
编译出ifs.bin
即可。
6.单独编译disk-qemu
目前是做不到的,生成的disk-qemu
是包含一个只读的system
分区,一个可读写的data
分区。
mkqnximage 原理
mkqnximage
是一个放在~/qnx800/host/common/bin/
的脚本,比如执行mkqnximage --build
创建一个新的qnx800 VM,那么就会执行以下的脚本片段:
1 | Turn the assorted partitions into the final disk image and then invoke any post build scripts |
当使用mkqnximage
相关的操作时,实际上会根据传入的参数来执行一系列预设好的动作。
这些预设好的动作已都在~/qnx800/host/common/mkqnximage/
目录各种配置文件和脚本中定义好了,不同的参数选择执行不同的配置或者脚本。
通过Generic x86_64 BSP编译出x86_64 vm image
1.下载Generic x86_64
BSP
从QNX软件中心下载Generic x86_64
的源码
2.添加串口支持
修改使用8250 debug port做为shell,这样子能保证我们能进行串口的调试,patch如下:
1 | index 6d8a06aa..44c1b411 100644 |
3.添加EIDE磁盘
通过在qnx虚拟机执行pci-tool
查看当前识别到的设备,发现识别到的IDE
磁盘为vid/did: 8086/7010
,与x86_64-generic.build
的文件指定的不一致,因此需要为其添加一个EIDE_8086_7010=8086/7010
的设备。
这个磁盘加载上后,就可以看到disk.img
对应的分区,然后将其挂载出来即可。
1 | --- a/bsp/BSP_x86_64_br-hw-rel_be-800_SVN989189_JBN50/images/generic-bios/x86_64-generic-bios.build |
4.添加网卡设备:
可以通过io-sock -d vtnet_pci
创建一个VirtIO PCI 网卡,然后启动qemu的时候添加与之对用的网卡名为br0
,那么QNX VM就会有一个与之对应的vtnet0
网卡。
1 | -netdev bridge,br=br0,id=net0 \ |
1 | diff --git a/bsp/BSP_x86_64_br-hw-rel_be-800_SVN989189_JBN50/images/generic-bios/x86_64-generic-bios.build b/bsp/BSP_x86_64_br-hw-rel_be-800_SVN989189_JBN50/images/generic-bios/x86_64-generic-bios.build |
启动qnx800 vm后,能看到qnx800 vm中的vtnet0
网卡:
1 | vtnet0: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 |
host端能看到一个br0
网卡
1 | br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 |
5.编译BSP
1 | source ~/qnx800/qnxsdp-env.sh |
之后在BSP_x86_64_br-hw-rel_be-800_SVN989189_JBN50/images/generic-bios/
目录下会生成运行于x86_64架构上bios启动所需的disk.img
镜像,这个镜像的布局如下,具体的布局是由disk.cfg
配置文件决定的。
各个image和disk.cfg
配置信息的关系如下:
6.启动qemu: 这个命令与mkqnximage
启动qemu的命令一致
1 | qemu-system-x86_64 -smp 2 --cpu max -m 1G \ |
通过BSP_aarch64_qemu_virt BSP编译出aarch64 vm image
1 | # QEMU Virtual Machine BSP for QNX |