1.1 qemu的安装
ubuntu 12.04下安装qemu很简单,
sudo apt-get install qemu
1.2 linux内核的编译
www.kernel.org 下载内核, 以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的编译
http://www.busybox.net/ 下载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
- #!/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 : 在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-
编译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)/$@ ../
../ 是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 -
- #!/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
- qemu-system-arm -kernel zImage -M vexpress-a9 -append "root=/dev/mmcblk0 console=ttyAMA0 console=tty0" -sd a9rootfs.ext3 -serial stdio
编译完成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 &
- #!/bin/sh
- echo "Executing /etc/qemu-ifup"
- sudo ifconfig $1 10.0.0.1
三. 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)
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"
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
http://www.linuxidc.com/Linux/2012-07/65478.htm