QEMU搭建ARM LINUX開發環境

QEMU搭建ARM LINUX開發環境


QEMU簡介:

QEMU是一種純軟件實現的虛擬化模擬器,幾乎能夠模擬全部硬件,包括咱們本次要用的ARM A9平臺。它的原理是將guest架構代碼轉換爲TCG中間代碼,再轉換爲host架構代碼。linux

環境:

虛擬機:ubuntu18.04 LTSexpress

步驟:

  1. 安裝gcc-arm-linux-gnueabi
sudo apt install gcc-arm-linux-gnueabi

安裝完成後,咱們能夠看一下該工具鏈支持的目標架構:ubuntu

arm-linux-gnueabi-gcc --target

翻一下結果能夠看到:架構

Known ARM CPUs (for use with the -mcpu= and -mtune= options):
    arm1020e arm1020t arm1022e arm1026ej-s arm10e arm10tdmi arm1136j-s
    arm1136jf-s arm1156t2-s arm1156t2f-s arm1176jz-s arm1176jzf-s arm2 arm250
    arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm70 arm700 arm700i arm710
    arm7100 arm710c arm710t arm720 arm720t arm740t arm7500 arm7500fe arm7d
    arm7di arm7dm arm7dmi arm7m arm7tdmi arm7tdmi-s arm8 arm810 arm9 arm920
    arm920t arm922t arm926ej-s arm940t arm946e-s arm966e-s arm968e-s arm9e
    arm9tdmi cortex-a12 cortex-a15 cortex-a15.cortex-a7 cortex-a17
    cortex-a17.cortex-a7 cortex-a32 cortex-a35 cortex-a5 cortex-a53 cortex-a57
    cortex-a57.cortex-a53 cortex-a7 cortex-a72 cortex-a72.cortex-a53 cortex-a73
    cortex-a73.cortex-a35 cortex-a73.cortex-a53 cortex-a8 cortex-a9 cortex-m0
    cortex-m0.small-multiply cortex-m0plus cortex-m0plus.small-multiply
    cortex-m1 cortex-m1.small-multiply cortex-m23 cortex-m3 cortex-m33 cortex-m4
    cortex-m7 cortex-r4 cortex-r4f cortex-r5 cortex-r7 cortex-r8 ep9312
    exynos-m1 fa526 fa606te fa626 fa626te fa726te fmp626 generic-armv7-a iwmmxt
    iwmmxt2 marvell-pj4 mpcore mpcorenovfp native strongarm strongarm110
    strongarm1100 strongarm1110 xgene1 xscale

支持的arch和CPU很是全,也支持咱們此次將要模擬的cortex-a9;甚至也支持cortex-m,也就能夠編譯無MMU的單片機的內核和應用。app

  1. 安裝qemu 快捷安裝以下,或者使用源碼安裝。
sudo apt install qemu
  1. 下載內核及busybox源碼
    下載主線源碼: http://cdn.kernel.org/pub/linux/kernel/v4.x
    下載busybox:https://busybox.net/downloads/busybox-1.31.1.tar.bz2
  2. 編譯busybox
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install

至此,在busybox目錄下生成了'_intall' 目錄,將做爲咱們構建根文件系統的目錄,在根文件系統目錄下補充一些內容。
增長如下目錄:dom

  • etc :主要存放一些配置文件如:inittab(init進程會解析此文件,看進一步動做);fstab(主要包含一些掛載的文件系統,如sys proc) init.rd/rcS(可存放一些可執行腳本,配合inittab使用)
  • proc : proc文件系統掛載點
  • sys : sys文件系統掛載點
  • tmp : tmp文件系統掛載點
  • dev : 設備文件
  • lib : 庫文件目錄(若是busybox採用動態連接庫,則須要將交叉編譯鏈的庫文件拷這裏)

a. dev目錄下靜態建立以下節點:工具

sudo mknod -m 666 tty1 c 4 1
sudo mknod -m 666 tty2 c 4 2
sudo mknod -m 666 tty3 c 4 3
sudo mknod -m 666 tty4 c 4 4
sudo mknod -m 666 console c 5 1
sudo mknod -m 666 null c 1 3

console 和 null 是必須的,若是沒有則會報錯。
b. etc/inittab 文件內容以下,可參考busyboxdir/examples/inittab編寫:oop

::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh

c. etc/fstab 文件內容以下,主要目的是指明一些文件系統掛載點:測試

#device mount-point type option dump fsck order
proc  /proc proc  defaults 0 0
temps /tmp  rpoc  defaults 0 0
none  /tmp  ramfs defaults 0 0
sysfs /sys  sysfs defaults 0 0
mdev  /dev  ramfs defaults 0 0

d. etc/init.d/rcS 文件內容以下,inittab第一條指明瞭從rcS中去執行腳本ui

