文章目录

  • 编译内核
  • 下载qemu
  • 构建initramfs根文件系统
    • 1.编译Busybox
    • 2.生成initrd
  • 3.测试根文件系统
  • gdb调试内核
  • 参考文献

编译内核

# make menuconfig // 调整编译选项

在内核编译选项中,开启如下"Compile the kernel with debug info"

Kernel hacking —>
Compile-time checks and compiler options —>
[ ] Compile the kernel with debug info

示意图如下,利用键盘选中debug选项,然后敲"Y"勾选:

(以上是别人博客中找到,确实类似gcc编译要gdb得加-g,但是我按照默认安装最后也默认了允许调试,算是现在新版本的一个福音吧。不然就重新再编译将近一小时吧(不过不知道打了ccache这下要跑多久,闲了可以测试测试))

先检查自己之前编译的内核有没有该信息。

# grep CONFIG_DEBUG_INFO .config
CONFIG_DEBUG_INFO=y

下载qemu

qemu有两种安装方式,第一种是使用命令行直接下载安装,第二种是通过源码进行编译安装,推荐命令行直接下载。

开始直接编译到最后安装的时候要Nanja但是我的源下不了这个。

所以我采用了直接安装qemu

sudo apt-get install qemu

直接安装也是最方便省事的,依赖文件现在也打包好了似乎。

构建initramfs根文件系统

1.编译Busybox

  • https://busybox.net/ 下载并解压源码

  • wget https://busybox.net/downloads/busybox-1.34.0.tar.bz2
    

首先安装静态依赖,否则会有报错。

sudo apt-get install glibc-static -y

会发现ubuntu找不到软件。

参考1:https://blog.csdn.net/ShawnWang1994/article/details/88812573

参考2:https://blog.csdn.net/itas109/article/details/104226783

  • centos
sudo yum install glibc-static
  • ubuntu
sudo apt-get install libc6-dev
sudo apt-get install libc-dev-bin

解压压缩包后

make menuconfig

看上面的英文是按y表示确认,确认后[]内有*

退出,提示保存,选Yes

开始编译

make -j4
make install

make 期间会遇到许多的warning,不用管它,对安装影响不大。

此时可以在busybox-1.34.0/中看到生成的_install目录。通过下面的命令可以验证busybox是否安装正确:./busybox ls

2.生成initrd

首先将上一步生成的_install文件夹复制到其他位置。

cd ..

mkdir ramdisk

cd ramdisk

