声明:本文由个人学习过程中整理而成,转载请注明出处。


主Makefile,负责uboot整个工程的配置和编译


1、配置版本号

U_BOOT_VERSION变量记录了配置好的版本号。

version_autogenerated.h文件是编译过程自动生成的。


VERSION = 1

PATCHLEVEL = 3

SUBLEVEL = 4

EXTRAVERSION =

U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)

VERSION_FILE = $(obj)include/version_autogenerated.h


2、确定主机的CPU架构和操作系统

HOSTARCH := $(shell 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:]' | \

   sed -e 's/\(cygwin\).*/cygwin/')


exportHOSTARCH HOSTOS


3、静默编译

make -s则是使用静默编译,不输出makefile编译信息。

通过findstring函数来找MAKEFLAGS是否有s的关键词。

如果没有找到s则返回空。如果找到s则返回s。


ifeq (,$(findstring s,$(MAKEFLAGS)))

XECHO = echo

else

XECHO = :

endif


4、设置编译输出目录

(1)两种编译输出目录分别是原处输出,指定输出。

原处输出:源代码与编译后生成的文件同处于一个文件夹,默认使用的方式。

指定输出:源代码编译后生成的文件存放到指定文件夹,有两种方式指定输出目录。

第一种:make O=输出目录

第二种:export BUILD_DIR=输出目录 然后再make

如果两种指定输出目录都设置,那么优先使用第一种方式。


ifdef O

ifeq ("$(origin O)", "command line")

BUILD_DIR := $(O)

endif

endif


ifneq ($(BUILD_DIR),)

saved-output := $(BUILD_DIR)


# Attempt to create a output directory.

$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})


# Verify if it was successful.

BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)

$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))

endif # ifneq ($(BUILD_DIR),)


(2)OBJTREE:编译后生成的目标文件所在文件夹的根目录。

SRCTREE:源代码所在的根目录(源码目录)。

CURDIR:表示Makefile当前的工作目录。CURDIR是Makefile的内嵌变量,显示当前路径。


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

SRCTREE:= $(CURDIR)

TOPDIR:= $(SRCTREE)

LNDIR:= $(OBJTREE)

exportTOPDIR SRCTREE OBJTREE


MKCONFIG:= $(SRCTREE)/mkconfig

export MKCONFIG


ifneq ($(OBJTREE),$(SRCTREE))

REMOTE_BUILD:= 1

export REMOTE_BUILD

endif


5、检查include/config.mk文件是否存在?

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))


(1)config.mk文件是mkconfig脚本文件所创建。

(2)config.mk文件内容的配置值来自于x210_sd_config

ARCH:arm(CPU架构)

CPU:s5pc11x(CPU型号)

BOARD:x210(目标板名称)

VENDOR:samsung

SOC:s5pc110(芯片名称)


include $(obj)include/config.mk

exportARCH CPU BOARD VENDOR SOC


(3)指定交叉编译器前缀

在不同CPU架构上的交叉编译工具链,只是前缀不一样,后缀都是一样的。

只需要在定义前缀时区分各种架构即可实现可移植性,CROSS_COMPILE用来定义交叉编译工具链的前缀。


ifndef CROSS_COMPILE

ifeq ($(HOSTARCH),$(ARCH))

CROSS_COMPILE =

else

ifeq ($(ARCH),ppc)

CROSS_COMPILE = ppc_8xx-

endif

ifeq ($(ARCH),arm)

#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-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


exportCROSS_COMPILE


6、uboot/config.mk文件包含进来

include $(TOPDIR)/config.mk


7、最后生成的各种镜像文件

(1)主Makefile中第一个目标all,make all。

all:$(ALL)


8、uconfig的作用是删除上一次make x210_sd_config所产生的文件,为了下一次的make x210_sd_config做准备

(1)include/config.mk,目标x210_sd_config中的设置值。

(2)include/autoconf.mk,开发板相关的配置。

(3)board/samsung/X210/config.mk,uboot的链接地址


unconfig:

@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)board/$(VENDOR)/$(BOARD)/config.mk


9、x210_sd_config

(1)主Makefile中第二个目标x210_sd_config,make x210_sd_config。

(2)调用uboot/mkconfig脚本并传递6个参数。

$1:x210_sd

$2:arm

$3: s5pc11x

$4:x210

$5: samsumg

$6:s5pc110


参考资料:《uboot和系统移植---朱有鹏老师》