uboot的配置流程分析
简单介绍一下uboot的基本配置流程。和绝大多数源码编译安装一样,uboot在执行make
之前需要执行make XXXconfig
来配置相关信息,而且uboot本身是针对多种平台的bootloader,所以编译的过程也会有一点小麻烦,需要对它的源码结构有一点了解。移植uboot,大体上的流程是:配置uboot->编译->配置相关平台的启动程序->烧录
选平台&工具链
平台就是CPU的架构,即exynos4412的平台就是arm,所以ARCH=arm
,交叉编译工具链我这里用的是arm-none-linux-gnueabi-
,因为我的电脑中有很多工具链,而很多工具链的工具名字还有所重叠,所以最好只有一个是apt-get
安装的,其他的都通过tar包安装,这样可以避免多个工具链都去修改环境变量,一旦我用的工具在多个工具链中都存在,就很可能导致我实际用的工具不是我想用的,因为系统会匹配它第一个在PATH中寻找到的工具。解决这个问题的一个方法就是每次使用工具的时候都指定相应的路径,比如我这里就应该是CROSS_COMPILE=/opt/arm-cross-compile/arm-none-linux-gnueabi-2014-05/bin/arm-none-linux-gnueabi-
,如果觉得每次都要修改uboot的顶层Makefile或者传入这么长的一个变量很麻烦,可以写一个shell脚本。我这里就使用shell脚本的方式配置相应的环境变量
export ARCH=arm export CROSS_COMPILE=/opt/arm-cross-compile/arm-none-linux-gnueabi-2014-05/bin/arm-none-linux-gnueabi- 。。。
配置流程
uboot的顶层配置主要依靠下面的这棵树
. ├── Makefile ├── mkconfig ├── include │ ├── config.mk │ └── config.h └── boards.cfg
uboot的配置就是通过键入相应的命令将相应的Makfile变量赋值,通过你的配置,Makefile相应的变量就知道编译哪个平台下的哪个cpu的哪个版本的开发板。通过顶层的README我们可以看到:
注意:不同版本的uboot的配置命令可能是不同的,拿到源码包看README是个很好的习惯,比如uboot-2016-07的配置命令是这个样子的:
在uboot-2013-01中,我们去到顶层目录下的boards.cfs文件中查看它支持的开发板和相应的信息,需要注意的是这个文件可不是README,后续的编译过程需要读取文件中的信息,所以不要随意修改,同理,如果我们需要配置我们自己的开发板,也就需要对其中的信息进行相应的修改
了解了这些,手痒的话就可以先执行下面的脚本试一下,但是并不会生成真正适配我们板子的uboot,只是适配参考板
#!/bin/bash export ARCH=arm export CROSS_COMPILE=/opt/arm-cross-compile/arm-none-linux-gnueabi-2014-05/bin/arm-none-linux-gnueabi- make origen_config make all
编译流程简析
首先,当我们键入make origen_config
的时候,显然是打算创建makefile里面的一个叫origen_config的目标。根据Makefile的语法,我们就可以找到下面这一段(然而并不是想象中的origen_config:)
根据Makefile语法,%
是Makefile中的通配符,表示任意字符串,所以我们的origen_config
就会与之相匹配,这个目标的依赖于unconfig
,就是说如果你键入两次make origen_config
,那么它最终只会形成一个相应的配置文件,这种写法在Makefile中很常见,可以学习。这个目标的生成方法是执行$(MKCONFIG) -A $(@:_config=)
,查看Makefile开头可以知道这个MKCONFIG
就是顶层目录下的mkconfig脚本,而$(@:_config=)
就是去除目标中的_config
串,所以实际上就是去到顶层目录下执行$mkconfig -A origen
这个命令。我们去里面看看它都做了什么
一上来我们就知道,我们传入的参数会导致脚本执行这个if里面的内容,即使用扩展正则表达式去顶层目录下的boads.cfg文件中提取含有origen
相应的行到line
变量中,并把line设置为新的参数列表。取得了这个参数字符串,mkconfig就可以把相应的头文件,链接和全局变量准备好,我们来稍微看点细节,首先,line里应该有的内容是我们在Boards.cfg中搜到的这个:
根据boards.cfg,这几个参数分别是:TARGET,ARCH,CPU,Board name,Vendor,SoC,Options(origen只有6个,加上之前的$1
一共7个参数),So执行的代码是:
从中可以看出,这段代码就是把之前line
的内容分段并赋值给开头的arch``cpu``board
等变量,显然,这些变量对于我们找到相应的目录,相应的文件进行编译至关重要。这些信息,会在mkconfig的之后写入到相应的文件中:
此外,还要建立一些硬链接:
至此,我们需要的include/config.mk
就配置完成了,这个文件是长成这个样子的:
除了生成include/config.mk
,MKCONFIG
还负责生成include/config.h
文件,不过有了之前准备好的变量,这部分只不过是将上面的变量和相应的文件夹进行了初步的定位,代码就是下面这部分: 它生成的include/config.h
最终是长成这个样子的: 有了这两个文件,当我们再执行make
的时候就可以找到相应的文件了。