前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >构建Linux内核调试环境

构建Linux内核调试环境

作者头像
用户4700054
发布2023-02-26 14:34:35
发布2023-02-26 14:34:35
2.7K00
代码可运行
举报
运行总次数:0
代码可运行

构建Linux内核调试步骤

系统版本

  • 当前宿主机内核版本
代码语言:javascript
代码运行次数:0
复制
// 目前的环境是ubuntu[root@ubuntu ~]$ uname -a
Linux ubuntu 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
  • 调试的内核版本
代码语言:javascript
代码运行次数:0
复制
linux-4.19.25

安装系统组件

  • qemu-kvm
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~]$ sudo apt install libvirt-daemon  qemu-kvm

编译Linux内核源码

  • 下载源码进行基本的配置
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~/debug-kernel-source]$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.255.tar.xz[root@ubuntu ~/debug-kernel-source]$ xz -d linux-4.19.255.tar.xz[root@ubuntu ~/debug-kernel-source]$ tar -xvf  linux-4.19.255.tar 

[root@ubuntu ~/debug-kernel-source]$ cd linux-4.19.255[root@ubuntu ~/debug-kernel-source/linux-4.19.255$ export ARCH=x86[root@ubuntu ~/debug-kernel-source/linux-4.19.255]$ make x86_64_defconfig[root@ubuntu ~/debug-kernel-source/linux-4.19.255]$ make menuconfig
  • 配置内核的选项
代码语言:javascript
代码运行次数:0
复制
Kernel hacking  ---> 
    [*] Kernel debugging
    Compile-time checks and compiler options  --->
        [*] Compile the kernel with debug info        [*]   Provide GDB scripts for kernel debuggin


Processor type and features ---->
    [] Randomize the address of the kernel image (KASLR)
  • 开始编译内核
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~/debug-kernel-source/linux-4.19.255]$ make -j 2.............
CRC 124cb347
Kernel: arch/x86/boot/bzImage is ready  (#1)

制作根文件系统

格式化根文件系统磁盘
  • 格式化根文件系统为ext4文件系统
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~/debug-kernel-source]$ dd if=/dev/zero of=rootfs.img bs=1M count=64// 格式化文件系统为ext4[root@ubuntu ~/debug-kernel-source]$ mkfs.ext4 rootfs.img 
// 挂在Ext文件系统到/root/debug-kernel-source/fs中[root@ubuntu ~/debug-kernel-source]$ mkdir fs[root@ubuntu ~/debug-kernel-source]$ sudo mount -t ext4 -o loop rootfs.img ./fs
busybox安装到文件系统
  • 下载busybox并进行基本配置
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~/debug-kernel-source]$ wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2[root@ubuntu ~/debug-kernel-source]$ tar -jxvf busybox-1.35.0.tar.bz2 


[root@ubuntu ~/debug-kernel-source]$ cd busybox-1.35.0
//执行安装菜单选项[root@ubuntu ~/debug-kernel-source/busybox-1.35.0]$ make menuconfig
// 选择编译安装选项如下的option,选择保存后退出
 Settings  --->
            [*] Build BusyBox as a static binary (no shared libs) // 执行安装[root@ubuntu ~/debug-kernel-source/busybox-1.35.0]$  sudo make install CONFIG_PREFIX=../fs[root@ubuntu ~/debug-kernel-source]$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
tmpfs                              392M  1.1M  391M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv   31G   14G   16G  46% /
tmpfs                              2.0G     0  2.0G   0% /dev/shm
tmpfs                              5.0M     0  5.0M   0% /run/lock
tmpfs                              2.0G     0  2.0G   0% /run/qemu
/dev/sda2                          2.0G  245M  1.6G  14% /boot
tmpfs                              392M  4.0K  392M   1% /run/user/1000
/dev/loop5                          56M   24K   52M   1% /root/debug-kernel-source/fs


// 添加busybox的配置到根文件系统[root@ubuntu ~/debug-kernel-source]$ mkdir ./fs/proc ./fs/dev ./fs/etc ./fs/home ./fs/mnt[root@ubuntu ~/debug-kernel-source]$ sudo cp -r ./busybox-1.35.0/examples/bootfloppy/etc/* ./fs/etc/
// 更改权限[root@ubuntu ~/debug-kernel-source]$ chmod -R 777 fs/

// 写在./fs系统,目前已经完成了busybox数据写入到根文件系统了[root@ubuntu ~/debug-kernel-source]$ umount ./fs

使用qemu-kvm启动内核

代码语言:javascript
代码运行次数:0
复制
// 终端内启动刚刚编译好的linux-4.19.255内核
// -kernel  指定内核
// -hda 指定启动系统的磁盘
// -append "root=/dev/sda console=ttyS0" 指定根文件系统 console=ttyS0 把QEMU的输入输出定向到当前终端上
// -nographic 非图形界面启动
// -s 是-gdb tcp::1234缩写,监听1234端口,在GDB中可以通过target remote localhost:1234连接

// 正常启动内核[root@ubuntu ~/debug-kernel-source]$ qemu-system-x86_64 -kernel /root/debug-kernel-source/linux-4.19.255/arch/x86_64/boot/bzImage  -hda /root/debug-kernel-source/rootfs.img  -append "root=/dev/sda console=ttyS0" -nographic


// 调试模式启动内核[root@ubuntu ~/debug-kernel-source]$ qemu-system-x86_64 -kernel /root/debug-kernel-source/linux-4.19.255/arch/x86_64/boot/bzImage  -hda /root/debug-kernel-source/rootfs.img  -append "root=/dev/sda console=ttyS0"  -s -S  -smp 1 -nographic

