最开始的就是start.S
<pre name="code" class="html"> 一个可执行的Image 必须有一个入口点并且只能有一个唯一的全局入口,通常这个入口放在Rom(flash)的0x0地址。
start.S
· _start:
<span style="font-family: Arial, Helvetica, sans-serif;"> /*异常向量表*/</span><pre code_snippet_id="650016" snippet_file_name="blog_20150422_2_4063097" name="code" class="plain"> /*大小32个字节,每个异常占据4个字节,保留4个字节空间*/<pre code_snippet_id="650016" snippet_file_name="blog_20150422_3_8027903" name="code" class="plain"> /*将异常中断处理程序注册到向量表,或使用跳转指令或使用数据
*读取指令LDR向PC中直接赋值
*/<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
//声明-----------
· breset /*复位,可能出现情况:系统加电,系统复位*/
· ldr pc,_undefined_instruction/*未定义:处理器认为当前指令未定义*/
· ldr pc,_software_interrupt/*软件中断:用户定义的中断指令,*/
· ldr pc,_prefetch_abort/*预取指令中止:预取指令的地址不存在或该地
*址不允许当前指令访问*/
· ldr pc,_data_abort /*数据中止:数据访问的地址不存在*/
· ldr pc,_not_used/*保留 未使用*/
· ldr pc,_irq /*外部中断请求*/
· ldr pc,_fiq /*快速异常中断,响应时间要求高*/
/*中断程序入口地址*/
· _undefined_instruction: .wordirq_undefined_instruction
· _software_interrupt: .word irq_software_interrupt
· _prefetch_abort: .word irq_prefetch_abort
· _data_abort: .word irq_data_abort
· _not_used: .word irq_not_used
· _irq: .word irq_irq
· _fiq: .word irq_firq
· _pad1: .word 0x12345678
.....
· /*
· * 复位程序入口
· */
· reset: //上电触发reset
· /*
· *MCU 微控制单元准备
· */
· ldr r0, =0x100
· delay_wait_mcu:
· sub r0, #1
· cmp r0, #0 //判断MCU是否准备好
· bne delay_wait_mcu
·
· ldr r0, =REG_BASE_SCTL
· mov r1, #0
· wait_mux_finish:
· add r1, r1, #1
· str r1, [r0, #REG_SC_GEN1] /*系统通用寄存器0x0084*/
· ldr r2, [r0, #REG_SC_GEN1]
· cmp r1, r2
· bne wait_mux_finish /*确保地址范围是可读写的 RAM 空间*/
· mrs r1,cpsr
/*将CPSR状态寄存器读取,保存到r1中 保存标志位FIQ.r8-10*/
· bic r2, r1, #0x1f /*反码0x1110 0000 低五位清零*/
· orr r2, r2, #0xd1 /*或 0x1101 0001*/
· msr cpsr,r2
· adrl r8,_start /*取地址 分组寄存器fiq单独的物理寄存器*/
· mov r9,r3
· mov r10,r4
· msr cpsr, r1
/初始化PLL DDR PIN/
· /*PLL(统一脉冲信号)/DDR/pin mux 引脚/...* /
· ldr r0, _blank_zone_start
· ldr r1, _TEXT_BASE
· sub r0, r0,r1
· add r0, r0,#RAM_START_ADRS
· mov r1, #0x0 /* flags: 0->normal 1->pm*/
· mov r2, #INIT_REG_ITEM1
· bl init_registers
/屏蔽中断/
/*设置为SVC32模式 系统模式*/
· mrs r0, cpsr
/*将状态寄存器的内容传送至通用寄存器,将CPSR中的内容传送至R0保存当前处理器状态,中断屏蔽位以及各标志位*/
· bic r0,r0,#0x1f /*位清除指令 将R0最低5位清零,其余位不变工作模式位清零 工作模式位清零,设置CPSR中相应的位,使处理器进入相应的执行模式*/
· orrr0,r0,#0xd3/*r0=(0xd3|r0)*/ /*工作模式位设置为10011,将中断禁止位和快中断位置1 "1101 0011" 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中*/
· msr cpsr, r0 /*将通用寄存器的内容传送至状态寄存器,将中的内容R0传送至CPSR*/
/*初始化串口*/
bl uart_early_init
/检查启动介质 NAND/SPI/EMMC FLASH/
· cmp r6, #BOOT_FROM_NAND /*判断启动介质*/
· bne check_from_spi
· cmp r0,#0x01
· bne check_from_nand
· cmp r6, #BOOT_FROM_SPI
· bne check_from_emmc
标准操作:
· /*i-cache初始化 指令cache 与数据cache*/
· mrc p15, 0, r0, c1, c0, 0
· orr r0, r0, #0x00001000
· mcr p15, 0, r0, c1, c0, 0
/*关闭MCU*/
· #ldr r0,=0xf840f000
· #ldr r1,[r0]
· #bic r1,r1,#0x1
· #str r1,[r0]
·
/*时钟*/
· # ldr r0,=REG_BASE_TIMER01
· #mov r1,#0
· #str r1,[r0,#REG_TIMER_CONTROL]
·
/*看门狗*/
· # mov r1,#0
· # str r1,[r4,#REG_SC_WDG_RST_CTRL]
/*初始化寄存器1*/
· normal_init_item1:
· ldr r0,_blank_zone_start
· ldr r1, _TEXT_BASE
· subr0,r0,r1
· ldr r1,[r4,#REG_SC_GEN14]
· add r0,r0,r1
· mov r1,#0x0 /*flags:0->normal1->pm*/
· mov r2,#INIT_REG_ITEM1
· bl init_registers
· b normal_init_item2
· copy_to_ddr: /*重定位uboot*/
· ldr r4,=REG_BASE_SCTL
· ldr r0, [r4, #REG_SC_GEN14]
· /*r0存放的是程序开始的地址*/
· ldr r1, _TEXT_BASE /* r1 存放的是内存中的地址*
·
· /* 比较两个地址是否相等*/
· cmp r0,r1
· beq stack_setup /* 比较r0/r1是否相等,这个比较就是确定当前是不是从Flash中执行的,还是这段代码已装载到_TEXT_BASE处执行的。如果不等,则将 FLASH中的u-boot代码搬到_TEXT_BASE处。*/
·如果不等
· ldr r2,_armboot_start
· ldrr3,_bss_start /*flash中存储的u-boot可执行文件中,代码段、数据段以及BSS段都是首尾相连存储的,所以在计算搬移大小的时候就是利用了用BSS段的首地址减去代码的首地址,这样算出来的就是实际使用的空间。*/
· sub r2,r3,r2
· /*memcpy(r1,r0,r2)*/
/*r1存放的是TEXT_BASE*/
· bl memcpy
·
· stack_setup: /*设置栈*/
· ldr r0,_TEXT_BASE /*往上128KB是重定位的uboot*/
· sub r0,r0,#CONFIG_BOOTHEAD_GAP
· sub r0, r0,#CONFIG_SYS_MALLOC_LEN
/* 向下分配空间 因为u-boot中其它地方调用了malloc函数,该空间就是供其动态分配的。*/
· sub r0,r0,#CONFIG_SYS_GBL_DATA_SIZE
/*全局数据区 为global_data结构体预留的空间*/
· sub sp,r0,#12 /*为取址中止异常留三个字*/
· and sp,sp,#~7 /*用户栈顶*/
·
· /*清零BSS段*/
· clear_bss:
· ldr r0,_bss_start
· ldr r1,_bss_end
· mov r2,#0x00000000
·
· clear_bss_loop:
· str r2,[r0] /*清零*/
· cmp r0, r1 //是否清理到段尾
· add r0, r0, #4 //移动指针
· bne clear_bss_loop
/*执行C程序,board.c参数r0,r1,r2*/
· ldr pc,_start_armboot
· _start_armboot: .word start_armboot