linux 3.10 busybox initramfs构建 qemu调试

linux 3.10 busybox initramfs构建 qemu调试

我的环境是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

编译过程出现错误

CC      loginutils/passwd.o

loginutils/passwd.c: 在函数‘passwd_main’中:

loginutils/passwd.c:104:16: 错误:‘rlimit_fsize’的存储大小未知

struct rlimit rlimit_fsize;

^

loginutils/passwd.c:188:2: 警告:隐式声明函数‘setrlimit’ [-Wimplicit-function-declaration]

setrlimit(RLIMIT_FSIZE, &rlimit_fsize);

^

loginutils/passwd.c:188:12: 错误:‘RLIMIT_FSIZE’未声明(在此函数内第一次使用)

setrlimit(RLIMIT_FSIZE, &rlimit_fsize);

^

loginutils/passwd.c:188:12: 附注:每个未声明的标识符在其出现的函数内只报告一次

loginutils/passwd.c:104:16: 警告:未使用的变量‘rlimit_fsize’ [-Wunused-variable]

vim include/libbb.h

在#include <sys/mman.h>后面添加

#include <sys/resource.h>

具体参考http://lists.busybox.net/pipermail/busybox/2012-May/077766.html

编译一个简单程序进行测试

vim ~/init.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()

{

while(1){

printf("Hello world!\n");

sleep(199999999);

}

return 0;

}

gcc -static ~/init.c -o /opt/busybox-1.20.0/_install/init

cd /opt/busybox-1.20.0/_install

mknod -m 600 dev/console c 5 1

进入创建目录和文件

cd _install

mkdir -p dev proc sys etc mnt

touch etc/mdev.conf

mknod -m 600 dev/null c 1 3

创建控制台设备文件,不创建这个文件,init脚本不能正常运行。console的初始化代码参考函数:init/main.c:kernel_init_freeable

mknod -m 600 dev/console c 5 1

创建init文件:

vim init

内容如下:

#!/bin/sh

echo

echo "###########################################################"

echo "## Author: [email protected]                                 ##"

echo "## Date: 2014/09/15 16:57:21 CST                           ##"

echo "###########################################################"

echo

PATH="/bin:/sbin:/usr/bin:/usr/sbin"

if [ ! -f "/bin/busybox" ];then

echo "cat not find busybox in /bin dir, exit"

exit 1

fi

BUSYBOX="/bin/busybox"

echo "build root filesystem..."

$BUSYBOX --install -s

if [ ! -d /proc ];then

echo "/proc dir not exist, create it..."

$BUSYBOX mkdir /proc

fi

echo "mount proc fs..."

$BUSYBOX mount -t proc proc /proc

if [ ! -d /dev ];then

echo "/dev dir not exist, create it..."

$BUSYBOX mkdir /dev

fi

echo "mount tmpfs in /dev..."

$BUSYBOX mount -t tmpfs dev /dev

$BUSYBOX mkdir -p /dev/pts

echo "mount devpts..."

$BUSYBOX mount -t devpts devpts /dev/pts

if [ ! -d /sys ];then

echo "/sys dir not exist, create it..."

$BUSYBOX mkdir /sys

fi

echo "mount sys fs..."

$BUSYBOX mount -t sysfs sys /sys

echo "/sbin/mdev" > /proc/sys/kernel/hotplug

echo "populate the dev dir..."

$BUSYBOX mdev -s

echo "drop to shell..."

$BUSYBOX sh

exit 0

给init执行的权限

chmod u+x init

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

make menuconfig

配置编译选项,选中

General setup --->

[*]Initramfs source file(s)

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

/opt/busybox-1.20.0/_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

6:其他问题

在xshell下直接执行

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

键盘输入会出现乱码。在虚拟机环境下执行不会出现这个情况。

时间: 2024-10-11 16:49:58

linux 3.10 busybox initramfs构建 qemu调试的相关文章

用qemu调试linux内核

1)dd if=/dev/zero of=./busybox.img bs=1M count=642)mkfs.ext3 busybox.img3)下载busybox,http://www.busybox.net/downloads/#tar jxvf busybox-1.18.0.tar.bz2 (解压busybox压缩包)#cd busybox-1.18.0 (进入到解压后的busybox源码目录)#make menuconfig (配置busybox)注意配置时,一定要选择静态链接选项,该

