U-Boot配置和编译

前面在大概了解U-Boot及其目录结构后,就可以开始配置和编译U-Boot了。

在U-Boot源码中有一个README文件,它描述了如何配置并编译U-Boot。(其实很多都有,只不过是英文的,哈哈哈)

正确编译U-Boot

正确编译U-Boot代码的过程如下:

1)首先是编译器的问题,如果使用GNU交叉编译工具链,请确保环境变量的设置生效。

2)为特定的板子建立配置文件。输入make NAME_config就可以,其中“NAME_config”代表一个存在的配置名称,顶层目录下的boards.cfg文件中是已经支持的配置名称。

3)最后,输入“make all”就可以得到U-Boot映像文件了。其中“u-boot.bin”是二进制文件,“U-Boot”是ELF二进制格式的文件。

其中第二步举个例子

第二步:为特定的硬件板pcDuino3建立配置文件,打开boards.cfg文件,添加一行配置信息:

Active  arm  armv7  sunxi  -  sunxi
pcDuino3  sun7i:PCDUINO,SPL,SUNXI_EMAC

然后输入make pcDuino3_config命令,执行第二步的命令,接下来分析这个命令做了什么:

%_config:: outputmakefile@$(MKCONFIG) -A $(@:_config=)

由于%是个通配符,所以无论是何种配置,make xxx_config都是这个目标。命令中的MKCONFIG在Makefile之前有如下定义:

MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG

该定义表明MKCONFIG是顶层目录下的mkconfig脚本文件。

我们继续来看完整的命令:@ ( M K C O N F I G ) − A (MKCONFIG)-A (MKCONFIG)−A(@:_config=),这里$(@:_config=)是变量的替换引用。

其具体使用方法为:格式为“ ( V A R : A = B ) ”或者“ (VAR:A=B)”或者“ (VAR:A=B)”或者“{VAR:A=B}”,意思是:**替换变量“VAR”中所有以“A”字符结尾的字为“B”结尾的字。**这将相当于把pcDuino3_config末尾的_config去除了。因此实际执行的是“mkconfig-A pcDuino3”命令。

执行该脚本将生成两个文件,这两个文件将在后面的步骤中被引用。

下面就是执行mkconfig脚本了:

mkconfig -A pcDuino3

执行该脚本,生成两个文件,一个是include/config.h,如下:

/* Automatically generated - do not edit */
#define CONFIG_PCDUINO        1
#define CONFIG_SPL        1
#define CONFIG_SUNXI_EMAC        1
#define CONFIG_SYS_ARCH  "arm"
#define CONFIG_SYS_CPU   "armv7"
#define CONFIG_SYS_BOARD "sunxi"
#define CONFIG_SYS_TARGET "pcDuino3"
#define CONFIG_SYS_SOC    "sunxi"
#define CONFIG_BOARDDIR board/sunxi
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/sun7i.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>

还有一个文件是include/config.mk,如下:

ARCH   = arm
CPU    = armv7
BOARD  = sunxi
SOC    = sunxi

下一步就是make。

因为在boards.cfg文件中有配置sun7i:PCDUINO、SPL、SUNXI_EMAC,所以这里我们将使用SPL框架。在spl目录下,有一个Makefile文件。我们简单分析一下这个Makefile文件。

(移植过uboot的都知道,uboot的启动其实是分为BL0,BL1,BL2三个阶段的,即:ROM->SPL->uboot.img.而这个SPL架构将可以编译产生一个uboot-spl.bin。即BL1的代码。也就是说SPL结构其实做的工作就是uboot的BL1阶段的工作。但是这个SPL不是必须的,后面再讲讲这个东西)

首先

CONFIG_SPL_BUILD := y
export CONFIG_SPL_BUILD

定义并导出CONFIG_SPL_BUILD,这个定义是SPL框架最重要的定义,在最初的汇编代码中很多代码段都由该定义隔开。

include include/config.mk
include $(TOPDIR)/config.mk

引入刚刚生成的include/config.mk和顶层目录下的config.mk,其中顶层目录下的config.mk是设置了一些编译链接的选项。

接下来是SPL需要的代码和模块。再往下是指定链接脚本。

