最小busybox initramfs构建 qemu调试

这篇文章是“linux 3.10 调试及跟文件系统构建”的改进版。我的环境是vm ware虚拟机跑的centos 7 64位系统

1: 安装qemu

先安装SDL,负责qemu运行后只出现VNC server running on `::1:5900',而不出现qemu运行窗口,具体参考:

http://www.crifan.com/qemu_test_arm_vnc_server_running_on_127_0_0_1_5900_no_other_output/

yum install SDL.i686 SDL.x86_64 SDL-devel.i686 SDL-devel.x86_64

下载源代码qemu-2.1.0.tar.bz2,解压编译,安装

./configure --prefix=/usr/local/ --target-list=x86_64-softmmu

make && make install

创建软链接

ln -n /usr/local//bin/qemu-system-x86_64 /bin/qemu

2:下载busybox-1.20.0.tar.bz2,解压,进入源代码目录,运行

make menuconfig 

选择

Busybox Settings --->

    Build Options ---> 

        [*] Build BusyBox as a static binary (no shared libs)

编译安装

make && make install

安装后的文件系统目录是源代码下的_install,  进入该目录,创建必要的文件

创建init文件,不创建这个文件系统启动不了,因为如果没有从参数传入用户空间初始化程序的文件名,系统会测试/init文件是否存在,存在则调用/init进行用户空间初始化,否则系统会尝试初始化,而系统初始化会失败,失败后系统会挂起。具体信息参考内核初始化函数kernel_init_freeableprepare_namespace

ln bin/busybox init

创建控制台文件,不创建这个文件busybox不能完成初始化

mkdir dev

mknod -m 600 dev/console c 5 1

创建配置目录及其文件

mkdir etc

vim etc/inittab

实际只要examples/inittab注释掉一些tty2::askfirst:-/bin/sh类似的行就可以了,因为我们只要一个控制台就可以了,文件内容只如下:

::sysinit:/etc/init.d/rcS

::askfirst:-/bin/sh

::restart:/sbin/init

::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount -a -r

::shutdown:/sbin/swapoff -a

创建初始化脚本:

mkdir etc/init.d

vim etc/init.d/rcS

chmod 777 etc/init.d/rcS

etc/init.d/rcS文件内容如下:

#!/bin/sh

export PATH=/sbin:/bin:

export HOSTNAME=ac

echo "start....."

这样一个只包含最简单内容的initramfs就创建成功了,用这个方法创建的initramfsbusybox初始化后不会出现/bin/sh: can't access tty; job control turned off信息。直接可以运行命令行。

3:下载linux-3.10.tar.xz,解压源码,进入源码目录,运行

make menuconfig 

配置编译选项,选中

General setup --->

[*]Initramfs source file(s)

选项,输入制作好的文件系统的目录就可以了,我这里是

/opt/busybox-1.22.1/_install

编译

make bzImage

运行虚拟机:

qemu -kernel ./arch/x86/boot/bzImage -append "no_timer_check"

在另一终端下进行gdp调试:

gdb vmlinux

target remote  127.0.0.1:1234

b start_kernel

4:在我的机器上不添加no_timer_check会输出

...trying to set up timer as Virtual Wire IRQ...

后卡住

解决这个问题的方法:

在源代码搜索trying to set up timer as Virtual Wire IRQ,找到函数输出语句在函数check_timer中。

运行虚拟机

qemu -kernel ./arch/x86/boot/bzImage -append "root=/dev/hda init=/bin/sh no_timer_check" -S -s

在内核源代码目录运行

gdb vmlinux

进入gdb命令行后输入命令

target remote  127.0.0.1:1234

b check_timer

c

断点后从输出trying to set up timer as Virtual Wire IRQ后往下执行,发现到timer_irq_works函数后卡住。在timer_irq_works中有语句:

if (no_timer_check)

return 1;

查找no_timer_check,Documentation/x86/x86_64/boot-options.txt中找到no_timer_check选项。

5:GDB 调试出现gdb 'g' packet reply is too long修正,

下载gdb-7.8.tar.xz

解压

xt -d gdb-7.8.tar.xz

tar xf gdb-7.8.tar.xz

编辑源代码:

vim gdb/remote.c

找到process_g_packet函数

注释调下面两行

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->pnum == -1)

            continue;

        if (rsa->regs->offset >= rsa->sizeof_g_packet)

            rsa->regs->in_g_packet = 0;

        else  

            rsa->regs->in_g_packet = 1;

    }     

}

配置编译

./configure --prefix=/usr/local/gdb

Make && make install

设置环境变量

export PATH=/usr/local/gdb/bin:$PATH

猜你喜欢

转载自blog.csdn.net/ancjf/article/details/42172847