目录

u-boot(二)makefile

  • 引入
  • 目录结构(1.1.6)
  • 配置文件
  • 目标
  • 配置具体的单板
  • 编译阶段
  • 过程
  • 链接入口
  • 配置链接地址
  • 附录
  • 附录A:mkconfig解析
  • 附录B 链接脚本

u-boot(二)makefile

引入

如果要分析uboot结构以及如何链接的话,最好的方法就是去分析它的makefile。我们是怎么编译的?先执行配置make 100ask24x0_config,然后编译make.所以在顶层目录下的Makefile一定存在这个100ask24x0_config.我们就从这里入手

目录结构(1.1.6)

  • 总体来说,命令是存放在common中,比如common中的cmd_nand.会调用驱动层的driver中的nand/nandbase.c,再去调用平台级别cpu,以及单板的(IO等)board.分为四层结构如下:
  • 在硬件层次,从上往下分别是 架构相关> CPU相关> 单板相关
  • 具体的说明在顶层的README中有讲
--------------------------------------------------lib_generic             common
--------------------------------------------------post    net     fs      disk
--------------------------------------------------dtt     nand_spl    rtc     drivers
--------------------------------------------------board       cpu     lib_xxx
目录 说明
lib_generic 通用的库文件(crc)等
common 通用程序,命令在这里
include 头文件和配置文件
  asm-arm
  config
↑↑↑↑↑↑↑↑↑↑↑ -------用户接口-------
disk 硬盘接口
net 网络驱动
fs 文件系统
↑↑↑↑↑↑↑↑↑↑↑ -------中间层-------
dtt 温度等其他传感器驱动
rtc 时钟
nand_spl nand启动相关
drivers 驱动程序
↑↑↑↑↑↑↑↑↑↑↑ --------驱动层--------
cpu 针对具体cpu
Lib_xxx 架构通用的文件
board 开发板相关的,Io等相关
↑↑↑↑↑↑↑↑↑↑↑ ------CPU相关,单板相关-------
doc 文档
example 测试程序
tools 制作u-boot格式映象工具等

顶层的mkconfig 配置了交叉编译工具的版本,链接参数等

配置文件

100ask24x0_config   :   unconfig@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0

执行make 100ask24x0_config 就相当于执行 mkconfig 100ask24x0  arm  arm920t  100ask24x0  NULL  s3c24x0,

上述命令以及参数分别对应                           $0                $1            $2        $3             $4               $5          $6

# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]

其中顶层mkconfig是一个shell脚本文件, 它会根据上面参数配置交叉编译工具的版本,链接参数等等。

###################################################################################
#                                                                                 #
#        首先是进行单板的配置                                                       #
#        make 100ask24x0_config                                                   #
#                                                                                 #
###################################################################################
100ask24x0_config   :   unconfig@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0##################################################################################
#unconfig 执行的操作如下,可以先不去管它
unconfig:@rm -f $(obj)include/config.h $(obj)include/config.mk \$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp##################################################################################
#当前目录
SRCTREE     := $(CURDIR)
# 当前目录下的mkconfig文件
MKCONFIG    := $(SRCTREE)/mkconfig
export MKCONFIG
##################################################################################
# $@表示目标,在$()中的@也表示目标,接下去的是字符串替换,也就是将目标中的_config 替换为空
# 开头@ 表示不回显
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
#也就是相当于
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
# 也就是调用外部shell脚本了

目标

  • ①配置单板的名字 100ask24x0
  • ②建立符号链接
include/asm include/asm-arm
include/asm-arm/arch include/asm-arm/arch-s3c24x0
include/asm-arm/proc include/asm-arm/proc-armv
  • ③建立include/config.mk,包含cpu,soc等信息
ARCH   = arm
CPU    = arm920t
BOARD  = 100ask24x0
SOC    = s3c24x0
  • ④新建include/config.h,开发板相关头文件,这个文件用来配置裁剪uboot,所以如果要在board目录下新建一个开发板的目录,需要在include/configs下建立$1.h头文件,此处$1 = 100ask24x0,所以包含configs/100ask24x0.h
/* Automatically generated - do not edit */
#include <configs/100ask24x0.h>

配置具体的单板

