uboot version确定
(1)uboot的版本号分3和级别:
VERSION:主版本号
PATCHLEVEL:次版本号
SUBLEVEL:再次版本号
EXTRAVERSION:另外附加的版本信息,可以自己定义的
这4个用 . 分隔开共同构成了最终的版本号。
(2)Makefile中版本号最终生成了一个变量U_BOOT_VERSION,这个变量记录了Makefile中配置的版本号
(3)include/version_autogenerated.h文件是编译过程中自动生成的一个文件,所以源目录中没有,但是编译过后的uboot中就有了。它里面的内容时一个宏定义,宏定义的值内容就是我们在Makefile中配置的uboot的版本号。
(4)验证方法:自己修改主Makefile中几个version有关的变量,然后重新编译uboot,然后烧录到SD卡中,从SD卡启动,然后去看启动时uboot打印出来的版本信息,看变化是不是和主机的分析一致。
HOSTARCH和HOSTOS
(1)直接在shell中执行uname -m得到i686,得到的值其实你当前执行这个命令的电脑的CPU的版本号
(2)shell中的 | 叫做管道,管道的作用就是把管道前面一个运算式的输出作为后面一个的输入再去做处理,最终的输出才是我们整个式子的输出。
(3)HOSTARCH这个名字:HOST是主机,就是当前我们在做开发的这台电脑就叫主机;ARCH是architecture(架构)的缩写,表示CPU的架构。所以HOSTARCH就表示主机的CPU的架构
(4)这两个环境变量是主机的操作系统和主机的CPU架构,得出后保存备用,后面自然会用到
静默编译
(1)平时默认编译时命令行会打印很多的编译信息,有时候我们不希望看到这些编译信息,就后套编译即可,这就叫静默编译。
(2)使用方法就是编译时make -s,-s会作为MAKEFLAGS传给Makefile,在这段代码下XECHO变量就会变成空(默认等于echo),于是实现了静默编译.
ifeq (,$(findstring s,$(MAKEFLAGS)))
XECHO = echo
else
XECHO = :
endif
uboot2种编译方法(原地编译和单独输出文件夹来编译)
(1)编译复杂项目,makefile提供2中编译管理方法,默认情况下是当前文件夹中的.c文件,编译出来的.o文件会放在同一文件夹下。这种方式叫原地编译。原地编译的好处就是处理起来简单。
(2)原地编译有一些坏处:第一,污染了源文件目录。第二缺陷就是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。
(3)为解决以上的问题,uboot支持单独输出文件方式的编译(linux kernel也支持,说白了uboot就是向linux kernel 学习的)基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成的.o文件或生成的其它文件全部丢到那个输出目录下去。源代码目录不做任何污染,这样输出目录就承载了本次配置编译的所有结果。
make disclean//配置我们的uboot
(4)具体用法:默认的就是原地编译。如果需要指定具体的输出目录编译则有2种方式来指定输出目录。
第一种:make o=输出目录
第二种:export BUILD_DIR = 输出目录,然后再make
如果两个都指定了(既有BUILD_DIR 环境变量存在,又有o=xx),则o=xx具有更高优先级
ifdef O
ifeq ("$(origin O)","command line")
BUILD_DIR := $(O)//这里的o其实就是我们的目录
endif
endif
ifneq ($(BUILD_DIR),)//如果为空,则保存
saved-output := $(BUILD_DIR)
#尝试创建输出目录
$(shell [ -d ${
BUILD_DIR} ] || mkdir -p ${
BUILD_DIR})
#验证他是否成功
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR))
OBJTREE :=$(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))//将来要编译的.o的文件目录
SRCTREE :=$(CURDIR)//源代码的根目录
TOPDIR :=$(SRCTREE)
LNDIR :=$(OBJTREE)
export TOPDIR SRCTREE OBJTREE
MKCONFIG :=$(SRCTREE)/mkconfig
export MKCONFIG
ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD :=1//远程编译,如果为0的话就是原地编译
export REMOTE_BUILD
endif
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
else
obj :=
src :=
endif
export obj src
OBJTREE,SRCTREE,TOPDIR
(1)OBJTREE:编译出的.o文件存放的目录的根目录,在默认编译下,OBJTREE等于当前目录;在O=xx编译下,OBJTREE就等于我们设置的那个输出目录。
(2)SRCTREE:源码目录,其实就是源代码的根目录,也就是当前目录。
总结:默认编译下,OBJTREE和SRCTREE相等,在O=xx这种编译下OBJTREE和SRCTREE不相等。makefile中定义这两个变量,其实就是为了记录编译后的.o文件往哪里放,就是为了实现O=xx的这种编译方式的。
MKCONFIG
(1)makefile中定义的一个变量(后面使用,十分重要),它的值就是我们源码根目录下面的mkconfig。这个mkconfig是一个脚本,这个脚本就是uboot配置阶段的配置脚本
MKCONFIG :=$(SRCTREE)/mkconfig//就是我们源代码下的mkconfig
export MKCONFIG
include $(obj) include/config.mk
(1)include、config.mk不是源码自带的(你在没有编译过的源代码目录下是找不到这个文件的),要在配置过程(make x210_sd_config)中才会生成这个文件。因此这个文件的值和我们配置过程有关,是有配置过程根据我们的配置自动生成的。
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
(2)我们x210在iNand情况下配置生成的config.mk内容为:
ARCH = arm
CPU = s5pc11x
BOARD = x210
VENDOR = samsung
SOC = s5pc110
(3)我们在下一行(134行)export导出了这5个变量作为环境变量。所以这两行加起来其实就是为当前makefile定义了5个环境变量而已。之所以不直接给出这5个环境变量的值,是因为我们希望这5个值是可以被人很容易的,集中的配置的
(4)这里的配置值来自于2589行哪里的配置项。如果我们要更改这里的某个配置值要到2589行那里的配置项。如果我们要更改这里的某个配置值要到2589行那里调用MKCONFIG脚本传参时的参数。
x210_sd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
@echo "TEXT_BASE = 0xc3e00000" > $(obj)
board/samsung/x210/config.mk
ARCH CROSS COMOILE
(1)接下来有2个很重要的环境变量。一个是ARCH,上面导出来的,值来自于我们的配置过程,它的值会影响后面的CROSS_COMPILE环境变量的值。ARCH的意义是定义当前编译的目标CPU的架构。
(2)CROSS_COMPILE是定义交叉编译工具链的前缀的。定义这些前缀是为了在后面用(用前缀加上后缀来定义编译过程中用到的各种工具链中的工具)。我们把前缀和后缀分开的一个原因就是:在不同CPU架构上的交叉编译工具链,值是前缀不一样,后缀都是一样的。因此定义时把前缀和后缀分开,只需要在定义前缀时区分各种架构即可实现可移植性。
(3)CROSS_COMPILE是在136-182行确定的。CROSS_COMPILE是被ARCH所确定的,只要配置了ARCH=arm,那么我们就只能在ARM的那个分支去设置CROSS_COMPILE的值。这个设置值只要能保证找到那个交叉编译工具链即可,不一定非的是全路径的,相对路径也是可以的。(如果已经将工具链到处到环境变量,并且设置了符号链接,这样CROSS_COMPILE = arm-linux-就可以)
ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE =
else
ifeq ($(ARCH),ppc)
CROSS_COMPILE = ppc_8xx-
endif
ifeq ($(ARCH),arm)
CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-endif
endif
ifeq ($(ARCH),i386)
CROSS_COMPILE =i386-linux-
endif
ifeq ($(ARCH),mips)
CROSS_COMPILE =mips-4KC-
endif
ifeq ($(ARCH),nions)
CROSS_COMPILE =nios-elf-
endif
ifeq ($<