本文主要是介绍新路程----海思 uboot(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
先看start.s吧
.globl _start //.global声明_start为全局符号,_start就会被连接器链接到,也就是链接脚本中的入口地址了。
_start: b reset //跳转到reset 下面的代码是设置arm的异常向量表ldr pc, _undefined_instruction //把label后的数据或者指令内容赋值给pcldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irqldr pc, _fiq
8种异常分别占用4个字节,因此每种异常入口处都填写一条跳转指令,直接跳转到相应的异常处理函数中,reset异常是直接跳转到reset函数,其他7种异常是用ldr将处理函数入口地址加载到pc中。
_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
_pad: .word 0x12345678 /* now 16*4=64 */
__blank_zone_start:
.fill 1024*4,1,0
__blank_zone_end:.globl _blank_zone_start
_blank_zone_start:
.word __blank_zone_start.globl _blank_zone_end
_blank_zone_end:
.word __blank_zone_end.balignl 16,0xdeadbeef //接下来定义的_end_vect中用.balignl来指定接下来的代码要16字节对齐,空缺的用0xdeadbeef,方便更加高效的访问内存。
接下来看第二段
mov r0, pc, lsr#28 // pc中的内容逻辑右移28位后 再传送到 R0cmp r0, #8 // r0减去立即数8 并根据结果设置CPSR程序状态寄存器的标志位bleq relocateldr r0, _blank_zone_startldr r1, _TEXT_BASEsub r0, r0, r1 // r0=r0-r1adrl r1, _start //伪指令----中等范围的地址读取add r0, r0, r1 //r0=r0+r1mov r1, #0 /* flags: 0->normal 1->pm */ 清零bl init_registers //当程序无条件跳转到标号 init_registers 处执行时,同时将当前的 PC 值保存到 R14 中ldr sp, =STACK_TRAINING //把STACK_TRAINING 的运行地址赋值为pc
#ifdef CONFIG_SVB_ENABLEbl start_svb
#endif#ifdef CONFIG_DDR_TRAINING_V300ldr r0, =REG_BASE_SCTLbl start_ddr_training /* DDR training */
#endif#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:@copy arm exception table in 0 addressadrl r0, _startmov r1, #0mov r2, #0x100 /* copy arm Exception table to 0 addr */add r2, r0, r2
copy_exception_table:ldmia r0!, {r3 - r10}
//LDMIA R0!,{R1-R4} ;R1<----[R0]
;R2<----[R0+4]
;R3<----[R0+8]
;R4<----[R0+12]
stmia r1!, {r3 - r10} 将R3-R9的数据存储到R1指向的地址上,R1值更新cmp r0, r2ble copy_exception_table@ relocate U-Boot to RAMadrl r0, _start @ r0 <- current position of codeldr r1, _TEXT_BASE @ test if we run from flash or RAMcmp r0, r1 @ don't reloc during debug
第三段
ldr r0, _armboot_start @ get data regions start@ move past malloc poolsub r0, r0, #(CONFIG_SYS_MALLOC_LEN)@ move past gbl and a couplesub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)@ spots for abort stackstr lr, [r0] @ save caller lr in position 0将r1寄存器的值,传送到地址值为r0的(存储器)内存中@ of saved stackmrs r0, spsr @ get the spsr MRS指令用于将状态寄存器的内容读到通用寄存器中 程序状态保存寄存器 SPSR用于保存CPSR的状态
str lr, [r0, #4] @ save spsr in position 1 of @ saved stackldr r0, [r13] @ restore r0add r13, r13, #4 @ pop stack entry.endm.macro get_irq_stack @ setup IRQ stackldr sp, IRQ_STACK_START.endm.macro get_fiq_stack @ setup FIQ stackldr sp, FIQ_STACK_START.endm/** exception handlers*/.align 5
undefined_instruction:get_bad_stackbad_save_user_regsbl do_undefined_instruction.align 5
software_interrupt:get_bad_stack_swibad_save_user_regsbl do_software_interrupt.align 5
prefetch_abort:get_bad_stackbad_save_user_regsbl do_prefetch_abort.align 5
data_abort:get_bad_stackbad_save_user_regsbl do_data_abort.align 5
not_used:get_bad_stackbad_save_user_regsbl do_not_used#ifdef CONFIG_USE_IRQ.align 5
irq:get_irq_stackirq_save_user_regsbl do_irqirq_restore_user_regs.align 5
fiq:get_fiq_stack/* someone ought to write a more effective fiq_save_user_regs */irq_save_user_regsbl do_fiqirq_restore_user_regs#else.align 5
irq:get_bad_stackbad_save_user_regsbl do_irq.align 5
fiq:get_bad_stackbad_save_user_regsbl do_fiq
其他部分参考链接http://blog.csdn.net/skyflying2012/article/details/25804209
这篇关于新路程----海思 uboot(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!