u-boot中SPL源代码分析
来源:互联网 发布:新的邮政软件 编辑:程序博客网 时间:2024/05/19 02:19
[Author: Bo Shen <voice.shen@gmail.com>
[u-boot: 2014.01-rc1]
本文将使用sama5d3xek SPL实现做为例子,具体代码可查看:https://github.com/voiceshen/u-boot/tree/sama5d3xek_spl_spi_nand
u-boot SPL (second program loader), 对许多人来说也说很陌生。下面对此进行一个简单介绍。
1. ARM SoC的启动过程:
RomBoot --> SPL --> u-boot --> Linux kernel --> file system --> start application
(RomBoot是固化在SoC内部的。)
u-boot实现了一个新功能,能在编译u-boot的同时生成SPL二进制文件。
2. SPL运行代码go through
从u-boot-spl.lds链接文件可知,启动代码也是start.S。
(reset) <arch/arm/cpu/armv7/start.S> (b lowlevel_init: arch/arm/cpu/armv7/lowlevel_init.S) (b _main) --> <arch/arm/lib/crt0.S> (bl board_init_f) --> <arch/arm/lib/spl.c> (board_init_r) --> <common/spl/spl.c> (jump_to_image_no_args去启动u-boot) 到此SPL的生命周期结束。
简单来讲:SPL所做工作,一些硬件的初始化,然后读取u-boot,最后调转至u-boot。
3. 下面具体分析SPL的相关代码。
<arch/arm/cpu/armv7/start.S>
111:如果没有重新定义save_boot_params,则使用<arch/arm/cpu/armv7/start.S>中的save_boot_params。其不做任何事情,直接返回。116~138: 看注释即可明白。
141: 因为SPL主要是对SoC进行初始化,所以不会定义CONFIG_SKIP_LOWLEVE_INIT, 即142,143行得以执行。
142: cpu_init_cpu15, 主要作用invalidate L1 I/D cache, disable MMU. 检查是否需要workaround。
143: cpu_init_crit直接跳转到lowlevel_init
下面看看lowlevel_init的实现:
<arch/arm/cpu/armv7/lowlevel_init.S>
23: 确保sp是8字节对齐。
25:将gdata的地址存入到r9寄存器中。
39:跳转到s_init。对Atmel sama5d3xek board, s_init定义在:<arch/arm/cpu/at91-common/spl.c> 此处暂时不分析。
然后返回到start.S处,接下来调用:bl _main到<arch/arm/lib/crt0.S>
65: 重新对SP赋值69: 确认sp是8字对齐
70:相当于保留一个global_data的大小。
71: 确认更新后的sp是8字对齐
72:r9指向global_data
73:r0赋值0
74:跳转到board_init_f中运行。
board_init_f在<arch/arm/lib/spl.c>定义:
26: board_init_f是一个弱函数,是可以被重新定义的。29:对BSS段进行清零操作。
34: 跳转到board_init_r
board_init_r在<common/spl/spl.c>中定义:
135: 输出debug信息:>>spl:board_init_r();
137~140: 如果定义了:CONFIG_SYS_SPL_MALLOC_START, 则进行memory的malloc池初始化。以后调用malloc就在这个池子里面分配内存。
142~148: 如果没有定义:CONFIG_PPC, 则进行timer的初始化:timer_init() <arm/arm/cpu/armv7/at91/time.c>
150~150: CONFIG_SPL_BOARD_INIT, 则调用spl_board_init(). 这是board相关的定义,<board/atmel/sama5d3xek/sama5d3xek.c>
一切就绪后,就要检查从什么设备来启动了。这里就贴出RAM,MMC, NAND相关代码
154: 获取spl_boot_device,即从什么设备启动。157~161:如果定义了CONFIG_SPL_RAM_DEVICE, 则执行spl_ram_load_image(),其就是将image下载到ram中。
162~168:如果定义了CONFIG_SPL_MMC_SUPPORT, 则执行spl_mmc_load_image(),其就是将image从mmc/sd里面读取到ram中。
169~173:如果定义了CONFIG_SPL_NAND_SUPPORT, 则执行spl_nand_load_image(), 其就是将image从nand flash中读取到ram中。
当要启动的image位于RAM中后,我们就可以启动之。
213: 判断image的类型。214:如果是u-boot,则直接到227去运行u-boot。
218:如果是Linux,则到221去启动Linux.
至此,SPL结束它的生命,控制权交于u-boot或Linux。
- u-boot中SPL源代码分析
- u-boot中SPL源代码分析
- u-boot中SPL源代码分析
- u-boot中SPL源代码分析
- u-boot中SPL源代码分析
- u-boot中SPL源代码分析
- u-boot中SPL源代码分析
- u-boot之SPL分析
- u-boot 5、源代码分析
- 关于 U-BOOT 中 SPL 的移植一
- 关于 U-BOOT 中 SPL 的移植 二
- u-boot SPL的理解
- u-boot怎样生成spl
- U-BOOT中Makefile分析
- U-BOOT移植过程详解: SPL
- U-BOOT移植过程详解: SPL
- 移植u-boot到mini2440--SPL初探
- U-BOOT移植过程详解: SPL
- 调整数组使奇数全部都位于偶数前面。
- 如何把Eclipse工程导入到Android Studio
- 实现mybatis多对多功能
- 取消了自动缩进和智能缩进vim
- 【操作系统笔记】第一章
- u-boot中SPL源代码分析
- C++面试题(一)
- Ajax获取html数据传到后台,获取返回值,添加到input框里
- Android BaseActivity 分享
- C++相对路径设置
- C++面试题(二)
- Retrofit2.0的简单使用
- (二)洞悉linux下的Netfilter&iptables:内核中的ip_tables小觑
- ubuntu16.04 Error: libcudart.so.7.5: cannot open shared object file: No such file or directory最新解决方案