Centos7 搭建qemu模拟器模拟arm-vexpress-a9开发板
-
参考:
整理: 寒水司天 https://www.cnblogs.com/phldylj/p/8299326.html
发布: 2018-01-16 23:06
原作: 用Qemu模拟vexpress-a9 by 摩斯电码 https://www.cnblogs.com/pengdonglin137/p/5023342.html -
转载说明:
参考以上资料,在CentOS7中搭建成功,感谢摩斯电码等先行的分享。搭建的时候填了一些坑,希望对来者有所帮助,以下是搭建手记。
1、交叉编译器的下载与安装
-
1、下载地址:http://blog.csdn.net/dldw8816/article/details/46004167
linaro.org的编译工具链 (https://releases.linaro.org/components/toolchain/binaries/)
-
linaro.org, arm-linux-gnueabi, 6.3.1-2017.05
- gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi.tar.xz — 27-Feb-2018 00:35 97.8M (OK)
- gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz — 26-Feb-2018 23:50 77.0M
- runtime-gcc-linaro-6.3.1-2017.05-arm-linux-gnueabi.tar.xz — 28-Jan-2018 18:33 6.2M
- sysroot-glibc-linaro-2.23-2017.05-arm-linux-gnueabi.tar.xz — 27-Feb-2018 00:35 38.4M
-
linaro.org, arm-eabi (bare-metal, 裸机), 6.3-2017.05
ARM官方的编译工具链
- arm.com, arm-eabi (AArch32 bare-metal target, 裸机), 8.2-2019.01
- AArch32 target with soft float (arm-linux-gnueabi)
-
-
2、然后解压缩
# tar jxvf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 tar xvf gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabi.tar.xz
-
3、添加环境变量,假定压缩包所在目录为/home,解压后目录为arm-linux-gnueabi-6。
vim /etc/profile # 在最下面添加 export PATH=$PATH:/home/arm-linux-gnueabi-6/bin # 然后更新 source /etc/profile
-
4、测试是否安装成功
arm-linux-gnueabi-gcc -v
2、qemu的安装
-
参考:
-
步骤:
# 下载源代码 wget https://download.qemu.org/qemu-3.1.0.tar.xz tar xvf qemu-3.1.0.tar.xz # 新建编译目标路径 mkdir build # 编译 cd qemu-3.1.0 ./configure --target-list=arm-softmmu --audio-drv-list= --prefix=/root/qemu/build # 配置qemu,支持模拟arm架构下的全部单板 # ./configure --prefix=/root/xxx/build make -j8 make install # 说明: $./configure --enable-kvm --enable-debug --enable-vnc --enable-werror --target-list=arm-softmmu --audio-drv-list= # configure脚本用于生成Makefile,其选项可以用./configure --help查看。这里使用到的选项含义如下: # --enable-kvm:编译KVM模块,使QEMU可以利用KVM来访问硬件提供的虚拟化服务。 # --enable-vnc:启用VNC。 # --enalbe-werror:编译时,将所有的警告当作错误处理。 # --target-list:选择目标机器的架构。默认是将所有的架构都编译,但为了更快的完成编译,指定需要的架构即可。
3、uboot安装
-
1)、源文件下载: http://ftp.denx.de/pub/u-boot/
wget http://ftp.denx.de/pub/u-boot/u-boot-2018.09.tar.bz2
-
2)、解压源文件
tar jvxf u-boot-2018.01.tar.bz2 -C xxxx (xxx为需要解压的目录)
-
3)、进入U-Boot 源文件目录,然后执行:
# export CROSS_COMPILE=arm-none-eabi- export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi- # 要求bison等 yum install bison flex # 编译 make vexpress_ca9x4_defconfig make # 或执行如下2个步骤 # make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_ca9x4_defconfig # make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm
编译完成后,如果目录下生成 u-boot 文件,则说明编译成功。
-
4)、在U-Boot源码目录下编写脚本 run.sh
qemu-system-arm -M vexpress-a9 -nographic -m 512M -kernel u-boot
然后 chmod +x run.sh 增加文件执行权限。
-
5)、最后执行./run.sh,可以看到启动了bootloader,但是会提示没有映像文件
smc911x: MAC 52:54:00:12:34:56 Wrong Image Format for bootm command ERROR: can't get kernel image! =>
按 Ctrl+a,X 退出
4、编译内核
-
参考博文: http://blog.csdn.net/aggresss/article/details/54946438
-
Git clone
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-
直接下载
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v3.x/linux-3.18.135.tar.xz
-
1)、从arch/arm/configs下找到需要编译内核的配置文件vexpress_defconfig,复制到源码根目录下
-
2)、执行命令
# export CROSS_COMPILE=arm-none-eabi- # export ARCH=arm make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig # 生成vexpress开发板的config文件 make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm zImage make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm modules make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm dtbs
-
3)、编译后生成 在 arch/arm/boot 目录下生成 zImage 文件,则说明编译成功。
- 测试
qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage -nographic -append "console=ttyAMA0"
- 内核启动参数中的console=参数应该填上哪个tty?
- 参考:https://blog.csdn.net/qingtian12138/article/details/53609526
- 解决: 因为不同单板串口驱动类型不尽相同,创建的tty设备名当然也是不相同的。那vexpress单板的tty设备名是哪个呢? 其实这个值可以从生成的.config文件CONFIG_CONSOLE宏找到。
- 测试
-
4)、关于内核版本
- 参考: https://www.cnblogs.com/mfmdaoyou/p/6934098.html
- 说明: 发现主线上3.18版本号和后面版本号的代码,使用这样的搭建方法执行不起来。眼下未查明问题的根因。假设读者想高速搭建成功。建议选用3.16版本号的内核进行搭建。
-
5)、笔者用5.4版本的arm-none-eabi-编译3.1.16版本的内核时,报如下错误
include/linux/compiler-gcc.h:106:30: fatal error: linux/compiler-gcc6.h: No such file or directory #include gcc_header(__GNUC__)
- 可在Linaro官网(https://releases.linaro.org/components/toolchain/binaries/)上下载相应版本的交叉编译工具解决这个问题。
# 原因是因为我使用的交叉编译工具链版本太高(6.2.1版本)导致,先在内核代码根目录下搜索compiler-gcc* ./include/linux/compiler-gcc3.h ./include/linux/compiler-gcc5.h ./include/linux/compiler-gcc.h ./include/linux/compiler-gcc4.h # 支持的版本有3、4、5,在Linaro官网上下载5版本的交叉编译工具链即可解决问题。
- 笔者用gcc-linaro-6.3.1版本的arm-linux-gnueabi编译3.1.16时也报告上述问题,编译3.18.135版本未有报告上述问题。
- 可在Linaro官网(https://releases.linaro.org/components/toolchain/binaries/)上下载相应版本的交叉编译工具解决这个问题。
5、编译busybox
-
1)、从https://busybox.net/downloads/下载busybox
-
2)、进入 Busybox 源文件目录下执行 make menuconfig,如果报错,则yum list ncurses,然后安装列出来的东西
Busybox Setting -> Build options -> Build Busybox as a static binary (no shared libs) # 选中 静态编译。 -> Cross Compiler prefix # 交叉编译器配置(arm-linux-gnueabi-,可make命令带入) -> Installation options -> BusyBox installation prefix # 默认目标位置(若不指定,需手动移到rootfs;若已有rootfs,可指定rootfs位置<推荐,自动完成>)
注意:若不选中“Build Busybox as a static binary (no shared libs)”,起qemu运行时,将会报“kernel panic”错误!
-
3)、编译
make distclean # 清除原有配置 make menuconfig # 配置命令选项 make CROSS_COMPILE=arm-linux-gnueabi- make CROSS_COMPILE=arm-linux-gnueabi- install # 在_install 目录下生成编译文件: bin sbin linuxrc usr 等
-
4)、问题
- 用arm-none-eabi-编译busybox时,报找不到curses.h错误
# make menuconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/basic/split-include HOSTCC scripts/basic/docproc HOSTCC scripts/kconfig/conf.o HOSTCC scripts/kconfig/kxgettext.o HOSTCC scripts/kconfig/mconf.o HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/mconf HOSTCC scripts/kconfig/lxdialog/checklist.o In file included from scripts/kconfig/lxdialog/checklist.c:24:0: scripts/kconfig/lxdialog/dialog.h:31:20: 致命错误:curses.h:没有那个文件或目录 #include CURSES_LOC
- 解决:
- 方法: 编译application时,不适合使用**arm-none-eabi-版本的编译器,而应该使用arm-linux-gnueabi-**版本的编译器
- 参考: ARM交叉编译器GNUEABI、NONE-EABI、ARM-EABI、GNUEABIHF等的区别 (http://www.veryarm.com/296.html)
6、制作根文件系统
-
1)、创建一个空白文件,32M
dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
-
2)、格式化
mkfs.ext3 a9rootfs.ext3
-
3)、创建根文件系统目录
mkdir rootfs
-
4)、拷贝busybox下的文件
cp busybox/busybox-1.26.2/_install/* -r rootfs/
-
5)、拷贝交叉编译器的lib
mkdir rootfs/lib/ cp -P /xxx/arm-linux-gnueabi/lib/* rootfs/lib/
-
6)、创建终端设备
mkdir rootfs/dev/ mknod rootfs/dev/tty1 c 4 1 mknod rootfs/dev/tty2 c 4 2 mknod rootfs/dev/tty3 c 4 3 mknod rootfs/dev/tty4 c 4 4 mknod rootfs/dev/console c 5 1 mknod rootfs/dev/null c 1 3
-
7)、创建必要目录
mkdir -p rootfs/proc/ mkdir -p rootfs/sys/ mkdir -p rootfs/tmp/ mkdir -p rootfs/root/ mkdir -p rootfs/var/ mkdir -p rootfs/mnt/
-
8)、创建临时目录并与空白文件映射,目的是将根文件系统拷贝进去
mkdir tmpfs mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop cp -r rootfs/* tmpfs/ umount tmpfs
-
0)、以上步骤的脚本
建立一个目录,将zImage,vexpress-v2p-ca9.dtb,_install目录拷贝在一个目录下# 打开脚本文件 vim mkrootfs.sh # 粘贴如下内容 rm -rf rootfs rm -rf tmpfs rm -f a9rootfs.ext3 mkdir rootfs cp ../busybox/busybox-1.26.2/_install/* rootfs/ -raf # 与你的busybox的目录有关 mkdir -p rootfs/proc/ mkdir -p rootfs/sys/ mkdir -p rootfs/tmp/ mkdir -p rootfs/root/ mkdir -p rootfs/var/ mkdir -p rootfs/mnt/ cp -arf ~/xxx/arm-linux-gnueabi-6/lib/lib rootfs/ # 与你的arm-linux-gnueabi-的目录有关 rm rootfs/lib/*.a arm-linux-gnueabi-strip rootfs/lib/* mkdir -p rootfs/dev/ mknod rootfs/dev/tty1 c 4 1 mknod rootfs/dev/tty2 c 4 2 mknod rootfs/dev/tty3 c 4 3 mknod rootfs/dev/tty4 c 4 4 mknod rootfs/dev/console c 5 1 mknod rootfs/dev/null c 1 3 dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32 mkfs.ext3 a9rootfs.ext3 mkdir -p tmpfs mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop cp -r rootfs/* tmpfs/ umount tmpfs
7、启动
# 拷贝kernel文件到a9rootfs.ext3所在目录,以便执行
cp -r ../kernel/linux-3.18.135/arch/arm/boot/ .
# 执行
qemu-system-arm -nographic -sd a9rootfs.ext3 -M vexpress-a9 -m 512M -kernel zImage -dtb ./dts/vexpress-v2p-ca9.dtb -append "init=/linuxrc root=/dev/mmcblk0 rw rootwait earlyprintk console=ttyAMA0"
qemu-system-arm -serial stdio -sd a9rootfs.ext3 -M vexpress-a9 -m 512M -kernel zImage -dtb ./dts/vexpress-v2p-ca9.dtb -append "init=/linuxrc root=/dev/mmcblk0 rw rootwait earlyprintk console=ttyAMA0"
8、注意
- 1)、以上在编译前请确保export ARCH=arm ;export CROSS_COMPILE=arm-linux-gnueabi-
- 2)、若报错,一般是某些库没有包含,自行百度或google
9、问题
- 1)、audio: Could not init `oss’ audio driver
- 解决: [QEMU下虚拟机内的声卡模拟方法总结 (https://blog.csdn.net/hubbybob1/article/details/77199567)] (https://blog.csdn.net/hubbybob1/article/details/77199567)