Linux-lab3: 基于Qemu/Busybox的内核跟踪调试

Linux内核编译与调试:从start_kernel到根文件系统

Linux内核的核心目录

init : 其中的main.c中的start_kernel函数是内核的起点

kernel : 主内核代码 (内核的内核)

mm : memory management

fs : file system,实现了文件系统

ipc : inter-process communication,进程通信

net : 实现网络,如TCP/IP协议栈

drivers: 设备驱动程序

lib : 库文件,因为内核无法使用C标准库函数

include :建立内核代码时所需的公共的头文件,它们是各种体系结构(例如:ARM/x86)共用的

调试过程

下载linux内核源代码并解压:

sudo apt install axel
axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar
cd linux-5.4.34

下载编译工具:

sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev         # 编译器大礼包
make defconfig     # 进行默认设置。每个新的内核版本都会带来一串新的选项,我们不需要在每次内核发布时升级我们的defconfig。[r1]
make -j$(nproc)    # 编译内核,时间较久
sudo apt install qemu    # install QEMU
qemu-system-x86_64 -kernel arch/x86/boot/bzImage # 使用qemu运行内核程序
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev # 这里相比上一个实验多了一个工具

在linux-5.4.34文件夹下:

make menuconfig

在UI中设置debug选项并关闭KASLR (kernel address space layout randomize,为提高内核安全性将kernel随机的加载到不同的物理地址运行。但是这一特性将导致实验中打断点失败)

UI使用技巧:按space选中[*]或取消选择

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

 返回cmd输入以下命令:

make -j$(nproc)
qemu-system-x86_64 -kernel arch/x86/boot/bzImage # 测试内核能不能正常加载运行

内核运行结果如下,由于没有文件系统,导致kernel panic。

 以下我们借助Busybox制作一个简易根文件系统,它能提供基本的用户态可执行程序。下载安装:

axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2
tar -jxvf busybox-1.31.1.tar.bz2
cd busybox-1.31.1
make menuconfig                    # 设置BusyBox
make -j$(nproc) && make install    # 编译BusyBox

编译过程:

 编译成功的提示:

 将相关文件复制到文件夹rootfs中:

mkdir rootfs
cd rootfs
cp ../busybox-1.31.1/_install/* ./ -rf
mkdir dev proc sys home    # 建立多个文件夹
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/

然后新建一个init脚本文件,内容如下:

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome MengningOS!"
echo "--------------------"
cd home
/bin/sh

然后给该脚本文件加可执行权限:

chmod +x init

打包成内存根文件系统镜像;

测试挂载根文件系统,可以发现启动完成后执行了init脚本。

使用以下命令打开或关闭虚拟机:

qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s        # 新窗口启动虚拟机
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s -nographic -append "console=ttyS0" # 使用纯命令行下启动虚拟机
killall qemu-system-x86_64  # 强行关闭虚拟机

在linux内核文件夹下启动一个新的终端,加载内核符号表,这样就能在命令行中调试内核代码了。

 也可以在VSCode中进行断点调试,但需要额外配置调试环境。

 

Linux内耗启动分析(main.c)

 1、内核起点start_kernel();

通过init_task()创建0号进程,它同样也是idle进程(用于维持内核态的无限循环),它能将该函数及其之前的一系列指令都划归到0号进程的进程环境中。

 2、内核初始化init_task();

lockdep_init()             // 内核依赖关系表和哈希表
boot_init_stack_canary():  // 栈保护,防止缓冲区攻击
tick_init():               // 启动时钟
boot_cpu_init():           // 激活CPU
setup_arch():              // 设置不同CPU的参数
trap_init():               // 硬件中断门
mm_init():                 // 内存分配
sched_init():              // 任务调度
init_IRQ():                // 中断向量
set_intr_gate;             // 中断门
set_system_trap_gate;      // 系统调用

3、rest_init()函数创建了kernel_init()和kthreadd两个线程,后者负责对其他内核线程管理调度。

 4、当根文件系统就绪后,kernel_init()函数通过do_execve系统调用执行/sbin/init文件,此时OS进入用户态。

 

参考资料

跟踪分析Linux内核启动过程

跟踪分析Linux内核的启动过程

孟宁 / linuxkernel

| WARNING: Backtrace (BB generated script): | #1: do_configure, /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/temp/run.do_configure.1013554, line 152 | #2: main, /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/temp/run.do_configure.1013554, line 156 ERROR: Task (/home/tisdk/tisdk/sources/oe-core/meta/recipes-devtools/qemu/qemu-native_8.2.2.bb:do_configure) failed with exit code '1' WARNING: qemu-native-8.2.2-r0 do_populate_lic: Could not copy license file /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2/COPYING to /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/license-destdir/x86_64/qemu-native/COPYING: [Errno 2] No such file or directory: '/home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2/COPYING' WARNING: qemu-native-8.2.2-r0 do_populate_lic: Could not copy license file /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2/COPYING.LIB to /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/license-destdir/x86_64/qemu-native/COPYING.LIB: [Errno 2] No such file or directory: '/home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2/COPYING.LIB' ERROR: qemu-native-8.2.2-r0 do_populate_lic: QA Issue: qemu-native: LIC_FILES_CHKSUM points to an invalid file: /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2/COPYING [license-checksum] ERROR: qemu-native-8.2.2-r0 do_populate_lic: QA Issue: qemu-native: LIC_FILES_CHKSUM points to an invalid file: /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2/COPYING.LIB [license-checksum] ERROR: qemu-native-8.2.2-r0 do_populate_lic: Fatal QA errors were found, failing task. ERROR: Logfile of failure stored in: /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/temp/log.do_populate_lic.1121716 ERROR: Task (/home/tisdk/tisdk/sources/oe-core/meta/recipes-devtools/qemu/qemu-native_8.2.2.bb:do_populate_lic) failed with exit code '1'
最新发布
07-30
<think>我们正在处理一个Yocto构建错误,涉及两个任务失败:`do_configure` 和 `do_populate_lic`。 首先,错误信息显示: 1. `qemu-native_8.2.2.bb:do_configure` 失败,退出码为1。 2. `do_populate_lic` 任务失败,因为找不到许可证文件(COPYING和COPYING.LIB),导致QA检查失败。 分析: - `do_configure` 失败是根本原因,因为配置失败导致后续任务(包括编译和安装)无法进行,从而没有生成许可证文件。 - `do_populate_lic` 失败是结果,因为配置失败后,源码目录可能没有正确设置或构建,导致许可证文件缺失。 因此,我们需要重点解决 `do_configure` 的失败。 步骤: 1. 查看 `do_configure` 的日志文件:`/home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/temp/log.do_configure.1013554`(注意:实际路径中的数字可能不同,但日志路径在错误信息中已给出)。 2. 根据日志分析配置失败的具体原因。 常见原因: - 依赖缺失:qemu在配置阶段可能需要某些主机上的开发包(如glib、zlib等)。 - 配置选项错误:配方中传递的配置参数可能存在问题。 - 权限问题:构建目录权限不足。 - 环境问题:环境变量设置不正确。 由于错误信息中未给出具体配置错误,我们需要查看日志。 但是,我们也可以尝试以下通用解决方法: 1. 清理并重新构建: ```bash bitbake -c cleansstate qemu-native bitbake qemu-native ``` 2. 确保主机满足构建要求:根据Yocto文档,安装必要的主机包(如ubuntu上): ```bash sudo apt-get install gcc g++ make libssl-dev libglib2.0-dev zlib1g-dev ``` 3. 检查配方中的配置选项:查看 `qemu-native_8.2.2.bb` 文件,特别是 `EXTRA_OECONF` 变量。 4. 手动运行配置步骤(在构建目录中): ```bash cd /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2 ./configure --help # 查看配置选项,然后尝试运行配方中使用的配置命令(从日志中获取) ``` 关于 `do_populate_lic` 的失败,在解决 `do_configure` 后应该会自动解决,因为许可证文件是源码自带的,如果源码解压正确就应该存在。如果源码解压后没有这些文件,可能是源码包问题。 注意:在构建过程中,如果 `do_configure` 失败,那么 `do_populate_lic` 任务也会失败,因为它在配置之后运行(但实际顺序可能因依赖关系而不同,不过通常配置失败后不会继续后续任务,但这里似乎触发了许可证检查)。 但是,错误信息显示在 `do_populate_lic` 任务中找不到许可证文件,这可能是由于配置失败导致源码目录没有正确生成?或者源码下载解压失败?需要检查 `do_unpack` 是否成功。 建议步骤: 1. 检查源码目录是否存在:`/home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/qemu-8.2.2`。 2. 如果不存在,则可能是 `do_unpack` 失败,需要检查下载和解压步骤。 3. 如果存在,检查该目录下是否有 `COPYING` 和 `COPYING.LIB` 文件。如果没有,可能是源码包问题;如果有,则可能是路径错误。 由于配方中 `LIC_FILES_CHKSUM` 指向这些文件,如果文件存在但路径不匹配,可能是配方中的路径设置错误。 但是,当前错误信息显示文件不存在,所以先解决 `do_configure` 失败的问题,再确认源码目录。 因此,我们首先解决配置错误。 由于没有具体的配置错误日志,我们只能提供一般性指导。如果用户能提供日志,可以进一步分析。 总结: 主要解决 `do_configure` 失败。清理状态,检查依赖,查看配置日志。 §§相关问题§§ 1. 如何查看Yocto构建任务的具体日志文件? 2. 在Yocto中,如何解决常见的配置(do_configure)失败问题? 3. 为什么在配置失败后会出现许可证文件缺失的错误? 4. 如何确保主机系统满足构建qemu-native的依赖要求? 5. 在Yocto配方中,LIC_FILES_CHKSUM的作用是什么?如何正确设置?</think>这个错误发生在 Yocto/OE 构建系统中,主要涉及两个任务失败:`qemu-native_8.2.2.bb:do_configure` 和 `do_populate_lic`。以下是详细分析和解决方案: ### 错误分析: 1. **`do_configure` 失败**(核心问题): - QEMU 的配置阶段失败(`qemu-native_8.2.2.bb:do_configure`) - 错误代码:`exit code &#39;1&#39;` - 可能原因: - 缺少主机依赖(如 Python、Ninja 等) - 配置选项冲突 - 构建目录权限问题 - 源码损坏或补丁应用失败 2. **`do_populate_lic` 失败**(衍生问题): - 因配置失败,无法找到许可证文件: - `/qemu-8.2.2/COPYING` - `/qemu-8.2.2/COPYING.LIB` - 触发 QA 错误:`LIC_FILES_CHKSUM points to an invalid file` - 根本原因是配置未完成导致源码未正确准备 ### 解决步骤: 1. **检查配置日志**: ```bash less /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/temp/log.do_configure.1013554 ``` 查找关键错误信息(如缺失依赖、配置中止位置) 2. **安装主机依赖**(常见解决方案): ```bash # Ubuntu/Debian 示例 sudo apt install ninja-build meson pkg-config libglib2.0-dev libpixman-1-dev ``` 3. **清理并重建**: ```bash bitbake -c cleansstate qemu-native bitbake -c cleanall qemu-native bitbake qemu-native ``` 4. **检查配方元数据**: - 确认 `qemu-native_8.2.2.bb` 中的配置选项: ```bitbake EXTRA_OECONF = " \ --disable-werror \ --enable-modules \ --enable-linux-user \ --disable-gtk --disable-vte \ ``` - 验证 `LIC_FILES_CHKSUM` 是否匹配源码: ```bitbake LIC_FILES_CHKSUM = "file://COPYING;md5=... \ file://COPYING.LIB;md5=..." ``` 5. **手动验证源码**: ```bash cd /home/tisdk/tisdk/build/arago-tmp-default-glibc/work/x86_64-linux/qemu-native/8.2.2/ ls qemu-8.2.2/COPYING* # 确认文件存在 ``` ### 预防措施: 1. 在 `local.conf` 中添加: ```bitbake LICENSE_FLAGS_ACCEPTED = "commercial" ``` 2. 定期更新层和配方: ```bash cd sources/oe-core && git pull ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值