您的位置:首页 > 其它

uboot 分析之 配置+编译过程

2016-10-22 22:00 411 查看
http://blog.chinaunix.net/uid-23193900-id-3181496.html

所有的注释都用 # 标示

#第一步:配置 make smdk2410_config ,从这里执行,在Makefile里面找目标##:smdk2410_config。可以自己设置这么一个目标,如mini2440_config

smdk2410_config : unconfig #unconfig前面定义的有。该目标smdk_2410依赖于unconfig目标。

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

#这条命令就是

# MKCONFIG := $(SRCTREE)/mkconfig

# OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))

# if函数计算OBJTREE的值,如果BUILD_DIR不为空,if函数的值就是BUILD_DIR,否则是CURDIR.

# SRCTREE := $(CURDIR) CURDIR是个环境变量。代表当前文件的目录。

# $(@:_config=) $@是目标smdk2410_config,这里将_config 替换为空。

# 上面的命令可以替换如下

# @$(CURDIR)/mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0

unconfig: #执行rm -f 命令,将以前的配置信息删除,

#配置文件:include/config.h + config.mk

# board/*/config.tmp board/*/*/config.tmp

# include/autoconf.mk include/autoconf.mk.dep

@rm -f $(obj)include/config.h $(obj)include/config.mk \

$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \

$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep

# $(obj) and (src) are defined in config.mk but here in main Makefile

# we also need them before config.mk is included which is the case for

# some targets like unconfig, clean, clobber, distclean, etc.

ifneq ($(OBJTREE),$(SRCTREE)) #如果 OBJTREE!=SRCTREE,这里人为的指定BUILD_DIR,OBJTREE=$(BUILD_DIR),CURDIR

#是个环境变量,代表当前目录

obj := $(OBJTREE)/ #这时obj 被赋值为OBJTREE

src := $(SRCTREE)/ #src也被赋值为SRCTREE.

else #这才是没有指定BUILD_TREE编译目录时,OBJTREE=CURDIR,与SRCTREE相等,

obj :=
#obj为空

src := #src为空

endif

export obj src #导出obj src

OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))

SRCTREE := $(CURDIR)

TOPDIR := $(SRCTREE)

LNDIR := $(OBJTREE)

export TOPDIR SRCTREE OBJTREE

MKCONFIG := $(SRCTREE)/mkconfig

export MKCONFIG

第二步:mkconfig文件的执行

这是一个shell脚本文件,主要功能是

1.确定开发板名称

2.创建到平台/开发板相关的头文件的连接

3.创建顶层Makefile包含的include/config.mk文件

4.创建开发板相关的头文件include/config.h

mkconfig文件的内容:

APPEND=no # Default: Create new config file

BOARD_NAME=""
# Name to print in make output

[ "${BOARD_NAME}" ] || BOARD_NAME="$1" #BOARD_NAME如果不为空,就不用赋值,如果为空,赋值$1.

#如果变量数目小于4或大于6,就直接退出。否则执行下面的

[ $# -lt 4 ] && exit 1

[ $# -gt 6 ] && exit 1

#打印输出下面这么一句话

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

#

# Create link to architecture specific headers

#

cd ./include #切换到include目录下,删除asm文件,创建新的asm文件,连接指向asm-arm

rm -f asm

ln -s asm-$2 asm

#删除asm-arm920t/arch 目录,为什么???

rm -f asm-$2/arch

#如果$6为0 或为空,这里$6=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 #ln -s arch-s3c24x0 asm-arm920t/arch

fi

#

# Create include file for Make

#

echo "ARCH = $2" > config.mk #将$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

echo "#include " >>config.h #在config.h文件中包含conf#igs/$(board_name).h文件,该文件需要手动创建

exit 0

创建开发板相关的头文件:include/configs/$(board_name).h

该文件存放的是开发板的配置信息,包括两类:

1.选项,前缀为CONFIG_,

2.参数,前缀为CFG_

在mini2440.h文件里添加如下配置:

#define CONFIG_MINI2440 1

#define CONFIG_S3C2440 1

第三步:make 命令的执行--uboot的编译连接过程

配置完后,执行make命令。

make执行中要用到哪些信息:

1.include $(OBJTREE)/include/config.mk include目录下的config.mk文件,该文件包含ARCH,CPU,BOARD,VENDOR,SOC信息

2.include $(TOPDIR)/config.mk 顶层目录下的config.mk文件,该文件根据上面文件中的四个变量,确定了编译器,编译选项等。

$(TOPDIR)/config.mk 的内容:

BOARDDIR = $(BOARD) #确定了开发板名称,使用参数BOARD,这里是smdk2410,我们可以认为是mini2440

sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules

LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds #本开发的连接脚本,该脚本会向后期的start_armboot函数

#传入一些参数,如__bss_start,_end,__u_boot_cmd_start,

#__u_boot_cmd_end..供C函数调用

LDFLAGS += -Bstatic -T $(LDSCRIPT) $(PLATFORM_LDFLAGS) #连接选项

在board/mini2440/config.mk文件中,定义了TEXT_BASE = 0x33f80000.

接着看Makefile:

#################################################################

# U-Boot objects....order is important (i.e. start must be first)

OBJS = cpu/$(CPU)/start.o
 #OBJS第一个成员必须是start.o

OBJS := $(addprefix
$(obj),$(OBJS)) #添加上前缀,使路径完整

LIBS = lib_generic/libgeneric.a

LIBS += lib_generic/lzma/liblzma.a

LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \ #看文件是否存在。

"board/$(VENDOR)/common/lib$(VENDOR).a"; fi)

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 fs/yaffs2/libyaffs2.a

LIBS += net/libnet.a

LIBS += disk/libdisk.a

LIBS += drivers/bios_emulator/libatibiosemu.a

LIBS += drivers/block/libblock.a

LIBS += drivers/dma/libdma.a

LIBS += drivers/hwmon/libhwmon.a

LIBS += drivers/i2c/libi2c.a

LIBS += drivers/input/libinput.a

LIBS += drivers/misc/libmisc.a

LIBS += drivers/mmc/libmmc.a

LIBS += drivers/mtd/libmtd.a

LIBS += drivers/mtd/nand/libnand.a

LIBS += drivers/mtd/nand_legacy/libnand_legacy.a

LIBS += drivers/mtd/onenand/libonenand.a

LIBS += drivers/mtd/spi/libspi_flash.a

LIBS += drivers/net/libnet.a

LIBS += drivers/net/phy/libphy.a

LIBS += drivers/net/sk98lin/libsk98lin.a

LIBS += drivers/pci/libpci.a

LIBS += drivers/pcmcia/libpcmcia.a

LIBS += drivers/spi/libspi.a

LIBS += drivers/rtc/librtc.a

LIBS += drivers/serial/libserial.a

LIBS += drivers/usb/libusb.a

LIBS += drivers/video/libvideo.a

LIBS += common/libcommon.a

LIBS += libfdt/libfdt.a

LIBS += api/libapi.a

LIBS += post/libpost.a

LIBS := $(addprefix $(obj),$(LIBS)) #也是给LIBS目标添加上完整的路径

.PHONY : $(LIBS) $(VERSION_FILE)

ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)

