經過若幹天的反覆測試,搜索。終於成功利用 Qemu 在 u-boot 下引導 ARM Linux 4.7.3 內核。如下詳細解釋整個構建過程。 準備環境 運行環境:Ubuntu 16.04 需要的虛擬機:Qemu 交叉編譯環境:ARM GCC 內核源碼:Linux 4.7.3 u-boot源碼:u- ...
經過若幹天的反覆測試,搜索。終於成功利用 Qemu 在 u-boot 下引導 ARM Linux 4.7.3 內核。如下詳細解釋整個構建過程。
準備環境
- 運行環境:Ubuntu 16.04
- 需要的虛擬機:Qemu
- 交叉編譯環境:ARM GCC
- 內核源碼:Linux 4.7.3
- u-boot源碼:u-boot-2016.09
安裝 Qemu 、 ARM GCC
$ sudo add-apt-repository ppa:linaro-maintainers/tools $ sudo apt-get install linaro-image-tools qemu-user-static qemu-system $ sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi $ sudo apt install bridge-utils
下載、編譯 U-BOOT 源碼
- 下載源碼
$ wget -c ftp://ftp.denx.de/pub/u-boot/u-boot-2016.09.tar.bz2 $ tar xvf u-boot-2016.09.tar.bz2 $ cd u-boot-2016.09
- 修改配置文件 include/configs/vexpress_common.h
#define V2M_BASE 0x80000000 #define CONFIG_SYS_TEXT_BASE 0x80800000 #endif /* 添加如下三行代碼 */ #define CONFIG_IPADDR 192.168.0.5 #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_SERVERIP 192.168.0.3 /* * Physical addresses, offset from V2M_PA_CS0-3 */ #define V2M_NOR0 (V2M_PA_CS0) #define V2M_NOR1 (V2M_PA_CS1) ........ ........ ........ /* 對如下 CONFIG_BOOTCOMMAND 作出修改 */ /* Basic environment settings */ #define CONFIG_BOOTCOMMAND \ "run distro_bootcmd; " \ "run bootflash; " #undef CONFIG_BOOTCOMMAND #define CONFIG_BOOTCOMMAND "tftp 0x62008000 kernel; setenv bootargs 'root=/dev/mmcblk0 console=ttyAMA0,38400n8'; bootz 0x62008000" #define BOOT_TARGET_DEVICES(func) \ func(MMC, mmc, 1) \ func(MMC, mmc, 0) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na) #include <config_distro_bootcmd.h>
- 編譯源碼
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_ca9x4_defconfig $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- $ mkdir -p ~/tftp $ ln -sf $PWD/u-boot ~/tftp
準備內核鏡像文件
- 下載源碼
$ wget -c https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.7.3.tar.xz $ tar xvf linux-4.7.3.tar.xz $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_defconfig $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
- 打開如下幾個選項
- 編譯,一個漫長的過程
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all $ ln -sf arch/arm/boot/dts/vexpress-v2p-ca9.dtb ~/tftp $ ln -sf arch/arm/boot/zImage ~/tftp
準備 Qemu 網路
- qemu-ifup 內容如下。
#!/bin/sh # #cript to bring up the tun device in QEMU in bridged mode # first parameter is name of tap device (e.g. tap0) # # some constants specific to the local host - change to suit your host # ETH0IPADDR=192.168.0.3 MASK=255.255.255.0 GATEWAY=192.168.0.1 BROADCAST=192.168.0.255 ETH=enp0s3 # 根據自己的網路介面修改。 # # First take eth0 down, then bring it up with IP address 0.0.0.0 # ifdown $ETH ifconfig $ETH 0.0.0.0 promisc up # # Bring up the tap device (name specified as first argument, by QEMU) # #/usr/sbin/openvpn --mktun --dev $1 --user `id -un` ifconfig $1 0.0.0.0 promisc up # # create the bridge between eth0 and the tap device # brctl addbr br0 brctl addif br0 $ETH brctl addif br0 $1 # # only a single bridge so loops are not possible, turn off spanning tree protocol # brctl stp br0 off # # Bring up the bridge with ETH0IPADDR and add the default route # ifconfig br0 $ETH0IPADDR netmask $MASK broadcast $BROADCAST route add default gw $GATEWAY # # stop firewall - comment this out if you don't use Firestarter # #service firestarter stop
- qemu-ifdown
#!/bin/sh # # Script to bring down and delete bridge br0 when QEMU exits # # Bring down eth0 and br0 # ETH=enp0s3 ifdown $ETH ifdown br0 ifconfig br0 down # # Delete the bridge # brctl delbr br0 # # bring up eth0 in "normal" mode # ifconfig $ETH -promisc ifup $ETH # # delete the tap device # #/usr/sbin/openvpn --rmtun --dev $1 # # start firewall again # #service firestarter start
- 複製到 /etc 目錄
$ sudo cp qemu-if* /etc $ sudo chmod +x /etc/qemu-if*
搭建 TFTP 服務
- 本文中設置的 TFTP 服務的根目錄為 ~/tftp 。
- 參考如下文章,配置 TFTP 服務。
- How do I install and run a TFTP server?
準備啟動 U-BOOT
- append 設備樹到 zImage
$ cd ~/tftp && cp zImage kernel $ cat express-v2p-ca9.dtb >> kernel
- 啟動 U-BOOT
$ sudo qemu-system-arm -M vexpress-a9 \ -m 128M -nographic \ -net nic -net tap,ifname=tap0 \ -kernel u-boot \ -dtb vexpress-v2p-ca9.dtb
- 如果中間沒有出現問題,則能成功啟動內核。
U-Boot 2016.07 (Sep 16 2016 - 11:18:06 +0800) DRAM: 128 MiB WARNING: Caches not enabled Flash: 128 MiB MMC: MMC: 0 *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: smc911x-0 Hit any key to stop autoboot: 0 smc911x: MAC 52:54:00:12:34:56 smc911x: detected LAN9118 controller smc911x: phy initialized smc911x: MAC 52:54:00:12:34:56 Using smc911x-0 device TFTP from server 192.168.0.3; our IP address is 192.168.0.5 Filename 'kernel'. Load address: 0x62008000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################ 2 MiB/s done Bytes transferred = 3571036 (367d5c hex) smc911x: MAC 52:54:00:12:34:56 Kernel image @ 0x62008000 [ 0x000000 - 0x3643e8 ] Starting kernel ... Uncompressing Linux... done, booting the kernel. Booting Linux on physical CPU 0x0 Linux version 4.7.3 (rain@rain-pc) (gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.1) ) #7 SMP Fri Sep 16 11:11:23 CST 2016 CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387d CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache Machine model: V2P-CA9 Memory policy: Data cache writeback CPU: All CPU(s) started in SVC mode.
參考文章
- ARM Versatile Express Emulation On Qemu: From Scratch
- Virtual ARM Linux environment
- Virtual_Development_Board
- How do I install and run a TFTP server?
- Does kernel config option “Use appended device tree blob to zImage (EXPERIMENTAL)” work?
- 用Qemu模擬vexpress-a9 (三)— 實現用u-boot引導Linux內核
- Kernel - Common Problems Booting Linux
Next : 構建 ARM Linux 4.7.3 嵌入式開發環境 —— BusyBox 構建 RootFS
原創文章、轉載請註明出處!