第一、二期衔接——5.2 u-boot分析与使用—Makefile结构分析

u-boot分析与使用—Makefile结构分析


一、前言

  在【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.mkconfig.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

猜你喜欢

转载自blog.csdn.net/weixin_42813232/article/details/106864431