all: $(ALL)

$(obj)u-boot.hex:
$(obj)u-boot

$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@

$(obj)u-boot.srec:
$(obj)u-boot

$(OBJCOPY) -O srec $< $@

$(obj)u-boot.bin:
$(obj)u-boot

$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

$(obj)u-boot.ldr:
$(obj)u-boot

$(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS)

$(obj)u-boot.ldr.hex: $(obj)u-boot.ldr

$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary

$(obj)u-boot.ldr.srec: $(obj)u-boot.ldr

$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I binary

$(obj)u-boot.img: $(obj)u-boot.bin

./tools/mkimage -A $(ARCH) -T firmware -C none \

-a $(TEXT_BASE) -e 0 \

-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \

sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \

-d $< $@

$(obj)u-boot.sha1: $(obj)u-boot.bin

$(obj)tools/ubsha1 $(obj)u-boot.bin

$(obj)u-boot.dis: $(obj)u-boot

$(OBJDUMP) -d $< > $@

$(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)

UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \

sed -n -e 's/.*\($(SYM_PREFIX)__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

$(OBJS): depend $(obj)include/autoconf.mk

$(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

#if函数:

#如果$1为真,计算第二个参数的值,

#并将第二个参数的值作为if函数的值,如果$1为假。

#计算第三个参数的值,如果第三个参数不存在,返回空。

#notdir抽取$@的除路径外的文件名

#上面这条命令,会进入cpu/arm目录下,对OBJS中每个成员进行make,依赖的Makefile是cpu/arm/下的

#该目标OBJS的成员在前面已经添加完毕,这里对每个目标文件进行编译。

#下面LIBS也是同理

depend dep: $(VERSION_FILE)

for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done

#目标depend dep 依赖于VERSION_FILE

#执行一个for循环,进入目录$dir,执行make命令,产生文件 _depend

#depend文件具体是如何生成,起什么作用。

VERSION_FILE = $(obj)include/version_autogenerated.h

$(LIBS): depend $(obj)include/autoconf.mk

$(MAKE) -C $(dir $(subst $(obj),,$@))

#dir抽取每一个文件名的路径部分,路径用空格隔开。

#subst,将$@中的每一个$(obj)用空格替换掉。

#切换到不同的路径下编译相应的库文件。

$(LIBBOARD): depend $(LIBS) $(obj)include/autoconf.mk

$(MAKE) -C $(dir $(subst $(obj),,$@))

$(SUBDIRS): depend $(obj)include/autoconf.mk

$(MAKE) -C $@ all

$(LDSCRIPT): depend $(obj)include/autoconf.mk

$(MAKE) -C $(dir $@) $(notdir $@)

$(NAND_SPL): $(VERSION_FILE) $(obj)include/autoconf.mk

$(MAKE) -C nand_spl/board/$(BOARDDIR) all

$(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk

cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin

$(ONENAND_IPL): $(VERSION_FILE) $(obj)include/autoconf.mk

$(MAKE) -C onenand_ipl/board/$(BOARDDIR) all

$(U_BOOT_ONENAND): $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk

cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin

cat $(obj)onenand_ipl/onenand-ipl-4k.bin $(obj)u-boot.bin > $(obj)u-boot-flexonenand.bin

$(VERSION_FILE):

@( printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' "$(U_BOOT_VERSION)" \

'$(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion $(TOPDIR))' \

) > $@.tmp

@cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: