Chinaunix首页 | 论坛 | 博客
  • 博客访问: 400999
  • 博文数量: 124
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 872
  • 用 户 组: 普通用户
  • 注册时间: 2018-03-29 14:38
个人简介

默默的一块石头

文章分类

全部博文(124)

文章存档

2022年(26)

2021年(10)

2020年(28)

2019年(60)

我的朋友

分类: LINUX

2019-10-21 11:15:38

form:https://blog.csdn.net/lwyeluo/article/details/63262489

下载并编译内核

内核源码可以在  下载,本文使用的内核为3.13

首先进行内核编译,在内核源码路径下执行:

sudo apt-get install m4 libncurses5-dev -y

 

make menuconfig(选中

         kernel hacking –> Kernel debugging

         kernel hacking –> Compile-time checks and compiler options  –> compile the kernel with debug info

         kernel hacking –> Compile-time checks and compiler options  -> compile the kernel with frame pointers

make

拷贝bzImage到我们用来调试的目录,如/opt/kernel-debug

mkdir -p /opt/kernel-debug

cp arch/x86/boot/bzImage /opt/kernel-debug

制作busybox所需要的rootfs

执行以下命令在/opt/kernel-debug下创建rootfs

cd /opt/kernel-debug

dd if=/dev/zero of=rootfs.img bs=1M count=10

mkfs.ext3 rootfs.img

mkdir rootfs

# 将其mount 到新创建到目录上

mount -t ext3 -o loop rootfs.img rootfs

cd rootfs

mkdir dev proc sys

安装qemu(使用apt install下载,无法终端)

下载qemu-1.3.0.tar.bz2到指定目录

  • 安装依赖包

apt-get install build-essential libtool automake \

libgmp-dev libnspr4-dev libnss3-dev openssl \

libssl-dev git iasl glib-2.0 libglib2.0-0 \

libglib2.0-dev libtasn1-6-dev tpm-tools \

libfuse-dev libgnutls-dev libsdl1.2-dev \

expect gawk socat libfdt-dev

编译qemu

tar -xjvf qemu-1.3.0.tar.bz2

cd qemu-1.3.0

./configure --enable-kvm --enable-sdl --target-list=x86_64-softmmu

make

make install

安装busybox

wget

tar -xjvf busybox-1.26.1.tar.bz2

cd busybox-1.26.1

make menuconfig

   - 选择静态编译:Busybox Settings->Build Busybox as a static binary

   - 取消选择Networking utilities->iptunnel (NEW)

   - 取消选择Networking utilities->inetd

make

安装到bzImage下的rootfs

make install CONFIG_PREFIX=/opt/kernel-debug/rootfs

unmount rootfs

cd /opt/kernel-debug

sudo umount rootfs

启动qemu进行调试

启动qemu

cd /opt/kernel-debug

1.使用busybox中的ash.c作为启动入口

qemu-system-x86_64  -S -kernel bzImage -hda rootfs.img -append "root=/dev/sda init=/bin/ash"

2.使用busybox中的init.c作为启动入口

qemu-system-x86_64  -S -kernel bzImage -hda rootfs.img -append "root=/dev/sda init=/sbin/init"


用鼠标点击qemu窗口,然后ctrl+alt+2切换到控制台,输入gdbserver tcp::1234

打开另外一个终端,安装ddd,并运行ddd vmlinux

apt-get install ddd

# 进入linux源码路径,本文路径为/usr/src/linux-3.13-obj

cd /usr/src/linux-3.13-obj

ddd vmlinux

界面为:

说明: 这里写图片描述

gdb的命令行中输入命令target remote localhost:1234qemu虚拟机连接到ddd的控制台
自此就可以通过ddd的控制台用gdb的命令来查看源码的运行信息了

gdb命令中输入continue,出现错误:

(gdb) continue

Continuing.

Continuing.

Remote 'g' packet reply is too long: edffffff00000000ffffffffffffffff0000000000000001000000000000000000000000000000004600000000000000b81ec081ffffffffb81ec081ffffffff000000000000000000000000000000002900000000000000689eea81ffffffff0000000000000000d81fc081ffffffffc022dd81ffffffffd81fc081ffffffff86050581ffffffff8602000010000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f030000000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000020202020202020202020202020202020000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff00000000000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000

(gdb) Quit

解决方案:

下载更高版本的gdb

wget

tar xzvf gdb-7.11.tar.gz

cd gdb-7.11

vim gdb/remote.c

注释掉

if (buf_len > 2 * rsa->sizeof_g_packet)

    error (_(“Remote ‘g’ packet reply is too long: %s”), rs->buf);

在其后加上

if (buf_len > 2 * rsa->sizeof_g_packet) {

      rsa->sizeof_g_packet = buf_len;

      for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {

          if (rsa->regs[i].pnum == -1)

              continue;

          if (rsa->regs[i].offset >= rsa->sizeof_g_packet)

              rsa->regs[i].in_g_packet = 0;

          else

             rsa->regs[i].in_g_packet = 1;

    }

}

安装gdb

apt-get install texinfo

./configure

make

make install

mv /usr/bin/gdb /usr/bin/gdb.bak

ln -s /usr/local/bin/gdb /usr/bin/gdb

再重新 ddd vmlinux后,gdb界面里显示:

(gdb) target remote localhost:1234

Remote debugging using localhost:1234

native_safe_halt () at /usr/src/octa-blockIMA/octa-blockIMA/arch/x86/include/asm/irqflags.h:50

(gdb)

关于ddd的介绍见 http://blog.csdn.net/mirage1993/article/details/50883824

调试示例

在本机上写一段程序:

root@BlockIMATest:~# cat fork.c

#include

 

int main() {

   int fd;

 

   fd = fork();

 

    if(fd == 0) {

       printf("I am child\n");

   } else if(fd > 0) {

       printf("I am parenet\n");

   }

   return 0;

}

root@BlockIMATest:~#

编译成静态的二进制程序

gcc -c -g -static fork.c

gcc -o test_fork -static fork.o

将该二进制拷贝到/opt/kernel-debug/rootfs/bin

cd /opt/kernel-debug

# 将其mount rootfs

mount -t ext3 -o loop rootfs.img rootfs

cd rootfs

cp ~/test_fork /opt/kernel-debug/rootfs/bin/

cd ../

sudo umount rootfs

启动qemu

cd /opt/kernel-debug

qemu-system-x86_64  -S -kernel bzImage -hda rootfs.img -append "root=/dev/sda init=/bin/ash"

用鼠标点击qemu窗口,然后ctrl+alt+2切换到控制台,输入gdbserver tcp::1234

另开一个终端,在内核目录下启动ddd vmlinux

gdb里连接到qemu,让其运行

GNU DDD 3.3.12 (x86_64-pc-linux-gnu), by Dorothea LReading symbols from vmlinux...done.

(gdb) target remote localhost:1234

Remote debugging using localhost:1234

0x0000000000000000 in irq_stack_union ()

(gdb) continue

Continuing.

说明: 这里写图片描述

qemu窗口,使用ctrl+alt+1切换到虚拟机界面,等待虚拟机启动。虚拟机启动成功后,在ddd界面里source->Breakpoints里添加一个断点,在弹出的Set point at文本框中输入do_fork

回到qemu窗口,执行test_fork,可以看到进入断点了~

说明: 这里写图片描述

阅读(2572) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~