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"
键盘输入会出现乱码。在虚拟机环境下执行不会出现这个情况。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。