Linux内核调试之qemu配合GDB调试linux内核

操作环境:x86-64位linux操作系统(特别注意是64位,如果你是32位则修改相应的安装参数就可以了,多少位是可选的,本文以Ubuntu14.04)、GCC、GDB、QEMU、./configure与make的依赖(有的系统自带了,如果没带那就坑了)

注意事项:严格注意自己的操作系统环境,缺啥补啥,并且要对应好环境,别拿32位跟64的配置搞错,其它的也自己注意一下,理解每个步骤是干啥。

修改记录:有的朋友反应说没有最小文件系统,所以装了一个busybox(1.25.0版本)

目录

目录

一、环境配置

二、编译linux内核

2.1 下载与编译内核

2.2 各种问题的解决方式

三、最小文件系统busybox(1.25.0版本)

3.1  源码编译

 3.2  生成initrd

3.3  测试根文件系统

四、qemu的使用

参考资料:


 

一、环境配置

在虚拟机上搭建Ubuntu就不介绍了,比较简单,如果不会可以参考VMWare安装Ubuntu,不过别在国外的源下载Ubuntu,速度很慢,推荐国内镜像

安装成功后得配置各种坑逼的环境,如果之后的步骤中遇到问题别急,缺什么补什么就可以了。大致的环境如下:

#建议最好新建一个文件夹,存放这些配置,网上用的比较多的是LinuxKernel,在/home/某用户 目录下创建
#如我的就是:
cd /home/tangff
mkdir LinuxKernel
cd LinuxKernel

sudo apt-get install texinfo

#没有这个make menuconfig会出错
sudo apt-get install libncurses5-dev
sudo apt-get install m4  #有的系统是sudo apt-get install 123m4
sudo apt-get install flex
sudo apt-get install bison

安装GCC环境

#必须要更新一下,不更新会出各种问题
sudo apt-get update
sudo apt-get install gcc

二、编译linux内核

2.1 下载与编译内核

#下载解压
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.20.4.tar.xz
xz -d linux-4.20.4.tar.xz
tar -zxvf linux-4.20.4.tar

#编译安装
cd linux-4.20.4
make mrproper 		//清除编译过程中产生的所有中间文件
make clean 	 	//清除上一次产生的编译中间文件
make menuconfig	//图形化界面,方便选择一些功能

就会出现如何配置界面:

 

找到kernel hacking,选中进去再选择 Compile-time checks and compiler options,选择后如下图:

图中的“*”代表选中,用空格键可以选择,上图箭头就是需要选择的选后,然后可以用键盘的上的左右键选择保存再退出,这样配置完成了。

编译,会花费比较长的时间:

#-jN会make得更快,N为核心数量的两倍,我给这台虚拟机配置了一个核心,所以是2
make -j2

2.2 各种问题的解决方式

实际上基本上都有提示,缺啥补啥

scripts/kconfig/conf  --syncconfig Kconfig
Makefile:940: *** "Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel".  Stop.

#解决方案
apt-get install libelf-dev


scripts/sign-file.c:25:30: fatal error: openssl/opensslv.h: No such file or directory
compilation terminated.
scripts/Makefile.host:90: recipe for target 'scripts/sign-file' failed
make[1]: *** [scripts/sign-file] Error 1
Makefile:1049: recipe for target 'scripts' failed
make: *** [scripts] Error 2
--------------------- 

#解决方案
apt-get install libssl-dev
make mrproper //清除编译过程中产生的所有中间文件

假如你之前也编译过内核,而你没有用此命令去清除之前编译产生的.o文件,那么,在make的时候,可能就会产生干扰。

三、最小文件系统busybox(1.25.0版本)

3.1  源码编译

下载源码地址,下载后解压

cd busybox-1.25.0

make clean

make defconfig

make menuconfig

在menuconfig中修改配置,使用静态编译busybox,否则在程序运行期间需要对相应的库进行动态加载,那么在根文件系统中则需要提供其所需的共享库。

-> Busybox Settings 

    -> Build Options  

        [*] Build BusyBox as a static binary (no shared libs)         

 跟前面的一样,选中这个就OK了。

make -j4
sudo make install

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

 3.2  生成initrd

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

 cd ..

 mkdir ramdisk

 cd ramdisk

