4、创建第一个虚拟机:定义VM配置文件、启动Guest OS(Linux/RTOS)、验证虚拟机运行

好,咱们终于到了动手的环节。前面几章讲了那么多理论,说实话,我自己当年学虚拟化的时候,最烦的就是光说不练。今天咱们直接上手,创建一个真正的虚拟机。

这一章的目标很明确:写一个VM配置文件,启动一个Guest OS(Linux或RTOS),然后验证它确实在跑。我会带着你一步步走,中间穿插一些我踩过的坑。

4.1 理解VM配置文件的结构

在QNX虚拟化里,虚拟机不是凭空产生的。你需要一个配置文件,告诉Hypervisor:这个虚拟机要多少内存?用几个CPU?网络怎么接?

这个文件通常叫 .vm 后缀,放在 /etc/system/config/ 下。说白了,它就是虚拟机的“出生证明”。

我个人习惯把配置文件分成三大块:

  • 资源分配:CPU、内存、中断
  • 设备模拟:串口、网卡、存储
  • 启动参数:内核路径、命令行

嗯,这里要注意:配置文件写错了,虚拟机根本起不来。我曾经有一次把内存单位写成了MB而不是KB,结果Guest OS一启动就崩溃,查了半天才发现。

4.2 编写第一个VM配置文件

咱们先来个简单的。假设我要启动一个Linux Guest,给它256MB内存,1个vCPU,一个串口输出。

下面是一个典型的配置文件:

# 文件名: my_first_vm.vm
name = "my_linux_vm"
memory = 256M
vcpus = 1

# 串口控制台
vio {
    name = "console"
    type = "serial"
    irq = 33
    base = 0x3f8
}

# 虚拟磁盘(从宿主机映射一个文件)
vdev {
    name = "rootfs"
    type = "block"
    backend = "file"
    path = "/data/images/linux_rootfs.img"
}

# 启动参数
boot {
    kernel = "/data/images/vmlinux"
    cmdline = "console=ttyS0 root=/dev/vda rw"
}

你看,结构很清晰。每个 viovdev 就是一个虚拟设备。我建议你刚开始时,只配一个串口,这样调试起来方便。

小技巧:串口的irq不要和宿主机冲突。QNX系统里,irq 32以下通常是系统保留的,所以我习惯从33开始用。

4.3 启动Guest OS

配置文件写好了,怎么启动?用 qvm 命令。

命令很简单:

qvm my_first_vm.vm

就这么一行。但别高兴太早,我第一次执行的时候,终端上什么都没显示。为什么?因为我忘了把串口输出重定向到当前终端。

正确的做法是:

qvm -c my_first_vm.vm

-c 参数的意思是“把虚拟机的串口控制台绑定到当前终端”。这样你就能看到Linux的启动日志了。

如果你启动的是RTOS(比如一个轻量级的实时系统),流程完全一样。只是内核和文件系统不同。我曾在项目里同时启动一个Linux做应用层,一个RTOS做实时控制,两个虚拟机跑在同一块芯片上。

注意:启动RTOS时,记得检查它的内存布局。RTOS通常对内存地址很敏感,如果配置文件和链接脚本对不上,它连串口都打不开。

4.4 验证虚拟机是否正常运行

虚拟机启动了,怎么确认它真的在跑?光看终端输出还不够。我一般用三个方法:

  1. 看进程列表:在宿主机上执行 pidin | grep qvm,如果看到qvm进程,说明虚拟机还在运行。
  2. 检查虚拟网络:如果配了网卡,用 ifconfig 看看虚拟网口有没有up。
  3. 登录Guest OS:通过串口控制台,直接敲回车,如果能出现登录提示符,那就稳了。

我记得有一次,虚拟机启动后终端显示正常,但网络就是不通。我查了半天,发现是虚拟网卡的MAC地址和宿主机冲突了。所以,验证不只是看“有没有启动”,还要看“功能对不对”

下面是一个简单的验证流程表:

验证项 命令/方法 预期结果
进程存在 pidin | grep qvm 显示qvm进程PID
串口输出 观察控制台 看到内核启动日志
网络连通 ping 192.168.1.100 收到回复
Guest OS登录 串口输入用户名 出现shell提示符

4.5 常见问题与避坑

说实话,第一次创建虚拟机,不出问题才奇怪。我把自己遇到过的几个典型问题列出来:

  • 虚拟机启动后立刻退出:多半是内核路径错了,或者内核格式不对。检查 boot.kernel 路径。
  • 串口没有输出:检查irq和base地址是否匹配。Linux内核默认串口是0x3f8,irq 4,但QVM里可以重新映射。
  • Guest OS卡在“Starting kernel...”:这通常是内存不够,或者设备树有问题。我曾经给一个RTOS只配了64MB,结果它初始化到一半就崩了。
避坑指南:我曾经在项目里犯过一个低级错误——配置文件里忘了加 vcpus = 1,结果QVM默认分配了0个CPU,虚拟机直接起不来。所以,每个参数都显式写出来,别依赖默认值。

4.6 小结

这一章我们做了三件事:写了配置文件、启动了虚拟机、验证了运行状态。说白了,就是“配、启、验”三步走。

你想想看,整个过程其实不复杂。但细节决定成败。一个irq号写错,一个路径打错,都可能导致虚拟机罢工。所以,我建议你从最简单的配置开始,一步步加功能。

下一章,我们会深入虚拟机的内存管理,讲讲怎么给Guest OS分配物理内存,以及如何避免内存踩踏。嗯,那才是真正考验功底的地方。