uboot——配置编译

本文详细介绍了uboot的配置编译过程,包括uboot的作用、如何学习uboot、配置编译的步骤以及编译过程中的依赖分析。uboot是嵌入式系统的通用引导加载器,其配置编译涉及配置文件生成、目录软链接、头文件创建、库文件的编译和链接等多个环节。通过对Makefile和相关脚本的解析,理解了uboot编译时的依赖关系和文件生成过程。
摘要由CSDN通过智能技术生成

一.什么是uboot?

     uboot: Universal Bootloader,是一种普遍的嵌入式系统bootloader。本篇以mini2440开发板为例.


二.uboot的作用

最终目标:启动Linux内核。

作用:硬件初始化,建立适当的软硬件环境。

uboot的工作流程可分为两个Stage:

(1)Stage1:

a. 硬件初始化:异常向量表和中断向量表的实现,关看门狗,初始化SDRAM,设置栈,设置时钟,设置I/D catch,nand初始化,代码重定位(Nor和Nand两种启动方式),串口初始化,清BSS等等;

b. 调用C函数进入Stage2。

Stage1主要用依赖于CPU体系结构的代码来实现,通常为汇编,会调用少量的C。

(2)Stage2:

a. 确定Linux内核所需的启动参数 

b. 将这些参数以特定的结构(uboot用结构体来表示)存放到特定的地址中。

Stage2用C语言实现,更好的可读性和可移植性。


三.如何学习uboot ?

对于我这样一个菜鸟来说,这个问题有点尴尬......

个人理解,无论学习uboot还是Linux内核,都需要一个切入点,就是Makefile。Makefile又分顶层Makefile(或者叫根目录Makefile?)和子目录Makefile,在make之前,通常有一些配置信息生成,供Makefile包含或调用,这是后话。Makefile中一定会使用链接脚本,链接脚本显示了二进制可执行文件中各个Section的内容,这样你就知道了uboot.bin的大概结构。

       通过Makefile和链接脚本,我们可以获得的信息是:第一个被执行的程序,加载地址等。下面就是顺藤摸瓜看代码了。

       另外一点就是uboot源码的选取,我是用的u-boot1.1.6的老版本,我们不需要了解uboot的全部代码,只需理解其核心功能。网上对u-boot1.1.6源码解析的文章比较多,便于学习。


四.uboot的配置编译


1.配置

我们在编译uboot的时候,一般分为两步

在根目录下输入:

a. make xxxx_config
b. make

当输入 make mini2440_config时,在Makefile中执行的语句是:

mini2440_config	:	unconfig	@$(MKCONFIG) 
$(@:_config=) arm arm920t mini2440 tekkamanninja s3c24x0

事实上,下载的官方uboot源码中是没有这条语句的,相似的可以看到 

smdk2410_config	:	unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

想要想编译mini2440bootloader,就需要我们自己添加一笔。下面来详细解读一下这些make语句 

执行make mini2440_config时,会自动跳转到上面的语句,紧接着执行unconfig,在Makefile中找到unconfig的定义

unconfig:	
<span style="white-space:pre">	</span> @rm -f $(obj)include/config.h $(obj)include/config.mk \	 
<span style="white-space:pre">	</span> $(obj)board/*/config.tmp $(obj)board/*/*/config.tmp

unconfig用于删除(rm -f)上一次make mini2440_config产生的文件,它们是:include/config.hconfig.mkboard/*/config.tmpboard/*/*/config.tmp,值得一提的是顶层目录下的config.mk用于设置编译选项,这里暂且不表。

接下来执行: 

@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 tekkamanninja s3c24x0

顶层MakefileMKCONFIG的定义是: 

MKCONFIG	:= $(SRCTREE)/mkconfig

又有: 

SRCTREE	 := $(CURDIR)

CURDIR可以在配置命令的时候用参数指定,或者像我一样在代码根目录下进行配置,默认CURDIR是当前目录。所以@$(MKCONFIG)就是当前目录(根目录)下的mkconfig文件。

下面来看 $(@:_config=),首先要了解一个规则,s:a=b是将s中的a替换成b(其实这是一个简化的GNU函数),把@所表示的变量中的_config替换成空,那么@表示什么?说一下Makefile@的用法:有的时候命令行以'@'打头,表示在执行到的时候不回显相应的命令内容,只显示命令的输出。这里的@并非如此,@$共同组成$@表示目标文件mini2440_config,所以此处是将mini2440_config文件中的_config换成空格。

替换后为:

./mkconfig   mini2440    arm   arm920t  mini2440  tekkamaninja s3c24x0

到顶层mkconfig文件中执行语句,参数是./mkconfig   mini2440    arm   arm920t  mini2440  tekkamaninja s3c24x0mkconfig 本身也作为bash的参数),分别对应参数06

接下来看顶层目录下的mkconfig文件: 

#!/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
TARGETS=""

while [ $# -gt 0 ] ; do
	case "$1" in
	--) shift ; break ;;
	-a) shift ; APPEND=yes ;;
	-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
	-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
	*)  break ;;
	esac
done

[ "${BOARD_NAME}" ] || BOARD_NAME="$1"

[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1

if [ "${ARCH}" -a "${ARCH}" != "$2" ]; then
	echo "Failed: \$ARCH=${ARCH}, should be '$2' for ${BOARD_NAME}" 1>&2
	exit 1
fi

echo "Configuring for ${BOARD_NAME} board..."

#
# Create link to architecture specific headers
#
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
fi

rm -f asm-$2/arch

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 [ "$2" = "arm" ] ; then
	rm -f asm-$2/proc
	ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi

#
# Create include file for Make
#
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
#
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

for i in ${TARGETS} ; do
	echo "#define CONFIG_MK_${i} 1" >>config.h ;
done

echo "#include <configs/$1.h>" >>config.h
echo "#include <asm/config.h>" >>config.h

exit 0

#!/bin/sh -e指定了脚本所用的解析器,如果你学过shell脚本,应该不会陌生。 

Script to create header files and links to configure U-Boot for a specific board.”这是一个脚本,用于创建头文件和链接,生成的头文件和链接用来配置特定的board.

Parameters: Target    Architecture     CPU      Board        [VENDOR]          [SOC] 

刚好对应了:mini2440  arm             arm920t  mini2440    tekkamanninja      s3c24x0

 

Target: 宿主机平台 

Architecture: 定义芯片架构(如MIPSPOWERPCARM等)

CPU: 定义芯片指令集版本(如ARM7ARM9ARM11等)

Board: 字面意思......

[VENDOR]: 按厂商划分(如AT9200S3C44B0等),这里一般写NULL<

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值