如何使用qemu调试内核
创始人
2024-03-09 08:07:48
0

文件系统

调试内核需要一个基本的文件系统,我们可以使用简单的 ramdisk来作为这个文件系统,如果,需要测试一些其它应用程序,我们还需要创建一个大一点根文件系统。

Ramdisk

也就是内核启动时的initrd.img,可以使用busybox来制作这个小文件系统,源码目录的INSTALL文件有编译和安装的说明。

  • make defconfig
  • make
  • make install : 默认目录 —— _install

制作initrd.img

  1. 把 busybox拷贝到 initrd根目录,并切换到initrd根目录。

  2. 创建init: ln -s bin/busybox init

  3. 创建系统文件夹:mkdir dev etc proc sys

  4. 配置etc目录

    .创建文件 etc/init.d/rcS,输入如下内容:

#!/bin/shmount proc
mount -o remount,rw /
mount -a    
clear

     .创建文件 etc/fstab,输入如下内容:

proc            /proc      proc           defaults    0       0
sysfs           /sys        sysfs          defaults    0       0
devtmpfs        /dev       devtmpfs        defaults    0       0

   .创建文件 etc/inittab,输入如下内容:

::sysinit:/etc/init.d/rcS   
::askfirst:-/bin/sh    
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount    -a   -r
::shutdown:/sbin/swapoff  -a

5.创建img 磁盘文件

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

磁盘文件系统

磁盘文件系统同 initrd.img的一个最大区别是需要bootloader,制作磁盘文件系统大概需要这么几个步骤:

  1. 先生成一个有MBR记录的磁盘文件(hda.img),文件系统是ext4,并mount.

  2. 安装grub到磁盘文件。

  3. 下载一个根文件系统(如:debootstrap --arch=i386 focal focal-rootfs)。

  4. 拷贝到磁盘文件,并做好配置。

文件系统配置

1:grub: 添加启动程序,设置sda1为rw, 下面的init是systemd的初始化进程。

linux /boot/bzImage rw text root=/dev/sda1  init=/usr/sbin/init

2:设置root密码,系统登陆时需要输入的密码

  1. mount hda.img 到 /mnt
  2. chroot, 进入chroot环境。
  3. password root,来设置初始密码。或者使用 useradd 来添加新的登陆账号。

3: 配置自动登陆,或者其它登陆账号。

vim lib/systemd/system/getty@.service,修改/sbin/agetty的输入参数.

添加 -a root[或者其它账号], 实现自动登陆。

qemu

使用initrd.img

qemu-system-x86_64 -kernel bzImage -boot c -m 1024 -initrd initrd.img -append "console=ttyS0, 115200" -serial stdio

-serial stdio: 把控制台重定向到当前终端,还可以这样来配置控制台:

"console=ttyS0,115200 console=tty0" -serial file:kernel.log

使用虚拟机系统的终端,运行日志写到当前目录下的 kernel.log

使用文件系统

qemu-system-x86_64 -hda hda.img -chardev stdio,id=terminal,mux=on -device isa-debugcon,iobase=0x402,chardev=terminal -serial chardev:terminal

qemu + gdb 调试内核

1:运行qemu命令时,后面添加 "-s -S",这样虚拟机启动后会暂停 ——,如:

qemu-system-x86_64 ...... -serial stdio -s -S

2:gdb加载对应内核的vmlinux文件,在gdb命令行输入:

(gdb) break start_kernel

(gdb) target remote :1234

(gdb) c

3:qemu运行,并停止在 start_kernel处,此时可以使用gdb的命令来单步执行,查看寄存器的值。

4:qemu在运行期间,也可以中断gdb,设置新的断点。

附录一: 创建磁盘文件系统的shell脚本

来源于网络,略作修改。

#!/bin/bash
# Echo commands to stdout as they execute.
set -x
set -eE
clean () {rm .hda.img || truesudo umount tmpmnt || truerm -rf tmpmnt || truesudo losetup -d ${HDA_LOOP_DEV} || true
}clean
# Create an empty 1G disk image, 自行调整大小。
truncate -s1G .hda.img/sbin/parted -s .hda.img mktable msdos
/sbin/parted -s .hda.img mkpart primary ext4 1 "100%"
/sbin/parted -s .hda.img set 1 boot onHDA_LOOP_DEV=$(sudo losetup -Pf --show .hda.img)
FS_LOOP_DEV="${HDA_LOOP_DEV?}p1"
sudo mkfs -t ext4 -v "${FS_LOOP_DEV?}"mkdir tmpmnt
sudo mount "${FS_LOOP_DEV?}" tmpmnt
sudo chown -R ${USER?} tmpmnt#安装grub
mkdir -p tmpmnt/boot/grub 
echo "(hd0) ${HDA_LOOP_DEV?}" >tmpmnt/boot/grub/device.map
sudo grub-install  -v  --directory=/usr/lib/grub/i386-pc \--boot-directory=tmpmnt/boot  ${HDA_LOOP_DEV?}  2>&1cat >tmpmnt/boot/grub/grub.cfg <

 ---
欢迎大家来我的公众号交流: 般若程序蝉

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...