这里只贴出Makefile、config.mk、u-boot.lds中关键的部分,不会全部列出,因为uboot中的Makefile、config.mk、u-boot.lds实在是太长了,仅仅是uboot的顶层Makefile就接近3200行….
在编译uboot之前,需要对uboot做的配置(make x210_sd_config),到底这一步做了什么呢?下面是我在Makefile中搜索目标后找到的相关的语句:
2589 x210_sd_config : unconfig
2590 @$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
2591 @echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk
执行命令传入6个参数,分别是x210_sd、arm s5pc11x x210 samsung s5pc110,其中$# = 6 、$1=arm、$2=s5pc11x、$3=x210、$4=samsung、$5=s5pc110这几个参数会被写入include/comfig.mk配置脚本中。
还有"TEXT_BASE = 0xc3e00000"这个地址被创建并追加到board/samsung/x210/config.mk这个配置文件中....
这里是uboot的24~42行,主要是定义了uboot版本、主机架构主机系统等信息,可以描述信息。
VERSION = 2017
PATCHLEVEL = 7
SUBLEVEL = 10
EXTRAVERSION = acer
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION) ## u-boot版本:2017.7.10.acer
VERSION_FILE = $(obj)include/version_autogenerated.h ## uboot/include/version_autogenerated.h
HOSTARCH := $(shell uname -m | \ #在linux命令行执行 uname -m 命令可查看主机架构
sed -e s/i.86/i386/ \
-e s/sun4u/sparc64/ \
-e s/arm.*/arm/ \
-e s/sa110/arm/ \
-e s/powerpc/ppc/ \
-e s/ppc64/ppc/ \
-e s/macppc/ppc/)
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ #在linux命令行下执行 uname -s 命令可查看主机系统
sed -e 's/\(cygwin\).*/cygwin/')
export HOSTARCH HOSTOS #导出环境变量:主机架构、主机系统
这里是uboot主Makefile的131~~184行,主要是加载主机架构、板级、cpu相关的信息,并指定交叉编译工具链...
# load ARCH, BOARD, and CPU configuration
include $(obj)include/config.mk
## 引入uboot配置阶段生成的配置文件include/config.mk,指明ARCH、CPU、BOARD、VENDOR、SOC
export
ARCH CPU BOARD VENDOR SOC
#导出来config.mk文件中这几个环境变量
ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE =
else
ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm) # arm 架构前面已经导出来了,就是HOSTARCH
#CROSS_COMPILE = arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.4.1-eabi-cortex-a8/usr/bin/arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
CROSS_COMPILE = /usr/local/arm/arm-linux-2009q3/bin/arm-none-linux-gnueabi-
endif
ifeq ($(ARCH),i386)
CROSS_COMPILE = i386-linux-
endif
ifeq ($(ARCH),mips)
CROSS_COMPILE = mips_4KC-
endif
ifeq ($(ARCH),nios)
CROSS_COMPILE = nios-elf-
endif
ifeq ($(ARCH),nios2)
CROSS_COMPILE = nios2-elf-
endif
ifeq ($(ARCH),m68k)
CROSS_COMPILE = m68k-elf-
endif
ifeq ($(ARCH),microblaze)
CROSS_COMPILE = mb-
endif
ifeq ($(ARCH),blackfin)
CROSS_COMPILE = bfin-uclinux-
endif
ifeq ($(ARCH),avr32)
CROSS_COMPILE = avr32-linux-
endif
ifeq ($(ARCH),sh)
CROSS_COMPILE = sh4-linux-
endif
ifeq ($(ARCH),sparc)
CROSS_COMPILE = sparc-elf-
endif
# sparc
endif
# HOSTARCH,ARCH
endif
# CROSS_COMPILE
export
CROSS_COMPILE
# load other configuration
include $(TOPDIR)/config.mk #加载顶层目录下的config.mk
这里是源码目录下config.mk,主要是如何构成一个完整的工具链,以及和前面inlcude/config.mk内核做比较并从刑定义一下目录结构...
#########################################################################
#
# Option checker (courtesy linux kernel) to ensure
# only supported compiler options are used
#
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
#########################################################################
# Load generated board configuration #加载生成的板级信息2018.06.15 ,该板级信息存在include/config.mk中
sinclude $(OBJTREE)/include/autoconf.mk
ifdef ARCH # ARCH = arm
sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules
endif
ifdef CPU # CPU = s5pc11x
sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules
endif
ifdef SOC #
sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk # include SoC specific rules
endif
ifdef VENDOR # VENDOR = samsung
BOARDDIR = $(VENDOR)/$(BOARD) ### BOARDDIR = samsung/x210
else
BOARDDIR = $(BOARD) #
endif
ifdef BOARD # BOARD = x210
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules ### board/samsung/x210/
endif
注意事项:在Makefile 或 配置脚本 中定义变量并赋值,需注意“=” 和 “:=” 这两种定义方法的区别
这里是config.mk的147行,引入链接u-boot.lds脚本:(144~148行)
ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
else
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds #u-boot.lds的引入
endif
这是u-boot.lds链接脚本的相关内容:(24~67行)
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start) # uboot启动的入口就是从这里开始的 (这里是个关键)
SECTIONS
{
. = 0x00000000; # 链接地址
. = ALIGN(4); # 4字节对齐
.text : # 代码段
{
cpu/s5pc11x/start.o (.text)
cpu/s5pc11x/s5pc110/cpu_init.o (.text)
board/samsung/x210/lowlevel_init.o (.text)
cpu/s5pc11x/onenand_cp.o (.text)
cpu/s5pc11x/nand_cp.o (.text)
cpu/s5pc11x/movi.o (.text)
common/secure_boot.o (.text)
common/ace_sha1.o (.text)
cpu/s5pc11x/pmic.o (.text)
*(.text)
}
. = ALIGN(4); # 4字节对齐
.rodata : { *(.rodata) } # 只读数据段
. = ALIGN(4);
.data : { *(.data) } # 数据段
. = ALIGN(4);
.got : { *(.got) } #自定义段
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) } #自定义段
__u_boot_cmd_end = .;
. = ALIGN(4);
.mmudata : { *(.mmudata) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) } #bss段
_end = .;
}
后续……..