QEMU 和 GDB 调试 Linux 内核

news/2025/2/1 3:27:37 标签: linux

使用 QEMU 和 GDB 调试 Linux 内核是一种非常强大的方法,可以帮助开发人员调试和分析内核的行为。下面将详细介绍如何设置和使用 QEMU 和 GDB 来调试 Linux 内核。

环境准备

::: tip 系统环境

  • 22.04.3-Ubuntu
  • gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
  • GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1 :::
编译 Linux 内核源码

# 获取 Linux 内核源码
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.10.6.tar.xz
# 解压
tar -xvf linux-6.10.6.tar.xz
cd linux-6.10.6

# 配置内核(使用默认配置)
make defconfig #运行结束生成 .config 文件在当前目录

# 生成调试符号并编译内核
make -j$(nproc) vmlinux

# 拷贝编译好的镜像备用
cp vmlinux ../
cp arch/x86/boot/bzImage ../

::: tip

  • vmlinux: 一个包含调试符号的未压缩内核映像,GDB 调试时会用到它,在当前目录linux-6.10.6
  • bzImage: 编译后的镜像 bzImage, 路径: linux-6.10.6/arch/x86/boot/bzImage :::
启动文件系统制作

wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xvf busybox-1.36.1.tar.bz2
cd busybox-1.36.1

make menuconfig
#-> Settings
# --- Build Options
#  [*] Build static binary (no shared libs) #进行静态编译 (CONFIG_STATIC)

# 安装完成后生成的相关文件会在 _install 目录下
make && make install   
#busybox-1.36.1/_install
cd _install 
mkdir proc
mkdir sys

# init 为内核启动的初始化程序, 内容在下面
vim init 
# 必须设置成可执行文件
chmod +x init  

# 打包启动的文件系统
find . | cpio -o --format=newc > ../../rootfs.img

::: tip init 文件内容

#!/bin/sh
echo "{==DBG==} INIT SCRIPT"
mkdir /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mount -t tmpfs none /tmp

mdev -s 
echo -e "{==DBG==} Boot took $(cut -d' ' -f1 /proc/uptime) seconds"

# normal user
setsid /bin/cttyhack setuidgid 1000 /bin/sh

:::

安装 QEMU

apt install qemu qemu-utils qemu-kvm virt-manager libvirt-daemon-system libvirt-clients bridge-utils

使用 QEMU 启动内核

::: tip

  • 确保已经安装QEMU
  • 确保以下文件准备好:
    • rootfs.img
    • bzImage
    • vmlinux :::

使用 QEMU 启动内核,并开启 QEMU 的 GDB 远程调试功能。

#ls 当前目录文件
#busybox-1.36.1 
#busybox-1.36.1.tar.bz2 
#rootfs.img
#bzImage
#vmlinux  
#linux-6.10.6 
#linux-6.10.6.tar.xz

qemu-system-x86_64 -kernel ./bzImage -initrd  ./rootfs.img -append "nokaslr console=ttyS0" -s -S -nographic

::: tip 参数说明

  • -kernel ./bzImage:指定启用的内核镜像;
  • -initrd ./rootfs.img:指定启动的文件系统;
  • -append "nokaslr console=ttyS0" :附加参数,其中 nokaslr 参数必须添加进来,防止内核起始地址随机化,这样会导致 gdb 断点不能命中;
  • -s :监听在 gdb 1234 端口;
  • -S :表示启动后就挂起,等待 gdb 连接;
  • -nographic:不启动图形界面,调试信息输出到终端与参数 console=ttyS0 组合使用 :::

此时,QEMU 已经启动并等待 GDB 的连接,CPU 被暂停。

使用 GDB 调试内核

在另一个终端中启动 GDB,加载 vmlinux 文件(未压缩的内核映像),以便使用调试符号。

gdb vmlinux

在 GDB 中,使用 target remote 命令连接到 QEMU 提供的 GDB 服务器:

(gdb) target remote :1234

