Linux操作系统学习笔记(番外篇)QEMU

一. 简介

  突然发现前文忘了写如何编译运行Linux内核并进行修改、调试,所以这里临时补上。主要使用QEMU搭建虚拟机,并在其基础上下载内核并编译从而实现内核调试。

二. QEMU虚拟机搭建

2.1 windows平台

  windows使用QEMU建立虚拟机需要以下步骤:

  • 官网下载QEMU的windows版安装程序并安装
  • 下载想用的虚拟机镜像 文件
  • 在windows的高级系统设置->环境变量中增加对应的QEMU位置
  • 使用qemu-img create -f qcow2 [name].qcow2 30G创建镜像
  • 使用qemu-system-x86_64 -accel whpx -hda .\[name].qcow2 -m 512 -net nic,model=virtio -net user -cdrom .\[name].iso -vga std -boot strict=on开启虚拟机。这里可以简化为qemu-system-x86_64 boot - d -cdrom .\[name].iso
  • 一步一步完成安装即可。

2.2 Linux平台

  这里以Ubuntu为例进行说明

  • 创建网桥并设置P地址
1
2
3
brctl addbr br0
ip link set br0 up
ifconfig br0 192.168.0.11/123
  • 配置iptables开启NAT访问外网功能
1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  • 通过apt-get install qemu安装QEMU
  • 安装libvirt
1
2
apt-get install libvirt-bin
apt-get install virtinst
  • 创建虚拟机镜像,如ubuntutest.img
1
qemu-system-x86_64 -enable-kvm -name ubuntutest  -m 2048 -hda ubuntutest.img -cdrom ubuntu-14.04-server-amd64.iso -boot d -vnc :19
  • 创建xml管理虚拟机。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<domain type='qemu'>
<name>ubuntutest</name>
<uuid>0f0806ab-531d-6134-5def-c5b4955292aa</uuid>
<memory unit='GiB'>4</memory>
<currentMemory unit='GiB'>4</currentMemory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-trusty'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/mnt/vdc/ubuntutest.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<controller type='pci' index='0' model='pci-root'/>
<interface type='bridge'>
<mac address='fa:16:3e:6e:89:ce'/>
<source bridge='br0'/>
<target dev='tap1'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
<listen type='address' address='0.0.0.0'/>
</graphics>
<video>
<model type='cirrus'/>
</video>
</devices>
</domain>
  • 保存xml为domain.xml,并交给libvirt托管
1
virsh define domain.xml
  • 启动虚拟机
1
virsh start ubuntutest
  • 修改登录界面工具,配置/boot/grub/下的grub.cfgmenu.lst

    • grub.cfg 中 submenu ‘Advanced options for Ubuntu’ 这一项,linux /boot/vmlinuz-4.15.0-55-generic root=UUID=470f3a42-7a97-4b9d-aaa0-26deb3d234f9 ro console=ttyS0 maybe-ubiquity 中,加上 console=ttyS0

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-470f3a42-7a97-4b9d-aaa0-26deb3d234f9' {
      menuentry 'Ubuntu, with Linux 4.15.0-55-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-55-generic-advanced-470f3a42-7a97-4b9d-aaa0-26deb3d234f9' {
      recordfail
      load_video
      gfxmode $linux_gfx_mode
      insmod gzio
      if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
      insmod part_gpt
      insmod ext2
      set root='hd0,gpt2'
      if [ x$feature_platform_search_hint = xy ]; then
      search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 470f3a42-7a97-4b9d-aaa0-26deb3d234f9
      else
      search --no-floppy --fs-uuid --set=root 470f3a42-7a97-4b9d-aaa0-26deb3d234f9
      fi
      echo 'Loading Linux 4.15.0-55-generic ...'
      linux /boot/vmlinuz-4.15.0-55-generic root=UUID=470f3a42-7a97-4b9d-aaa0-26deb3d234f9 ro console=ttyS0 maybe-ubiquity
      echo 'Loading initial ramdisk ...'
      initrd /boot/initrd.img-4.15.0-55-generic
      }
    • menu.lst 文件中,在 Ubuntu 18.04.2 LTS, kernel 4.15.0-55-generic 这一项,在 kernel /boot/vmlinuz-4.15.0-55-generic root=/dev/hda1 ro console=hvc0 console=ttyS0 这一行加入 console=ttyS0

      1
      2
      3
      4
      title           Ubuntu 18.04.2 LTS, kernel 4.15.0-55-generic
      root (hd0)
      kernel /boot/vmlinuz-4.15.0-55-generic root=/dev/hda1 ro console=hvc0 console=ttyS0
      initrd /boot/initrd.img-4.15.0-55-generic
  • 重启虚拟机,进入机器控制台

1
2
3
# virsh console ubuntutest
Connected to domain ubuntutest
Escape character is ^]

三. 内核编译

  内核编译主要包括源码的下载、解压缩、编译文件的添加、编译选项的修改等步骤。

  下载和压缩很简单

1
2
3
apt-get install linux-source-4.15.0

tar vjxkf /usr/src/linux-source-4.15.0.tar.bz2

  再安装以下依赖包

1
apt-get install libncurses5-dev libssl-dev bison flex libelf-dev gcc make openssl libc6-dev

  接着定义编译选项

1
2
3
4
5
6
make menuconfig

Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Compile the kernel with frame pointers

  编译内核可以通过nohup在后台完成,缺点是不易确定啥时候编译完

1
2
3
nohup make -j8 > make1.log 2>&1 &
nohup make modules_install > make2.log 2>&1 &
nohup make install > make3.log 2>&1 &

  完成后,启动虚拟机时在GRUB界面选择即可进入新的内核。

总结

  本文大致介绍了QEMU以及内核编译的知识,有兴趣的可以自己动手试一试。

参考文献

[1] Debugging kernel and modules via gdb

[2] 极客时间 趣谈Linux操作系统

坚持原创,坚持分享,谢谢鼓励和支持