利用KGDB双机调试内核
环境
- centos 7
- VMware
- 全程使用root用户
配置内核编译环境
- 这种方式调试内核需要两台机器,一台用来运行Linux内核,另一台对内核进行调试。一般有以下三种常用的方案,可以根据电脑的性能或资金状况来选择。可以开两个Linux系统的虚拟机;也可以在物理机系统是linux上面装虚拟机,然后虚拟机运行一个linux;再就是买开发板来调试内核。以下是在windows上开两个虚拟机的流程描述。
- vmware先开启一个虚拟机,命名为client(cpu核数可以设置跟物理机相同,可以提高后续编译速度)。
- 注:在之后的make操作时,如果缺失哪个组件,就安装完成后再执行命令。
在https://www.kernel.org/ 下载想调试版本的内核代码(可以下载tarball格式)。
1
2
3cd /usr/src/
wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-xxx.tar.xz
tar -xvf linux-xxx.tar进入目录,设置编译选项(选择将哪些功能编译进内核)。
1
2
3
4
5
6
7
8
9
10
11
12cd linux-xxx
make menuconfig
等待一下会出现设置页面,寻找以下几项然后确认是选中的。
Kernel hacking --->
[*]Compile the kernel with frame pointers
[*]Compile the kernel with debug info
[*]KGDB: kernel debugging with remote gdb
[*] KGDB: kernel debugger --->
KGDB: use kgdb over the serial console
确认以下一项没有选中。
Kernel hacking --->
Write protect kernel read-only data structures编译内核
1
2
3
4
5
6
7
8
9
10
11
12make -j8 bzImage #-j8设置8个线程来编译,bzImage会降低编译后内核的大小。
... ...
LD arch/x86/boot/setup.elf
OBJCOPY arch/x86/boot/setup.bin
BUILD arch/x86/boot/bzImage
Setup is 16704 bytes (padded to 16896 bytes).
System is 4642 kB
CRC 4c29589a
Kernel: arch/x86/boot/bzImage is ready (#1)
make -j8 modules #编译内核模块
# 这两步比较费时,我打开笔记本的高性能&虚拟机设置多核&多线程编译,将编译时间从一个小时降低到十几分钟了。用vmware克隆出server机(如果早已经克隆,只需拷贝linux-xxx文件夹到server即可。其实也可以在server编译内核,然后再把该目录拷贝到client)
1
scp -r linux-xxx root@172.21.66.111:/usr/src/
在server安装内核模块&内核
1
2make -j8 modules_install
make -j8 install在server的/usr/src/linux-xxx生成initrd.img文件(将下面的版本号都换成自己的)
1
2
3
4mkinitramfs -o initrd.img-xxx xxx
# 以上命令一般在Ubuntu/Debian用,在fedroa或centos一般是mkinitrd,如下
mkinitrd initrd.img-xxx xxx
# xxx为版本号在server,拷贝几个文件到/boot下
1
2
3
4cd /usr/src/linux-xxx
cp arch/x86_64/boot/bzImage /boot/vmlinuz-xxx-kgdb
cp System.map /boot/System.map-xxx-kgdb
cp initrd.img /boot/initrd.img-xxx-kgdb客户机修改设置开机启动项的grub配置文件,添加串口的设置
黄框中的内容表示要串口连接,当然加在下面一项的”GRUB_COMLINE_LINUX”中也可以。
配置完后需要更新一下grub,让配置生效:1
2在ubuntu是用该命令更新: update-grub
centos使用: grub2-mkconfig -o /boot/grub2/grub.cfg
Grub更新配置后,会自动修改/boot/grub/grub.cfg文件,直接修改grub.cfg不是不行,而是如果/etc/default/grub更新后,如果运行update-grub就又会更新一下grub.cfg,导致直接在grub.cfg中的配置失效.
- server机修改grub配置文件
这里与客户机配置比多加了一个参数text,这个参数的意思是系统启动后以text界面而不是图形界面显示(当然这个不是必须的,但是作为目标机我们进入系统直接用text界面界面就可以了)。
配置完后需要更新一下grub,让配置生效。
再看看/boot/grub2/grub.cfg,应该是下图这样,kgdbwait参数就为了在系统刚启动时就可以进入调试模式,如果没有,自己再手动加上吧。 给client机添加串行端口
1
2
3
4
5
6vmware关闭client,进入虚拟机设置,添加串行端口
选中启动时连接
选中使用命名的管道,并填入:
\\.\pipe\com_1
该端是客户端
另一端是虚拟机给server添加串行端口
1
2
3
4
5
6vmware关闭client,进入虚拟机设置,添加串行端口
选中启动时连接
选中使用命名的管道,并填入:
\\.\pipe\com_1
该端是服务器
另一端是虚拟机client和server添加串行端口后,测试一下:
1
2
3
4在一端输入:cat /dev/ttyS1
在另一端输入: echo helloworld > /dev/ttyS1
观察前者是否能接收到数据。
(我测试ttyS0不行,改成ttyS1可以了)
参考
欢迎与我分享你的看法。
转载请注明出处:http://taowusheng.cn/