码迷,mamicode.com
首页 > 其他好文 > 详细

uboot移植之start.S分析

时间:2015-05-29 11:36:49      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:

/*Name:ubootstart.S分析

Data:2015-3-3

Author:suj_un

*/

                        ubootstart.S

多数的bootloader都分为stage1stage2两部分。依赖于cpu体系结构的代码通常都放在stage1中并且用汇编语言来实现,而stage2则通常

c语言实现。这样就可以实现复杂的功能,并具有良好的移植性。

1.stage1代码结构

a,定义入口。一个可执行的Image必须有一个入口通常这个入口放在ROM0x0地址,因此,必告诉编译器这个地址。这部分工作可以通过修改链接脚本来完成。

b,设置异常向量表

c,设置CPU的速度,时钟频率和终端控制器

d,初始化内存

e,ROM中的程序复制到RAM

f,初始化堆栈,为C函数调用做准备

g,转到RAM中执行,这部分工作使用指令ldr PC来完成。

2.stage2 C语言代码部分

lib_arm/board.c中的start_arm_bootC语言开始的函数,也是整个启动代码中C语言的主函数同时也是整个uboot的主函数,其主要工作有:

a,调用一系列的初始化函数

b,初始化Flash设备

c,初始化系统内存分配函数

d,初始化启动设备,如nand

e,如果目标系统有显示设备,则初始化该类设备

f,初始化网络相关设备

g,进入命令循环等待串口输入命令并执行相关函数

 

代码分析及注释:

.globl _start              //系统复位位置,整个程序的入口

_start: breset             //跳转到reset所在位置并不会返回,此处代码位置是0x00000000

ldrpc, _undefined_instruction       //0x4

ldrpc, _software_interrupt       //0x8

ldrpc, _prefetch_abort        //0xc

ldrpc, _data_abort          //0x10

ldrpc, _not_used            //0x14

ldrpc, _irq              //0x18

ldrpc, _fiq              //0x1c

/*以上7个就是异常中断的初始地址,把每个地址对应的标号写入异常向量跳转表,每条指令占4个字节所以异常向量表的地址范围为0x00000000 - 0x0000002032个字节

ARM体系结构规定在上电复位的起始位置必须有8条连续的跳转指令,通过硬件来实现。它们就是异常向量表。ARM在上电复位后是从0x0开始启动,如果bootloader存在,则是从_start开始执行上面的跳转没有执行。设置异常向量表的作用是识别bootloader,以后每当系统有异常出现时,cpu会根据异常号从内存0x0处开始查找并做相应的处理*/

/*

当有异常出现ARM会自动执行以下步骤:

将下一条指令的地址存放在连接寄存器LR中,

将相应的CPSR复制到SPSR

根据异常类型,强制设置CPSR运行模式位

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

.global _end_vect

_end_vect:

.balignl 16,0xdeadbeef

 

_TEXT_BASE:

.wordTEXT_BASE                  //这个变量在文件/board/cotexa9/config.mk中定义

 

.globl _armboot_start

_armboot_start: 

.word _start                  //_start定义_armboot_start

.globl _bss_start

_bss_start:

.word __bss_start                //__bss_start定义_bss_start,其中__bss_start在链接脚本u-boot.lds中定义

 

.globl _bss_end

_bss_end:

.word _end                     //start

 

    .macro  cache_invalidate_dcache_v7

    MRC     p15, 1, r0, c0, c0, 1      @ read Cache Level ID register (clidr)

    ANDS    r3, r0, #0x7000000         @ extract level of coherency from clidr

    MOV     r3, r3, lsr #23            @ left align level of coherency bit field

    BEQ     finished_inval             @ if loc is 0, then no need to clean

 

    MOV     r10, #0                    @ start clean at cache level 0 (in r10)

loop_1:

    ADD     r2, r10, r10, lsr #1       @ work out 3x current cache level

    MOV     r1, r0, lsr r2             @ extract cache type bits from clidr

    AND     r1, r1, #7                 @ mask of the bits for current cache only

    CMP     r1, #2                     @ see what cache we have at this level

    BLT     skip_inval                 @ skip if no cache, or just i-cache

    MCR     p15, 2, r10, c0, c0, 0     @ select current cache level in cssr

    MOV     r1, #0

    MCR     p15, 0, r1, c7, c5, 4      @ prefetchflush to synch the new cssr&csidr

    MRC     p15, 1, r1, c0, c0, 0      @ read the new csidr

    AND     r2, r1, #7                 @ extract the length of the cache lines

    ADD     r2, r2, #4                 @ add 4 (line length offset)

    LDR     r6, =0x3ff

    ANDS    r6, r6, r1, lsr #3         @ find maximum number on the way size

    CLZ     r5,r6                       @ DCI 0xE16F5F16 , find bit position of way size increment

    LDR     r7, =0x7fff

    ANDS    r7, r7, r1, lsr #13        @ extract max number of the index size

loop_2:

    MOV     r8, r6                     @ create working copy of max way size

loop_3:

    ORR     r11, r10, r8, lsl r5       @ factor way and cache number into r11

    ORR     r11, r11, r7, lsl r2       @ factor index number into r11

    MCR     p15, 0, r11, c7, c6, 2     @ invalidate by set/way

    SUBS    r8, r8, #1                 @ decrement the way

    BGE     loop_3

 

    SUBS    r7, r7, #1                 @ decrement the index

    BGE     loop_2

skip_inval:

    ADD     r10, r10, #2               @ increment cache number

    CMP     r3, r10

    BGT     loop_1

finished_inval:

    .endm

/* 上面这一段是讯为4412开发板添加,用.marco声明了一个宏汇编,作用就是将一组常用的代码写成宏,在程序调用的时候直接使用这个宏而是代码清晰。具体什么功能没有看懂。。。。。。。貌似和cache有关*/

 

#if defined(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

/*       中断堆栈设置     */

reset:          //真正的上电执行的地方

#if 0

/*

 * set the cpu to SVC32 mode and IRQ & FIQ disable

 */

mrs r0, cpsr

bic r0, r0, #0x3f

orr r0, r0, #0xd3

msr cpsr, r0

#else

mrs r0, cpsr          //保存CPSPr0

bic r0, r0, #0x1f        //清除程序状态字低5

orr r0, r0, #0xd3        //设置cpu进入svc模式并屏蔽irqfiq 0x11010011

msr cpsr,r0           //将设置好的值写入到CPSR

#endif

/*ARM体系中的CPSR各个位的含义:32bit 长度的 CPSR 寄存器,其中最低 8bit 的用作控制位,最高4bit  的用作运算状态标志位,其它的24bit 保留,不可随意改写。主要介绍下低8位即CPSR_c(控制域)

 7  6   5   4     3    2      1    0  

 I   F   T  M4  M3  M2   M1  M0

 M0 - M4:模式位 10000 - 0x0010 用户模式

          10001 - 0x0011 快速中断

          10010 - 0x0012 中断

          10011 - 0x0013 管理

          10111 - 0x0017 未定义

          11111 - 0x001f 系统

T:状态位 1/0   Thumb/ARM

F:FIQ     1/0   disable/enable

I:IRQ     1/0   disable/enable

*/

接下来一段是讯为自己加的缓存初始化的汇编。略过。。。。。。

MMU和缓存

 

uboot移植之start.S分析

标签:

原文地址:http://www.cnblogs.com/sumingyuan/p/4537991.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!