// 启动后输入poweroff关闭系统
/ # poweroff
  • gdb调试内核(在do_mount上打断点)
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~/debug-kernel-source]$ cd linux-4.19.255[root@ubuntu ~/debug-kernel-source/linux-4.19.255]$ lsarch        certs    crypto         firmware  init    Kconfig  LICENSES     mm               Module.symvers  samples   sound       usr      vmlinux-gdb.py
block       COPYING  Documentation  fs        ipc     kernel   MAINTAINERS  modules.builtin  net             scripts   System.map  virt     vmlinux.o
built-in.a  CREDITS  drivers        include   Kbuild  lib      Makefile     modules.order    README          security  tools       vmlinux[root@ubuntu ~/debug-kernel-source/linux-4.19.255]$ gdb ./vmlinux(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x000000000000fff0 in exception_stacks ()(gdb) br do_mount
Breakpoint 1 at 0xffffffff811d6c10: file fs/namespace.c, line 2748.(gdb) c
Continuing.

Breakpoint 1, do_mount (dev_name=0xffff8880074021a0 "devtmpfs", dir_name=0xffffffff822061a7 "/", type_page=0xffff8880074021b0 "devtmpfs", flags=32768, data_page=0xffff888007439000) at fs/namespace.c:27482748    {(gdb) bt#0  do_mount (dev_name=0xffff8880074021a0 "devtmpfs", dir_name=0xffffffff822061a7 "/", type_page=0xffff8880074021b0 "devtmpfs", flags=32768, 
    data_page=0xffff888007439000) at fs/namespace.c:2748#1  0xffffffff811d7ee9 in ksys_mount (dev_name=0xffff888007439000 "mode=0755", dir_name=0xffffffff822061a7 "/", type=0xffff8880074021b0 "devtmpfs", flags=32768, 
    data=<optimized out>) at fs/namespace.c:3041#2  0xffffffff815c4563 in devtmpfsd (p=0xffffc90000043f04) at drivers/base/devtmpfs.c:386#3  0xffffffff8107bb82 in kthread (_create=0xffff88800751cf00) at kernel/kthread.c:259#4  0xffffffff81c00205 in ret_from_fork () at arch/x86/entry/entry_64.S:415#5  0x0000000000000000 in ?? ()(gdb) 
  • 调试ext4文件系统
  • 添加磁盘并格式化为ext4
代码语言:javascript
代码运行次数:0
复制
[root@ubuntu ~/debug-kernel-source]$ dd if=/dev/zero of=ext4.img bs=1M count=64[root@ubuntu ~/debug-kernel-source]$ mkfs.ext4 ext4.img
  • 启动调试版本内核
代码语言:javascript
代码运行次数:0
复制
// 在一个会话A中 添加一个ext4文件系统,并启动内核完成[root@ubuntu ~/debug-kernel-source]$ qemu-system-x86_64 -kernel /root/debug-kernel-source/linux-4.19.255/arch/x86_64/boot/bzImage  -hda /root/debug-kernel-source/rootfs.img  -append "root=/dev/sda console=ttyS0"  -s -S  -smp 1 -nographic -hdb /root/debug-kernel-source/ext4.img
  • 执行mount动作
  • gdb调试文件系统
代码语言:javascript
代码运行次数:0
复制
// 启动另外一个会话B
// 正常启动内核等待内核启动完毕,完毕后会出现如下的图[root@ubuntu ~/debug-kernel-source/linux-4.19.255]$ gdb ./vmlinux(gdb) target remote localhost:1234

Remote debugging using localhost:1234
0x000000000000fff0 in exception_stacks ()(gdb) br do_mount
Breakpoint 1 at 0xffffffff811d6c10: file fs/namespace.c, line 2748.(gdb) c
Continuing.

Breakpoint 1, do_mount (dev_name=0xffff888006bfa0d0 "/dev/sdb", dir_name=0x7ffd8c40df8d "/mnt", type_page=0xffff888006433208 "ext3", flags=32768, data_page=0x0 <irq_stack_union>) at fs/namespace.c:27482748    {(gdb) bt#0  do_mount (dev_name=0xffff888006bfa0d0 "/dev/sdb", dir_name=0x7ffd8c40df8d "/mnt", type_page=0xffff888006433208 "ext3", flags=32768, data_page=0x0 <irq_stack_union>)
    at fs/namespace.c:2748#1  0xffffffff811d7ee9 in ksys_mount (dev_name=0x0 <irq_stack_union>, dir_name=0x7ffd8c40df8d "/mnt", type=0xffff888006433208 "ext3", flags=32768, data=<optimized out>)
    at fs/namespace.c:3041#2  0xffffffff811d7f4c in __do_sys_mount (data=<optimized out>, flags=<optimized out>, type=<optimized out>, dir_name=<optimized out>, dev_name=<optimized out>)
    at fs/namespace.c:3055#3  __se_sys_mount (data=<optimized out>, flags=<optimized out>, type=<optimized out>, dir_name=<optimized out>, dev_name=<optimized out>) at fs/namespace.c:3052#4  __x64_sys_mount (regs=<optimized out>) at fs/namespace.c:3052#5  0xffffffff81002103 in do_syscall_64 (nr=<optimized out>, regs=0xffffc900000eff58) at arch/x86/entry/common.c:293#6  0xffffffff81c00078 in entry_SYSCALL_64 () at arch/x86/entry/entry_64.S:238#7  0x0000000001fa02d0 in ?? ()#8  0x0000000001fa03e0 in ?? ()#9  0x00007ffd8c40df8d in ?? ()#10 0x0000000000000000 in ?? ()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 构建Linux内核调试步骤
  • 系统版本
  • 安装系统组件
  • 编译Linux内核源码
  • 制作根文件系统
    • 格式化根文件系统磁盘
    • busybox安装到文件系统
  • 使用qemu-kvm启动内核
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档