用QEMU搭建Linux kernel开发调试环境

Linux驱动开发过程中,段错误和oops就是家常便饭,直接在本机上电脑会吃不消。以前都是找一个嵌入式开发板,用编译-下载-调试这样的方法。

也尝试过Virtualbox。VirtualBox内核安装比较麻烦,如果不是在虚拟机上开发,就要把代码目录共享上去,过程繁琐,还不如用开发板。

最近尝试了Qemu。qemu的配置要复杂一些,很多问题搞起来比较伤脑筋。不过一旦把配置搞定了,调试效率远超开发板和virtualbox。

这里对qemu的配置做个记录。

1. 编译内核

内核需要事先编译出来,这里展示的是通用的内核编译方法。

内核目录下选择通用配置文件:

 cp arch/x86/configs/x86_64_defconfig .config

调整内核配置文件适配当前内核版本:

make menuconfig

编译内核文件:

make bzImage

2. 生成根文件系统

这一步是最重要的,生成一个调试环境的文件系统。这里介绍四种方法。

2.1 制作busybox根文件系统 (方法一)

busybox是一个轻量级的工具集合,包含了init和大部分常用的Linux工具。官网:https://busybox.net

这个方法编译出来的根文件系统是最小的,起动速度也是最快的。就是自带工具可能比较少,有些东西需要自己编译。

2.1.1 创建镜像文件

创建raw格式的镜像文件:

qemu-img create -f raw disk.raw 512M
mkfs -t ext4 ./disk.raw

把raw文件挂载到临时目录:

sudo mount -o loop ./disk.raw ./img
2.1.2 安装模块

进入内核目录,把内核里的模块安装进文件系统:

sudo make modules_install \ # 安装内核模块
INSTALL_MOD_PATH=./img # 指定安装路径
2.1.3 busybox

下载busybox的源码,编译之前需要配置。busybox的配置方式和内核类似:

cd busybox
make defconfig
make menuconfig

调整其中以下选项,编译包含静态库:

Busybox Settings --->

--- Build Options
[*] Build BusyBox as a static binary (no shared libs)

然后编译busybox,这里的path_to_disk_img_mount_point就是刚才raw文件挂载的临时目录:

make CONFIG_PREFIX=<path_to_disk_img_mount_point> install
2.1.4 创建系统文件

配置init环境:
根目录下手工创建etc/init.d, dev, proc, sys 这三个目录。
/etc/inittab:

::sysinit:/etc/init.d/rcS
::askfirst:/bin/ash
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init

/etc/init.d/rcS:

#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys

并把/etc/init.d/rcS改为可执行文件。

2.1.5 内核启动脚本

正常启动内核:

qemu-system-x86_64 \
-m 512 \
-kernel ../kernel/arch/x86_64/boot/bzImage \
-drive format=raw,file=./disk.raw \
-append "init=/linuxrc root=/dev/sda rw"

查看内核串口输出:

qemu-system-x86_64 \
-m 512 \
-kernel ../kernel/arch/x86_64/boot/bzImage \
-drive format=raw,file=./disk.raw \
-append "init=/linuxrc root=/dev/sda rw console=ttyS0" \
-serial file:./serial.out

2.2 用ISO文件制作debian文件系统 (方法二)

这个方法类似于虚拟机安装系统,利用系统自带的安装引导程序生成文件系统。这样安装出来的是一个完整的debian,可以用apt安装工具。

2.2.1 生成镜像文件

生成raw镜像文件:

qemu-img create -f raw debiam-10G.img 10G

安装debian:

qemu-system-x86_64 -m 512 -boot d -hda ./debiam-10G.img -cdrom iso/debian-9.4.0-amd64-netinst.iso
2.2.2 内核启动脚本
qemu-system-x86_64 -m 512 -boot c -kernel ../kernel/arch/x86_64/boot/bzImage -append root=/dev/sda1 -hda ./debiam-10G.img -hdb ./fat.img -net nic -net user,hostfwd=tcp::10022-:22