uboot还没有类似linux一样的可视化配置界面(比如使用 make menuconfig来配置),要手动修改配置文件,从上述第4步骤我们可以发现,单板的具体配置是在include/configs/<board_name>.h中配置的,有以下两类配置,由两类宏进行配置:

  1. 选项配置(Options),前缀为"CONFIG_",用于选择CPU 、SOC、开发板类型,配置系统时钟,选择设备驱动等,还有功能开关,可以理解为1级开关
  2. 参数配置(Setting), 前缀为"CFG_",用于设置malloc缓冲池大小,u-boot命令选项,下载文件的默认加载地址,FLASH起始地址等。

可以这样认为,"CONFIG_"除了设置一些参数外,主要用来设置Uboot的功能、选择使用文件中的哪一部分;而"CFG_"用来设置更细节的参数。

编译阶段

过程

重新来看根目录的makefile

  • 包含配置阶段设置的参数
include $(OBJTREE)/include/config.mk
export    ARCH CPU BOARD VENDOR SOC#ARCH   = arm
#CPU    = arm920t
#BOARD  = 100ask24x0
#SOC    = s3c24x0
  • 配置交叉工具链
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
  • 包含启动文件,这里也就是cpu/arm920t/start.o
OBJS  = cpu/$(CPU)/start.o
  • 包含库文件BOARDDIR=100ask24x0,BOARD=100ask24x0,CPU=arm920t
IBS  = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
LIBS += drivers/usb/libusb.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)LIBS := $(addprefix $(obj),$(LIBS))
.PHONY : $(LIBS)
  • 目标all
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)all:      $(ALL)$(obj)u-boot.bin: $(obj)u-boot$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@$(obj)u-boot:     depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \-Map u-boot.map -o u-boot

链接入口

