文件:u-boot-1.1.6\cpu\arm920t\start.S
- reset部分代码详解
mrs指令语法
MRS{cond} Rd, psr
Rd 是目标寄存器。 Rd 不能为 r15。
psr 是下列项之一:
APSR 任何处理器,任何模式。
CPSR 不提倡使用的 APSR 同义词,用于调试状态,用于除
ARMv7-M 和 ARMv6-M 之外的任何处理器。
SPSR 用于除 ARMv7-M 和 ARMv6-M 之外的任何处理器,仅
可用于特权模式。
Mpsr 仅用于 ARMv7-M 和 ARMv6-M 处理器。
关于arm寄存器的介绍
寄存器名字
Reg# APCS 意义
R0 a1 工作寄存器
R1 a2 "
R2 a3 "
R3 a4 "
R4 v1 必须保护
R5 v2 "
R6 v3 "
R7 v4 "
R8 v5 "
R9 v6 "
R10 sl 栈限制
R11 fp 桢指针
R12 ip 内部过程调用寄存器
R13 sp 栈指针
R14 lr 连接寄存器
R15 pc 程序计数器
The following register names are predeclared:
r0-r15 andR0-R15
a1-a4 (argument, result, or scratch registers, synonyms for r0 to r3)
v1-v8 (variable registers, r4 to r11)
sb andSB (static base, r9)
ip andIP (intra-procedure-call scratch register, r12)
sp andSP (stack pointer, r13)
lr andLR (link register, r14)
pc andPC (program counter, r15).
CPSR寄存器介绍
格式(参考文档
- ARM Architecture Reference Manual
A2.5 Program status registers - CPU三星S3C2440A芯片手册
THE PROGRAM STATUS REGISTERS
)
mode bit各个对应值的相关参考,其他各个位均可参考ARM Architecture Reference Manual,这里就不一一列出来.
bic指令语法
BIC{}{S} , ,
Rd = Rn AND NOT shifter_operand
bit 位清除指令
格式:BIC{}{S} ,,;
功能:Rd=Rn AND (!op2) 用于清除寄存器Rn中的某些位,并把结果存放到目的寄存器Rd中
例:
BIC R0,R0,#5 ;R0中第0位和第2位清0,其余位不变
ORR 逻辑或指令
格式:ORR{}{S} ,,;
功能:Rd=Rn OR op2 一般用于设置Rn的特定几位。
例:
ORR R0,R0,#5 ;R0的第0位和第2位设置为1,其余位不变
_start: b reset
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr //将cpsr寄存器的内容放到r0寄存器中
bic r0,r0,#0x1f //将r0的bit4-bit0清零
orr r0,r0,#0xd3//r0的bit4-bit0 = 0xd3
msr cpsr,r0 //将cpsr寄存器赋值为r0寄存器里的内容,即设置为Supervisor模式,禁止IRQ和FIQ,运行于ARM stae
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
blne cpu_init_crit
#endif
接着往后看,adr指令获取_start符号的地址,因为adr是相对于pc进行计算符号的地址的,所以如果是刚上电的还没运行到sdram时PC的值是0,初始化完sdram把代码拷到sdram时是链接地址TEXT_BASE=0x33F80000.
ldr指令(这里不是伪指令ldr)是取出_TEXT_BASE处存放的内容(假如_TEXT_BASE的地址为0x10,里面存放的内容是0x11.那么使用上述指令r1 = 0x10,使用adr的话r1 = 0x10)
那么_TEXT_BASE处存放的是什么鬼?
//定义在satrt.S开头处
_TEXT_BASE:
.word TEXT_BASE
那么问题来了_TEXT_BASE存放的是TEXT_BASE,那么他又等于什么
TEXT_BASE定义在
u-boot-1.1.6/board/100ask24x0/config.mk中,这里你肯定会有疑问,一个start.S源文件,一个是makefile文件.怎么联系起来的,显然肯定是有人使用了include指示符包含了这个config.mk
在/u-boot-1.1.6/config.mk中
#使用sinclude和include没有区别,手册上说是为了和别的make程序兼容
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
包含了之后就要使用该变量了
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
-D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE)
使用了gcc -D选项定义了一个宏TEXT_BASE其值就等于0x33F80000..就是这么联系起来的.
所以上面那段代码可以判断程序是刚上电运行还是已经运行到sdram里面了.还是写的挺巧妙的..
进行栈的设置
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
初始化时钟
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl clock_init
#endif
ldr pc, _start_armboot
_start_armboot: .word start_armboot