cp -r ../busy-1.34.0/_install/* .

设置初始化进程init(建立一个软链接,一定不能直接复制过去)

cd ramdiskln -s bin/busybox init

设置开机启动程序

首先,我们需要先设定一些程序运行所需要的文件夹。

mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin},dev}

init程序首先会访问etc/inittab文件,因此,我们需要编写inittab,指定开机需要启动的所有程序。

cd etc
vim inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

直接把这个文件权限拉满

chmod 777 inittab

编写系统初始化命令。

从inittab文件中可以看出,首先执行的是/etc/init.d/rcS脚本,因此,我们生成初始化脚本。

在此新建文件夹并编写脚本

mkdir init.d
cd init.d
vim rcS

内容如下

#!/bin/shmount proc
mount -o remount,rw /
mount -a
clear
echo "My Tiny Linux Start :D ......"

同样权限给拉满。chmod 777 rcS

在rcS脚本中,mount -a 是自动挂载 /etc/fstab 里面的东西,可以理解为挂在文件系统,因此我们还需要编写 fstab文件来设置我们的文件系统。

ramdisk/ect/创建文件fstab

# /etc/fstabproc            /proc        proc    defaults          0       0sysfs           /sys         sysfs   defaults          0       0devtmpfs        /dev         devtmpfs  defaults          0       0

至此,我们已经完成了RAM Disk中相关文件的配置,可以压缩生成文件镜像了。

cd ramdiskfind . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img

最后生成的initramfs.img就是我们的根文件系统。

3.测试根文件系统

我的编译好的内核在的路径/home/yan/linux-5.4.1/arch/x86_64/boot/bzImage

每个人要去看自己的内核编好的放哪里了。

busybox-1.34.0目录下:

qemu-system-x86_64 -kernel /home/yan/linux-5.4.1/arch/x86_64/boot/bzImage -initrd ../initramfs.img
  • -kernel 指定编译好的调试版内核;
  • -initrd 指定制作好的initramfs;

按Enter键后,就可以进入到文件系统中,运行命令输入ls /dev检查是否挂载成功。

关机输入poweroff

gdb调试内核

qemu-system-x86_64 -kernel /home/yan/linux-5.4.1/arch/x86_64/boot/bzImage -initrd ../initramfs.img -smp 2  -S -s

先使用命令启动qemu。

kernel 是指定一个大内核文件,当仁不让的是bzImage。
initrd 是指定一个 initrd.img文件,这个文件就是我们使用busybox生成的initramfs.img。
smp 可以从名字猜想,它是给qemu指定几个处理器,或者是几个线程。
gdb则是启动qemu的内嵌gdbserver,监听的是本地tcp端口1234—如果这样写: -gdb tcp:192.168.1.100:1234 ,似乎也是没问题的。
S 就是挂起gdbserver,让gdb remote connect it。
s 默认使用1234端口进行远程调试,和-gdb tcp::1234类似。
m 2048 指定内存大小为2048M

此时,开启另一个terminal,运行如下命令:

gdb /home/yan/linux-5.4.1/vmlinux (修改成自己的vmlinux路径)target remote:1234 (默认端口是1234,进行远程连接)b start_kernel (设置断点)c (continue 运行到断点处)

可以发现这次失败了。因为断点没有停下来。

经过一番查阅:启动加上nokaslr

即:

qemu-system-x86_64 -kernel /home/yan/linux-5.4.1/arch/x86_64/boot/bzImage -initrd ../initramfs.img -smp 2  -S -s -append nokaslr

原因是kaslr开启随机地址,这样会导致 gdb 断点不能命中。加入nokaslr 参数,防止内核起始地址随机化,gdb断点就能找到了。

另外有说法老版本存在bug:打断点的时候使用hb start_kernel即可。不过我是关了随机地址可以,硬件断点也没用。

这次成功啦!

继续实验:

(gdb) target remote:1234
Remote debugging using :1234
0x000000000000fff0 in entry_stack_storage ()
(gdb) b register_filesystem
Breakpoint 1 at 0xffffffff812f8ff0: file fs/filesystems.c, line 73.
(gdb) c
Continuing.Thread 1 hit Breakpoint 1, register_filesystem (fs=0xffffffff82720180 <sysfs_fs_type>) at fs/filesystems.c:73
73  {

可以看到内核此时停住了。gdb这下可以调试内核了!

参考文献

https://blog.csdn.net/jasonLee_lijiaqi/article/details/80967912

https://blog.didiyun.com/index.php/2020/08/03/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8cgdb-qemu%E8%B0%83%E8%AF%95linux%E5%86%85%E6%A0%B8%E6%A8%A1%E5%9D%97/

https://www.ebpf.top/post/qemu_gdb_busybox_debug_kernel/

qemu+gdb调试linux内核相关推荐

  1. qemu debug linux内核,在QEMU环境中使用GDB调试Linux内核

    简介 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试.其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qem ...

  2. 利用QEMU+GDB搭建Linux内核调试环境

    前言 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试. 其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qe ...

  3. elipse调试linux内核,debug eclipse cdt + qemu虚拟机调试linux内核

    debug eclipse cdt + qemu虚拟机调试linux内核 (17页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.90 积分 A scr ...

  4. Vmware+gdb调试Linux内核——工欲善其事,必先利其器

    今天我最终忍受不了qemu的低速跟不可理喻的各种bug,開始寻找新的调试内核的方法.然后想到了Vmware,那么成熟的虚拟机怎么可能调试不了内核.于是尝试了一番,发现结果很的棒!所以立刻奋笔疾书.把这 ...

  5. 使用GDB调试Linux内核空指针问题

    1.概述 在Linux内核开发中,我们会经常遇到访问空指针导致内核Oops或panic.遇到这种问题,需要先定位出是哪一个函数.哪一个变量导致的异常.通常情况下,Linux内核会打印出异常时的栈.模块 ...

  6. eclipse 调试linux 内核

    搭建Eclipse+QEMU+GDB调试Linux Kernel环境 0.前言 本文讲述搭建环境的关键环节,相应的工具及版本如下: JDK:1.6.0_45 Eclipse:eclipse-cpp-k ...

  7. linux问号符号,调试linux内核时gdb中的问号符号4.10

    我想从linux内核中的函数start_kernel()调试linux内核.调试linux内核时gdb中的问号符号4.10 这基本上就是我已经做了 从kernel.org 下载4.10内核源提取源后: ...

  8. kgdb调试linux内核以及驱动模块

    kgdb调试linux内核以及驱动模块 本文将简要描述如何配置kgdb进行内核以及驱动模块调试,以嵌入式开发为例,但同样对于其他有需要调试kernel有一定的参考价值.本文实验环境为qemu搭建的ri ...

  9. 使用交叉编译工具链编译并调试linux内核

    内核源码的github地址 现在之后进入到目录之中 编译之前的准备工作:安装一些软件 sudo apt-get install qemu libncurses5-dev gcc-arm-linux-g ...

最新文章

  1. pc 页面在移动端怎么获取放大倍数、_百度移动搜索开放适配服务的3种方法
  2. Codeforces Round #476 (Div. 2) A. Paper Airplanes
  3. H265的国标PS流打包
  4. Spring框架整合JUnit单元测试
  5. Linux下动态库使用小结
  6. com.sun.jersey.api.client.UniformInterfaceException:returned a response status of 403
  7. 控制div的大小自适应_干货 | 浅谈模糊自适应PID控制
  8. 共享文件服务器密码更换,服务器共享文件密码
  9. python 拍照搜题_大学慕课2020用Python玩转数据答案搜题公众号
  10. Train Problem I(STL)基本运用stack
  11. cadence设计运算放大器_「好设计论文」一种用于高精度DAC的实用型CMOS带隙基准源...
  12. 5053刷奥迪Q5隐藏功能
  13. PHP开发环境phpnow的详细安装步骤
  14. ZooKeeper JMX enabled by default
  15. MPQ文件结构和Partial MPQ文件结构
  16. Maven详解【Idea搭建Maven项目、Maven常用指令、Maven的传递性和依赖性、排除依赖】
  17. 【运营】运营网课之活动运营
  18. CCD视觉检测设备如何选择光源
  19. CentOS镜像介绍及下载
  20. Excel粘贴长文本数字 精度丢失

热门文章

  1. [随时跳槽的能力]才是打工人最重要的能力
  2. 如何使用IAR,以及新建项目,参考善学坊,IAR版本10.10.1
  3. c#学习笔记05-treeview中添加图标
  4. 有关“吃”的十大健康杀手
  5. 为什么编程时间从1970年1月1日开始?
  6. html table清空数据,javascript清空table表格的方法
  7. expect常见用法
  8. 微信爬爬猫---公众号文章抓取代码分析
  9. android双亲委派机制,3分钟了解Java双亲委派机制
  10. 团队管理之—— 稳定性(一):如何应对事故并做好复盘?