用Qemu模擬vexpress-a9 (一) --- 搭建Linux kernel調試環境

參考: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

 

下載Linux內核

下載內核有兩種方法,一種是用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

 

安裝arm的交叉編譯工具鏈

 想必作嵌入式開發的朋友,對交叉編譯工具鏈不陌生。若是你訂製一個交叉編譯工具鏈,建議你使用crosstool-ng開源軟件來構建。但在這裏建議直接安裝arm的交叉編譯工具鏈:

sudo apt-get install gcc-arm-linux-gnueabi

編譯Linux內核

 生成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模擬器

下載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和內核可否運行成功

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進程。

根文件系統要考慮兩個方面:

1. 根文件系統的內容

    若是你看過《Linux From Scratch》,相信你會對這一步產生恐懼感,但若是一直從事嵌入式開發,就能夠放下心來。根文件系統就是簡單得不能再簡單的幾個命令集和態動態而已。爲何Linux From Scratch會有那麼複雜,是由於它要製做出一個Linux發生版。但在嵌入式領域,幾乎全部的東西,都是mini版本,根文件系統也不例外。

   本文制本的根文件系統 = busybox(包含基礎的Linux命令)  + 運行庫 + 幾個字符設備

 

2. 根文件系統放在哪裏

     其實依賴於每一個開發板支持的存儲設備,能夠放到Nor Flash上,也能夠放到SD卡,甚至外部磁盤上。最關鍵的一點是你要清楚知道開發板有什麼存儲設備。

     本文直接使用SD卡作爲存儲空間,文件格式爲ext3格式

下載、編譯和安裝busybox

我用的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目錄,該目錄下的程序就是單板運行所須要的命令。

造成根目錄結構

先在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/_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來模擬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 "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。

相關文章
相關標籤/搜索