1. 程式人生 > >u-boot(二)makefile

u-boot(二)makefile

目錄


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