title: u-boot(二)makefile

tags: linux

date: 2018-09-22 20:56:05

u-boot(二)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 #
# #
###################################################################################
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目录下新建一个开发板<board_name>的目录,需要在include/config 下建立<board_name>.h

    /* Automatically generated - do not edit */
    #include <configs/100ask24x0.h>

配置具体的单板

从上述第4步骤我们可以发现,单板的具体配置实在include/config/单板.h中配置的.有以下几类配置:

  1. 选项配置,用于配置系统时钟,CPU等,还有功能开关,可以理解为1级开关
  2. 参数配置,前缀为CFG_,设置malloc大小,u-boot命令选项,下载文件的默认地址,FLASH地址等

编译阶段

过程

重新来看根目录的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-LDFLAGS
    
    LDFLAGS=-Bstatic -T /home/book/Desktop/u-boot/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000
    origin = file
    value = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
    flavor = recursive
  • 也可以搜索下grep "LDFLAGS" * -nR,可以发现在顶层的config.mk看到定义

    LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)

附录

附录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 ] ; do
case "$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" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -f asm
mkdir asm-$2
ln -s asm-$2 asm
else
# 删除原有的asm链接,建立新的链接 ln -s asm-arm asm
cd ./include
rm -f asm
ln -s asm-$2 asm
fi rm -f asm-$2/arch # -z string 测试指定字符是否为空,空着真,非空为假
# -o: or
# $6=s3c24x0,执行else
# ln -s arch-s3c24x0 asm-arm/arch
# asm-arch指向了arch-s3c24x0 if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi # if满足,删除 asm-arm/proc
# 重新建立新的链接 proc-armc 到asm-arm/proc
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -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
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h exit 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 = .;
}

u-boot(二)makefile的更多相关文章

  1. Spring Boot(二十):使用spring-boot-admin对spring-boot服务进行监控

    Spring Boot(二十):使用spring-boot-admin对spring-boot服务进行监控 Spring Boot Actuator提供了对单个Spring Boot的监控,信息包含: ...

  2. Spring Boot 二十个注解

    Spring Boot 二十个注解 占据无力拥有的东西是一种悲哀. Cold on the outside passionate on the insede. 背景:Spring Boot 注解的强大 ...

  3. 联盛德 HLK-W806 (十二): Makefile组织结构和编译流程说明

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  4. spring boot(二):启动原理解析

    我们开发任何一个Spring Boot项目,都会用到如下的启动类 @SpringBootApplication public class Application { public static voi ...

  5. Spring Boot(二):数据库操作

    本文主要讲解如何通过spring boot来访问数据库,本文会演示三种方式来访问数据库,第一种是JdbcTemplate,第二种是JPA,第三种是Mybatis.之前已经提到过,本系列会以一个博客系统 ...

  6. spring boot(二十)使用spring-boot-admin对服务进行监控

    上一篇文章<springboot(十九):使用Spring Boot Actuator监控应用>介绍了Spring Boot Actuator的使用,Spring Boot Actuato ...

  7. Spring Boot(二) 配置文件

    文章导航-readme 一.配置Spring Boot热部署     技术的发展总是因为人们想偷懒的心理,如果我们不想每次修改了代码,都必须重启一下服务器,并重新运行代码.那么可以配置一下热部署.有了 ...

  8. spring boot(二):web综合开发

    上篇文章介绍了Spring boot初级教程:spring boot(一):入门篇,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续为大家介绍spring boot的其它 ...

  9. Spring Boot(二):Spring-Data-JPA操作数据库( Hibernate)增删改查

    一.Maven使用3.3.9版本或以上,选择Binary 版本 二.添加spring-data-jpa和数据库依赖,以oracle为例 三.添加连接数据库配置 四.新建model自动生成数据库表(不用 ...

随机推荐

  1. Jquery中val方法使用的坑

    Jquery中val方法使用 val()// 取得第一个匹配元素的当前值 val(val)// 设置所有匹配元素的值 val([val1, val2])// 设置多选的checkbox.多选selec ...

  2. kebu之rook-ceph

    准备工作 所有节点开启ip_forward cat <<EOF > /etc/sysctl.d/ceph.conf net.ipv4.ip_forward = 1 net.bridg ...

  3. Java归并排序的递归与非递归实现

    该命题已有无数解释,备份修改后的代码 平均时间复杂度: O(NLogN)  以2为底 最好情况时间复杂度: O(NLogN) 最差情况时间复杂度: O(NLogN) 所需要额外空间: 递归:O(N + ...

  4. zabbix 监控 WEB 应用性能

    1.介绍使用 zabbix_sender 发送采集的 WEB 状态值,使用 pycurl 来采集 WEB 状态zabbix_sender发送数据,需保证主机名与zabbix server记录的主机名一 ...

  5. Android 开发中 SQLite 数据库的使用

    SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP, ...

  6. 实验八 应用层协议Ⅱ-FTP协议分析

    实验八 应用层协议Ⅱ-FTP协议分析 一.实验目的 1.掌握FTP协议的实现原理. 2.了解控制通道和数据通道. 二.实验内容 用WareShark追踪ftp连接. 1.三次握手 2.ftp服务器回发 ...

  7. [2017-7-28]Android Learning Day6

    常用控件 Spinner DatePickerDialog TimePickerDiaog RadioButton CheckBox spinner(下拉菜单) <Spinner android ...

  8. https搭建实例

    :(用的)https://www.coderecord.cn/lets-encrypt-wildcard-certificates.html :acme.shvim .acme.sh/account. ...

  9. HDU6333 Harvest of Apples (杭电多校4B)

    这莫队太强啦 先推公式S(n,m)表示从C(n, 0) 到 C(n, m)的总和 1.S(n, m)   = S(n, m-1) + C(n, m) 这个直接可以转移得到 2.S(n, m)   = ...

  10. LOJ#6284. 数列分块入门 8

    分块的时候开一个数组标记这个区间是不是都是一样颜色的部分,如果是的话,我后面的查询,更新部分就可以直接整块操作,对于不是不全部都一样颜色的块在具体进到快里面去暴力. 在更新的时候对边上的两个不完整的块 ...