使用GDB+QEMU调试Cosmos内核代码

本文详细介绍了如何生成带调试符号的elf文件,包括修改GCC编译选项,移除ld的-s参数,并通过grep和sed命令批量处理。接着,展示了如何制作hd.img文件以在QEMU中运行Cosmos内核,包括生成内核映像、安装GRUB以及创建grub.cfg配置文件。最后,阐述了如何使用GDB进行调试,设置断点,并启动QEMU进行远程调试。整个过程涵盖了从编译到调试的完整流程。
摘要由CSDN通过智能技术生成

1. 生成带调试符号的elf文件

修改编译选项:
  1. GCC 的-O2参数要修改成O0 -g参数:-O0是告诉 GCC 编译器,在编译时不要对代码做优化,这么做可以避免在 GDB 调试时源码和实际程序对应不上的问题;-g参数是为了告诉编译器带上调试符号。

    使用grep命令查找需要修改的文件,使用sed命令批量替换,命令如下:

    grep -i '\-o2' -r  //-i 代表不区分大小写
    

    在这里插入图片描述

       sed -i 's/-O2/-O0 -g/' ./initldr/build/krnlbuidcmd.mh ./script/krnlbuidcmd.S
       sed -i 's/-Os/-O0 -g/' ./initldr/build/krnlbuidcmd.mh ./script/krnlbuidcmd.S 
    

    在这里插入图片描述

  2. 去掉 ld 的-s参数:-s是告诉 ld 程序链接时去掉所有符号信息,其中包括了调试符号。

    grep '\-s ' -r
    

    在这里插入图片描述

    使用 sed 命令批量去掉 ld 的-s参数,命令如下:

     sed -i 's/-s / /g' ./initldr/build/krnlbuidcmd.mh ./script/krnlbuidcmd.S
    

编译生成“带调试符号的 elf 文件"

执行make就可以编译出带有调试符号的 elf 文件,如下图:这里的“not stripped”就表示文件带有调试符号。

  1. Cosmos.elf:当需要调试“内核代码”时,可以在 GDB 中执行symbol-file ./build/Cosmos.elf加载调试符号
  2. initldrkrl.elf:当需要调试“二级加载器代码”时,可以在 GDB 中执行symbol-file ./initldr/build/initldrkrl.elf加载调试符号。
制作 hd.img, 用于QEMU运行Cosmos内核
  1. 打包生成内核映像文件Cosmos.eki
    将要打包的文件copy到同一个文件夹下,执行下列命令:

    ./lmoskrlimg -m k -lhf initldrimh.bin -o Cosmos.eki -f initldrkrl.bin initldrsve.bin Cosmos.bin background.bmp font.fnt logo.bmp 
    

    在这里插入图片描述

  2. 如果已有 hd.img,则需要先将其挂载到临时文件,然后替换新生成的Cosmos.eki

        cd mount hd.img /tmp/
        cp Cosmos.eki /tmp/boot/
        umount /tmp/
    
  3. 第一次生成hd.img需要按如下命令制作

    使用dd命令生成100MB的纯二进制文件,也就是我们要用到的虚拟硬盘文件hd.img:

    dd bs=512 if=/dev/zero of=hd.img count=204800
    
    ;bs:表示块大小,这里是512字节 
    ;if:表示输入文件,/dev/zero就是Linux下专门返回0数据的设备文件,读取它就返回0 ;
    of:表示输出文件,即我们的硬盘文件。 ;
    count:表示输出多少块
    

    格式化虚拟硬盘并挂载到本地目录下:

    sudo losetup /dev/loop0 hd.img // losetup命令将hd.img变成Linux的回环设备
    sudo mkfs.ext4 -q /dev/loop0  // mkfs.ext4格式化为ext4格式的文件系统
    sudo mount -o loop ./hd.img ./hdisk/   //将hd.img当做块设备挂载到硬盘文件中
    sudo mkdir ./hdisk/boot/   //建立boot目录
    

    如果提示回环设备忙,则使用losetup -f查找第一个空闲的设备,替换即可:
    在这里插入图片描述

    安装GRUB:

    sudo grub-install --boot-directory=./hdisk/boot/ --force --allow-floppy /dev/loop0 
    

    这时看到boot目录下多了一个grub目录,说明grub安装成功。

    创建grub.cfg文件:

    set timeout=2
    
    menuentry 'Cosmos' {
    insmod part_msdos
    insmod ext2
    set root='hd0' #我们的硬盘只有一个分区所以是'hd0'
    multiboot2 /boot/Cosmos.eki #加载boot目录下的Cosmos.eki文件
    boot #引导启动
    }
    set timeout_style=menu
    if [ "${timeout}" = 0 ]; then
      set timeout=10 #等待10秒钟自动启动
    fi
    
    

    将Cosmos.eki文件放置到boot目录下,解除挂载

    cp Cosmos.eki /tmp/boot/
    umount /hdisk/
    
  4. 如果要在virtualbox中启动,则需要转换成hd.vdi格式,命令如下:

    VBoxManage convertfromraw ./hd.img --format VDI ./hd.vdi
    

2. qemu启动内核

qemu-system-x86_64 -drive format=raw,file=hd.img -m 512M -cpu kvm64,smep,smap -s    // 一定要加-s参数,此参数可以打开调试服务。

3. 使用GDB加载调试符号

在这里插入图片描述

(gdb) symbol-file ./initldr/build/initldrkrl.elf  // 加载调试符号,这样才能在显示源码、可以用函数名下断点
Reading symbols from ./initldr/build/initldrkrl.elf...  //连接qemu-system-x86_64 -s选项打开的1234端口进行调试

4. 启动调试

 (gdb) target remote :1234   // 连接qemu-system-x86_64 -s选项打开的1234端口进行调试  
 Remote debugging using :1234  
0x0000000000200040 in _32bits_mode ()

5. 设置断点,使用GDB命令调试

在这里插入图片描述

  root# od -tx4 ./initldr/build/Cosmos.eki | head -3
  0000000 909066eb 1badb002 00010003 e4514ffb
  0000020 04000004 04000000 00000000 00000000
  0000040 04000068 90909090 e85250d6 00000000

根据GRUB 头结构,结合上面的 Cosmos.eki 文件头信息,我们很容易就能知道,_start符号地址是0x04000000,_entry符号地址是0x04000068。我们在这两个地址设置断点,通过 GDB 可以看到,程序不是在0x04000000断点暂停,而是直接在0x04000068 断点暂停,说明grub启动后会加载cosmos.eki 到0x04000000位置,但执行的第一条指令不是 _start 符号位置而是 _entry 符号位置。到 _entry 时,cr0 的 pe=1,表明此时保护模式已经打开了。

而在断点处执行的正是 _entry处的代码: ./initldr/ldrkrl/imginithead.asm
在这里插入图片描述

参考手册:

100个gdb小技巧

QEMU User Documentation

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值