你的位置:首页 > 操作系统

[操作系统]构建 ARM Linux 4.7.3 嵌入式开发环境 —— 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

  • 打开如下几个选项

append-dtb debuguart nfs-client

  • 编译,一个漫长的过程
$ 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.3MASK=255.255.255.0GATEWAY=192.168.0.1BROADCAST=192.168.0.255ETH=enp0s3 # 根据自己的网络接口修改。## First take eth0 down, then bring it up with IP address 0.0.0.0 #ifdown $ETHifconfig $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 br0brctl addif br0 $ETHbrctl 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 $BROADCASTroute 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=enp0s3ifdown $ETHifdown br0ifconfig br0 down # # Delete the bridge#brctl delbr br0 # # bring up eth0 in "normal" mode #ifconfig $ETH -promiscifup $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 MiBWARNING: Caches not enabledFlash: 128 MiBMMC:  MMC: 0*** Warning - bad CRC, using default environmentIn:  serialOut:  serialErr:  serialNet:  smc911x-0Hit any key to stop autoboot: 0 smc911x: MAC 52:54:00:12:34:56smc911x: detected LAN9118 controllersmc911x: phy initializedsmc911x: MAC 52:54:00:12:34:56Using smc911x-0 deviceTFTP from server 192.168.0.3; our IP address is 192.168.0.5Filename 'kernel'.Load address: 0x62008000Loading: #################################################################   #################################################################   #################################################################   #################################################################   #################################################################   #################################################################   #################################################################   #################################################################   #################################################################   #################################################################   ################################################   2 MiB/sdoneBytes transferred = 3571036 (367d5c hex)smc911x: MAC 52:54:00:12:34:56Kernel image @ 0x62008000 [ 0x000000 - 0x3643e8 ]Starting kernel ...Uncompressing Linux... done, booting the kernel.Booting Linux on physical CPU 0x0Linux 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 2016CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387dCPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cacheMachine model: V2P-CA9Memory policy: Data cache writebackCPU: 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

未完、待续…… 原创文章、转载请注明出处。