首发于 内核源码
搭建 Linux 内核网络调试环境(vscode + gdb + qemu)

搭建 Linux 内核网络调试环境(vscode + gdb + qemu)

前言

如题,主要搭建 linux 内核的调试环境。

qemu 模拟器运行 linux,然后通过 gdb 调试 linux 内核源码。

前段时间曾出过两个视频,比较粗糙,最近重新整理了一下环境搭建流程,还加入了网桥搭建流程,可以调试 linux 内核虚拟网卡的驱动部分源码。

文章来源: 搭建 Linux 内核网络调试环境(vscode + gdb + qemu)

1. 环境

macos + vmware + ubuntu + gdb + qemu + linux kernel。

调试环境是跑在虚拟机里的,相信 windows 也能搭建起来。
环境布局

2. 视频

3. 流程

3.1. 下载 ubuntu

# 镜像下载链接。
http://mirrors.aliyun.com/ubuntu-releases/14.04/ubuntu-14.04.6-desktop-amd64.iso

3.2. vmware 安装 ubuntu

  1. 虚拟系统磁盘空间,尽量给大一些,例如 100 G。
  2. 通过 root 权限安装 linux 内核。
  • 安装常用工具。
# 设置 root 密码。
sudo passwd
# 切换 root 用户。
su root

# 安装部分工具。
apt-get install vim git tmux openssh-server -y

vi /etc/ssh/sshd_config
# 注释掉禁止 root 远程登录项。
#PermitRootLogin without-password

# 启动 ssh. 方便远程操作,避免后面 qemu 调试导致界面卡死,可以远程关闭进程。
ps -e | grep ssh
sudo /etc/init.d/ssh start

# 添加快捷命令方便操作终端。
vim ~/.bashrc
# 添加 alias c='clear'
# 添加 alias linux='cd /root/linux-5.0.1'
source ~/.bashrc

3.3. 下载编译 linux 内核

# 下载内核源码。
cd /root
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.gz
tar zxf linux-5.0.1.tar.gz
cd linux-5.0.1

# 安装编译依赖组件。
apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev -y

# 设置调试的编译菜单。
export ARCH=x86
make x86_64_defconfig
make menuconfig

# 下面选项如果没有选上的,选上(点击空格键),然后 save 保存设置,退出 exit。
##################################################################
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Device Drivers  --->
    [*] Block devices  --->
        <*> RAM block device support
            (65536) Default RAM disk size (kbytes)

Processor type and features  --->
    [*] Randomize the address of the kernel image (KASLR)
    
Kernel hacking  --->
    Compile-time checks and compiler options  ---> 
        [*] Compile the kernel with debug info
            [*] Provide GDB scripts for kernel debugging

Device Drivers --> 
    Network device support --> 
        <*> Universal TUN/TAP device driver support

[*] Networking support --> 
        Networking options --> 
            <*> 802.1d Ethernet Bridging
##################################################################

# 编译内核。
make -j4

3.4. 源码安装 gdb

源码安装高版本的 gdb 8.3。

# 删除 gdb
gdb -v | grep gdb
apt remove gdb -y

# 安装其它组件。
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt install software-properties-common
sudo apt-get update

# 安装高版本 gcc。
gcc --version
sudo apt-get install gcc-snapshot -y
sudo apt install gcc-9 g++-9 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g++ g++ /usr/bin/g++-9
gcc --version

# 下载解压 gdb
cd /root
#wget https://mirror.bjtu.edu.cn/gnu/gdb/gdb-8.3.tar.xz
wget http://ftp.gnu.org/gnu/gdb/gdb-8.3.tar.gz
tar zxf gdb-8.3.tar.gz

# 修改 gdb/remote.c 代码。
cd gdb-8.3
vim gdb/remote.c


/* Further sanity checks, with knowledge of the architecture.  */
// if (buf_len > 2 * rsa->sizeof_g_packet)
//   error (_("Remote 'g' packet reply is too long (expected %ld bytes, got %d "
//      "bytes): %s"),
//    rsa->sizeof_g_packet, buf_len / 2,
//    rs->buf.data ());

if (buf_len > 2 * rsa->sizeof_g_packet) {
    rsa->sizeof_g_packet = buf_len;
    for (i = 0; i < gdbarch_num_regs(gdbarch); i++) {
        if (rsa->regs[i].pnum == -1)
            continue;
        if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
            rsa->regs[i].in_g_packet = 0;
        else
            rsa->regs[i].in_g_packet = 1;
    }
}


./configure
make -j4
cp gdb/gdb /usr/bin/

# 恢复低版本 gcc。
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100

3.5. gdb 调试内核

通过 gdb 远程调试内核。

# 安装 qemu 模拟器,以及相关组件。 
apt install qemu libc6-dev-i386 -y

# 虚拟机进入 linux 内核源码目录。
cd /root/linux-5.0.1

