虚拟化专题-开篇

虚拟化是用来解决复用硬件资源的一个方法,主要的目的是用来降成本。
比如你有一台PC机,使用的时候从来没有让这台机器满负载,其实可以通过虚拟化技术
把这台机器虚拟成好几台机器,而且每台机器的使用体验和真实机器类似的话,是不是
有种多了几台机器的错觉呢:)

虚拟化其实并不陌生,运行一个虚拟机和运行一个进程/线程很类似,只是进程/线程中,
跑的是简单的程序,而虚拟机这个进程里面跑的是操作系统而已。

为了更容易理解,这里借助KVM的API给大show一段代码例子,演示虚拟机是怎么运行的,
这个例子主要参考了:

例子可以直接在海思的开放单板D05上运行。

无图无真相,先看下在D05单板上最终的运行效果。

kvm-demo.gif

代码分成两部分:

使用kvm api

用kvm api创建虚拟机的代码,没什么新意,这里说下大概步骤:

  1. ioctl KVM_CREATE_VM
  2. mmap映射一段内存,通过ioctl KVM_SET_USER_MEMORY_REGION制定给虚拟机
  3. 往该内存,写hello world的binary代码
  4. ioctl KVM_CREATE_VCPU创建vcpu
  5. 通过ioctl KVM_GET_VCPU_MMAP_SIZE指定vcpu运行空间
  6. 指定vcpu->vcpu_thread_func运行函数,以便后续创建的线程运行vcpu
  7. 创建一个线程,运行vcpu
  8. 在线程中,初始化vcpu的运行上下文,具体包括以下几个步骤

    • ioctl KVM_ARM_PREFERRED_TARGET
    • ioctl KVM_ARM_VCPU_INIT
    • ioctl KVM_SET_ONE_REG
    • ioctl KVM_RUN
    • 监听虚拟机退到host的原因
  9. 收到KVM_EXIT_MMIO的时候,打印虚拟机传到host的数据

具体KVM API如何使用,可以参考

hello world

“hello world”程序要注意三点:

  • 要有link脚本,把代码放在虚拟机的内存的开始处,link脚本怎么写,可以参考源码。
  • 需要找到D05单板串口控制器DR的地址,这个grub configure的cmdline里面就有
  • 编译成二进制的时候,需要使用objcopy生成binary的格式,而不是ELF的格式
知道是不会有人点的,但万一有人呢:)