#后面的.不要忘记
 cp -r ../busy-1.25.0/_install/*  .

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

#进入刚刚创建的ramdisk目录
cd ramdisk

ln -s bin/busybox init

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

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

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

cd etc
vim inittab

 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 +x inittab

编写系统初始化命令 

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

#在ramdisk/etc目录下
mkdir init.d
cd init.d
vim rcS

rcS文件的内容如下所示: 


#!/bin/sh

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

赋予可执行权限 

chmod +x rcS

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

cd ramdisk/etc/

vim fstab

 fstab文件内容如下:


# /etc/fstab


proc            /proc        proc    defaults          0       0

sysfs           /sys         sysfs   defaults          0       0

devtmpfs        /dev         devtmpfs  defaults          0       0

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

cd ramdisk

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

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

3.3  测试根文件系统

先按照步骤4安装qemu。然后再运行:

#注意自己的Linux编译的路径跟生成的initramfs.img路径
#本示例的以下语句在 ramdisk目录下运行
qemu-system-x86_64 -kernel Linux-4.6.2/arch/x86_64/boot/bzImage -initrd ../initramfs.img

这时qemu上会显示出内核打印的各种信息,最终显示:

按Enter键后,就可以进入到文件系统中,运行命令 "ls /dev",如下如果能够成功显示目录下所有文件,则文件系统挂载成功。

四、qemu的使用

#当然,有特殊需求可以编译安装,编译安装也很简单,这里介绍直接安装
sudo apt-get install qemu

#在linux源码目录下运行以下指令,如果安装了最小文件系统,那么可以运行后面的指令
qemu-system-x86_64 -S -kernel arch/x86_64/boot/bzImage -m 1024

qemu-system-x86_64 -kernel linux源码目录/arch/x86_64/boot/bzImage -initrd ../initramfs.img -smp 2 -S -s -m 1024

#其中特别注意第一个选项是我的64操作系统,-kernel后跟的是编译自动生成的镜像文件,我这里也是调试64位
#如果有其它需求,可以做相应的修改

qemu-system-x86_64的参数比较多,这里简单说下: 
  -kernel 是指定一个大内核文件,当仁不让的是bzImage。 
  -initrd 是指定一个 initrd.img文件,这个文件就是我们使用busybox生成的initramfs.img。 
  -smp 可以从名字猜想,它是给qemu指定几个处理器,或者是几个线程<嗯,大概意思就thread吧>。 
  -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

接下来会出现一个黑色的界面,ctrl+alt+1 与 ctrl+alt+2可以切换,前者是屏幕输出,后者是qemu控制台,运行起来后是黑屏,我们要切换到控制台,用鼠标点击窗口,然后ctrl+alt+2,如下图所示输入,然后回车,ctrl+alt+1切换回来,ctrl+alt切出鼠标。记得输入下图中的指令。

在另一个终端中
 

cd linux-4.20.4/
gdb vmlinux

(gdb) target remote localhost:1234

 好了可以正式开始你的调试之旅了,可以先

#设置断点
b start_kernel

然后就是正常的GDB调试了。

后记:qemu实际上是一个仿真环境,有的人还会去搭建一个最小文件系统来模拟linux内核的文件系统,大家有更多需求的可以在文中的基础上去搭建。如果因为环境冲突搭不起的,却又没有其它需求的,可以用实验楼的实验环境。

参考资料:

https://blog.csdn.net/gdt_a20/article/details/7231652

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

https://blog.csdn.net/xiao_jj_jj/article/details/82755954

https://www.cnblogs.com/pingandezhufu/p/4392297.html

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 VS Code 中使用 GDB 调试 Linux 内核源码的步骤如下: 1. 安装插件:首先需要在 VS Code 中安装插件 "Native Debug",该插件提供了对 GDB 的支持。 2. 配置工作目录:在 VS Code 中打开 Linux 内核源码所在的目录,并在 VS Code 中打开一个终端,进入到内核源码目录中。 3. 生成内核配置:使用 "make menuconfig" 命令生成内核配置,可以根据需要选择需要编译的内核模块。 4. 编译内核:使用 "make -j4" 命令编译内核,其中 "-j4" 表示使用 4 个线程进行编译。 5. 启动 GDB:在终端中输入 "gdb ./vmlinux" 命令启动 GDB,其中 "vmlinux" 是内核文件名。 6. 配置 GDB:在 GDB 中输入以下命令进行配置: * "set architecture i386:x86-64:intel":设置架构为 x86-64。 * "set sysroot /usr/src/linux":设置系统根路径为内核源码路径。 * "file vmlinux":设置内核文件名。 * "target remote :1234":连接到远程目标,端口号为 1234。 7. 启动虚拟机:在另一个终端中启动虚拟机,使用以下命令: ``` qemu-system-x86_64 -s -S -kernel arch/x86/boot/bzImage -nographic ``` 其中 "-s" 表示开启 GDB 服务器,"-S" 表示启动时暂停虚拟机,"-kernel" 指定内核文件名,"-nographic" 表示不使用图形界面。 8. 调试内核:在 GDB 中输入 "continue" 命令,让虚拟机继续执行,即可开始调试内核。 在调试过程中,可以使用 GDB 提供的各种命令进行调试,例如 "break" 设置断点,"step" 单步执行,"print" 打印变量值等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值