大杀招之使用QEMU调试Linux内核代码

Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试. 这里的方法是用QEMU来调试Linux内核.因为QEMU自己实现了一个gdb server, 所以可以非常方便的使用gdb来调内核. 这对内核的学习也非常有帮助. 为了尽量不多花时间在QEMU设置上,这里直接使用以下的内核image: http://free-electrons.com/community/demos/qemu-arm-directfb/ 1. QEMU的安装 这个可以自己去QEMU的官网下载编译,

使用QEMU调试Linux内核代码

Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试.这里的方法是用QEMU来调试Linux内核.因为QEMU自己实现了一个gdb server, 所以可以非常方便的使用gdb来调内核. 这对内核的学习也非常有帮助. 为了尽量不多花时间在QEMU设置上,这里直接使用以下的内核image: http://free-electrons.com/community/demos/qemu-arm-directfb/ 1,QEMU的安装 这个可以自己去QEMU的官网下载编译,如果

精通initramfs构建step by step

http://hi.baidu.com/jonathan2004/blog/item/db7bf38aad11759ea4c2721d.html 精通initramfs构建step by step (1)--hello world 2009-12-08 19:19 一.initramfs是什么 在2.6版本的linux内核中,都包含一个压缩过的cpio格式的打包文件.当内核启动时,会从这个打包文件中导出文件到内核的rootfs文件系统, 然后内核检查rootfs中是否包含有init文件,如果有则

Linux 4.10.8 根文件系统制作(一)---环境搭建

一.工具 制作工具为busybox 下载地址:https://busybox.net/ 解压: 二.制作文件系统 进入目录,执行make menuconfig: 2.1 busybox setting 2.1.1 设定交叉编译器 改为 保存退出,然后执行 make 编译. 编译完成后创建文件系统存放目录: 2.2.2 安装glibc 安装完成后,fs_mini下会生成以下目录: 进入交差编译工具链的目录,找出lib库: 拷贝sysroot下的lib目录和usr/lib目录下的 .so 文件到fs

ubuntu下linux内核源码阅读工具和调试方法总结

http://blog.chinaunix.net/uid-20940095-id-66148.html 一 linux内核源码阅读工具 windows下当然首选source insight, 但是linux下就没有source insight这么优秀的工具了,但是也有不少的替代品,但觉绝对部分人会选择vim+ctags+cscope的组合,还有部分人或选择wine中的source insight或选择navigatror,当然对于代码阅读来说vim+ctags+cscope的组合还是比较好的一

使用Qemu调试内核

利用Qemu进行内核源码级调试 http://blog.csdn.net/gdt_a20/article/details/7231652 用Qemu调试Linux内核 http://blog.chinaunix.net/uid-26009923-id-3825761.html From printk to qeum kernel debugging http://www.slideshare.net/xen_com_mgr/from-printk-to-qemu-xenlinux-kernel-

Linux 4.10中两个新特性与我的一段故事

今早5点半起来没有开始写文章,而是去西湾红树林连跑带走折腾了将近20公里,回来后就8点多了...洗了个澡之后坐稳当,开始写一段关于我的故事.        在2014年到2015年期间,我在负责研发一款无线安全网关,其实就是一个VPN,接入设备包括手机,xPad,盒子...这些设备的OS除了iOS之外,基本上都是基于Linux的Android.这个网关一般用于各种需要高性能加密通信的场合,在数据传输之前需要比较强的认证,服务端支持4G的加密带宽,支持复杂的接入控制和访问控制,支持复杂的Qos,另

linux 驱动开发-模块的构建

1.模块的含义 linux 是采用模块化的方式构建的,允许内核在运行时动态地向其中插入或从中删除代码,这些代码(包扩函数,数据,模块入口函数,模块出口函数)被一并组合 在一个单独的二进制镜像,就是所谓的可装载内核模块. 模块可以是基本的内核镜像尽可能小,同时可以方便地对新功能进行调试,还可以实现热插拔(后续会学习如何实现设备的热插拔功能,暂时无需深究),和内核的核心子系统不一样,模块文件需要有入口点和出口点. 模块与应用程序的区别: a.模块和库函数类似,一个模块通常包含若干函数和数据,每个函数