内核实验(一):使用QEMU+GDB断点调试Linux内核代码

news/2024/11/6 21:45:11/

文章目录

  • 一、篇头
  • 二、环境配置
    • 2.1 安装QEMU
    • 2.2 安装编译工具链
  • 三、编译内核
    • 3.1 编译配置
    • 3.2 编译
  • 四、GDB断点调试
    • 4.1 启动内核
    • 4.2 GDB远程连接
  • 五、 附录
    • 1. 查看内核版本号
    • 2. 编译器 gnueabi和gnueabihf的区别

一、篇头

日常工作中对于内核的调试,大部分情况下只能使用printk来追加打印。而如果只是学习内核代码的话,则可以借助QEMU虚拟机+GDB的配置,来做到断点调试,同时又不需要额外购置任何设备,例如开发板、JTAG等等。

二、环境配置

2.1 安装QEMU

$ sudo apt-get install qemu-system-arm

2.2 安装编译工具链

  • 下载地址:https://releases.linaro.org/components/toolchain/binaries/
  • 本文采用的linux kerenl源码为 4.0版本,其支持的最高工具链版本为 gcc-linaro-5.x.x 版本
# (1)下载 gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz 版本
wget https://releases.linaro.org/components/toolchain/binaries/5.5-2017.10/arm-linux-gnueabi/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz# (2)解压到 home/szhou/works/test_tools/# (3)解压后 export 路径
export CROSS_COMPILE=/home/szhou/works/test_tools/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-

三、编译内核

3.1 编译配置


szhou@bc01:~/works/linuxkernel_4.0$ export ARCH=arm
szhou@bc01:~/works/linuxkernel_4.0$ export CROSS_COMPILE=/home/szhou/works/test_tools/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-
szhou@bc01:~/works/linuxkernel_4.0$ make vexpress_defconfigHOSTCC  scripts/basic/fixdepHOSTCC  scripts/kconfig/conf.oSHIPPED scripts/kconfig/zconf.tab.cSHIPPED scripts/kconfig/zconf.lex.cSHIPPED scripts/kconfig/zconf.hash.cHOSTCC  scripts/kconfig/zconf.tab.oHOSTLD  scripts/kconfig/conf
arch/arm/Kconfig:1399:warning: 'HZ_FIXED': number is invalid
arch/arm/Kconfig:1400:warning: 'HZ_FIXED': number is invalid
#
# configuration written to .config
#
szhou@bc01:~/works/linuxkernel_4.0$ 

3.2 编译

#(1) 编译命令
szhou@bc01:~/works/linuxkernel_4.0$ make -j24#(2) 编译成功AS      arch/arm/boot/compressed/lib1funcs.oAS      arch/arm/boot/compressed/ashldi3.oAS      arch/arm/boot/compressed/bswapsdi2.oLD [M]  mm/kmemleak-test.koAS      arch/arm/boot/compressed/piggy.gzip.oLD      arch/arm/boot/compressed/vmlinuxOBJCOPY arch/arm/boot/zImageKernel: arch/arm/boot/zImage is ready

四、GDB断点调试

4.1 启动内核

下面命令执行后,其启动QEMU虚拟机并加载了所编译的内核镜像,同时通过大小S参数,会开启GDB远程调试服务,并且让内核的启动冻住,等待GDB客户端对其进行调试。

  • 参数 -S:表示QEMU虚拟机会冻结CPU,直到远程的GDB输入相应的控制命令。
  • 参数 -s:表示在1234端口接受GDB的调试连接。
qemu-system-arm -nographic -M vexpress-a9 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -S -s

4.2 GDB远程连接

另外启动一个终端,如下操作,如下图所示,内核启动后停留在了start_kernel函数入口处

$ cd /works/linuxkernel_4.0
$ gdb-multiarch --tui vmlinux
(gdb) set architecture arm        <= 设置GDB为ARM架构
(gdb) target remote localhost:1234   <= 通过1234端口远程连接到QEMU平台
(gdb) b start_kernel           <= 在内核的start_kernel处设置断点
(gdb) c                                 <= 继续运行,如下图所示,内核启动后停留在了start_kernel函数入口处

image


五、 附录

1. 查看内核版本号

