參考:node
http://blog.csdn.net/linyt/article/details/42504975linux
Win7 64 + Vmware 11 + ubuntu14.04 32git
u-boot 版本:u-boot-2015-04express
Linux kernel版本:linux-3.16.yubuntu
busybox版本:1_24_stablebash
交叉編譯工具鏈:arm-linux-gnueabi-架構
qemu版本:stable-2.4app
下載內核有兩種方法,一種是用git直接下載內核代碼樹,方便後面的內核開發。另外一種是直接到內核社區下載對應版本的源碼包。我採用第一種方法,但後面發現 主線上3.18版本和後面版本的代碼,使用這種搭建方法運行不起來。目前未查明問題的根因。若是讀者想快速搭建成功,建議選用3.16版本的內核進行搭建。(這個剛開始我用的是linux-4.4版本的內核,用qemu-system-arm沒法運行,而後我就改用linux-3.16的內核了)工具
方法一:使用gitoop
git clonegit://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
想必作嵌入式開發的朋友,對交叉編譯工具鏈不陌生。若是你訂製一個交叉編譯工具鏈,建議你使用crosstool-ng開源軟件來構建。但在這裏建議直接安裝arm的交叉編譯工具鏈:
sudo apt-get install gcc-arm-linux-gnueabi
生成vexpress開發板子的config文件:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 vexpress_defconfig
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 menuconfig
將:
System Type --->
[ ] Enable the L2x0 outer cache controller
即, 把 Enable the L2x0 outer cache controller 取消, 不然Qemu會起不來, 暫時還不知道爲何。
編譯:
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm O=./out_vexpress_3_16 zImage -j2
生成的內核鐿像位於./out_vexpress_3_16/arch/arm/boot/zImage, 後續qemu啓動時須要使用該鏡像。
下載qemu,我用的版本是2.4版本,能夠用以下方式下載,而後checkout到2.4分支上便可
git clone git://git.qemu-project.org/qemu.git
cd qemu git checkout remotes/origin/stable-2.4 -b stable-2.4
配置qemu前,須要安裝幾個軟件包:
sudo apt-get install zlib1g-dev sudo apt-get install libglib2.0-0
sudo apt-get install libglib2.0-dev sudo apt-get install libtool sudo apt-get install libsdl1.2-dev
sudo apt-get install autoconf
配置qemu,支持模擬arm架構下的全部單板,我爲了使qemu的代碼乾淨一些,採用以下方式編譯,最後生成的中間文件都在build下
mkdir build cd build ../qemu/configure --target-list=arm-softmmu --audio-drv-list=
編譯和安裝:
make
make install
查看qemu支持哪些板子
qemu-system-arm -M help
qemu已經安裝好了,內核也編譯成功了,到這裏最好是測試一下,編譯出來的內核是否OK,或者qemu對vexpress單板支持是否夠友好。
運行命令很簡單:
qemu-system-arm \ -M vexpress-a9 \ -m 512M \ -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage \ -nographic \ -append "console=ttyAMA0"
能夠把上面的命令放到一個腳本中執行。
若是看到內核啓動過程當中的打印,說明前的搭建是成功的。
Booting Linux on physical CPU 0x0 Initializing cgroup subsys cpuset Linux version 3.16.7 (root@ubuntu) (gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-12ubuntu1) ) #5 SMP Sat Dec 5 21:17:17 PST 2015 CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c53c7d CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache Machine: ARM-Versatile Express Memory policy: Data cache writeback CPU: All CPU(s) started in SVC mode. sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns PERCPU: Embedded 7 pages/cpu @9fbed000 s7552 r8192 d12928 u32768 Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048 Kernel command line: console=ttyAMA0 PID hash table entries: 2048 (order: 1, 8192 bytes) Dentry cache hash table entries: 65536 (order: 6, 262144 bytes) Inode-cache hash table entries: 32768 (order: 5, 131072 bytes) Memory: 513272K/524288K available (4563K kernel code, 190K rwdata, 1292K rodata, 239K init, 149K bss, 11016K reserved) Virtual kernel memory layout: ...... VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6 Please append a correct "root=" boot option; here are the available partitions: 1f00 131072 mtdblock0 (driver?) Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.16.7 #5 [<8001507c>] (unwind_backtrace) from [<800115d4>] (show_stack+0x10/0x14) [<800115d4>] (show_stack) from [<8044f9c8>] (dump_stack+0x74/0x90) [<8044f9c8>] (dump_stack) from [<8044ce08>] (panic+0x90/0x1fc) [<8044ce08>] (panic) from [<805c210c>] (mount_block_root+0x1a0/0x254) [<805c210c>] (mount_block_root) from [<805c22b4>] (mount_root+0xf4/0x114) [<805c22b4>] (mount_root) from [<805c2400>] (prepare_namespace+0x12c/0x190) [<805c2400>] (prepare_namespace) from [<805c1d8c>] (kernel_init_freeable+0x1f4/0x240) [<805c1d8c>] (kernel_init_freeable) from [<8044adb8>] (kernel_init+0x8/0xec) [<8044adb8>] (kernel_init) from [<8000e4b8>] (ret_from_fork+0x14/0x3c) ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
這裏簡單介紹下qemu命令的參數:
-M vexpress-a9 模擬vexpress-a9單板,你可使用-M ?參數來獲取該qemu版本支持的全部單板
-m 512M 單板運行物理內存512M
-kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage 告訴qemu單板運行內核鏡像路徑
-nographic 不使用圖形化界面,只使用串口
-append "console=ttyAMA0" 內核啓動參數,這裏告訴內核vexpress單板運行,串口設備是哪一個tty。
注意:
我每次搭建,都忘了內核啓動參數中的console=參數應該填上哪一個tty,由於不一樣單板串口驅動類型不盡相同,建立的tty設備名固然也是不相同的。那 vexpress單板的tty設備名是哪一個呢? 其實這個值能夠從生成的.config文件CONFIG_CONSOLE宏找到。
若是搭建其它單板,須要注意內核啓動參數的console=參數值,一樣地,可從生成的.config文件中找到。
此時只能經過殺死qemu-system-arm這個進程來退出,我簡單寫了一個腳原本完成這個任務 kill_qemu.sh
#!/bin/bash ps -A | grep qemu-system-arm | awk '{print $1}' | xargs sudo kill -9
到這裏是否大功告成了呢? 其實在上面的測試中,你會發現內核報panic,由於內核找不到根文件系統,沒法啓init進程。
根文件系統要考慮兩個方面:
若是你看過《Linux From Scratch》,相信你會對這一步產生恐懼感,但若是一直從事嵌入式開發,就能夠放下心來。根文件系統就是簡單得不能再簡單的幾個命令集和態動態而已。爲何Linux From Scratch會有那麼複雜,是由於它要製做出一個Linux發生版。但在嵌入式領域,幾乎全部的東西,都是mini版本,根文件系統也不例外。
本文制本的根文件系統 = busybox(包含基礎的Linux命令) + 運行庫 + 幾個字符設備
其實依賴於每一個開發板支持的存儲設備,能夠放到Nor Flash上,也能夠放到SD卡,甚至外部磁盤上。最關鍵的一點是你要清楚知道開發板有什麼存儲設備。
本文直接使用SD卡作爲存儲空間,文件格式爲ext3格式
我用的busybox版本是1_24,下載地址:https://busybox.net/downloads/
配置:
在busybox下執行 make menuconfig
作以下配置:
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
(arm-linux-gnueabi-) Cross Compiler prefix
而後執行
make
make install
安裝完成後,會在busybox目錄下生成_install目錄,該目錄下的程序就是單板運行所須要的命令。
#!/bin/bash sudo rm -rf rootfs sudo rm -rf tmpfs sudo rm -f a9rootfs.ext3 sudo mkdir rootfs sudo cp busybox/_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
其中,etc下是啓動配置文件,能夠的到這裏下載:
qemu-system-arm \ -M vexpress-a9 \ -m 512M \ -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage \ -nographic \ -append "root=/dev/mmcblk0 console=ttyAMA0" \ -sd /root/tq2440_work/busybox_study/a9rootfs.ext3
上面是不太圖形界面的,下面的命令能夠產生一個圖形界面:
qemu-system-arm \ -M vexpress-a9 \ -serial stdio \ -m 512M \ -kernel /root/tq2440_work/kernel/linux-stable/out_vexpress_3_16/arch/arm/boot/zImage \ -append "root=/dev/mmcblk0 console=ttyAMA0 console=tty0" \ -sd /root/tq2440_work/busybox_study/a9rootfs.ext3
下一節,用Qemu模擬運行vexpress的u-boot。