uboot之第一阶段start.s

Makefile分析完成后,发现0bj 第一个文件时start.o,我们找到start.s进行分析。

1.首先看到的是中断向量表

_start:	b       reset               //0
	ldr	pc, _undefined_instruction  //0x4
	ldr	pc, _software_interrupt     //0x8
	ldr	pc, _prefetch_abort         //0xc
	ldr	pc, _data_abort             //0x0
	ldr	pc, _not_used               //0x14
	ldr	pc, _irq                   //0x18
	ldr	pc, _fiq                   //0x1c

_undefined_instruction:	.word undefined_instruction
_software_interrupt:	.word software_interrupt
_prefetch_abort:	.word prefetch_abort
_data_abort:		.word data_abort
_not_used:		.word not_used
_irq:			.word irq
_fiq:			.word fiq

irq:
	sub	lr, lr, #4			        @ the return address
	ldr	sp, IRQ_STACK_START	        @ the stack for irq
	stmdb	sp!, 	{ r0-r12,lr }	@ save registers
	
	ldr	lr,	=int_return		        @ set the return addr
	ldr	pc, =IRQ_Handle		        @ call the isr
int_return:
	ldmia	sp!, 	{ r0-r12,pc }^	@ return from interrupt

就以irq为例,如果发生中断就会跳转到 irq(0x14地址上面),然后取出irq中保存的函数地址,跳转到该函数执行。跳转该函数之前,做了哪些操作呢?

1. lr_irq保存有被中断模式中的下一条即将执行的指令的地址
2. SPSR_irq保存有被中断模式的CPSR
3. CPSR中的M4-M0被设置为10010, 进入到irq模式
4. 跳到0x14的地方执行程序 

然后从0x14中取出函数地址赋给PC,跳转到该函数执行,具体可以看一眼反汇编更清楚:

 

跳转到该函数后,

1.设置返回地址

2.设置栈sp寄存器。

3.保存r0-r12到栈中,为了中断函数执行完成后可以恢复现场。

4.跳转到中断函数里面执行。执行完成后跳转到lr。

5.恢复现场,会把lr_irq的地址赋给pc,恢复栈中保存的r0-r12寄存器,并把spsr中的值赋给cpsr。

2.开机后首先跳转到reset执行

2.1 设置为SVC32模式,系统模式可以访问相关IO寄存器等。


	mrs	r0,cpsr  //修改程序状态寄存器为系统模式。将程序状态寄存器传给通用寄存器。
	bic	r0,r0,#0x1f//清0寄存器。0x1f = 011111b,将r0[0-4]清0,
	orr	r0,r0,#0xd3//或运算。设置为系统模式,关fiq中断。
	msr	cpsr,r0 //将运算后的r0寄存器传给cpsr。

2.2关闭看门狗,防止没有喂狗程序reset。

	ldr     r0, =pWTCON //伪指令,实际和mov一样,不是arm体系架构提供的ldr.
	mov     r1, #0x0
	str     r1, [r0]//和ldr相反,将寄存器数据写入到存储器中。*r0 = r1.[r0]为存储器地址。

2.3关闭中断

	mov	r1, #0xffffffff
	ldr	r0, =INTMSK
	str	r1, [r0]//INTMSK=#0xfffffff

2.4 调用c函数之前必须设置栈和内存分布图

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                        */

	sub	sp, r0, #12		/* leave 3 words for abort-stack    */

2.5设置时钟

  bl clock_init  //c函数设置 Mpll,初始化fclk,hclk,pclk

2.6代码重定位

函数里面判断是nand启动还是nor启动,根据lds里面的设置,确定运行地址和加载地址。将加载地址(flash中的内容)拷贝到运行地址中(sdram)。

	bl  CopyCode2Ram	/* r0: source, r1: dest, r2: size */

2.7清bss

clear_bss:
	ldr	r0, _bss_start		/* find start of bss segment        */
	ldr	r1, _bss_end		/* stop here                        */
	mov 	r2, #0x00000000		/* clear                            */

2.8跳转到uboot的第二阶段


	ldr	pc, _start_armboot   //绝对跳转,不是相对跳转

_start_armboot:	.word start_armboot

 

你可能感兴趣的:(uboot)