硬件平台为东南大学自主研发的ARM720T芯片SEP4020
代码目录:cpu/sep4020/start.s
#include <config.h>
#include <version.h>
/*
* Jump vector table
*/
//_start是GNU汇编器默认的入口标签,.global将_start声明为外部程序可访问的
.globl _start
//向量跳转表,每条占一个字节,地址范围为0x00000000-0x00000020
//ldr和str指令是用来在存储器和寄存器传递数据的,两者方向相反
//ldr为存储器到寄存器,str为寄存器到存储器
_start: b reset
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
//.word为GNU ARM汇编特有的伪操作,为分配一段字内存单元(分配的单元为字对齐)
_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
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* relocate u-boot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
//TEXT_BASE定义了代码运行时所在的地址
_TEXT_BASE:
.word TEXT_BASE
//用_start来初始化_armboot_start
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
//_bss_start保存的是_bss_start标号所在的地址
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
//中断的堆栈设置
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
//复位后开始初始化CPU的寄存器,这里才是真正CPU的初始化
reset:
/*stack setup for each mode*/
/* SVC32 mode*/
mrs r0,cpsr //将cpsr寄存器的值传递到通用寄存器r0
bic r0,r0,#0x1f //将cpsr低5为清零
orr r0,r0,#0x13 //将cpsr位0,1,4置1,对于sep4020来说M[4:0]为10011,即进入管理模式
msr cpsr,r0 //将设置好的值写回cpsr寄存器
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12
//以下代码是在SEP4020各个模式下进行配置
//SEP4020的操作模式由cpsr的低五位进行配置
//SEP4020操作模式有:User,FIQ,IRQ,Supervisor,Abort,Undefined,System
//如果设置了CONFIG_USE_IRQ,则配置中断模式
#ifdef CONFIG_USE_IRQ
/* IRQ mode*/
//配置cpsr,0xD2表示:处理器操作模式为中断模式,并且拒绝接收中断和快速中断请求
mov R4, #0xD2
msr cpsr, R4
//初始化堆栈
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
sub r0, r0, #(CONFIG_STACKSIZE_FIQ)
sub sp, r0, #12
/* FIQ mode*/
//配置cpsr,0xD1表示:处理器操作模式为快速中断模式,并且拒绝接收中断和快速中断请求
mov R4, #0xD1
msr cpsr, R4
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
sub sp, r0, #12
#endif
/* ABORT mode*/
//配置cpsr,0xD7表示:处理器操作模式为中止模式,并且拒绝接收中断和快速中断请求
mov R4, #0xD7
msr cpsr, R4
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
sub sp, r0, #8
/* UNDEFINE mode*/
//配置cpsr,0xDB表示:处理器操作模式为未定义模式,并且拒绝接收中断和快速中断请求
mov R4, #0xDB
msr cpsr, R4
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE
sub sp, r0, #4
/* SYSTEM mode*/
//配置cpsr,0xDF表示:处理器操作模式为系统模式,并且拒绝接收中断和快速中断请求
mov R4, #0xDF
msr cpsr, R4
ldr r0, _TEXT_BASE
sub r0, r0, #CFG_MALLOC_LEN
sub sp, r0, #CFG_GBL_DATA_SIZE
/*Return to SVC mode*/
//返回SVC模式
//配置cpsr,0xDB表示:处理器操作模式为管理模式,并且拒绝接收中断和快速中断请求
mov R4, #0xD3
msr cpsr, R4
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
//如果配置了CONFIG_SKIP_LOWLEVEL_INIT,则初始化CPU
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
bl lowlevel_init
#endif
remap:
mov r0, pc
add r0, r0, #0x20000000
add r0, r0, #0x08
mov pc, r0
mov r0, r0
mov r0, r0
mov r0, r0
mov r0, r0
ldr r4, =0x11000020
ldr r5, =0xb
str r5, [ r4 ]
/*
init BSS section
*/
ldr r0, = 0
ldr r1, _bss_start
ldr r2, _bss_end
bss_init:
str r0, [r1]
add r1,r1,#4
cmp r1,r2
blt bss_init
//U-boot将自己从flash搬移到RAM中
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
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 */
beq vector_copy
//通过比较_start和_TEXT_BASE的值来确定U-boot是否在内存中,_TEXT_BASE为连接时存放地址,_start
//为连接时存放地址,若两者不同则表示U-boot当前在内存中
ldr r2, _armboot_start //_armboot_start为_start地址
ldr r3, _bss_start //_bss_start为数据段地址
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
/*
now copy to sram the interrupt vector
*/
vector_copy:
ldr r0, _TEXT_BASE
add r2, r0, #128
ldr r1, =0x30000000 /*modified by shixq from 0x0c000000 to 0x30000000*/
/* add r1, r1, #0x08 *//*deleted by shixq*/
vector_copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble vector_copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
/*enable the irq*/
mrs R4, cpsr
bic R4, R4, #0x80
msr cpsr, R4
ldr pc, _start_armboot
_start_armboot: .word start_armboot
//到这里第一阶段结束,进入第二阶段C代码的start_armboot
/*
//CPU初始化,这段初始化代码与具体使用的硬件相关,这里为SEP4020
cpu_init_crit:
/* PLLCON */
//配置系统时钟为88M
ldr r0, =0x10001004 /*72M*/
ldr r1, =0x400b
str r1, [r0]
//设置系统启动模式为Normal模式
ldr r0, =0x10001014 /*Normal*/
ldr r1, =0x1
str r1, [r0]
//配置系统时钟为88M
ldr r0, =0x10001004 /*72M*/
ldr r1, =0xC00b
str r1, [r0]
//打开系统所有模块时钟
ldr r0, =0x1000100C /*open all*/
ldr r1, =0xFFFFFFFF
str r1, [r0]
/*UARTCON*/
#if 1
//设置串口每个数据传输的比特数为8,Divisor Latch被访问
ldr r0, =0x1000500C /*databit:8*/
ldr r1, =0x83
str r1, [r0]
//配置波特率为115200,这里波特率寄存器中值为0x002F=88M/16/115200
ldr r0, =0x10005004 /*baud=9600*/
ldr r1, =0x0
str r1, [r0]
ldr r0, =0x10005000
ldr r1, =0x2F
str r1, [r0]
//设置串口每个数据传输的比特数为8,普通寄存器被访问
ldr r0, =0x1000500C
ldr r1, =0x3
str r1, [r0]
#endif
mov pc, lr