一.qemu模拟x86
1.1 qemu的安装
ubuntu 12.04下安装qemu很简单,
sudo apt-get install qemu
1.2 linux内核的编译
下载内核, 以linux-3.0.1为例
sun@ubuntu:/work/x86/kernel$ tar xf ./linux-3.0.1.tar.bz2
sun@ubuntu:/work/x86/kernel$ cd linux-3.0.1/
sun@ubuntu:/work/x86/kernel/linux-3.0.1$ make menuconfig
sun@ubuntu:/work/x86/kernel/linux-3.0.1$ make bzImage
这样就会生成内核文件 arch/x86/boot/bzImage
1.3 busybox的编译
下载busybox, 以busybox-1.21.1.tar.bz2为例
sun@ubuntu:/work/x86/kernel$ tar xv busybox-1.21.1.tar.bz2
sun@ubuntu:/work/x86/kernel$ cd busybox-1.21.1/
sun@ubuntu:/work/x86/kernel/busybox-1.21.1$ make menuconfig
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
//静态方式编译
Networking Utilities --->
[ ] inetd
//去掉inetd
sun@ubuntu:/work/x86/kernel/busybox-1.21.1$ make install
这会生成 _install目录
1.4 最小文件系统的建立
只用一个脚本creatfs.sh就可以生成cramfs文件系统
-
#!/bin/sh
-
KERNEL=$(pwd)
-
BUSYBOX=$(find busybox* -maxdepth 0)
-
LINUX=$(find linux* -maxdepth 0)
-
-
#create filesystem
-
cd $BUSYBOX
-
mkdir -pv proc sys dev etc etc/init.d //先创建系统目录
-
cat << EOF > etc/init.d/rcS //生成rcS文件
-
#!/bin/sh
-
mount -t proc none /proc
-
mount -t sysfs none /sys
-
/sbin/mdev -s
-
EOF
-
-
chmod 777 ./etc/init.d/rcS //修改rcS权限
-
cd -
-
-
#create cpio img
-
cd $BUSYBOX/_install
-
find . | cpio -o --format=newc > $KERNEL/rootfs.img
-
cd -
-
-
#create zip img
-
cd $KERNEL
-
gzip -c rootfs.img > rootfs.img.gz
1.5 启动qemu
-
#!/bin/sh
-
LINUX=$(find linux* -maxdepth 0)
-
#启动qemu
-
if [ $# = 0 ] ; then
-
qemu-system-i386 -kernel $LINUX/arch/i386/boot/bzImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=sbin/init noapic"
-
fi
-
-
if [ "$1" = "s" ] ; then
-
qemu-system-i386 -s -S -kernel $LINUX/arch/i386/boot/bzImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=sbin/init noapic"
-
fi
如果没有参数直接运行qemu, 如果有参数s, 则进入调试模式
qemu参数:
-s : 在1234接受gdb调试连接
-S : 虚拟机启动后立即暂停,等侍gdb连接
最后所有文件如下:
sun@ubuntu:/work/x86/kernel$ tree -L 1
.
├── busybox-1.21.1
//busbyox及_install
├── creatfs.sh
//文件系统生成脚本
├── linux-3.0.1
//Linux源码,及 bzImage
└── start.sh
//启动qemu
注意:
a. 将linux启动信息打印到串口
在qemu启动时加上:
qemu-system-i386 -kernel $LINUX/arch/i386/boot/bzImage -initrd
rootfs.img.gz -append "root=/dev/ram rdinit=sbin/init noapic
console=ttyS0"
-serial file:/tmp/serial.out
就会在/tmp/serial.out中出现系统的信息
b. 将linux启动信息直接打印到控制台
加入 -nographic 和stdio,则会在当前运行的terminal中把linux启动信息打印出来
qemu-system-i386 -kernel $LINUX/arch/i386/boot/bzImage -initrd
rootfs.img.gz -append "root=/dev/ram rdinit=sbin/init console=ttyS0"
-nographic
c. qemu的快捷键
C-a h print this help
C-a x exit emulator
C-a s save disk data back to file (if -snapshot)
C-a t toggle console timestamps
C-a b send break (magic sysrq)
C-a c switch between console and monitor
C-a C-a sends C-a
二.qemu模拟ARM
2.1 qemu-system-arm的安装
如果只是apt-get install qemu,不会安装qemu-system-arm
sun@ubuntu:/work/qemu$ sudo apt-get install qemu qemu-system qemu-utils
sun@ubuntu:/work/qemu$ qemu-system-arm --version
QEMU emulator version 1.0.50 (Debian 1.0.50-2012.03-0ubuntu2.1), Copyright (c) 2003-2008 Fabrice Bellard
注意: 编译工具链可以不用apt-get install 来安装,试过6410自带的交叉编译工具链是完全可用的。
2.2 编译u-boot, kernel, busybox
这儿的编译跟x86的不同之处是:
不论是编译u-boot 还是 linux-3.0.1 还是busybox都需要个改Makefile中的ARCH与CROSS_COMPILE两个变量c
-
ARCH ?= arm
-
CROSS_COMPILE ?= /opt/6410/4.3.2/bin/arm-none-linux-gnueabi-
编译u-boot时是用的make ca9x4_ct_vxp_config
编译Linux-3.0.1时是用的 arch/arm/configs/vexpress_defconfig
内核编译命令: make vexpress_defconfig && make -j16
a.copy zImage
在arch/arm/Makefile中
-
278 zImage Image xipImage bootpImage uImage: vmlinux
-
279 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
-
280 echo "$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@"
-
281 cp $(boot)/$@ ../
其中$(boot)/$@是zImage的路径
../ 是linux-3.01源码的上一层
2.3 用ext3系统启动
编译完成busybox, make install 后,用mkfs.sh脚本生成文件系统,只是生成,不用打包成其它格式
-
#!/bin/sh
-
KERNEL=$(pwd)
-
BUSYBOX=$(find busybox* -maxdepth 0)
-
LINUX=$(find linux* -maxdepth 0)
-
#create filesystem
-
cd $BUSYBOX
-
mkdir -pv proc sys dev etc etc/init.d //先创建系统目录
-
cat << EOF > etc/init.d/rcS //生成rcS文件
-
#!/bin/sh
-
mount -t proc none /proc
-
mount -t sysfs none /sys
-
/sbin/mdev -s
-
EOF
-
chmod 777 ./etc/init.d/rcS //修改rcS权限
-
cd -
用ext3.sh脚本创建ext3文件系统
-
#!/bin/sh
-
#创建一个32M的空文件
-
dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
-
-
#格式化为EXT3
-
sudo mkfs.ext3 a9rootfs.ext3
-
-
# 挂载到a9rootdir目录
-
mkdir -pv /tmp/a9rootdir
-
sudo mount -t ext3 a9rootfs.ext3 /tmp/a9rootdir/ -o loop
-
-
#拷贝文件到该目录,相对于放到a9rootfs.ext3里面
-
sudo cp /work/qemu/rootfs/* /tmp/a9rootdir/ -Rf
-
-
sudo umount /tmp/a9rootdir
2.3.1文件系统的目录结构
-
cong@msi:/tmp/a9rootdir$ tree
-
.
-
├── bin
-
│ ├── busybox
-
│ ├── init -> busybox
-
│ ├── ls -> busybox
-
│ ├── mount -> busybox
-
│ └── sh -> busybox
-
├── dev
-
│ ├── console
-
│ ├── null
-
│ └── tty1
-
├── etc
-
│ ├── fstab
-
│ ├── init.d
-
│ │ └── rcS
-
│ └── inittab
-
├── lib
-
│ ├── ld-2.8.so -->解释器
-
│ ├── ld-linux.so.3 -> ld-2.8.so
-
│ ├── libc-2.8.so -->libc库运行时必需
-
│ ├── libcrypt-2.8.so -->libcrypt是busybox需要用的
-
│ ├── libcrypt.so.1 -> libcrypt-2.8.so
-
│ ├── libc.so.6 -> libc-2.8.so
-
│ ├── libgcc_s.so -> libgcc_s.so.1
-
│ ├── libgcc_s.so.1 -->运行时必需
-
│ ├── libm-2.8.so -->libm是busybox需要用的
-
│ └── libm.so.6 -> libm-2.8.so
-
├── linuxrc -> ./bin/busybox
-
├── lost+found [error opening dir]
-
├── proc
-
├── sbin
-
│ └── mdev -> ../bin/busybox
-
└── sys
2.3.2启动的流程
kernel-->/bin/init -->/etc/inittab--> /etc/init.d/rcS --> mount 会用到/etc/fstab
-
cong@msi:/tmp/a9rootdir$ cat etc/inittab
-
::sysinit:/etc/init.d/rcS
-
ttyAMA0::askfirst:-/bin/sh
-
#console::askfirst:-/bin/sh
-
cong@msi:/tmp/a9rootdir$ cat etc/init.d/rcS
-
#!/bin/sh
-
mount -a
-
/sbin/mdev -s
-
cong@msi:/tmp/a9rootdir$ cat etc/fstab
-
proc /proc proc defaults 0 0
-
sysfs /sys sysfs defaults 0 0
2.3.3启动:
-
qemu-system-arm -kernel zImage -M vexpress-a9 -append "root=/dev/mmcblk0 console=ttyAMA0 console=tty0" -sd a9rootfs.ext3 -serial stdio
2.4 用NFS启动
编译完成busybox, make install 后,用mkfs.sh脚本生成文件系统,只是生成,不用打包成其它格式
启动:
-
qemu-system-arm -m 256 -kernel zImage -serial stdio -M vexpress-a9 -append root="/dev/nfs console=ttyAMA0 console=tty0 nfsroot=10.0.0.1:/work/qemu/rootfs rw ip=10.0.0.2:10.0.0.1:10.0.0.1:255.255.255.0 " -net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=qemu-ifup &
qemu-ifup脚本如下:
-
#!/bin/sh
-
echo "Executing /etc/qemu-ifup"
-
sudo ifconfig $1 10.0.0.1
前提是主机上的nfs-server己配置好
三. qemu调试linux系统
3.1 启动调试模式下的qemu
sun@ubuntu:/work/x86/kernel$ sh start.sh s
3.2 另起一个terminal
-
sun@ubuntu:/work/x86/kernel/linux-3.0.1$ gdb vmlinux
-
Reading symbols from /work/x86/kernel/linux-3.0.1/vmlinux...done.
-
(gdb) target remote localhost:1234
-
Remote debugging using localhost:1234
-
0x0000fff0 in ?? ()
-
(gdb) b kernel_init
-
Breakpoint 1 at 0xc15c7786: file init/main.c, line 781.
-
(gdb) c
-
Continuing.
-
-
Breakpoint 1, kernel_init (unused=0x0) at init/main.c:781
-
781 {
-
(gdb) l
-
776 panic("No init found. Try passing init= option to kernel. "
-
777 "See Linux Documentation/init.txt for guidance.");
-
778 }
-
779
-
780 static int __init kernel_init(void * unused)
-
781 {
-
782 /*
-
783 * Wait until kthreadd is all set-up.
-
784 */
-
785 wait_for_completion(&kthreadd_done);
-
(gdb)
3.3 每次都这么操作比较麻烦,可以建立一个gdbinit脚本
sun@ubuntu:/work/x86/kernel/linux-3.0.1$ vi .gdbinit
-
target remote localhost:1234
-
b kernel_init
-
c
然后下次运行时就可以
sun@ubuntu:/work/x86/kernel/linux-3.0.1$ gdb vmlinux
注意,如果用gdbinit脚本时出现以下问题:
-
warning: File "/work/x86/kernel/linux-3.0.1/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
-
To enable execution of this file add
-
add-auto-load-safe-path /work/x86/kernel/linux-3.0.1/.gdbinit
-
line to your configuration file "/home/sun/.gdbinit".
-
To completely disable this security protection add
-
set auto-load safe-path /
-
line to your configuration file "/home/sun/.gdbinit".
-
For more information about this security protection see the
-
"Auto-loading safe path" section in the GDB manual. E.g., run from the shell:
-
info "(gdb)Auto-loading safe path"
sun@ubuntu:/work/x86/kernel/linux-3.0.1$ vi ~/.gdbinit
set auto-load safe-path /
在~/.gdbini中加入上面这一行,取消掉
[参]:
以QEMU模拟Linux,学习linux内核
http://www.cnblogs.com/senix/archive/2013/02/21/2921221.html
使用qemu调试linux内核
http://blog.csdn.net/aero_boy/article/details/6262609
使用qemu模拟Coretex-A9运行u-boot和Linux
阅读(11275) | 评论(0) | 转发(1) |