此时,GDB 已经连接到 QEMU,并可以控制虚拟机的执行。可以在内核的特定位置设置断点,并开始调试。例如,可以设置断点在 start_kernel 函数:

(gdb) b start_kernel

然后使用 continue 命令继续运行内核:

(gdb) c

当内核运行到 start_kernel 时,GDB 会暂停并命中断点,接下来你可以逐步执行代码 (step 或 next 命令),查看变量的值等。

常用 GDB 命令

  • b <function>:在函数入口处设置断点。
  • b *<address>:在特定内存地址设置断点。
  • info breakpoints:查看当前设置的断点。
  • c:继续执行程序,直到下一个断点。
  • step:单步执行代码,进入函数内部。
  • next:单步执行代码,跳过函数调用。
  • print <variable>:打印变量的值。
  • x/<n> <address>:查看指定地址的内存内容。

::: important 注意事项

  • 内核编译时需要启用调试符号 (.config 文件CONFIG_DEBUG_INFO=y)。
  • QEMU 的 -s 和 -S 参数用于设置 GDB 远程调试的端口和暂停启动。 :::

参考:

  • 官方文档
  • 其他资料1
  • 其他资料2

http://www.niftyadmin.cn/n/5838982.html

相关文章

数学建模算法汇总(全网最全,含matlab案例代码)

数学建模常用的算法分类 全国大学生数学建模竞赛中&#xff0c;常见的算法模型有以下30种&#xff1a; 最小二乘法数值分析方法图论算法线性规划整数规划动态规划贪心算法分支定界法蒙特卡洛方法随机游走算法遗传算法粒子群算法神经网络算法人工智能算法模糊数学时间序列分析马…

PyTorch 与 Python 版本对应关系

PyTorch 支持多个 Python 版本&#xff0c;但不同版本的 PyTorch 可能对 Python 版本有不同的要求。一般来说&#xff1a; PyTorch 与 Python 版本对应关系 PyTorch 版本支持的 Python 版本2.2.x3.8 - 3.122.1.x3.8 - 3.112.0.x3.8 - 3.101.13.x3.7 - 3.101.12.x3.7 - 3.101.…

7层还是4层?网络模型又为什么要分层?

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 一、为什么要分层 \quad 网络通信的复杂性促使我们需要一种分层的方法来理解和管理网络。就像建筑一样&#xff0c;我们不会把所有功能都混在一起…

举例说明python单利模式的必要性

单例模式的核心目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。这种设计模式在某些场景下非常必要&#xff0c;尤其是在需要严格控制资源访问、共享状态或配置管理的场景中。下面通过几个具体的例子来说明Python中单例模式的必要性。 1. 数据库…

python-leetcode-填充每个节点的下一个右侧节点指针 II

117. 填充每个节点的下一个右侧节点指针 II - 力扣&#xff08;LeetCode&#xff09; """ # Definition for a Node. class Node:def __init__(self, val: int 0, left: Node None, right: Node None, next: Node None):self.val valself.left leftself.r…

基于微信小程序的辅助教学系统的设计与实现

标题:基于微信小程序的辅助教学系统的设计与实现 内容:1.摘要 摘要&#xff1a;随着移动互联网的普及和微信小程序的兴起&#xff0c;基于微信小程序的辅助教学系统成为了教育领域的一个新的研究热点。本文旨在设计和实现一个基于微信小程序的辅助教学系统&#xff0c;以提高教…

网站快速收录:利用新闻源的优势

本文来自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/23.html 网站快速收录的过程中&#xff0c;利用新闻源的优势可以显著提升收录速度和效果。以下是对如何利用新闻源优势实现网站快速收录的详细阐述&#xff1a; 一、新闻源的优势 传播速度…

C++ deque(1)

1.deque介绍 deque的扩容不像vector那样麻烦 直接新开一个buffer 不用重新开空间再把数据全部移过去 deque本质上是一个指针数组和vector<vector>不一样&#xff0c;vector<vector>本质上是一个vector对象数组&#xff01;并且vector<vector>的buffer是不一…