文章目录

  • 编译内核
  • 下载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. 网络正常,但是网络图标上有黄色的三角图标
  2. 机器人编程语言python-10大热门机器人编程语言,你掌握了哪种?
  3. edem颗粒替换_EDEM后处理问题的大汇总,方便易懂!
  4. Ubuntu-Python2.7安装 scipy,numpy,matplotlib
  5. 区域锁(Scoped locking)
  6. 计算机系统结构怎么提高代码效率,北邮 计算机系统结构 实验报告(全部)指令流水线相关性分析 DLX 处理器程序设计 代码优化.doc...
  7. (3.5)HarmonyOS鸿蒙上下左右方向滑动
  8. Confluence 6 考虑使用自定义 CSS
  9. html中如何计算图片的像素,html – 浏览器的1px计算问题(子像素问题)
  10. Objective-C 方法重载 - Selector 标识起决定作用
  11. 阿里负载均衡,配置中间证书问题(在starcom申请免费DV ssl)
  12. bios开发 c语言,BIOS开发环境
  13. linux怎样打开终端命令,Linux命令-初学者入门之打开终端
  14. 编写MQTT客户端程序——python
  15. php 发送curl跨域请求,php跨域传输(curl)
  16. 高职计算机专业英语说课ppt,专业英语说课.ppt
  17. python爬取加密qq空间_python+selenium+requests爬取qq空间相册时遇到的问题及解决思路...
  18. Pycharm报错:AttributeError: ‘NoneType‘ object has no attribute ‘_gdal‘的解决办法
  19. 沙漠 草原 湖泊 羊群 骆驼(2)
  20. OpenGL基础知识(四)

热门文章

  1. vue3.0中使用render渲染函数渲染组件或标签
  2. eclipse中使代码快速对齐的快捷键
  3. python线程退出或应用程序请求_Python 线程和进程
  4. 基于SSM的分布式网络商城系统设计与实现
  5. 不断进阶:从“学渣”到P10,一位阿里工程师的逆袭故事
  6. 2022javascript面试题
  7. loadView、viewDidLoad及viewDidUnload的关系(李明杰老师)
  8. linux终端中超级用户用( )符号,Linux系统及应用-中国大学mooc-题库零氪
  9. 技术雪球里的小度,向内寻找答案
  10. # 个人日记-书籍《晚安·夜风相伴》读后感-20210816