uboot启动阶段分析一

从上一章的链接脚本分析中,我们知道了uboot的程序是从*ENTRY(_start)*开始的

在整个uboot工程下搜索 _start ,可以找到一个 start.S 文件包含了这个label,因此uboot启动的分析从这个文件开始

头文件分析

#include <config.h>
#include <version.h>
#if defined(CONFIG_ENABLE_MMU)
#include <asm/proc/domain.h>
#endif
#include <regs.h>

start.S 一开始include的config.h这个头文件是由*$(TOPDIR)/mkconfig*自动生成的,具体生成的脚本如下

#
# Create board specific header file
#
if [ "$APPEND" = "yes" ]	# Append to existing config file
then
	echo >> config.h
else
	> config.h		# Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include <configs/$1.h>" >>config.h

config.h这个头文件中的内容如下,configs/x210_sd.h中包含的是与x210特性相关的用于适配的宏

/* Automatically generated - do not edit */
#include <configs/x210_sd.h>

通过搜索这个头文件,我们可以发现CONFIG_ENABLE_MMU被定义,所以会包含asm/proc/domain.h这个头文件

greedyhao@greedyhao-PC:.../qt_x210v3s_160307/uboot$ cat include/configs/x210_sd.h | grep CONFIG_ENABLE_MMU
#define CONFIG_ENABLE_MMU
#ifdef CONFIG_ENABLE_MMU
#ifdef CONFIG_ENABLE_MMU

通过ls -l可以发现这个头文件是proc-armv文件夹的一个软连接

greedyhao@greedyhao-PC:.../qt_x210v3s_160307/uboot$ ls -il include/asm/ | grep proc
6430221 lrwxrwxrwx 1 greedyhao greedyhao      9 3月  15 09:31 proc -> proc-armv

之所以使用proc而不是proc-armv,是为了可移植性。

试想一下,在移植时需要去把proc-xxx一个个修改是件多么痛苦的事,而且这种启动代码应该可重用的部分很多,使用软连接的方式可以减少很多不必要的工作

启动文件的校验头

uboot 选择 SD/NAND 启动方式,需要启动文件提供一个16字节的校验头,start.S 就在开头填充了16字节的空间

#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
	.word 0x2000
	.word 0x0
	.word 0x0
	.word 0x0
#endif

在 uboot 编译完,得到可执行文件后,还需要补充这16字节的校验和,uboot才能启动

三星有提供程序用来计算这个校验和,下面简单看看

计算校验和

程序的用法如下

Usage: mkbl1 <source file> <destination file> <size>

在使用这个程序的时候,会向程序的 main 函数中传递一个参数数组 *argv[] ,而且 argv[0] = mkbl1,argv[1] = source file,argv[2] = destination file,argv[3] = size,这些都是基本常识,就不多说了

mkbl1 在得到文件的大小后,先会分配一个缓冲区,准备用来存放需要处理的文件

BufLen = atoi(argv[3]);
Buf = (char *)malloc(BufLen);
memset(Buf, 0x00, BufLen);

准备好缓冲区后,就把需要处理的文件读入,使用 fseek 计算文件长度,再使用 fread 将文件读入

// 已删除错误处理
fp = fopen(argv[1], "rb");

fseek(fp, 0L, SEEK_END);
fileLen = ftell(fp);
fseek(fp, 0L, SEEK_SET);

nbytes = fread(Buf, 1, BufLen, fp);
fclose(fp);

计算校验和的时候需要跳过前16个字节,然后从第9个字节开始写入计算出来的校验和

a = Buf + 16;
for(i = 0, checksum = 0; i < BufLen - 16; i++)
	checksum += (0x000000FF) & *a++;

a = Buf + 8;	
*( (unsigned int *)a ) = checksum;

写入也和读取类似,先 fopen 再使用 fwrite 写入,最后释放掉缓存区的空间

异常向量表

.globl _start
_start: b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
...
.global _end_vect
_end_vect:
	.balignl 16,0xdeadbeef

异常向量表是当程序发生异常时的处理方式,在向量表制作完后,使用 balignl 伪指令,让内存16字节对齐,加速硬件访问;至于 0xdeadbeef 代表用来补位垃圾数据

复位向量设置

_TEXT_BASE:
	.word	TEXT_BASE

定义了一个 _TEXT_BASE 标签用来存放复位向量,主要是用在处理器初始化和 stack 的设置

至于 TEXT_BASE 之前介绍过,由 makefile 文件导入

x210_sd_config :	unconfig
	@$(MKCONFIG) $(@:_config=) arm s5pc11x x210 samsung s5pc110
	@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk

博客地址
公众号:greedyhao

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值