2.3 用debootstrap制作Debian根文件系统 (方法三)

这方法是利用debian官方的debootstrap,把debian装在本机的一个目录里。这个系统也是完整的debian。

2.3.1 生成镜像文件

生成raw镜像文件:

qemu-img create -f raw debiam-10G.img 10G

挂载文件系统:

sudo mount -o loop ./debiam-10G.img ./img
2.3.2 安装debian

安装debian,这里的path_to_disk_img_mount_point就是刚才镜像文件的挂载点:

sudo debootstrap --arch amd64 stretch <path_to_disk_img_mount_point>
2.3.3 配置网络

这里的网络是主机和虚拟机之间的网络。

让系统启动时自动运行dhclient:

$ cat > <path_to_disk_img_mount_point>/etc/systemd/network/eth.network <<__END__
[Match]
Name=eth0
[Network]
DHCP=yes
__END__
$ systemctl enable systemd-networkd
$ systemctl start systemd-networkd

脚本里的网络设备名设置为eth0。不同的设备可能不一样,比如有些电脑会叫enp0s3。具体网卡名称可以通过ip link查看。

2.3.4 内核启动脚本
qemu-system-x86_64 \
    -m 512 \
    -kernel ../../kernel/arch/x86_64/boot/bzImage \
    -drive format=raw,file=./debian-stretch-x86_64.img,index=0 \
    -drive format=raw,file=./../fat/fat.winxp.img,index=1 \
    --append "console=ttyS0 root=/dev/sda rw" \
    -enable-kvm \
    -nographic \
    -device e1000,netdev=net0 \
    -netdev user,id=net0,hostfwd=tcp::5555-:22

系统启动后,在本机上可以用ssh -p 5555 localhost远程登录虚拟机。

2.4 使用Fedora cloud image (方法四)

Fedora官方有相应的的镜像,叫cloud image,可以直接下载:https://alt.fedoraproject.org/

3 虚拟机访问公网

qemu的网络配置是一个比较纠结的问题,这里用桥接的方式,只能用有线网卡,不支持无线网卡。

没什么技巧可言,直接用脚本启动桥接,系统中途会断网片刻:

#!/bin/bash
ETH_DEV=enp3s0
USERNAME=myname

brctl addbr br0
ip addr flush dev ${ETH_DEV}
brctl addif br0 ${ETH_DEV}
tunctl -t tap0 -u ${USERNAME}
brctl addif br0 tap0

ip link set ${ETH_DEV} up
ip link set tap0 up
ip link set br0 up

brctl show

dhclient -v br0

与此同时,kernel的启动脚本也要有所改变,这里以debian镜像为例:

qemu-system-x86_64 \
    -m 512 \
    -enable-kvm \
    -kernel ../../kernel/arch/x86_64/boot/bzImage \
    -drive format=raw,file=./debian-stretch-x86_64.img,index=0 \
    --append "root=/dev/sda rw" \
    -device e1000,netdev=network0 \
    -netdev tap,id=network0,ifname=tap0,script=no,downscript=no

Reference:

使用 qemu 搭建内核开发环境 . https://www.cnblogs.com/hellogc/p/7482066.html

Creating a Minimal Kernel Development Setup using KVM/Qemu . https://saurorja.org/2011/07/04/creating-a-minimal-kernel-development-setup-using-kvmqemu/
Creating a minimal kernel development setup using QEMU and Archlinux . https://medium.com/@clem.boin/creating-a-minimal-kernel-development-setup-using-qemu-and-archlinux-987896954d84

Setting up QEMU-KVM for kernel development . https://www.collabora.com/news-and-blog/blog/2017/01/16/setting-up-qemu-kvm-for-kernel-development/

Switching to systemd-networkd . https://www.joachim-breitner.de/blog/664-Switching_to_systemd-networkd

Qemu Documentation/Networking . https://wiki.qemu.org/Documentation/Networking

Archlinux QEMU . https://wiki.archlinux.org/index.php/QEMU

转载于:https://my.oschina.net/chenchacha/blog/2208824

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值