# Linker Script
ifdef CONFIG_SPL_LDSCRIPT
# need to strip off double quotes
LDSCRIPT := $(addprefix $(SRCTREE)/,$(CONFIG_SPL_LDSCRIPT:"%"=%))
endif
ifeq ($(wildcard $(LDSCRIPT)),)LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-spl.lds
endif
ifeq ($(wildcard $(LDSCRIPT)),)LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-spl.lds
endif
ifeq ($(wildcard $(LDSCRIPT)),)LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot-spl.lds
Endif
ifeq ($(wildcard $(LDSCRIPT)),)
$(error could not find linker script)
endif

再下面是描述最终的目标:

ALL-y   += $(obj)/$(SPL_BIN).bin
ifdef CONFIG_SUNXI
ifndef CONFIG_SPL_FEL
ALL-y   += $(obj)/sunxi-spl.bin
endif
endif

所以最后在该目录下会生成u-boot-spl.bin和sunxi-spl.bin,其中sunxi-spl.bin是使用mksunxiboot工具生成的:

ifdef CONFIG_SUNXI
quiet_cmd_mksunxiboot = MKSUNXI $@
cmd_mksunxiboot = $(OBJTREE)/tools/mksunxiboot $< $@
$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin$(call if_changed,mksunxiboot)
Endif

签名分析的是makefile
接下来分析一下链接脚本。根据前面关于链接脚本的一系列判断和指定,此处的链接脚本采用的是arch/arm/cpu/armv7/sunxi/u-boot-spl.lds,脚本如下:

MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\LENGTH = CONFIG_SPL_MAX_SIZE }
MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{.text      :{__start = .;arch/arm/cpu/armv7/start.o        (.text)*(.text*)} > .sram. = ALIGN(4);.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram. = ALIGN(4);.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram. = ALIGN(4);__image_copy_end = .;_end = .;.bss :{. = ALIGN(4);__bss_start = .;*(.bss*). = ALIGN(4);__bss_end = .;} > .sdram
}

在脚本最开始处,使用MEMORY命令定义了两个存储区域:一个是sram,起始地址为CONFIG_SPL_TEXT_BASE,长度为CONFIG_SPL_MAX_SIZE;另一个是sdram,起始地址为CONFIG_SPL_BSS_START_ADDR,长度为CONFIG_SPL_BSS_MAX_SIZE。这几个定义都是在include/configs/sunxi-common.h中:

#define                CONFIG_SPL_TEXT_BASE           0x20
#define                CONFIG_SPL_TEXT_BASE           0x5fe0
#define                CONFIG_SPL_BSS_START_ADDR      0x50000000
#define                CONFIG_SPL_BSS_MAX_SIZE        0x80000

这里可以看到TEXT段的基址定为0x20,这是因为mksunxiboot的存在,它会加上大小为0x20的特定的头。

在SECTIONS命令中定义了.text、.rodata、.data和.bss这四个段。其中.text、.rodata和.data段放在sram内存区域中,而.bss段放在sdram内存区域中。

在.text段中,我们将arch/arm/cpu/armv7/start.o中的.text段放置在最前面,其他对象文件的.text段随后放置。在.rodata段和.data段中,使用SORT_BY_ALIGNMENT将各个对象文件的相应段对齐排序。

或许到这里你很困惑,这是因为你和我一样对SPL框架没有认识,下面我们来学一下SPL,在了解了SPL以后,再反过来看看这里对SPL的Makefile和ldscript的讲解。

