thorn@ubuntu:~$ arm-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/4.9/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.9.3-13ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/arm-linux-gnueabi/include/c++/4.9.3 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-armel-cross/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-armel-cross --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-armel-cross --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libgcj --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv5t --with-float=soft --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include
Thread model: posix
gcc version 4.9.3 (Ubuntu/Linaro 4.9.3-13ubuntu2)
qemu版本:
git clone git://git.qemu-project.org/qemu.git
cd qemu
git checkout remotes/origin/stable-2.4 -b stable-2.4
linux源码内核版本:
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.tar.xz
作为一个希望在嵌入式方向发展的同学,目前还没有真正的接触过嵌入式linux开发,很是惭愧,那么从模拟器开始吧。
总共花了2个多小时的时间,包括下载代码。由于对其中的某些过程还不是很理解,一路很是曲折。即便搭建起来了环境,还需要自己慢慢品味才行。
1. 首先下载Linux内核,以流行的3.16为例的原因是,作为一个初学者,希望有更多的参考资料。
两种方法:
使用git
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
直接下载3.16源代码包
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.16.tar.xz
与大多数的搭建过程不同,我选择了直接下载源码,原因有2:
以源码为基础,与大多数时候的开发环境相符,且更有成就感
因为是压缩包,源码的下载速度更快
内核下载完毕之后,解压。这些基本的操作大家都不会陌生。紧接下来的,安装arm的交叉编译链工具,这一步特别关键。很多参考资料直接给出了这样的命令行sudo apt-get install gcc-arm-linux-gnueabi
,这是不严谨的,因为,随着gcc的更新,相关的工具链会做更新。
然而内核的编译过程却还是依赖着比较老的gcc工具链,这会导致编译过程中出现很多莫名其妙的问题,而这些问题,对于新手的成长弊大于利。
我在这个问题上面花了太多的时间,因为在编译的过程中总会出现莫名其妙的错误,改了一个,又出现另一个,如:
fatal error: linux/compiler-gcc5.h: No such file or directory
Makefile:901: recipe for target 'init' failed
scripts/Makefile.build:390: recipe for target 'init/mounts.o' failed
multiple definition of `return_address
可能要开始怀疑人生了。
对于每一个版本的内核,官方都会有推荐的工具链,版本不一定越高越好,匹配才行。
比如3.16的内核,gcc用4.9的是ok的,那么可能需要自己手动安装。
thorn@ubuntu:/usr/bin$ ls -l
找到下面我们需要的关键信息,即一个软链接文件。
lrwxrwxrwx 1 root root 34 Feb 27 21:56 arm-linux-gnueabi-gcc -> /usr/bin/arm-linux-gnueabi-gcc-5
这个文件表明我们使用的arm-linux-gnueabi-gcc 实际上是arm-linux-gnueabi-gcc-5,那么就需要自己手动安装:
sudo apt-get install gcc-4.9-arm-linux-gnueabi
sudo apt-get install gcc-4.9-arm-linux-gnueabi-base
由于不知道有何区别,索性都安装了下。
并不需要卸载老版本的gcc,安装之后,只需要自己手动更改默认的gcc版本:
删除arm-linux-gnueabi-gcc,它只是个到/usr/bin/arm-linux-gnueabi-gcc-5的软链接
thorn@ubuntu:/usr/bin$ sudo rm /usr/bin/arm-linux-gnueabi-gcc
重新建立我们需要的软链接
thorn@ubuntu:~/linux-3.16$ sudo ln -s /usr/bin/arm-linux-gnueabi-gcc-4.9 /usr/bin/arm-linux-gnueabi-gcc
做过了这一步再编译,云开见日,以前莫名其妙的错误都消失了。
那么thorn@ubuntu:/usr/bin$ ls -l
后可以看到,gcc已经指向正确:
lrwxrwxrwx 1 root root 34 Feb 27 21:56 arm-linux-gnueabi-gcc -> /usr/bin/arm-linux-gnueabi-gcc-4.9
编译linux内核:
生成vexpress开发板的config文件
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 vexpress_defconfig
网上资料有如下步骤,据说是如果不做这个步骤,后面qemu会起不来。按照这个步骤,结果没有问题:
执行如下命令:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 menuconfig
将System Type -->的Enable the L2x0 outer cache controller 取消
git clone git://git.qemu-project.org/qemu.git
cd qemu
git checkout remotes/origin/stable-2.4 -b stable-2.4
配置以前需要安装若干个软件包,惭愧的是自己并不知道这几个软件包的作用
sudo apt-get install zlib1g-dev libglib2.0-0 libglib2.0-dev libtool libtool libsdl1.2-dev autoconf
配置qemu,为了使qemu代码干净,中间文件都生成到build目录下
thorn@ubuntu:~/qemu$ mkdir build
thorn@ubuntu:~/qemu$ cd build/
thorn@ubuntu:~/qemu/build$ ../configure --target-list=arm-softmmu --audio-drv-list=
编译,安装
sudo make install
如果不是在root权限下,一定要加上sudo,比如我之前不知,就出现了如下的错误:
install -d -m 0755 "/usr/local/share/qemu"
cannot change permissions of ‘/usr/local/share/qemu’: No such file or directory
感谢google,我找到了这个error的解决办法。
测试qemu和内核能否运行成功
qemu已经安装好了,内核也编译成功了,到这里测试一下,编译出来的内核是否OK,或者qemu对vexpress单板支持是否够友好。
命令如下:
thorn@ubuntu:~/linux-3.16/out_vexpress_3_16$ qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/thorn/linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage -nographic -append "console=ttyAMA0"
如果看到内核启动过程中的打印,说明前的搭建是成功的。
-M vexpress-a9 模拟vexpress-a9单板,你可以使用-M ?参数来获取该qemu版本支持的所有单板
-m 512M 单板运行物理内存512M
-kernel /home/ivan/kernel_git/linux/arch/arm/boot/zImage 告诉qemu单板运行内核镜像路径
-nographic 不使用图形化界面,只使用串口
-append "console=ttyAMA0" 内核启动参数,这里告诉内核vexpress单板运行,串口设备是哪个tty。
以下命令杀死qemu-system-arm这个进程:
ps -A | grep qemu-system-arm | awk '{print $1}' | xargs sudo kill -9
以上就是本人arm运行环境的搭建过程,如有问题,欢迎评论,参考如下:
从零使用qemu模拟器搭建arm运行环境
用Qemu模拟vexpress-a9 (一) --- 搭建Linux kernel调试环境
Google
3. 制作根文件系统
你会注意到,有panic,我们还没有制作根文件系统
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
下载、编译和安装busybox
wget http://www.busybox.NET/downloads/busybox-1.20.2.tar.bz2
thorn@ubuntu:~/busybox-1.20.2$ make defconfig
thorn@ubuntu:~/busybox-1.20.2$ make CROSS_COMPILE=arm-linux-gnueabi-
thorn@ubuntu:~/busybox-1.20.2$ make install CROSS_COMPILE=arm-linux-gnueabi-
安装完成后,会在busybox目录下生成_install目录,该目录下的程序就是单板运行所需要的命令。
形成根目录结构
先在Ubuntu主机环境下,形成目录结构,里面存放的文件和目录与单板上运行所需要的目录结构完全一样,然后再打包成镜像(在开发板看来就是SD卡),这个临时的目录结构称为根目录。
可以写一个脚本mkrootfs.sh完成这个任务
#!/bin/bash
sudo rm -rf rootfs
sudo rm -rf tmpfs
sudo rm -f a9rootfs.ext3
sudo mkdir rootfs
sudo cp ~/busybox-1.20.2/_install/* rootfs/ -raf
sudo mkdir -p rootfs/proc/
sudo mkdir -p rootfs/sys/
sudo mkdir -p rootfs/tmp/
sudo mkdir -p rootfs/root/
sudo mkdir -p rootfs/var/
sudo mkdir -p rootfs/mnt/
sudo cp ~/etc rootfs/ -arf
sudo cp -arf /usr/arm-linux-gnueabi/lib rootfs/
sudo rm rootfs/lib/*.a
sudo arm-linux-gnueabi-strip rootfs/lib/*
sudo mkdir -p rootfs/dev/
sudo mknod rootfs/dev/tty1 c 4 1
sudo mknod rootfs/dev/tty2 c 4 2
sudo mknod rootfs/dev/tty3 c 4 3
sudo mknod rootfs/dev/tty4 c 4 4
sudo mknod rootfs/dev/console c 5 1
sudo mknod rootfs/dev/null c 1 3
sudo dd if=/dev/zero of=a9rootfs.ext3 bs=1M count=32
sudo mkfs.ext3 a9rootfs.ext3
sudo mkdir -p tmpfs
sudo mount -t ext3 a9rootfs.ext3 tmpfs/ -o loop
sudo cp -r rootfs/* tmpfs/
sudo umount tmpfs
thorn@ubuntu:/$ sudo ./mkrootfs.sh
由于在根目录下执行这个sh文件,故需要加上sudo。
接下来,就可以启动qemu来模拟vexpress开发板了,命令参数如下:
sudo qemu-system-arm \
-M vexpress-a9 \
-m 512M \
-kernel /home/thorn/linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage \
-nographic \
-append "root=/dev/mmcblk0 console=ttyAMA0" \
-sd a9rootfs.ext3
由于要读写根目录下的文件,故,执行qemu时要加上sudo。
其中要注意的是,-sd a9rootfs.ext3,这个指的是绝对路径,由于我是在根目录下做这个的,所以,-sd后面直接是a9rootfs.ext3。
执行结果如下:
-serial stdio \
-m 512M \
-kernel /home/thorn/linux-3.16/out_vexpress_3_16/arch/arm/boot/zImage \
-append "root=/dev/mmcblk0 console=ttyAMA0 console=tty0" \
-sd a9rootfs.ext3
执行结果如下: