持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
一、使用GDB调试内核方法
1.ARM
- sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi buildessent 安装编译需要的工具包。
- 下载linux源码,和下载busybox工具包:busybox.net/downloads/b…
- 利用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)
-
然后make install 编译完成,在busybox跟目录会生成一个__install的目录,该目录是编译好的文件系统需要的一些命令集合。
-
下载linux内核源码。 把_install目录复制到linux源码目录下。然后进入__install目录。
mkdir etc mkdir dev mkdir mnt mkdir -p etc/init.d/ -
创建etc,dev等目录。
-
在__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 -
在__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 -
在__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 -
在__install/dev目录下创建如下设备节点,需要root权限。
cd _install/dev sudo mknod console c 5 1 sudo mknod null c 1 3 -
编译内核
cd linux-4.*.** export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi- make vexpress_defconfig make menuconfig -
配置如下所示:
-
开始编译内核
make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make dtbs -
安装gdb调试工具。
sudo apt-get install gdb-arm-none-eabi发现UOS没有这个软件,但是有个新版本的。 叫gdb-multiarch,安装上述软件时会自动安装这个,应该是更新版。
-
首先要确保编译的内核包含调试信息。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 #开始让内核运行。
如下图所示:
完全运行时,进入系统后显示如下图所示:
上述内容为使用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