如何利用QEMU开发调试linux kernel
文章目录
开发linux kernel是一件很有趣的事情,但缺乏调试工具往往会使这一过程也充满痛苦。QEMU作为一种虚拟化方案,提供了一种将kernel运行在user space,利用gdb进行调试的方法。善加利用,可以大大提高效率。
关闭编译linux kernel的优化
linux kernel不支持关掉编译优化选项,这给直接用gdb调试造成很多困难。常常会发现想要看的变量的值被编译器优化掉了。这里提供一个patch,可以将linux kernel的编译优化级别设置为'-Og',这样能解决掉大部分因优化引入的问题。
|
|
选择“DEBUG”就可以使能这一功能。 这里提供一个相对精简的linux kernel config,里面包含了大部分网络相关的功能。
准备initial ram disk
modify initramfs_desc
|
|
run command gen_init_cpio
|
|
为了准备一些网络工具,我们需要把他们编译称静态的版本。
-
iperf
1
./configure "LDFLAGS=--static" --without-openssl --enable-static --disable-shared ; make ;
boot kernel with qemu
|
|
‘nokaslr’ 的目的是为了能够用gdb调试,没有它你会发现断点不能正常工作。
network
QEMU的网络配置可以分为前端和后端。前端的网络配置是指在如何创建Guest OS中可见的网卡,而Guest OS中的网卡要想和Host OS的网络进行通信,或多个Guest OS之间想要互相通信,就需要通过后端的网络配置,在Host OS里创建和Guest OS里的网卡对应的网卡。这样在Guest OS中网卡收到的数据,就会被QEMU传递给Host OS中对应的网卡。
TAP NIC + Bridge
最常见的配置方法,就是在Host网络中创建一个单独的bridge, 然后为每一个Guest OS中的网卡在Host OS中创建一个类型为TAP的网卡, 然后将这些TAG网卡都挂载在bridge下。这种方法开销小,传输速度快,有一点麻烦的地方,就是每次启动虚拟机时,都要将Host OS中创建的网卡挂载在bridge下。 不过QEMU提供了一个脚本,来帮助我们自动完成这个工作。
配置‘qemu-bridge-helper’
|
|
启动虚拟机,配置网络
|
|
这里,'-netdev tap,id=n1,“helper=/path/to/qemu-bridge-helper”' 的作用是在Host网络中创建一个类型为TAP的网卡,其id为’n1',调用 qemu-bridge-helper脚本将其自动挂载在我们之前在'/etc/qemu/bridge.conf’中配置的’br0’上。 ’-net nic,netdev=n1,model=virtio,macaddr=52:54:00:12:34:56’的含义是在Guest OS里创建一个网卡,使用的driver是 virtio,通过‘netdev=n1’, 这个虚拟网卡会和Host OS里的网卡连接起来。
ipv4 only
主机A:
|
|
主机B:
|
|
reference
http://www.h7.dion.ne.jp/~qemu-win/HowToNetwork-en.html
https://blog.nelhage.com/2013/12/lightweight-linux-kernel-development-with-kvm/
debug
gdb ./vmlinux target remote localhost:1234 continue
reference
https://lwn.net/Articles/660404/
IPv6 Big Packets issue with qemu
setup
three qemu virtual machine.
-
machine A with two nics connect to B and C qemu-system-x86_64 -nographic -kernel arch/x86/boot/bzImage -initrd ./initramfs.img -append “console=ttyS0 nokaslr” -net nic,model=virtio,macaddr=52:54:00:12:34:56 -net socket,listen=localhost:12345 -net nic,model=virtio,macaddr=52:54:00:12:34:57 -net socket,listen=localhost:54321
ip -6 addr add 2200:fe00::1/64 dev eth0 ip -6 addr add 4400:fe00::1/64 dev eth1
ip6tables -I FORWARD -t filter -p ipv6-icmp -m icmp6 –icmpv6-type 1 -j ACCEPT ip6tables -I FORWARD -t filter -p ipv6-icmp -m icmp6 –icmpv6-type 2 -j ACCEPT ip6tables -I FORWARD -t filter -p ipv6-icmp -m icmp6 –icmpv6-type 3 -j ACCEPT ip6tables -I FORWARD -t filter -p ipv6-icmp -m icmp6 –icmpv6-type 128 -j ACCEPT ip6tables -I FORWARD -t filter -p ipv6-icmp -m icmp6 –icmpv6-type 129 -j ACCEPT
-
machine B connect to A qemu-system-x86_64 -nographic -kernel arch/x86/boot/bzImage -initrd ./initramfs.img -append “console=ttyS0 nokaslr” -net nic,model=virtio,macaddr=52:54:00:12:34:58 -net socket,connect=localhost:12345 ip -6 addr add 2200:fe00::2/64 dev eth0 ip -6 route add default via 2200:fe00::1
-
machine C connect to A qemu-system-x86_64 -nographic -kernel arch/x86/boot/bzImage -initrd ./initramfs.img -append “console=ttyS0” -net nic,model=virtio,macaddr=52:54:00:12:34:59 -net socket,connect=localhost:54321 ip -6 addr add 4400:fe00::2/64 dev eth0 ip -6 route add default via 4400:fe00::1
-
enable ipv6 forward sysctl -w net.ipv6.conf.all.forwarding=1
-
load ko symbol add-symbol-file drivers/mydrivers/mydriver.o 0xbf098000
-
run
vlan config with qemu
two qemu virtual machine
- create bridge sudo brctl addbr br0 ifconfig br0 up
- config bridge helper so that tap device can be created without root previledge sudo chmod u+s /usr/local/libexec/qemu-bridge-helper sudo echo “allow br0” > /usr/local/etc/qemu/bridge.conf
- machine A with one nic connect to bridge br0 qemu-system-x86_64 -s -nographic -kernel arch/x86/boot/bzImage -initrd ./initramfs.img -append “console=ttyS0” -net nic,model=virtio,macaddr=52:54:00:12:34:56 -net bridge,br=br0
- machine B with one nic connect to bridge br0 qemu-system-x86_64 -nographic -kernel arch/x86/boot/bzImage -initrd ./initramfs.img -append “console=ttyS0” -net nic,model=virtio,macaddr=52:54:00:12:34:58 -net bridge,br=br0 ifconfig eth0 10.0.0.1
- ping from B to A
run qemu with bridge network which connected to gateway and an extented PC reachable
config on qemu
ifconfig eth0 192.168.3.101 route add 192.168.3.100 dev eth0 route add -net 0.0.0.0 gw 192.168.3.100 dev eth0
config on host
sudo brctl addbr br0 sudo ifconfig br0 up sudo ifconfig br0 192.168.3.100 sudo route add -net 200.200.200.0/24 dev eth1 gw 192.168.0.1 sudo echo 1 > /proc/sys/net/ipv4/ip_forward
config on gateway
route add -net 192.168.3.0 netmask 255.255.255.0 gw 192.168.0.100 dev br-lan
文章作者 Griffin
上次更新 2021-06-16