第一部分
2.3.1uboot配置编译实践
1)源头的源代码时uboot官网下载的。这个下载的源代码可能没有你当前使用的开发板的移植,甚至找不到当前开发板使用的SoC对应的移植版本。
2)SoC厂商在退出一款SoC后,厂商的工程师会去uboot官网下载一个uboot,根据自己Soc进行第一步移植,移植的目标是厂商推出的开发板。(譬如三星的S5PV210芯片厂商出的开发板就叫SMDKV210),所以三星的工程师移植的uboot是根据他们自己的SMDKV210开发板移植的。
3)具体的开发板提供商(譬如X210的生产商深圳市九鼎科技)首先购买三星的SMDKV210开发板,然后进行裁剪(把一些无用的接口功能裁剪去,配置降低一下,某些配置会被替换)。硬件替换和裁剪之后生成的新的开发板和三星官方的SMDKV210有所不同,因此uboot也不同,但是因为SoC是相同的,所有相似度至少60%以上,所有具体开发板供应商会以三星SMDK210中移植的uboot为蓝本来移植的到自己的开发板的一个uboot移植。我们买x210开发板时厂商光盘中带的BSP中的uboot源码就是他移植过的。
1. tq210移植过的uboot开发板光盘的BSP中。BSP就是board support package(板级支持包,一般由开发板供应商提供),里面的内容就是这个开发板的所有相关的源代码,文档,教程等。
2. 将整个BSP打包文件弄到linux的原生目录中取解压分析,不要在windows中的共享文件夹中解压打开。
3. 我们在linux下维持一份uboot,在windows下也维持一份uboot,在我们没有开始任何工作之前,这两份uboot内容一样,都是天嵌官方uboot内容,我们这样做的目的;在linux中进行编译,在windows下进行代码分析和观看。(windows下有sourceinsight等很好的工具辅助我们看代码,编辑代码,在linux下编译和看代码都很麻烦。)
4. 配置 uboot和linux kernel等复杂项目都不能直接编译,都要先配置,然后编译。 Uboot也要先配置,方法:首先cd进入源码的根目录,配置的原因,uboot支持很多开发板,但编译后的镜像只能用在某一个开发板上,所有需要配置。一般配置的文件在Makefile中搜索开发板的名字。在根目录下执行make TQ210_config 配置命令。一般会出现 Configuring for TQ210 board…. 接下来就是编译,一定要检查arm-linux-gcc 对不对,检查分两步,1.检查当前编译环境中有没有安装合适的arm-linux-gcc。2.检查当前目录下(uboot根目录)的makefile中编译器的设置是否正确。在工程的总的makefile中会设置交叉编译工具链的路径和名字,必须确保这个路径和名字和我们自己装的一致,否则会编译出错。确保以上2点,即可进行编译,编译很简单,直接make,或者make
-j4
1. uboot的源码目录分析1
天嵌官方uboot和三星原版uboot对比,以天嵌官方为蓝本来学习的,以三星官方的这份为对照。不同版本的uboot或者同一版本不同人移植的uboot,可能目录结构和文件内容都有所不同。将来大家懂了之后大家可以自己添加,更改,删除uboot。天嵌在以三星的uboot为原材料进行移植时,把三星版本的uboot中很多不必要的文件夹,文件给删掉了。这个删掉把很多用不到的删掉。
2. 各个文件介绍:
1. .gitignore git工具的文件,git是一个版本管理工具。(类似的还有个svn),这个文件和git有关,和uboot本身无关,不用去管。
2. arm_config.mk 后缀是.mk,是一个Makefile文件,将来在某个makefile中会调用它。
3. 三个changelog文件,修改记录文件,该文件记录了这个uboot项目的版本变迁及每个版本较上个版本修改的记录。正式的项目都有这些记录的。主要是给维护uboot的工程师用的。
4. Config.mk 和arm_config.mk差不多的性质
5. COPYING.版权声明,uboot本身是GPL许可证的。
6. CREDITS. 鸣谢。里面记录了对uboot有贡献的人。
7. Image_split。一个脚本,看说明是用来分割uboot.bin到BL1,暂时用不到,先不管。
8. MAINTAINERS 维护者,就是当前参与维护uboot源码的社区工作者。
9. MAKEALL.一个脚本,应该是帮助编译uboot的。
10. Makefile.这个很重要,是uboot源代码的主makefile,将来整个uboot被编译时就用这个makefile管理编译的,所以我们在下个课程中研究uboot配置编译过程就要分析这个makefile 。
11. Mkconfig 这个很重要,是uboot配置阶段的主要配置脚本。Uboot的可移植性很大程度就是靠这个配置脚本在维护的。我们在下个课程中研究uboot配置编译过程就要分析这个配置脚本。
12. Mkmovi。 一个脚本,和Inand、sd卡启动有关。
13. Readme。所有的软件都有reandme,一般拿到一个东西先读readme,这个东西就是一个简单的说明书。
14. Rules.mk 这个文件是我们uboot的makefile使用的规则,本身很非常重要,但是我们不去分析,不去看到
以上这些文件。对我们比较重要的,需要认真看的2个,mkconfig和makefile。一个负责uboot的配置,一个负责编译。需要详细解释。
Uboot源码目录分析:
1. API: 硬件无关的功能函数的API.uboot移植时基本不用管,这些函数是uboot本身使用的。
2. Api_examples: api相关测试实例代码。
3. Board :board是板的意思,板就是开发板,board文件夹下每个文件代表一个开发板。这个文件夹下面放的文件就是用来描述这一个开发板的信息的。Board目录下有多少个文件夹,就表示当前这个uboot已经被移植到多少个开发板上(当前的uboot支持多少个开发板)。问题一;思考uboot如何支持多套开发板,如何具有可移植性。 问题二:board下那么多文件夹,究竟如何确定具体使用的是哪一个?uboot在配置阶段会有一些手段帮我们来确定具体使用的是board目录下的哪一个文件夹。问题三:开发板越来越多,board目录下文件夹越来越多,不方便管控。于是乎uboot就新增了一种机制,可以在board目录下不直接放开发板目录,而是在board下放厂家目录(vendor目录,以具体芯片厂商名字命名),然后将这个IC厂商的所有芯片开发板都丢到这个vendor目录下面去。所以大家会发现我们TQ210对应的开发板目录在/board/Samsung/EmbedSky/TQ210.多了这层目录会影响配置阶段,在uboot的配置阶段要注意时的路径深度和实际存放要对应,不然配置后编译时找不到文件编译就会失败。注意一个细节就是历史原因造成的兼容性麻烦。最开始board目录下就是开发板名字,后来才改成厂商名字。但是因为要向前兼容,同一个厂商原来还在外面的开发板并没有挪用到厂商名字下。
注意:强调一下,uboot的配置阶段(其实就是根目录下面的mkconfig脚本和Makefile中配置有关的部分)主要解决的问题就是在可移植性领域能够帮助我们确定具体的文件夹路径,然后编译时可以应该找到的文件,才能编译成功。因此board目录下的不同会造成配置时的不同。如果移植没注意这里,肯定会失败。
4. Common : common是普遍的普通的。这个文件夹下放的一些与具体硬件无关的普通使用的一些代码。譬如控制台实现,crc校验。但是更多的主要是两类:一类是cmd开头的,是用来实现uboot的命令系统的;另一类是env开头的,是用来实现环境变量的。
5. Cpu:这个目录是Soc相关的,里面存放的代码都是soc相关初始化和控制代码(譬如cpu的,中断的,串口等soc内部外设的,包括起始代码start.S也在里面。) 里面很多子文件夹,每一个子文件夹就是一个soc系列。这个文件夹是严格和硬件相关的,因此一直也要注意。但是因为这个文件夹内都是soc有关的。我们自己的开发板和三星的开发板虽然板子设计不同但是soc都是同一个,一般不需要怎么改。
6. Disk。磁盘有关的,没研究过,没用过。
7. Doc。文档目录,里面存放了很多uboot相关文档,这些文档可以帮我们理解uboot代码。但是纯英文
8. Drivers。顾名思义,驱动,这里面放的就是从linux源代码中扣出来的原封不动的linux设备驱动,主要是开发板上必须用到的一些驱动,如网卡驱动,inand/sd卡 nand flash等驱动。要知道:uboot中的驱动其实就是linux中的驱动,uboot在一定程度上移植了linux驱动给自己用。但是linux是操作系统而uboot是个裸机程序,因此这种移植会有不同,让我说,uboot中的驱动其实是linux中驱动的一部分。
9. Example:实例代码。没用过
10. Fs:文件系统0 filesystem.这个也是从linux源代码中移植过来的。用来管理flash等资源
11. Include:头文件的目录,uboot和linux kernel在管理头文件时都采用同一个思路,就是把所有头文件全部集中存放在include目录下,而不是头文件跟着自己对应c文件。所有在uboot中头文件包含时路径结构要在这里去找。
12. Lib_开头的一些 (典型的lib_arm和lib_generic)架构相关的库文件。譬如lib_arm里面就是arm架构使用的一些库文件。Lib_generic里面所有架构通用的库文件。这类文件夹中的内容移植时基本不用管。
13. Libfdt。设备树有关的。Linux内核在3.4左右的版本的时候更改了启动传参的机制,改用设备树进行启动传参,进行硬件信息的描述了。
14. Nand_spl nand相关的。
15. Net 。网络相关的。譬如uboot中的tftp nfs ping 命令,都是在这里实现的。
16. Onenand开头的。是onenand相关代码,是三星加的。标准uboot中应该没有的。
17. Post。没关注过。
18. Sd_fusing。这里面代码实现了烧录uboot镜像到SD卡的代码。后面要仔细研究的。
19. Tools:里面是一些工具类代码。譬如mkimage.
总结:会用的到的 board common cpu drivers include lib_arm sd_fusing lib_generic
第四部分:uboot主Makefile分析1
1.1 uboot version确定 (Makefile 24-29行) U_BOOT_VERSION “1.3.4xyz”
1)uboot版本号分为4个级别:
VERSION : 主板号
PATCHLEVEL : 次版本号
SUBLEVEL : 再次版本号
EXTRAVERSION : 另外附加的版本信息
这4个用 . 分隔开共同构成了最终的版本号。
2)makefile中版本号最终生成一个变量U_BOOT_VERSION,这个变量记录了Makefile中配置的版本号。 Include/version_autogenerated.h文件是编译过程中自动生成的一个文件,所有源目录中没有,但是编译过后的uboot中就有了。它里面的内容是一个宏定义,宏定义的值就是我们在Makefile中配置的uboot版本号。
3)验证方法:自己修改主makefile中几个version有关的变量,然后编译uboot,然后烧录到SD卡中,从SD卡中启动,然后去看启动时uboot打印出来的版本信息,看看变化是不是和自己的分析一致。
2.1 HOSTARCH和HOSTOS
1. 直接在shell中执行uname -m得到i686,得到的值其实是你当前执行这个命令的电脑的cpu的版本号。
2. shell中的|叫管道,管道的作用就是把管道前面一个运算式的输出作为后面一个的输入再去做处理,最终的输出才是我们整个式子的输出。
3. HOSTARCH这个名字:HOST主机,就是当前在做开发用的这台电脑就叫主机;ARCH是architecture(架构),表示cpu的架构,所有HOSTARCH就主机cpu的架构。 这两个环境变量是主机的操作系统和主机的cpu架构,得出后保存,后面能用到。
2.3 静默编译问题:(50-54)
1. 平时默认编译时命令行会打印出来很多编译信息,但是有时候我们不希望看到这些编译信息,就后台编译即可。这就是静默编译。 使用方法就是编译时make -s , -s会作为MAKEFLAGS传给Makefile,在50-54行这段代码作用下XECHO变量就会被变成空。于是实现了静默编译。
2.4 2中编译方法(原地编译和单独输出文件夹编译)
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),)
OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE := $(CURDIR)
TOPDIR := $(SRCTREE)
LNDIR := $(OBJTREE)
export TOPDIR SRCTREE OBJTREE
1.编译复杂项目,Makefile提供了2中编译管理方法。默认情况下是当前文件夹中.c文件,编译出来的.o文件会放在同一文件夹下,这种方式叫做原地编译。原地编译的好处就是处理起来简单。 原地编译有一些坏处:第一,污染了源文件目录。第二缺陷是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。
2.为了解决以上2中缺陷,uboot支持单独输出文件夹方式的编译(linux kernel也支持),而且uboot这种技术就是从linux kernel学习来的。基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成.o文件或生成的其他文件全部丢到那个输出目录下。源代码目录不做任何污染,这样输出目录就承载了本次配置编译的所有结果。 具体用法:默认的就是原地编译,如果需要指定具体的输出目录编译则有2中方式来指定输出目录:(56-76注释内容)
1) make O=输出目录
2) 第二种: export BUILD_DIR=输出目录 然后再make
如果两个都指定了,(既有BUILD_DIR环境变量存在,又有O=xx),则O=xx优先级高。
两种编译的实现代码在Makefile 78-123
2.4 OBJTREE SRCTREE TOPDIR
OBJTREE:编译出的.o文件存放的目录的根目录。在默认编译下,OBJTREE等于当前目录;在O=xx编译下,OBJTREE就等于我们设置的那个输出目录。
SRCTREE:源码目录,其实就是源代码的根目录,也就是当前目录。 总结:在默认编译下,OBJTREE 和 SRCTREE相等。在O=xx编译下OBJTREE和SRCTREE不相等。Makefile中定义这两个变量,其实就是为了记录编译后.o文件往哪里放。就是为了实现O=xx的这种编译方式。 MKCONFIG 在makefile中定义的一个变量,在这里定义,在后面使用,它的值就是我们源码根目录下的mkconfig,它就是一个配置脚本。这个脚本就是uboot配置阶段的配置脚本。后面要用至少3节课详细讲这个配置脚本的工作。
MKCONFIG := $(SRCTREE)/mkconfig (Makefile 101)
export MKCONFIG
2.4.3.3 include $(obj)include/config.mk (133行)
(1)include/config.mk 不是源码自带的,(你在没有编译过的源码目录下是找不到这个文件的),要在配置过程(make TQ210_config)中才会生成这个文件。因此这个文件的值和我们配置过程有关,是由配置过程根据我们的配置自动生成的。
(2)我们TQ210在iNAND情况下配置生成的config.mk内容的:
ARCH = arm
CPU = s5pv210
BOARD = TQ210
VENDOR = EmbedSky
SOC = s5pv210
(3)我们在下一行就是(134)export导出了这5个变量作为环境变量。所以着两行加起来其实就是为当前makefile定义了5个环境变量而已。之所以不直接给出这5个环境变量,是因为我们希望这5个值是可以被人很容易的,集中的配置的。
(4)这里的配置值来自2596行那里的配置项。如果我们要更改这里的某个配置值要到2596行调用MKCONFIG脚本传参时的参数。
(5)ARCH CROSS_COMPILE
接下来有2个重要的环境变量。一个是ARCH,上面导出的,值来自于我们的配置过程,它的值会影响后面的CROSS_COMPILE环境变量的值,ARCH的意义定义当前编译的目标CPU的架构。CROSS_COMPILE是定义交叉编译工具的前缀的。定义这些前缀是为了在后面用(用前缀加上后缀来定义编译过程中用到的各种工具链中的工具)。我们把前缀和后缀分开还有一个原因是:在不同cpu架构上的交叉编译工具链,只是前缀不一样,后缀都是一样的。因此定义时把前缀和后缀分开,只需要在定义前缀时区分各种架构即可实现移植。CROSS_COMPILE在136-142中定义的。CROSS_COMPILE是被ARCH所确定的,只要配置了ARCH=arm,那么我们就只能在ARM的那个分支去设置CROSS_COMPILE的值。这个设置值只要能保证找到那个交叉编译工具链即可,不一定非得是全路径的,相对路径也可以。(如果已经将工具链导出到环境变量,并且设置了符号链接,这样CROSS_COMPILE=arm-linux-就可以)。实际运行时,我们可以在Makefile中更改设置CROSS_COMPILE的值,也可以在编译时make
CROSS_COMPILE=xxx 来设置,而且编译时传参的方法可以覆盖Makefile里面的设置。
2.4.4 include $(TOPDIR)/config.mk 189行
1.编译工具的定义:在config.mk 97 – 107
2. 包含开发板配置项目(config.mk,112行)
Autoconfig.mk文件不是源码提供的,是配置过程自动生成的。 这个文件的作用就是用来指导整个uboot的编译过程,这个文件内容其实就是很多CONFIG_开头的宏。(可以理解为变量)。这些宏或者变量会影响我们uboot编译过程的走向(原理就是条件编译)。在uboot代码中有很多地方使用条件编译进行编写,这个条件编译就用来实现可移植性的。(可以说uboot的源代码在很大程度上说是拼凑起来的,同一个代码包含了各种不同开发板的适用代码,用条件编译进行区别)。
这个文件不是凭空产生的,配置过程也是需要原材料来产生这个文件的,原材料在源码的目录是:include/configs/xxxx.h头文件。(x210开发板中为include/configs/TQ210.h)。这个h头文件里面全是宏定义,这些宏定义就是我们对当前开发板的移植。每个开发板的移植都对应这个目录下的一个头文件,这个头文件里每一个宏定义都很重要,这些配置的宏定义就是我们移植uboot的关键所在。
2.4.5.1 链接器脚本(config.mk) 144-147
1.如果定义了CONFIG_NAND_U_BOOT宏,则链接器脚本叫u-boot-nand.lds,如果未定义这个宏则链接器脚本叫u-boot.lds。
2.从字面意思分析,即可知:CONFIG_NAND_U_BOOT是在Nand
版本情况下才使用的,我们使用TQ210都是iNand版本,因此这个宏没有的。
2. 实际在board\EmbedSky\TQ210\u-boot.lds,这个就是链接器脚本。我们在分析uboot的编译连接过程时要考虑这个链接脚本。
2.4.5.2 TEXT_BASE (config.mk )
1.Makefile中配置TQ210开发板时,在board\EmbedSky\TQ210\目录下生成了一个文件config.mk其中的内容就是 : TEXT_BASE = 0xC3E00000。
2.TEXT_BASE是将来我们整个uboot链接时指定的链接地址。因为uboot中启用了虚拟地址映射,因此这个C3E00000地址就等于0x23e00000(也可能是33e00000具体地址要取决于uboot中做的虚拟地址映射关系)。
3.回顾裸机中讲的链接地址的问题,再想想dnw方式先下载TQ210_usb.bin,然后再下载uboot.bin时为什么第二个地址是23E0000.
2.4.5.3.自动推导规则(config.mk 239-256)
我们在讲Makefile 是提到过自动推导规则,具体理解可以参考(跟我一起学Makefile)。
Uboot主Makefile分析:
1.291行出现了整个主Makefile中第一个目标all(也就是默认目标,我们在uboot根目录下make其实就等于make all,就等于make这个目标)
2.目标中有一些比较重要的。譬如:u-boot是最终编译链接生成的elf格式的可执行文件。
3.unconfig字面意思来理解就是未配置。这个符号用来做为我们各个开发板配置目标的依赖。目标是当我们已经配置过一个开发板后再次去配置时还可以配置。
4.我们配置开发板时使用;make TQ210_config,因此分析TQ210_config肯定是主Makefile中的一个目标。
2.4.7 uboot配置过程详解1
1. Mkconfig脚本的6个参数。TQ210_config : unconfig
$(MKCONFIG) $(@:_config=) arm s5pv210 TQ210 EmbedSky s5pv210
TQ210_config里面的_config部分用空替换,得到:TQ210,这就是第一个参数,所以:
$1: TQ210
$2: arm
$3: s5pv210
$4: TQ210
$5: EmbedSky
$6: s5pv210
所以$# = 6
3. 第23行,其实就是看BOARD_NAME变量是否有值,没有就赋值。结果BOARD_NAME=TQ210
4. 第25行,如果$#小于4,则 exit 1 (mkconfig脚本返回1)。
5. 第26行,如果$#大于6,则 exit 1
所以:mkconfig脚本传参只能是4,5,6.其他值都不行。
LINUX符号链接:从33-118行结束。这些符号链接就是配置的核心,这些符号链接文件(文件夹)的主要作用是,给头文件包含等过程提供指向性连接。根本目的是让uboot具有可移植性。
Uboot可移植性的实现原理:在uboot中很多彼此平行的代码,各自属于各自不同的架构/cpu/开发板,我们在具体到一个开发板的编译时用符号链接的方式提供一个具体名字的文件夹供编译时使用。这样就可以在配置过程中通过不同的配置使用不同的文件,就可以正确包含正确的文件。
(6)创建的符号链接:
第一个:在include目录下创建asm文件,指向asm-arm(46-48行)
第二个:在include/asm-arm下创建一个arch文件,指向include/asm-arm/arch-s5pv210
第三个:在include目录下创建一个regs.h文件,指向include/s5pv210.h
删除第二个。
第四个:在include/asm-arm下创建一个arch文件,指向include/asm-arm/arch-s5pv210
第五个:在include/asm-arm下创建一个proc文件,指向include/asm-arm/proc-arm
总结:一共创建了4个符号链接。这4个符号链接将来写代码过程中,头文件包含非常有用。譬如一个头文件包含可能是:#include<asm/xx.h>
2.4.8 uboot配置详解第二部分:
(1)创建include/config.mk文件(mkconfig文件12-129)
(2)创建include/config.mk文件是为了让主Makefile在第133行
思考:uboot的配置和编译过程的配合。编译的时候需要ARCH=arm CPU=xx 等这些变量来指导编译,配置的时候就是为编译阶段提供这些变量。那为什么不在Makefile中直接定义这些变量去使用,而要在mkconfig脚本中创建config.mk文件,然后又在Makefile中include这些文件呢?
理解这些脚本,需要时刻注意自己的路径。
(5)创建(默认情况)/追加(make -a时追加)include/config.h文件(mkconfig文件的134-141)
(6)这个文件里面的内容就一行#include <configs/TQ210.h>这个头文件时我们移植TQ210开发板时,对开发板的宏定义配置文件,这个文件是我们移植TQ210时最主要的文件。
(7)TQ210.h文件会被用来生成一个autoconfig.mk文件,这个文件会被主Makefile引入,指导整个编译过程,这里面的这些宏定义会影响我们对uboot中大部分.c文件中一些条件编译的选择。从而实现最终的可移植性。
注意uboot的整个配置过程,很多文件之间是由关联的(有时候这个文件是在哪个文件创建出来,有时候这个文件被哪个文件包含进去;有时候这个文件是由哪个文件的内容生成的决定的)
Uboot中配置和编译过程,所有的文件或者全局变量都是字符串形式(不是指c语言字符串的概念,指的是字符组成的序列)。这意味着我们整个uboot的配置过程都是字符串匹配的,所以一定要细节,注意大小写,要注意不要输错字符,因为一旦错一个最后会出现一些默默奇妙的错误,很难排查,这个是uboot移植过程中新手来说最难的地方。
2.4.9 uboot的连接脚本
1.uboot的连接脚本和我们之前裸机中的链接脚本并没有本质区别,难度高点,文件多一些,使用技巧多一些。
2.ENTRY(_start)用来指定整个程序的入口地址,所谓入口地址就是整个程序的开头地址。可以认为就是整个程序的第一句指令。有点像c语言中的main。
3.之前在裸机中告诉大家,指定程序的链接地址有2中方法:一种是在Makefile中ld的flags用-Ttext
0x20000000来指定:第二种是在链接脚本的SECTIONS开头用.=0x20000000来指定。两种都可以实现相同效果。其实,这两种技巧是可以共同配合使用的。两个都指定以后以-Ttext指定为准。
5. uboot的最终链接起始地址就是在Makefile中用-Ttext来指定,注意TEXT_BASE变量。最终来源是Makefile中配置对应的命令中,在make xxx_config时得到的。
6. 在代码段中注意文件排列的顺序。指定必须放在前面部分的那些文件就是那些必须安排在前16kb内的文件,这些文件中的函数在前16kb会被调用。在后面第二部分中调用的程序,前后顺序就无所谓了。
7. 链接脚本中除了.text .data .rodata .bss段等编译工具自带的段之外,编译工具还允许我们自定义段。譬如uboot中的 .u_boot_cmd段就是自定义段。自定义段很重要。
1.5.1 start.S引入
u-boot.lds中找到start.S入口
1. c语言中整个项目的入口就是main函数(这是c语言规定的),所以譬如说一个有10000个.c文件的项目,第一个要分析的文件就是包含了main函数的那个文件。
2. 在uboot中因为有汇编阶段参与,因此不能直接找main.c。整个程序入口取决于链接器脚本中ENTRY声明的地方。ENTRY(_start)因此_start符号所在的文件就是整个程序的起始文件,_start所在处的代码就是整个程序的起始代码。
3. 利用SI工具搜索共_start,然后分析那个是我们所需要的文件。然后进入start.S文件中,然后进入76,77行,就是_start标号的定义处,我们就找到了整个uboot的入口代码。
4. 我们开始从start.S文件分析uboot的第一阶段代码。
5. 在SI中,如果我们知道我们要找的文件的名字,但是我们又不知道它在哪个目录下,我们要怎样找到并打开这个文件?方法是在SI中先打开右边的工程项目管理栏目,然后点击最左边那个(这个是以文件未单位来浏览的),然后再上面输入栏中输入要找的文件名字。我们在输入时,SI在不断帮我们进行匹配,即使你不记得文件名只能记得大概名字,也能帮你找到你要的文件。