u-boot分析與使用—Makefile結構分析
- 硬件平臺:韋東山嵌入式Linxu開發板(S3C2440.v3)
- 軟件平臺:運行於VMware Workstation 12 Player下UbuntuLTS16.04_x64 系統
- 參考資料:《嵌入式Linux應用開發手冊》、《嵌入式Linux應用開發手冊第2版》
- 開發環境:Linux 2.6.22.6 內核、arm-linux-gcc-3.4.5-glibc-2.3.6工具鏈、u-boot-1.1.6
一、前言
在【5.1 u-boot分析與使用—u-boot編譯體驗】中,分析了u-boot的主要目的是啓動內核,至於其如何成功的使用內核,需要分析其的代碼,對於代碼的分析需要先分析Makefile
來了解整個工程的編譯流程。
二、配置與編譯過程:make 100ask24x0_config
在配置u-boot時,在/work/system/u-boot-1.1.6
目錄下,直接執行make 100ask24x0_config
命令。
1、Makefile
調用mkconfig
通過搜索Makefile
文件中100ask24x0_config
可以找到如下代碼:
最終拆開後代碼如下:
mkconfig 100ask24x0_config arm arm920t 100ask24x0 NULL s3c24x0
可以看到此時會調用源文件所在目錄下的mkconfig
2、分析mkconfig
可以看到在/work/system/u-boot-1.1.6
目錄下有一個mkconfig
- 具體執行的源碼如下(分析的完全源碼在下一項):
# mkconfig 100ask24x0_config arm arm920t 100ask24x0 NULL s3c24x0
# $0 $1 $2 $3 $4 $5 $6
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
# 判斷BOARD_NAME是否有定義
# 若定義就執行[ "${BOARD_NAME}" ]
# 未定位就執行BOARD_NAME="$1" $1(命令的第一個參數或第一條命令)--->100ask24x0_config
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
# BOARD_NAME = 100ask24x0_config
# 打印Configuring for ${BOARD_NAME} board...
echo "Configuring for ${BOARD_NAME} board..."
# Create link to architecture specific headers
# OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
# 如果定義 OBJTREE=$BUILD_DIR 未定義OBJTREE=$CURDIR
# BUILD_DIR := $(O)未定義,
# SRCTREE := $(CURDIR)
# 如果 SRCTREE != OBJTREE 條件成立
cd ./include
rm -f asm
ln -s asm-$2 asm #ln -s asm-arm asm 建立鏈接文件asm->asm-arm
fi
rm -f asm-$2/arch # rm -f asm-arm/arch
# 如果$6(第六個參數)爲空或者爲NULL
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch #ln -s arch-s3c24x0 asm-arm/arch 建立鏈接文件asm-arm/arch->arch-s3c24x0
fi
# 如果$2(第二個參數) = "arm"
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc #ln -s proc-armv asm-arm/proc 建立鏈接文件asm-arm/proc->proc-armv
fi
# Create include file for Make
# > 表示新建一個文件config.mk,>> 表示追加,在config.mk中追加
echo "ARCH = $2" > config.mk # ARCH = arm
echo "CPU = $3" >> config.mk # CPU = arm920t
echo "BOARD = $4" >> config.mk # BOARD = 100ask24x0
# $6(第六個參數)存在 且 不等於"NULL"
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk # SOC = s3c24x0
# config.mk內容如下:
# ARCH = arm
# CPU = arm920t
# BOARD = 100ask24x0
# SOC = s3c24x0
# Create board specific header file
# 創建一個單板相關的頭文件
# APPEND = “no”
else
> config.h # Create new config file 新建一個config.h文件
fi
# config.h的內容:
# /* Automatically generated - do not edit */
# #include <configs/100ask24x0_config.h> 配置文件
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h
# 退出
exit 0
通過查看 /work/system/u-boot-1.1.6/include
目錄下的config.mk
、config.h
文件可以知道其執行的上述代碼過程
- 帶註釋分析源碼如下:
#!/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>
#
# mkconfig 100ask24x0_config arm arm920t 100ask24x0 NULL s3c24x0
# $0 $1 $2 $3 $4 $5 $6
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
#分析命令傳入的參數有沒有--、-a、-n、*這些東西
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}" ]
# 未定位就執行BOARD_NAME="$1" $1(命令的第一個參數或第一條命令)--->100ask24x0_config
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
# BOARD_NAME = 100ask24x0_config
[ $# -lt 4 ] && exit 1 # 參數小於4個退出
[ $# -gt 6 ] && exit 1 # 參數大於6個退出
# 打印Configuring for ${BOARD_NAME} board...
echo "Configuring for ${BOARD_NAME} board..."
#
# Create link to architecture specific headers
# OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
# 如果定義 OBJTREE=$BUILD_DIR 未定義OBJTREE=$CURDIR
# BUILD_DIR := $(O)未定義,
# SRCTREE := $(CURDIR)
# 如果 SRCTREE != OBJTREE 條件成立
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
cd ./include
rm -f asm
ln -s asm-$2 asm #ln -s asm-arm asm 建立鏈接文件asm->asm-arm
fi
rm -f asm-$2/arch # rm -f asm-arm/arch
# 如果$6(第六個參數)爲空或者爲NULL
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch #ln -s arch-s3c24x0 asm-arm/arch 建立鏈接文件asm-arm/arch->arch-s3c24x0
fi
# 如果$2(第二個參數) = "arm"
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc #ln -s proc-armv asm-arm/proc 建立鏈接文件asm-arm/proc->proc-armv
fi
#
# Create include file for Make
# > 表示新建一個文件config.mk,>> 表示追加,在config.mk中追加
echo "ARCH = $2" > config.mk # ARCH = arm
echo "CPU = $3" >> config.mk # CPU = arm920t
echo "BOARD = $4" >> config.mk # BOARD = 100ask24x0
# $5(第五個參數)存在 且 不等於"NULL"
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk # VENDOR = NULL
# $6(第五個參數)存在 且 不等於"NULL"
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk # SOC = s3c24x0
# config.mk內容如下:
# ARCH = arm
# CPU = arm920t
# BOARD = 100ask24x0
# SOC = s3c24x0
# Create board specific header file
# 創建一個單板相關的頭文件
# APPEND = “yes”
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file 新建一個config.h文件
fi
# config.h的內容:
# /* Automatically generated - do not edit */
# #include <configs/100ask24x0_config.h> 配置文件
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h
# 退出
exit 0
3、Makefile
生成u-boot.bin
對於執行make
命令輸出的信息如下:可以看到它使用了目錄下的u-boot.lds
腳本
4、u-boot.lds
腳本
其源碼如下:
/*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <[email protected]>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; //鏈接地址:0x33f80000 + 0x00000000 = 0x33f80000
. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text) //這個文件的代碼段 /cpu/arm920t/start.S
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段
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}
三、推薦
對於這篇文章,只是比較簡單的大致流程分析,詳細的推薦大家可以看看這篇https://blog.csdn.net/dhauwd/article/details/80149843