专栏首页RainMark 的文章构建 ARM Linux 4.7.3 嵌入式开发环境 —— U-BOOT 引导 Kernel

构建 ARM Linux 4.7.3 嵌入式开发环境 —— U-BOOT 引导 Kernel

经过若干天的反复测试,搜索。终于成功利用 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/openV** --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/openV** --rmtun --dev $1
#
# start firewall again
# 
#service firestarter start

  • 复制到 /etc 目录
$ sudo cp qemu-if* /etc
$ sudo chmod +x /etc/qemu-if*

搭建 TFTP 服务

准备启动 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.

参考文章

原创文章、转载请注明出处!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux 下终端 C 语言控制光标的技巧

    RainMark
  • I2C 总线协议

    1.I2C协议 2条双向串行线,一条数据线SDA,一条时钟线SCL。 SDA传输数据是大端传输,每次传输8bit,即一字节。 支持多主控(...

    RainMark
  • awk 基础入门

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为...

    RainMark
  • Kubernetes基础知识:先学会如何驱动它【Containers】

    在本系列的前两篇文章中,我解释了Kubernetes如何像自卸车,并且总是需要学习一些曲线来理解诸如Kubernetes(以及自卸车,起重机等)之类的优雅而专业...

    王欣壳
  • Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9

    Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9 当前两个手头有两个项目都是都需要在ARM板中使用OpenCV,...

    剑影啸清寒
  • AI诊所来了!英国将启用5家人工智能诊所

    2018年11月6日,英国政府宣布将在2019年正式启用5家人工智能医疗诊所, 这些中心将使用人工智能进行疾病诊断。

    人工智能快报
  • SAP UI5应用访问OData metadata的url和Destination

    直接在WebIDE里本地运行该Fiori应用,在Chrome开发者工具里把metadata请求的url抄下来:

    Jerry Wang
  • 热点丨无线充电行业繁华前景可预见 手机、汽车厂商齐布局

    导读:从2015年开始,各消费电子巨头纷纷推出具有无线充电功能的产品:包括苹果推 出apple watch、三星推出gear watch、S6/S6 edge、...

    钱塘数据
  • 用R根据logFC和p值批量标注基因上下调的N种方法

    Y大宽
  • 欧盟将在机场测试针对入境旅客的AI测谎系统

    一项欧盟资助的项目正在开发自动化边境管控系统,让旅客接受测谎机器人的测试。该项目在边境管控中引入了人工智能。这个名为“智能边境管控”(iBorderCtrl)的...

    人工智能快报

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动