Uboot配置(mkconfig)和编译过程(Makefile)详解

目录

2.4.1.uboot主Makefile分析1

2.4.2.uboot主Makefile分析2

2.4.3.uboot主Makefile分析3

2.4.1.uboot主Makefile分析1

1.uboot version确定(Makefile的24-29行)

Uboot配置(mkconfig)和编译过程(Makefile)详解

(1)uboot的版本号分3个级别:      

VERSION:主板本号

PATCHLEVEL:次版本号

SUBLEVEL:再次版本号

EXTRAVERSION:另外附加的版本信息

这4个用.分隔开共同构成了最终的版本号。

(2)Makefile中版本号最终生成了一个变量U_BOOT_VERSION,这个变量记录了Makefile中配置的版本号。

(3)include/version_autogenerated.h文件是编译过程中自动生成的一个文件,所以源目录中没有,但是编译过后的uboot中就有了。它里面的内容是一个宏定义,宏定义的值内容就是我们在Makefile中配置的uboot的版本号。

Uboot配置(mkconfig)和编译过程(Makefile)详解

Makefile下单独执行$(obj)为空,这里是 = $(obj) ,所以后面应该会有对变量obj的定义

CURDIR 其实是make 的内嵌变量,自动设置位当前目录。一般obj = $ (CURDIR),  所以一般$(obj)代表当前目录

  1. HOSTARCH和HOSTOS

Uboot配置(mkconfig)和编译过程(Makefile)详解

(1)直接在shell中执行uname -m得到i686,得到的值其实你当前执行这个命令的电脑的CPU的硬件版本号。

(2)shell中的|叫做管道,管道的作用就是把管道前面一个运算式的输出作为后面一个的输入再去做处理,最终的输出才是我们整个式子的输出。

(3)HOSTARCH这个名字:ubuntu主机架构。所以HOSTARCH就表示主机的CPU的架构。

#uname -m 查看主机类型:i686  32位的ubuntu 。  统一把i686的Ubuntu修改为i386

#HOSTOSuname -s 查看主机操作系统,tr '[:upper:]' '[:lower:]'将所有大写变小写,然后假如有cygwin.*,替换成cygwin,并将结果放入变量HOSTOS

 Cygwin是以前win下的unix开发环境,之前没有ubuntu。 这个一般也不用了。

(4)这两个环境变量是主机的操作系统和主机的CPU架构,得出后保存备用,后面自然会用到。

export导出变量HOSTARCH HOSTOS ,export这个一般是用来提供该目录下子目录makefile(sub make)中访问的,同一级的另外一个makefile中,是无法访问/得到的。(可以通过makefile中内置变量MAKELEVEL查看得知当前makefile的levlel)

Sed:

-e : 可以在同一行里执行多条命令

不加 -e 只有 's/11/00/g' 进行了操作

sed是用来处理文本的   s/正则表达式/替换字符串/    :表示将正则表达式的内容替换为后面的字符串   -e    :多点编辑(这个没懂)

 

tr: translate的简写,即翻译的意思。主要用来从标准输入中通过替换或删除操作进行字符转换。只接受标准输入,不接受文件参数。

命令语法:

 tr [–c/d/s/t] [SET1] [SET2]

SET1/SET2: 字符集

-t: truncate-set1,将SET1用SET2替换,一般缺省为-t
 

2.4.2.uboot主Makefile分析2

 

1、静默编译(50-54行)

(1)平时默认编译时命令行会打印出来很多编译信息。但是有时候我们不希望看到这些编译信息,就后台编译即可。这就叫静默编译。

(2)使用方法就是编译时make -s,-s会作为MAKEFLAGS传给Makefile,在50-54行这段代码作用下XECHO变量就会被变成空(默认等于echo),于是实现了静默编译。

#如果MAKEFLAGS中包含s,则静默编译

Uboot配置(mkconfig)和编译过程(Makefile)详解

$(findstring FIND,IN)

函数名称:查找字符串函数—findstring。

函数功能:搜索字串“IN”,查找“FIND”字串。

返回值:如果在“IN”之中存在“FIND” ,则返回“FIND”,否则返回空。

函数说明:字串“IN”之中可以包含空格、[Tab]。搜索需要是严格的文本匹配。

示例:

$(findstring a,a b c)

$(findstring a,b c)

第一个函数结果是字“a”;第二个值为空字符。

 

2、2种编译方法(原地编译和单独输出文件夹编译)

(1)编译复杂项目,Makefile提供2种编译管理方法。默认情况下是当前文件夹中的.c文件,编译出来的.o文件会放在同一文件夹下。这种方式叫原地编译。原地编译的好处就是处理起来简单。

(2)原地编译有一些坏处:第一,污染了源文件目录。第二的缺陷就是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。

(3)为了解决以上2种缺陷,uboot支持单独输出文件夹方式的编译(linux kernel也支持,而且uboot的这种技术就是从linux kernel学习来的)。基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成的.o文件或生成的其他文件全部丢到那个输出目录下去。源代码目录不做任何污染,这样输出目录就承载了本次配置编译的所有结果。

(4)具体用法:默认的就是原地编译。如果需要指定具体的输出目录编译则有2种方式来指定输出目录。(具体参考Makefile 56-76行注释内容)

第一种:make O=输出目录  。第一种方式会覆盖环境变量 BUILD_DIR

第二种:通过设置全局变量export BUILD_DIR=输出目录 然后再make。

 如果没有显式指定使用哪种方式,编译脚本会自动进行本地编译,目标文件被存放在当前文件夹里

 

Uboot配置(mkconfig)和编译过程(Makefile)详解

如果两个都指定了(既有BUILD_DIR环境变量存在,又有O=xx),则O=xx具有更高优先级,听他的。

(5)两种编译的实现代码在Makefile的78-123行。

Uboot配置(mkconfig)和编译过程(Makefile)详解

#如果命令行里有“O”, BUILD_DIR指定为命令中的目录

$(origin O)中的origin函数不直接操作变量的值,而告诉你这个变量是从哪里来的,其语法是: $(origin   variable)。

其中,variable是变量的名字而不是引用,所以不需要使用“$”字符。origin函数会以返回值告诉你这个变量的“出生情况”,返回值详情如下:

返回值为"command line"时,表示variable变量由命令行定义,即由make variable= 传入。

Uboot配置(mkconfig)和编译过程(Makefile)详解

#如果BUILD_DIR有定义 不等于空,saved-output保存$(BUILD_DIR)

#检测BUILD_DIR是否是一个目录,如果不存在则创建这个BUILD_DIR对应的目录

#[]和test测试命令一样,Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试


#如果能cd $(BUILD_DIR),则输出这个目录的路径

&&换句话说,“如果这个命令执行成功&&那么执行这个命令”。

#检测BUILD_DIR是否为空,如果为空则提示错误并终止make
if函数——$(if CONDITION,THEN-PART[,ELSE-PART]).如果“CONDITION”的展开结果非空,则将第二个,“CONDITION”的展开结果为空,则执行第三个参数。

error——$(error TEXT...)产生致命错误,并提示“TEXT...”信息给用户,并退出make执行,没有返回值。

Uboot配置(mkconfig)和编译过程(Makefile)详解

CURDIR 其实是make 的内嵌变量,自动设置位当前目录。其它就没啥可说的了,都是一些变量包含路径的定义

  1. 编译方法实践

Uboot配置(mkconfig)和编译过程(Makefile)详解

Vi下 /O= 查找如下

Uboot配置(mkconfig)和编译过程(Makefile)详解

按照这个顺序执行,遇到目录未创建的情况,创建即可。 但最后编译不成功,可能是X210官方从三星移植过来时给干了?

Uboot配置(mkconfig)和编译过程(Makefile)详解

 

2.4.3.uboot主Makefile分析3

 

1、OBJTREE、SRCTREE、TOPDIR

(1)OBJTREE:编译出的.o文件存放的目录的根目录。在默认编译下,OBJTREE等于当前目录;在O=xx编译下,OBJTREE就等于我们设置的那个输出目录。

(2)SRCTREE: 源码目录,其实就是源代码的根目录,也就是当前目录。

总结:在默认编译下,OBJTREE和SRCTREE相等;在O=xx这种编译下OBJTREE和SRCTREE不相等。Makefile中定义这两个变量,其实就是为了记录编译后的.o文件往哪里放,就是为了实现O=xx的这种编译方式的。

2、MKCONFIG(Makefile的101行)

(1)Makefile中定义的一个变量(在这里定义,在后面使用),它的值就是我们源码根目录下面的mkconfig。这个mkconfig是一个脚本,这个脚本就是uboot配置阶段的配置脚本。Uboot移植的重点

3、include $(obj)include/config.mk(133行)

(1)include/config.mk不是源码自带的(你在没有编译过的源码目录下是找不到这个文件的),要在配置过程(make x210_sd_config)中才会生成这个文件。因此这个文件的值和我们配置过程有关,是由配置过程根据我们的配置自动生成的。

(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行那里调用MKCONFIG脚本传参时的参数。