szhou@bc01:~/works/$ cat /proc/version
Linux version 5.19.0-35-generic (buildd@lcy02-amd64-020) (x86_64-linux-gnu-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #36~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 17 15:17:25 UTC 2

2. 编译器 gnueabi和gnueabihf的区别

  • gcc-arm-linux-gnueabi – The GNU C compiler for armel architecture
  • gcc-arm-linux-gnueabihf – The GNU C compiler for armhf architecture

可见这两个交叉编译器适用于armel和armhf两个不同的架构, armel和armhf这两种架构在对待浮点运算采取了不同的策略(有fpu的arm才能支持这两种浮点运算策略)
其实这两个交叉编译器只不过是gcc的选项-mfloat-abi的默认值不同. gcc的选项-mfloat-abi有三种值soft,softfp,hard(其中后两者都要求arm里有fpu浮点运算单元,soft与后两者是兼容的,但softfp和hard两种模式互不兼容):
soft : 不用fpu进行浮点计算,即使有fpu浮点运算单元也不用,而是使用软件模式。
softfp : armel架构(对应的编译器为gcc-arm-linux-gnueabi)采用的默认值,用fpu计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算。
hard : armhf架构(对应的编译器gcc-arm-linux-gnueabihf)采用的默认值,用fpu计算,传参数也用fpu中的浮点寄存器传,省去了转换, 性能最好,但是中断负荷高。
原文: arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别


http://www.ppmy.cn/news/358979.html

相关文章

随机池化(Stochastic Pooling)

前言 CNN中卷积完后有个步骤叫pooling, 在ICLR2013上&#xff0c;作者Zeiler提出了另一种pooling手段(最常见的就是mean-pooling和max-pooling)&#xff0c;叫stochastic pooling。只需要对Feature Map中的元素按照其概率值大小随机选择&#xff0c;元素选中的概率与其数…

内核实验(二):自定义一个迷你Linux ARM系统,基于Kernel v5.15.102, Busybox,Qemu

文章目录 一、篇头二、内核部分2.1 源码下载2.1.1 官网2.1.2 镜像站点2.1.3 代码下载 2.2 编译2.2.1 设置工具链2.2.2 配置2.2.3 make2.2.4 编译成功 三、busybox部分3.1 源码下载3.2 编译3.2.1 配置3.2.3 编译3.2.4 查看编译结果 四、制作根文件系统4.1 回顾busybox4.2 修改bu…

BC1.2

► BC1.2规范颁布之前 在2007年第一个电池充电规范颁布之前&#xff0c;尝试为电池充电本质上是一种冒险——结果非常难以预测。当2000年 出现USB 2.0时&#xff0c;外设默认吸收100mA电流&#xff0c;除非明确协商将电流增大至最高500mA。如果总线上经过一段延迟后 没有数据活…

Fabric

1 安装Go、docker、docker-compose 1.1 安装Go 获取go的安装包并解压到/usr/local文件夹下&#xff1a; sudo wget -P /usr/local https://studygolang.com/dl/golang/go1.15.linux-amd64.tar.gz cd /usr/local sudo tar -zxvf go1.15.linux-amd64.tar.gz添加环境变量 vim …

BCC入门

简介 BPF编译器集合&#xff08;BPF Compiler Collection&#xff0c;简称BCC&#xff09;。项目地址https://github.com/iovisor/bcc&#xff0c;是一个用于创建高效内核跟踪和操作程序的工具包&#xff0c;包括几个有用的工具和示例。它利用了扩展的 BPF&#xff08;伯克利包…

【NLP】第3章 微调 BERT 模型

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

内核实验(三):编写简单Linux内核模块,使用Qemu加载ko做测试

文章目录 一、篇头二、QEMU&#xff1a;挂载虚拟分区2.1 创建 sd.ext4.img 虚拟分区2.2 启动 Qemu2.3 手动挂载 sd.ext4.img三、实现一个简单的KO3.1 目录文件3.2 Makefile3.3 编译3.3.1 编译打印3.3.2 生成文件 3.4 检查&#xff1a;objdump3.4.1 objdump -dS test\_1.ko3.4.2…

B001_简介篇

&#x1f3c6;一、Oracle的历史和发展 Oracle公司成立于1977年&#xff0c;由拉里埃里森&#xff08;Larry Ellison&#xff09;、鲍勃明特&#xff08;Bob Miner&#xff09;和埃德奥茨&#xff08;Ed Oates&#xff09;共同创立。起初&#xff0c;公司的主要业务是开发和销售…