U-BOOT小全(二)相关推荐

  1. 《Spring Boot+Vue全栈开发实战》读书笔记

    写在前面 嗯,回家处理一些事,所以离职了,之前的公司用开源技术封装了一套自己的低代码平台,所以之前学的spring Boot之类的东西都忘了很多,蹭回家的闲暇时间复习下. 笔记整体以 Spring B ...

  2. ICANN认证注册商小全 英、德、法

    转载 在ICANN认证注册商小全(一)和ICANN认证注册商小全(二)中,QQPCC介绍了美洲的各ICANN认证注册商.今天我们移师欧洲,介绍欧洲的ICANN认证注册商,欧洲的注册商也很多,不可能在一 ...

  3. windos命令小全

    win&dos命令小全 net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ " ...

  4. Java生成微信小程序二维码,5种实现方式,一个比一个简单

    文章目录 前言 先看官网 一.JDK自带的URLConnection方式 二.Apache的HttpClient方式 三.okhttp3方式 四.Unirest方式 五.RestTemplate方式 ...

  5. python画二维温度云图_“绘图,让化学生动起来”:Python-matplotlib绘图(全二维气相色谱图分析专题)...

    作者简介:85后一名分析化学工作者及科学爱好者,深爱着北京的老北京人,爱好运动,科学,旅行,本文作者的个人微信公众号<科学是什么东东>,欢迎关注! 作者的本职工作为分析化学,因此,在这一专 ...

  6. 生活小窍门小全-热爱生活,就收藏它吧!

    * 生活小窍门小全-热爱生活,就收藏它吧!       [转贴 2006-03-03 23:15:14 ] 发表者: 盈富基金 1 .生活窍门:巧用牙膏6:若有小面积皮肤损伤或烧伤.烫伤,抹上少许牙膏 ...

  7. 读书笔记《Spring Boot+Vue全栈开发实战》(下)

    本书将带你全面了解Spring Boot基础与实践,带领读者一步步进入 Spring Boot 的世界. 前言 第九章 Spring Boot缓存 第十章 Spring Boot安全管理 第十一章 S ...

  8. 【Redis版】spring boot高性能实现二维码扫码登录(中)

    作者: 刘冬 来源:http://www.cnblogs.com/GoodHelper/p/8643071.html 前言 本打算用CountDownLatch来实现,但有个问题我没有考虑,就是当用户 ...

  9. ICLR 2022|唯快不破!面向极限压缩的全二值化BiBERT

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者 秦浩桐 量子位 转载 | 公众号 QbitAI 近年来,预训练 ...

  10. 小程序之 保存canvas生成商品图片附加小程序二维码 分享到朋友圈

    小程序之 保存canvas生成商品图片附加小程序二维码 分享到朋友圈 一.概述 需要用到的生成二维码组件(可自行下载添加到小程序根目录utils里):https://github.com/demi52 ...

最新文章

  1. 【bzoj1511】[POI2006]OKR-Periods of Words KMP-next数组
  2. 洛谷【算法1-4】递推与递归
  3. JS-Object 对象的相关方法
  4. 在 WebStorm 中误添加自定义的 HTML 属性,如何删除
  5. .NET Core采用的全新配置系统[7]: 将配置保存在数据库中
  6. “老师,弃了吧,做个别的……”“笑话,都到这个份上了,怎么能弃掉呢?”...
  7. mysql 触发器 for each row 理解_“for each row”如何在mysql中的触发器中工作?
  8. mysql slow log 分析工具_mysql slow log分析工具的比较
  9. 学了java然后深入_JAVA8学习——从源码角度深入Stream流(学习过程)
  10. python坦克大战小游戏,打包为exe文件
  11. python实现求解列表中元素的排列和组合问题
  12. 计算机应用基础课程基本要求,《计算机应用基础》课程建设规范
  13. Maven环境变量配置及是否成功
  14. 爆料!爆料!亚马逊跨境电商店铺骗局被骗真相曝光!不要在上当了!
  15. Python打印简单杨辉三角形
  16. krait和kryo_HBase和Kryo混合使用时出现的jar包冲突
  17. 操作系统--05输入输出
  18. C#(三十二)之Windows绘图
  19. 电化学工作站求峰高实现设计
  20. Docker网络、端口映射详解篇(三)

热门文章

  1. 使用 Go 构建 Kubernetes 应用
  2. 信号与系统3-傅里叶变换与频域分析
  3. MP4文件中h264的 SPS、PPS获取
  4. HTTP就绪状态和HTTP状态码
  5. 【iuap5.0特性解读】构建以业务创新和能力沉淀为核心的中台架构体系
  6. 【C++模板】类模板的全部特例化和局部特例化(偏特化-partial specialization)
  7. UI实用素材|衬线字体素材的应用要点
  8. Twitter相关功能集成
  9. iOS中ImageIO框架详解与应用分析
  10. 一个9年运维的经验之路