u-boot(二)makefile

目录

  • u-boot(二)makefile

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


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
##################################################################################
# [email protected]表示目标,在$()中的@也表示目标,接下去的是字符串替换,也就是将目标中的_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目录下新建一个开发板
    /* 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 $< [email protected]
    
    $(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
##################################################################################
# [email protected]表示目标,在$()中的@也表示目标,接下去的是字符串替换,也就是将目标中的_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 <[email protected]>
#

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 = .;
}

原文地址:https://www.cnblogs.com/zongzi10010/p/10023667.html

时间: 2024-10-12 08:11:42

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

spring boot(二): spring boot+jdbctemplate+sql server

前言 小项目或者做demo时可以使用jdbc+sql server解决即可,这篇就基于spring boot环境使用jdbc连接sql server数据库,和spring mvc系列保持一致. 在spring boot中使用jdbc 连接sql server数据只需要引入两个jar:spring-boot-starter-jdbc.spring-boot-starter-data-jpa 项目结构 和上篇spring boot入门保持相同 pom.xml <dependencies> <

GNU-makefle (二) Makefile 文件名,include,make工作方式

参考链接:http://blog.csdn.net/haoel/article/details/2888 文件名 make [-f|--file] [filename]  如: make -f mk1           mk1含有一个makefile的定义. include关键字 类似C语言的效果.将被包含的文件的内容原样放置在当前位置. include a b c d e ...      abcde为文件名,以空格或tab隔开. 注意:include之前不要用tab,tab表示这是个命令,

Spring Boot 二三事:WEB 应用消息推送的那点事

阅读对象:本文适合SpringBoot 初学者及对SpringBoot感兴趣的童鞋阅读. 背景介绍:在企业级 WEB 应用开发中,为了更好的用户体验&提升响应速度,往往会将一些耗时费力的请求 (Excel导入or导出,复杂计算, etc.) 进行异步化处理. 由此带来的一个重要的问题是如何通知用户任务状态,常见的方法大致分为2类4种: HTTP Polling client pull HTTP Long-Polling client pull Server-Sent Events (SSE) s

Spring Boot二:Web 综合开发

Web 开发 Spring Boot Web 开发非常的简单,其中包括常用的 json 输出.filters.property.log 等 json 接口开发 在以前使用 Spring 开发项目,需要提供 json 接口时需要做哪些配置呢 添加 jackjson 等相关 jar 包 配置 Spring Controller 扫描 对接的方法添加 @ResponseBody 就这样我们会经常由于配置错误,导致406错误等等,Spring Boot 如何做呢,只需要类添加 @RestControll

Spring Boot (二)

SpringBoot使用JSP 1.创建一个webapp子项目 2.导入依赖 <!-- 配置springboot的父节点依赖,之后引入就不需要添加version配置了! springboot会自动选择最合适的版本进行添加依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId&g

Spring Boot快速入门(二):http请求

原文地址:https://lierabbit.cn/articles/4 一.准备 postman:一个接口测试工具 创建一个新工程 选择web 不会的请看Spring Boot快速入门(一):Hello Spring Boot 二.开始 新建java类RequestCtrl 1.添加一个all方法,使用@RequestMapping注解,可以处理所有的http请求 @RestController//这是一个控制器并只返回数据不寻找视图 public class RequestCtrl { @R

Makefile学习(二)----生成静态库文件

Lunix下编译静态库文件: .o后缀文件:编译生成的中间代码文件: .a后缀文件:静态库文件,编译的时候会合到可执行程序中,文件比较大: .so后缀文件:动态库文件,只是一个指向,不会合到可执行程序中,当要调用函数库的时候才使用: 用一个简单的例子阐述下在lunix环境下生成静态库文件的过程: 一.   源码文件: so_test.h: void test_a(); void test_b(); void test_c(); test_a.c: #include "so_test.h"

一个通用的Makefile

一 makefile的作用 Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中记录有文件的信 息,在make时会决定在链接的时候需要重新编译哪些文件.Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件.当那些依赖文件有了改变,编译器会自动发现最终的生成文件已经过时,而应该重新编译相应的模块. makefile带来的好处就是—"自动化编译",一旦写好,只需要

Linux内核Makefile文件(翻译自内核手册)

转载自:http://www.cnblogs.com/jason-lu/p/3728198.html --译自Linux3.9.5 Kernel Makefiles(内核目录documention/kbuild/makefiles.txt) kbuild(kernel build) 内核编译器 This document describes the Linux kernel Makefiles 本文当介绍了Linux内核的Makefile === Table of Contents=== 目录