# 从 github 下载内核测试源码。
git clone https://github.com/wenfh2020/kernel_test.git
# wget https://codeload.github.com/wenfh2020/kernel_test/zip/refs/heads/main
# unzip main
# mv kernel_test-main kernel_test

# 进入测试源码目录。
cd kernel_test/test_epoll_thundering_herd
# make 编译
make
# 通过 qemu 启动内核测试用例。
make rootfs
# 在 qemu 窗口输入小写字符 's', 启动测试用例服务程序。
s
# 在 qemu 窗口输入小写字符 'c', 启动测试用例客户端程序。
c

# 通过 qemu 命令启动内核测试用例进行调试。
qemu-system-x86_64 -kernel ../../arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -S -s
# 在 qemu 窗口输入小写字符 's', 启动测试用例服务程序。
s
# 在 qemu 窗口输入小写字符 'c', 启动测试用例客户端程序。
c

# gdb 调试命令。
gdb vmlinux
target remote : 1234
b start_kernel
b tcp_v4_connect
c
focus
bt

3.6. vscode 配置

3.6.1. vscode 插件

  • remote-ssh
避免 remote-ssh 工作过程中频繁要求输入登录密码,最好设置一下 ssh 免密码登录(参考: [shell] ssh 快捷登录)。
  • ms-vscode.cpptools

3.6.2. 项目调试配置

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "kernel-debug",
            "type": "cppdbg",
            "request": "launch",
            "miDebuggerServerAddress": "127.0.0.1:1234",
            "program": "${workspaceFolder}/vmlinux",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "logging": {
                "engineLogging": false
            },
            "MIMode": "gdb",
        }
    ]
}

3.7. 搭建网桥

  • 安装相关更新组件。
apt-get update

# 虚拟网桥工具
apt-get install bridge-utils

# UML(User-mode linux)工具
apt-get install uml-utilities
  • 修改配置文件。
# vim /etc/network/interfaces
auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp

bridge_ports eth0
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_stp off

auto tap0
iface tap0 inet manual
pre-up tunctl -t tap0 -u root
pre-up ifconfig tap0 0.0.0.0 promisc up
post-up brctl addif br0 tap0
  • 刷新网络(重启虚拟机)。
  • 修改测试源码 ip。
cd /root/linux-5.0.1/kernel_test/test_epoll_thundering_herd
vim main.c

# 修改 SERVER_IP 宏对应的局域网 IP。
# 这个是我工作环境的局域网 IP,应该根据你自己的工作环境,填充对应的 IP。
#define SERVER_IP "192.168.10.221" /* server's ip. */

make rootfs
  • 网络参数。
# qemu 网络参数配置。
-net nic -net tap,ifname=tap0,script=no,downscript=no

# 运行命令。
qemu-system-x86_64 -kernel ../../arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -net nic -net tap,ifname=tap0,script=no

# 调试命令。
qemu-system-x86_64 -kernel ../../arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -S -s -net nic -net tap,ifname=tap0,script=no
  • telnet 测试网络设置情况。
注意:下面 telnet 的这个局域网 IP,是我工作环境的局域网 IP。你在测试时,应该填充你的局域网 IP。
telnet 192.168.10.221 5001

4. 注意

  • 跑通了流程,记得备份保存镜像,避免以后修改了配置跑不起来。

5. 更好方案

前段时间有一位热心网友在我的博客上留言,给出了一个更好的解决方案:描述了使用 docker 搭建调试环境。

6. 参考

  • qemu虚拟机与外部网络的通信
  • 从源码编译linux-4.9内核并运行一个最小的busybox文件系统(最新整理版)
  • linux内核开发第1讲:从源码编译 linux-4.9.229 内核和 busybox 文件系统
  • QEMU 网络配置一把梭
  • vscode + gdb 远程调试 linux 内核源码(附视频)
  • gdb 调试 Linux 内核网络源码(附视频)

深圳SEO优化公司绥化设计公司网站报价安顺网站关键词优化多少钱白城关键词排名哪家好郑州SEO按效果付费报价广东网站关键词优化哪家好深圳网站优化排名哪家好汕头品牌网站设计公司阜新优秀网站设计山南如何制作网站价格大庆网络广告推广多少钱大庆SEO按天收费价格松原网站优化按天收费价格镇江企业网站制作多少钱泉州百度爱采购多少钱深圳网站优化排名报价广东seo优化哪家好中山模板制作价格濮阳营销型网站建设价格廊坊关键词排名哪家好坑梓网站优化报价衡阳模板制作多少钱绵阳网站定制推荐荆州优化推荐大运关键词排名包年推广运城关键词按天收费多少钱天门模板制作哪家好衢州关键词按天扣费多少钱喀什网站搜索优化公司天津网站优化多少钱鹤壁网站制作哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化