作者: Linux-小企鹅
博客地址:http://blog.csdn.net/u012319379/article/details/77882602
上一节中单独注释了Makefile文件,这节联系实际操作分析编译和Makefile的联系。
u-boot编译
配置交叉工具链
export PATH=$PATH:/mnt/zdh/zdh/sdb2/lollipop-5.1.1_r6/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin检验环境变量
arm-eabi-gcc -v,如果可以显示gcc version 4.8 (GCC)就是正确的。配置uboot
make ARCH=arm s5p4418_drone2_config
make
如果成功编译的话会生成u-boot.bin…等文件
Makefile分析
- 板级配置
make ARCH=arm s5p4418_drone2_config
将会执行Makefile文件的下面内容,然后通过mkconfig -A s5p4418_drone2_config进行处理。
# 这边是分析make XXX_config的解析生成config.h
%_config:: outputmakefile
@$(MKCONFIG) -A $(@:_config=)
mkconfig 脚本部分内容
if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
# Automatic mode
line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' $srctree/boards.cfg`
if [ -z "$line" ] ; then
echo "make: *** No rule to make target \`$2_config'. Stop." >&2
exit 1
fi
set ${line}
# add default board name if needed
[ $# = 3 ] && set ${line} ${1}
fi
上面的这段脚本解析boards.cfg的这个内容
Active arm slsiap s5p4418 s5p4418 drone2 s5p4418_drone2 -
如果没有的话输出没有规则就退出,有的话该脚本生成config.h文件。
config.h文件内容
/* Automatically generated - do not edit */
#define CONFIG_SYS_ARCH "arm"
#define CONFIG_SYS_CPU "slsiap"
#define CONFIG_SYS_BOARD "drone2"
#define CONFIG_SYS_VENDOR "s5p4418"
#define CONFIG_SYS_SOC "s5p4418"
#define CONFIG_BOARDDIR board/s5p4418/drone2
#include <config_cmd_defaults.h>
#include <config_defaults.h>
#include <configs/s5p4418_drone2.h>
#include <asm/config.h>
#include <config_fallbacks.h>
#include <config_uncmd_spl.h>
- 编译u-boot与Makefile结合分析
make ARCH=arm
执行该命令后定位到默认目标规则ALL
all: $(ALL-y)
ALL-y += u-boot.srec u-boot.bin System.map binary_size_check
此时make会找到u-boot.srec u-boot.bin System.map binary_size_check和其他ALL-*的依赖,我们关心我们需要的文件,u-boot.bin。
u-boot.bin: u-boot FORCE
$(call if_changed,objcopy)
$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
$(BOARD_SIZE_CHECK)
cp mkuboot_4418 mkuboot
./nx_bingen-4418 -t 2ndboot -d other -o 2ndboot.bin -i 2ndboot_sdmmc_4418.bin -n nsih.txt -l 0xffff0000 -e 0xffff0000
./create_uboot 2ndboot.bin u-boot.bin u-boot-iTOP-4418.bin
u-boot.bin依赖u-boot
# 生成u-boot,需要u-boot-init,u-boot-main, u-boot.lds
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds
$(call if_changed,u-boot__)
u-boot依赖三个子项目u-boot-init,u-boot-main,u-boot.lds
u-boot-init := $(head-y)
u-boot-main := $(libs-y)
# 编译后需要链接的文件,start.o必须放在第一个
head-y := $(CPUDIR)/start.o
head-$(CONFIG_4xx) += arch/powerpc/cpu/ppc4xx/resetvec.o
head-$(CONFIG_MPC85xx) += arch/powerpc/cpu/mpc85xx/resetvec.o
libs-y += lib/
libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
libs-y += $(CPUDIR)/
ifdef SOC
libs-y += $(CPUDIR)/$(SOC)/
endif
libs-$(CONFIG_OF_EMBED) += dts/
libs-y += arch/$(ARCH)/lib/
libs-y += fs/
libs-y += net/
libs-y += disk/
libs-y += drivers/
libs-$(CONFIG_DM) += drivers/core/
libs-y += drivers/dma/
libs-y += drivers/gpio/
libs-y += drivers/i2c/
libs-y += drivers/input/
libs-y += drivers/mmc/
ifdef CONFIG_NAND_MTD
libs-y += drivers/mtd/
libs-y += drivers/mtd/nand/
libs-y += drivers/mtd/onenand/
libs-y += drivers/mtd/spi/
libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/
endif
libs-y += drivers/net/
libs-y += drivers/net/phy/
libs-y += drivers/pci/
libs-y += drivers/power/ \
...
这里可以看到我们u_boot-init的目标文件对应的$(CPUDIR)/start.o,libs对应的是其他的功能实现,u-boot.lds是链接脚本,用于定义程序的空间结构。
arch/arm/cpu/slsiap/u-boot.lds
/*
* Copyright (c) 2004-2008 Texas Instruments
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*定义程序的输出格式,elf文件头32位小端程序*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*输出架构为ARM*/
OUTPUT_ARCH(arm)
/*代码段的入口*/
ENTRY(_stext)
/*代码端的定义*/
SECTIONS
{
/*代码端基地址,现在是0,在程序链接的的时候可以看到一个CONFIG_SYS_TEXT的宏定义值*/
. = 0x00000000;
/*对齐方式:4byte对齐*/
. = ALIGN(4);
/*代码段*/
.text :
{
*(.__image_copy_start)
SDIR/start.o (.text*)
*(.text*)
}
. = ALIGN(4);
/*只读数据段*/
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
/*数据段*/
.data : {
*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
.end :
{
*(.__end)
}
_image_binary_end = .;
/*
* Deprecated: this MMU section is used by pxa at present but
* should not be used by new boards/CPUs.
*/
. = ALIGN(4096);
.mmutable : {
*(.mmutable)
}
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu.hash : { *(.gnu.hash) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}
总结
从这节的分析可以知道一个程序的入口是start.o,链接脚本是u-boot.lds,后面内容就从start.o的入口来分析吧。