内核调试技术之arm

368 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

一、使用GDB调试内核方法

1.ARM

  1. sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi buildessent 安装编译需要的工具包。
  2. 下载linux源码,和下载busybox工具包:busybox.net/downloads/b…
  3. 利用busybox编译最小文件系统:
   cd busybox
   export ARCH=arm
   export CROSS_COMPILE=arm-linux-gnueabi-
   make menuconfig

进入menuconfig后,配置成静态编译。

Busybox Settings ----> Build Options -----> [*]Build BusyBox as a static binary (no shared libs)

  1. 然后make install 编译完成,在busybox跟目录会生成一个__install的目录,该目录是编译好的文件系统需要的一些命令集合。

  2. 下载linux内核源码。 把_install目录复制到linux源码目录下。然后进入__install目录。

    mkdir etc
    mkdir dev
    mkdir mnt
    mkdir -p etc/init.d/
    
  3. 创建etc,dev等目录。

  4. 在__install /etc/init.d/目录下创建rcS文件,写入如下内容,并赋予可执行权限。

    mkdir -p /proc
    mkdir -p /tmp
    mkdir -p /sys
    mkdir -p /mnt
    /bin/mount -a
    mkdir -p /dev/pts
    mount -t devpts devpts /dev/pts
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev -s
    
  5. 在__install/etc目录下创建一个fstab文件,并写入如下内容。

    proc /proc proc defaults 0 0
    tmpfs /tmp tmpfs defaults 0 0
    sysfs /sys sysfs defaults 0 0
    tmpfs /dev tmpfs defaults 0 0
    debugfs /sys/kernel/debug debugfs defaults 0 0
    
  6. 在__install/etc下创建一个inittab文件,并写入如下内容。

    ::sysinit:/bin/chmod 777 /etc/init.d/rcS
    ::sysinit:/etc/init.d/rcS
    ::respawn:-/bin/sh
    ::askfirst:-/bin/sh
    ::ctrlaltdel:/bin/umount -a -r
    
  7. 在__install/dev目录下创建如下设备节点,需要root权限。

    cd _install/dev
    sudo mknod console c 5 1
    sudo mknod null c 1 3
    
  8. 编译内核

    cd linux-4.*.**
    export ARCH=arm
    export CROSS_COMPILE=arm-linux-gnueabi-
    make vexpress_defconfig
    make menuconfig
    
  9. 配置如下所示:

1.png

2.png

  1. 开始编译内核

    make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
    make dtbs
    
  2. 安装gdb调试工具。

    sudo apt-get install gdb-arm-none-eabi
    

    发现UOS没有这个软件,但是有个新版本的。 叫gdb-multiarch,安装上述软件时会自动安装这个,应该是更新版。

  3. 首先要确保编译的内核包含调试信息。Kernel haking-->Compile-time checks and compiler options --->[*]Compile the kernel with debug info。 勾选后重新编译内核。 然后启动内核:

    qemu-system-arm -nographic -M vexpress-a9 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -S -s
    

    #实验通过,使用-sd 指定硬盘时,需要在步骤12中删除_install所在文件夹,不将rootfs编译到内核中。 #qemu 使用console=ttyAMA0或者tty0时,需要在qemu中修改显示,为串口或者其他。 qemu-system-arm -nographic -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -append "root=/dev/mmcblk0 rw console=ttyAMA0" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -sd rootfs_ext4.img

    qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-4.4.76/arch/arm/boot/zImage -dtb linux-4.4.76/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -append "root=/dev/mmcblk0 rw console=tty0" -sd rootfs.ext3

重新启动一个控制台,运行gdb-multiarch vmlinux,进入控制台,开始打断点并执行,命令如下:

    target remote localhost:1234          #通过1234端口远程连接到QEMU平台
b start_kernel                      #在start_kernel处打一个断点。 
    b sort_main_extable                    #在sort_main_extable函数处打一个断点。
    c                         #开始让内核运行。

如下图所示:

3.png 5.png

完全运行时,进入系统后显示如下图所示:

6.png

上述内容为使用qemu直接启动linux内核,没有使用u-boot引导.

若要使用u-boot进行引导,则下载uboot代码,进行对应平台的编译如下命令,然后qemu参数填写对应平台,填写u-boot位置,并启动. 启动后可以通过tftp下载内核,进行引导.

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make  vexpress_ca9x4_defconfig
make -j4


qemu-system-arm -M vexpress-a9 -m 256 -kernel u-boot --nographic

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make  vexpress_ca9x4_defconfig
make -j4
​
​
qemu-system-arm -M vexpress-a9 -m 256 -kernel u-boot --nographic

16.如果出现根目录是只读的,则先查看自己的内核启动参数加“rw“。

如果加了,看内核启动时报啥错,如果报什么必须加内核某个编译模块加入。 则make menuconfig加入该模块编译后,重新启动。

17.创建共享磁盘

先在本地创建共享文件夹mkdir ./mnt

qemu-system-arm启动内核时,后边加入参数:

--fsdev local,id=kmod_dev,path=$PWD/mnt,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount

说明加入一个fsdev,设置挂载标签为kmod_mount

修改文件系统中的/etc/fstab,或者进入到系统中手动挂载都可以。

加入一行,让系统启动时挂载.

kmod_mount /mnt 9p trans=virtio 0 0

最后命令为:

qemu-system-arm -nographic -M vexpress-a9 -m 512M -kernel zImage -append "root=/dev/mmcblk0 rw console=ttyAMA0" -dtb vexpress-v2p-ca9.dtb -sd rootfs_disk.img --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_moun