mount -a
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
/sbin/mdev -s       # 根據/etc/mdev.conf中的配置進行生成設備節點
mount -a

順便修改rcS的權限:

chmod 777 etc/init.d/rcS

e. lib 文件拷貝,由於busybox咱們採用默認的動態連接(建議),這樣能夠節省根文件系統大小,由於應用也能夠連接相應的庫。首先經過下邊3條命令任意一條查看busybox依賴的庫文件。

arm-linux-readelf -d busybox | grep NEEDED
arm--linux-objdump -x busybox | grep NEEDED
strings busybox | grep ^lib

注意:ld-linux.so.3有時候不會顯示,咱們也必須拷貝它,若是之後編譯應用程序,咱們也要查看依賴的庫,補足根文件系統中缺乏的庫文件。

cp /usr/arm-linux-gnueabi/lib/ld-linux.so.3 _install/lib/
cp /usr/arm-linux-gnueabi/lib/libc.so.6 _install/lib/
cp /usr/arm-linux-gnueabi/lib/libm.so.6 _install/lib/
cp /usr/arm-linux-gnueabi/lib/libresolv.so.2 _install/lib/
  1. 編譯內核
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig(option)
make

將 zImage dtb文件拷貝出來,方便使用。 若是已經咱們已經開發了一些驅動,須要進行測試,除了將ko文件拷貝到根文件系統中,也應該執行模塊安裝命令,不然modules依賴關係,參數、符號等沒法使用。

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules_install INSTALL_MOD_PATH=busybox-dir/_install/

執行完成後,將在根文件系統的lib下建立modules目錄。

  1. 建立根文件系統鏡像文件
    使用dd命令建立一個空白的32M(根據實際狀況)文件:
dd if=/dev/zero of=rootfs.ext3 bs=1M count=32

將該空白文件格式化爲ext3格式(內核默認支持文件系統,若是使用其餘須要配置內核):

mkfs.ext3 rootfs.ext3

將該空白文件,掛載在一個目錄下:

mkdir fs
sudo mount -o loop rootfs.ext3 ./fs

將busybox構建的根文件系統拷貝到掛載點下,而後再卸載

sudo cp -rf busybox-dir/_install/* ./fs
sudo umount ./fs
  1. 使用qemu運行,驗證。
    爲了方便不每次都輸一串命令,咱們能夠創建一個run.sh腳本,內容以下:
qemu-system-arm \
	-M vexpress-a9 \
	-kernel ./zImage \
	-nographic \
	-m 512M \
	-smp 4 \
	-sd ./rootfs.ext3 \
	-dtb vexpress-v2p-ca9.dtb \
	-append "init=/linuxrc root=/dev/mmcblk0 rw rootwait earlyprintk console=ttyAMA0"

上述腳本,-M 指定了目標板, -kernel 指定了linux內核鏡像, -nographic 指定無圖形顯示,-m 512M指定了運行內存大小,-smp 指定4核, -sd 指定了外部有1個sd卡,卡內是rootfs.ext3鏡像文件, -dtb 指定了設備樹文件, -append 指定了bootargs; bootargs中init=/linuxrc 指定了init進程是根文件系統下的linuxrc(busybox生成), root=/dev/mmcblk0 指定了根文件系統爲sd卡, console指定了ttyAMA0,即控制檯。

運行結果:

Booting Linux on physical CPU 0x0
Linux version 4.19.86 (yhangzzz@yhangzzz-virtual-machine) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1)) #2 SMP Sun Dec 1 13:35:37 CST 2019
CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
OF: fdt: Machine model: V2P-CA9
Memory policy: Data cache writealloc
random: get_random_bytes called from start_kernel+0x98/0x474 with crng_init=0
percpu: Embedded 16 pages/cpu s32780 r8192 d24564 u65536
Built 1 zonelists, mobility grouping on.  Total pages: 130048
Kernel command line: init=/linuxrc root=/dev/mmcblk0 rw rootwait earlyprintk console=ttyAMA0
log_buf_len individual max cpu contribution: 4096 bytes
...
...
...
EXT4-fs (mmcblk0): mounting ext3 file system using the ext4 subsystem
random: fast init done
EXT4-fs (mmcblk0): recovery complete
EXT4-fs (mmcblk0): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext3 filesystem) on device 179:0.
Freeing unused kernel memory: 1024K
Run /linuxrc as init process
random: crng init done
mount: mounting temps on /tmp failed: No such device

Please press Enter to activate this console. 
/bin/sh: can't access tty; job control turned off
/ # ls
bin         etc         lib         lost+found  sbin        tmp
dev         home        linuxrc     proc        sys         usr
/ #

本文中,使用qemu搭建了arm-a9的虛擬化平臺,用於linux內核開發、驅動開發、根文件系統構建、應用開發,或者uboot開發。雖然是虛擬的,可是和實際開發中的步驟基本一致。

相關文章
相關標籤/搜索