Hi3515 start.S文件分析

Hi3515是华为海思半导体的一款多媒体处理芯片,这款芯片广泛的被应用于安防监控行业。它采用arm9架构的V5指令集,为了方便的以后的工作,加深对该芯片的了解,我对hi3515上电后执行的一段汇编代码做了大致分析,分析以注释的形式书写在start.s的文件中。

/*

board\hi3515v100\u-boot.lds 是UBOOT的链接脚本

其中 ENTRY(_start) 指定了程序的入口地址。

_start是cpu加电后执行的第一条指令。

Hi3515在加电后0x0到0x0400000映射为启动器件的地址

可以为NOR-FLASH或NAND-FLASH

*/

.globl _start

_start:

@跳转到reset执行

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

_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!

* setup Memory and board specific bits prior to relocation.

* relocate armboot to ram

* setup stack

*

*

*/

_TEXT_BASE:

.word TEXT_BASE

.globl _armboot_start

_armboot_start:

.word _start

.globl _img_end

_img_end:

.word __img_end

/*

* These are defined in the board-specific linker script.

*/

.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

#ifdef CONFIG_HISILICON

_clr_remap_rom_entry:

.word ROM_TEXT_ADRS + do_clr_remap - TEXT_BASE

_clr_remap_nand_entry:

.word NAND_TEXT_ADRS + do_clr_remap - TEXT_BASE

#endif

/*

* the actual reset code

*/

reset:

/*

* set the cpu to SVC32 mode

*/

@设置ARM的工作模式为特权模式

mrs r0,cpsr

bic r0,r0,#0x1f

orr r0,r0,#0xd3

msr cpsr,r0

/*

* we do sys-critical inits only at reboot,

* not when booting from ram!

*/

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

/*

* flush v4 I/D caches

*/

@关闭P15协处理器,即关闭MMU和CACAHE

mov r0, #0

mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */

mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

/*

* disable MMU stuff and caches

*/

mrc p15, 0, r0, c1, c0, 0

bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */

bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */

orr r0, r0, #0x00000002 /* set bit 2 (A) Align */

mcr p15, 0, r0, c1, c0, 0

@获取3515的启动模式,判断是从NOR或者NAND启动,保存到R4中

ldr r0, =REG_BASE_SCTL

ldr r1, [r0, #0x8c]

and r1, r1, #0x60

lsr r4, r1, #5

@Check if I need jump to rom

@movs r0, pc, lsr#24 /* Z flag if r0 == 0 then 1 else 0 */

@bne do_clr_remap

/*判断高8位是否为0,首次加电的时候,肯定是0,

如果已经在RAM中运行了,则不是零。*/

mov r0, pc, lsr#24

cmp r0, #0x0

bne do_clr_remap

@如果从r4中判断是从NOR启动,则PC指向以NOR-flash为基地址(0X80000000),以do_clr_remap函数为偏移量的地址。

@即PC指向了NOR-flash中的do_clr_remap函数

@如果从r4中判断是从NAND启动,则PC指向以NAND-flash为基地址(0X70000000),以do_clr_remap函数为偏移量的地址。

@即PC指向了NAND-flash中的do_clr_remap函数

cmp r4, #2 /* boot from nand flash*/

ldreq pc, _clr_remap_nand_entry

cmp r4, #0 /* boot from nor flash */

ldreq pc, _clr_remap_rom_entry

do_clr_remap:

ldr r4, =REG_BASE_SCTL

@ldr r0, =REG_VALUE_SC_NOLOCK

@str r0, [r4, #REG_VALUE_SC_LOCKED]

ldr r0, [r4, #REG_SC_CTRL]

@清除重映射

@Set clear remap bit.

orr r0, #(1<<8)

str r0, [r4, #REG_SC_CTRL]

@重映射后零地址不再指向NAND或NOR而是指向了ITCM(指令紧耦合存储器),3515的ITCM的大小是2KB,地址从0x0到0x00000800

@设置ITCM的大小和启用CACHE

@Setup ITCM (ENABLED, 2KB)

ldr r0, =( 1 | (MEM_CONF_ITCM_SIZE<<2) | MEM_BASE_ITCM)

mcr p15, 0, r0, c9, c1, 1

@enable I-Cache now

mrc p15, 0, r0, c1, c0, 0

orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */

mcr p15, 0, r0, c1, c0, 0

@设置栈指针,指向ITCM区域后紧邻的地址即 0x00000800

@Setup lowlevel sp

ldr sp, =(MEM_BASE_ITCM + MEM_SIZE_ITCM)

@通过检测高四位地址,以判断当前指令实在是RAM还是FLASH中运行,

@如果是在NOR中就是0X8 如果是在nand中就是0x7

@如果是在RAM中就是0XC

@首次加电的话就是0x8或0x7,即在FLASH中运行

@Check if I'm running in static mem bank

mov r0, pc, lsr#28

cmp r0, #(TEXT_BASE>>28)

/*

* Go setup Memory and board specific bits prior to relocation.

*/

@如果判断出已经在内存中,即跳转到relocate,越过执行lowlevel_init,

@首次加电,肯定不会执行跳转

beq relocate

@初始化cpu、切换3515的系统运行模式到NORMAL、启用PLL锁相环、启用DDR控制器,也就是说这以后RAM才真正可用了

@具体代码参考cpu\arm926ejs\hi3515v100\lowlevel_init.c中的void lowlevel_init(void)函数

bl lowlevel_init /* go setup pll,mux,memory */

#endif

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

@下面就开始把UBOOT从FLASH搬运到RAM的准备工作了

relocate: /* relocate U-Boot to RAM */

@从3515的SC_PERCTRL23寄存器读取芯片选定的启动模式

ldr r0, =REG_BASE_SCTL

ldr r6, [r0, #0x8c]

and r6, #0x60

lsr r4, r6, #5

@R4=0 从NOR启动 R4=2从NAND启动

@下面这一段代码,有点不是很确定。

@果从FLASH启动那么 _start为0 _TEXT_BASE为0xc0500000

@其中 _TEXT_BASE的指定在board\hi3515v100\config.mk文件中

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 stack_setup

@ _armboot_start等价于 _start

ldr r2, _armboot_start

ldr r3, _img_end

sub r2, r3, r2 /* r2 <- size of armboot */

cmp r4, #2

ldreq r2, =(CFG_NAND_U_BOOT_ONE_PART)

add r2, r0, r2 /* r2 <- source end address */

@把UBOOT搬运到RAM中去,循环操作,如果是从NOR中搬运,第一次循环时R0=0X80000000 R1=_TEXT_BASE为0xc0500000

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

#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

/* Set up the stack */

@设置0XC0500000-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZ-3的内存为栈地址

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

#ifdef CONFIG_USE_IRQ

sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

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

clear_bss:

ldr r0, _bss_start /* find start of bss segment */

ldr r1, _bss_end /* stop here */

mov r2, #0x00000000 /* clear */

@对BSS段的内存数据清零

clbss_l:str r2, [r0] /* clear loop... */

add r0, r0, #4

cmp r0, r1

ble clbss_l

@调用start_armboot函数,进入C代码阶段,以后PC就指向RAM的地址了,代码在RAM中运行

ldr pc, _start_armboot

_start_armboot:

.word start_armboot

对嵌入式物联网感兴趣的小伙伴,可以多了解一下相关信息。(看过来)

 

Hi3515 start.S文件分析_第1张图片

你可能感兴趣的:(linux,c语言,开发语言)