UNDEF_SYM=`arm-linux-objdump -x lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a |sed  -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\cd /home/book/Desktop/u-boot/u-boot-1.1.6 && arm-linux-ld -Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000  $UNDEF_SYM cpu/arm920t/start.o \--start-group lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a --end-group -L /opt/gcc-3.4.5-glibc-2.3.6/bin/../lib/gcc/arm-linux/3.4.5 -lgcc \-Map u-boot.map -o u-boot
arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
  • 查看下最后的链接,可以看到链接脚本是board/100ask24x0/u-boot.lds,代码段的基地址0x33F80000,也就是说,链接脚本里面的地址会加上这个数字.
arm-linux-ld -Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000  $UNDEF_SYM cpu/arm920t/start.o \..................

也就是说该u-boot应该在0x33F80000这个位置运行

配置链接地址

  • 搜索下0x33F80000,在board/100ask24x0/config.mk中有定义TEXT_BASE = 0x33F80000
  • 链接参数由makefile中可以看出来$(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS)是在LDFLAGS中定义,我们可以用debug.mk调试,可以使用d-再一层解析具体的,但是这里已经能够看到$(TEXT_BASE)定义了这个地址了
make -f Makefile  -f debug.mk  d-LDFLAGSLDFLAGS=-Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 origin = filevalue = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)flavor = recursive
  • 也可以搜索下grep "LDFLAGS" * -nR,可以发现在顶层的config.mk看到定义
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
  • 如何知道uboot的整体执行流程,将start.S从头分析到尾就可以大概知道。根据makefile分析所得cpu/arm920t/start.S是uboot的第1个执行文件,从这个文件一路分析下去就可以把uboot贯通起来。

附录

附录A:mkconfig解析

###################################################################################
#                                                                                 #
#        首先是进行单板的配置                                                       #
#        make 100ask24x0_config                                                   #
#                                                                                 #
###################################################################################
100ask24x0_config   :   unconfig@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0##################################################################################
#unconfig 执行的操作如下,可以先不去管它
unconfig:@rm -f $(obj)include/config.h $(obj)include/config.mk \$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp##################################################################################
#当前目录
SRCTREE     := $(CURDIR)
# 当前目录下的mkconfig文件
MKCONFIG    := $(SRCTREE)/mkconfig
export MKCONFIG
##################################################################################
# $@表示目标,在$()中的@也表示目标,接下去的是字符串替换,也就是将目标中的_config 替换为空
# 开头@ 表示不回显
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
#也就是相当于
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
# 也就是调用外部shell脚本了###################################################################################
#                                                                                 #
#        mkconfig的文件注释,shell脚本调用                                          #
#        mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0                  #
#          [$0]      [$1]    [$2]  [$3]    [$4]     [$5]   [$6]                   #
###################################################################################
#!/bin/sh -e# Script to create header files and links to configure
# U-Boot for a specific board.
#
# Parameters:  Target  Architecture  CPU  Board [VENDOR] [SOC]
#
# (C) 2002-2006 DENX Software Engineering, Wolfgang Denk <wd@denx.de>
#APPEND=no   # Default: Create new config file
BOARD_NAME=""   # Name to print in make output# 不包含这些打头的参数,忽略这段代码
# $# 参数个数,-gt 大于
while [ $# -gt 0 ] ; docase "$1" in--) shift ; break ;;-a) shift ; APPEND=yes ;;-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;*)  break ;;esac
done# 利用了||的特性,如果未定义BOARD_NAME,BOARD_NAME=参数1=100ask24x0
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"# 参数个数合法性判断,必须是5个
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1# 打印显示
echo "Configuring for ${BOARD_NAME} board..."#
# Create link to architecture specific headers
## 这里SRCTREE=OBJTREE=$(CURDIR),我们可以去顶层的makefile中看到
# 也可以使用debug打印变量 make -f Makefile  -f debug.mk  OBJTREE
# OBJTREE       := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
# SRCTREE       := $(CURDIR)
# 也就是说 执行else 分支
# 建立asm的符号连接
if [ "$SRCTREE" != "$OBJTREE" ] ; thenmkdir -p ${OBJTREE}/includemkdir -p ${OBJTREE}/include2cd ${OBJTREE}/include2rm -f asmln -s ${SRCTREE}/include/asm-$2 asmLNPREFIX="../../include2/asm/"cd ../includerm -rf asm-$2rm -f asmmkdir asm-$2ln -s asm-$2 asm
else# 删除原有的asm链接,建立新的链接 ln -s asm-arm asmcd ./includerm -f asmln -s asm-$2 asm
firm -f asm-$2/arch# -z string 测试指定字符是否为空,空着真,非空为假
# -o: or
# $6=s3c24x0,执行else
# ln -s arch-s3c24x0 asm-arm/arch
# asm-arch指向了arch-s3c24x0if [ -z "$6" -o "$6" = "NULL" ] ; thenln -s ${LNPREFIX}arch-$3 asm-$2/arch
elseln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi# if满足,删除 asm-arm/proc
# 重新建立新的链接 proc-armc 到asm-arm/proc
if [ "$2" = "arm" ] ; thenrm -f asm-$2/procln -s ${LNPREFIX}proc-armv asm-$2/proc
fi#
# Create include file for Make
#
# ARCH   = arm
# CPU    = arm920t
# BOARD  = 100ask24x0
# SOC    = s3c24x0
echo "ARCH   = $2" >  config.mk
echo "CPU    = $3" >> config.mk
echo "BOARD  = $4" >> config.mk[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC    = $6" >> config.mk#
# Create board specific header file
#
# /* Automatically generated - do not edit */
# #include <configs/100ask24x0.h>if [ "$APPEND" = "yes" ]    # Append to existing config file
thenecho >> config.h
else> config.h      # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.hexit 0

附录B 链接脚本

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{. = 0x00000000;     //这个地址会加上 -Ttext 0x33F80000 这个地址. = ALIGN(4);.text      :{//代码段的第一个文件是这个cpu/arm920t/start.o   (.text)board/100ask24x0/boot_init.o (.text)//其他所有代码段   *(.text)}. = ALIGN(4);.rodata : { *(.rodata) }. = ALIGN(4);.data : { *(.data) }. = ALIGN(4);.got : { *(.got) }. = .;__u_boot_cmd_start = .;.u_boot_cmd : { *(.u_boot_cmd) }__u_boot_cmd_end = .;. = ALIGN(4);__bss_start = .;.bss : { *(.bss) }_end = .;
}

转载:https://www.cnblogs.com/zongzi10010/p/10023667.html

u-boot分析之makefile分析(二)相关推荐

  1. USB摄像头驱动--LCD显示摄像头图像(附Makefile分析)

    对于一个应用程序,最重要的是明白目的是什么:将摄像头的数据解析出来,按一帧一个图片的方式将数据传到LCD的Framebuffer中去(如果LCD没有自动将Framebuffer中的数据刷到LCD上还需 ...

  2. Linux内核移植之一:内核源码结构与Makefile分析

    内容来自 韦东山<嵌入式Linux应用开发完全手册> 一.内核介绍 1.版本及其特点 Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,比如下面几行它们构成了Linu ...

  3. u-boot的Makefile分析

    U-BOOT是一个LINUX下的工程,在编译之前必须已经安装对应体系结构的交叉编译环境,这里只针对ARM,编译器系列软件为arm-linux-*. U-BOOT的下载地址: http://source ...

  4. uboot源码——主Makefile分析

    以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 一.配置编译初体验 1.uboot来源于官方(uboot官网下载),或者SoC官方(研发s5pv210芯片的公司推出的开发板,SMDKV21 ...

  5. 韦东山衔接班——1.2_uboot分析之Makefile结构分析

    作者:GWD 时间:2019.8.21 一.分析Makefile的配置过程 (从输入配置命令到创建config.h头文件的过程): 1.顶层Makefile中执行100ask24x0_config后就 ...

  6. 开发板与虚拟机组网、uboot源码makefile分析、uboot安全启动与非安全启动方式、uboot源码配置与编译流程、制作TF启动盘

    开发板与虚拟机组网. 局面:开发板.PC(Ubuntu系统).网线直连PC:设置Ubuntu系统:1.设置桥接模式,桥接到PC的有线网卡上:2.手动配置IP V4的地址信息,注意和开发板保持在同一网段 ...

  7. 【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 二 )

    文章目录 前言 一.ActivityManagerService.attachApplicationLocked 二.ActivityStackSupervisor.attachApplication ...

  8. 【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 二 | AMS 进程相关源码 | 主进程相关源码 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  9. 操作系统课设--NACHOS试验环境准备、安装与MAKEFILE分析

    山东大学操作系统课设lab1 实验一 NACHOS试验环境准备.安装与MAKEFILE分析(lab1) 实验环境: 分析记录: 1. 准备虚拟机下LINUX宿主操作系统环境 2. NACHOS实验代码 ...

最新文章

  1. vue 封装dialog_element-dialog封装成子组件
  2. 图像处理——图像边缘检测
  3. python查看各列数据类型_pandas中查看数据类型的几种方式
  4. 网络字节序 —— 主机字节序 (Socket编程) 转
  5. UVA - 1587 ​​​​​​​Box
  6. 爬虫4-正则表达式及Python的re模块
  7. JAVA与SAP数据交互的方式总结
  8. Django:ORM基本操作-CRUD,管理器对象objects,----->查询1(all,values,values_list,order_by)
  9. 谁说国产操作系统没救了? | 人物志
  10. 【Codeforces 851D Arpa and a list of numbers】
  11. Java中string,map,json之间的常用转换方法(json转map,map转json,json转string等)
  12. 数论著作读书笔记(2013-04-14 23:22)
  13. IDEA上的文字转拼音名
  14. ubuntu_使用ros显示imu的状态(6)
  15. 从代数结构上理解数集的分类
  16. 华为新机预装鸿蒙,华为新机来了!预装鸿蒙OS,搭载麒麟9000
  17. keep-alive 理解 如何实现?缓存是什么?
  18. 蓝桥杯 算法训练 ALGO-932低阶行列式计算 python解法
  19. 微信小程序开发工具安装破解
  20. 【等待事件】序列等待事件总结(enq: SQ - contention、row cache lock、DFS lock handle和enq: SV - contention)...

热门文章

  1. slimphp中间件调用流程的理解
  2. Java排序算法总结
  3. 【Win 10应用开发】SplitView控件
  4. jQuery源码学习
  5. Oracle ORA-04031 错误 说明
  6. UA MATH566 统计理论 证明UMVUE的方法
  7. linux内核技术文章
  8. target和currentTarget
  9. ubuntu网卡问题
  10. 中科院分词ICTCLAS5.0_JNI 使用方法