虚拟化是用来解决复用硬件资源的一个方法,主要的目的是用来降成本。
比如你有一台PC机,使用的时候从来没有让这台机器满负载,其实可以通过虚拟化技术
把这台机器虚拟成好几台机器,而且每台机器的使用体验和真实机器类似的话,是不是
有种多了几台机器的错觉呢:)
虚拟化其实并不陌生,运行一个虚拟机和运行一个进程/线程很类似,只是进程/线程中,
跑的是简单的程序,而虚拟机这个进程里面跑的是操作系统而已。
为了更容易理解,这里借助KVM的API给大show一段代码例子,演示虚拟机是怎么运行的,
这个例子主要参考了:
例子可以直接在海思的开放单板D05上运行。
无图无真相,先看下在D05单板上最终的运行效果。
代码分成两部分:
使用kvm api
用kvm api创建虚拟机的代码,没什么新意,这里说下大概步骤:
ioctl KVM_CREATE_VM
- mmap映射一段内存,通过
ioctl KVM_SET_USER_MEMORY_REGION
制定给虚拟机 - 往该内存,写hello world的binary代码
ioctl KVM_CREATE_VCPU
创建vcpu- 通过
ioctl KVM_GET_VCPU_MMAP_SIZE
指定vcpu运行空间 - 指定
vcpu->vcpu_thread_func
运行函数,以便后续创建的线程运行vcpu - 创建一个线程,运行vcpu
在线程中,初始化vcpu的运行上下文,具体包括以下几个步骤
ioctl KVM_ARM_PREFERRED_TARGET
ioctl KVM_ARM_VCPU_INIT
ioctl KVM_SET_ONE_REG
ioctl KVM_RUN
- 监听虚拟机退到host的原因
收到
KVM_EXIT_MMIO
的时候,打印虚拟机传到host的数据
具体KVM API如何使用,可以参考
hello world
“hello world”程序要注意三点:
- 要有link脚本,把代码放在虚拟机的内存的开始处,link脚本怎么写,可以参考源码。
- 需要找到D05单板串口控制器DR的地址,这个grub configure的cmdline里面就有
- 编译成二进制的时候,需要使用objcopy生成binary的格式,而不是ELF的格式