uboot之start.s分析1

最简单的bootloader的编写步骤:

1.设置CPU工作模式

2. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH

3. 如果bootloader比较大,要把它重定位到SDRAM

4. 把内核从NAND FLASH读到SDRAM

5. 设置"要传给内核的参数"

6. 跳转执行内核





我们学习uboot start.s 首先我么要很好的理解上面的几个个图片

另外  在ARM中

            ROM主要指:NAND Flash,Nor Flash
            RAM主要指:PSRAM,SDRAM,SRAM,DDRAM

首先我们去Uboot官网下载一个UBOOT(ftp://ftp.denx.de/pub/u-boot/),然后找到相应的start.s文件。

1. uboot 硬件初始化 CPU工作模式设置

.globl _start   //声明一个全局变量   系统复位位置,真个程序的入口

_start: b          start_code  //各个异常向量对应的相对跳转代码 ,0x00

  
ldr	pc, _undefined_instruction  //未定义指令异常,0x04
ldr	pc, _software_interrupt    //软中断异常,0x08
ldr	pc, _prefetch_abort  //内存操作异常,0x0c
ldr	pc, _data_abort     //数据异常,0x10
ldr	pc, _not_used      //未适用,0x14
ldr	pc, _irq          //慢速中断异常,0x18 
ldr	pc, _fiq         //快速中断异常,0x1c


这是系统异常向量表, 不是让你一条一条来顺序执行的。这是系统remap之前用的中断向量。除了reset vector 有意义外,其他基本上是死循环。
系统重启动时, 就走第一个向量 执行 b start_code, 跳到下面start_code下执行startup code.
如果系统出现问题,执行到一条不认识的指令时,这时系统异常中断发生,系统跳转到第二个向量, 执行ldr     pc, _undefined_instruction;这时pc被设置成undefined_instruction,CPU到_undefined_instruction地址去执行这一地址下的指令, 结果还是一个未定义指令,如此循环下去; 其他异常向量,原理类似。

.balignl 16,0xdeadbeef  //对齐内存为16的倍数
start_code:                        /*复位启动子程序,设置cpu运行在SVC32模式。共有7种模式*/	
     mrs	r0,cpsr            /*复制当前程序状态寄存器cpsr到r0*/
     bic	r0,r0,#0x1f       //这里使用位清除指令,把中断全部清除,只置位模式控制位 这里我们可以看到把第五位全部清理了
     orr	r0,r0,#0xd3      /*选择新模式,(现在设为超级保护模式)*/    11010011   管理模式
	
	msr	cpsr,r0  /*设置cpsr为超级保护模式*/
   /*通过设置ARM的CPSR寄存器,让CPU运行在操作系统模式,为后面进行其它操作作好准备*/
通过上面 我们可以看到我们把CPU初始化成SVC模式了 可是为什么我们要初始化SVC模式了                                                                                          1中止模式和未定义模式                                                                                                                                             首先可以排除的是,中止abt和未定义und模式,那都是不太正常的模式,此处程序是正常运行的,所以不应该设置CPU为其中任何一种模式,所以可以排除。                       2.快中断fiq和中断irq模式
         其次,对于快中断fiq和中断irq来说,此处uboot初始化的时候,也还没啥中断要处理和能够处理,而且即使是注册了终端服务程序后,能够处理中断,那么这两种模式,也是自动切换过去的,所以,此处也不应该设置为其中任何一种模式。
        3.用户usr模式
        虽然从理论上来说,可以设置CPU为用户usr模式,但是由于此模式无法直接访问很多的硬件资源,而uboot初始化,就必须要去访问这类资源,所以此处可以排除,不能设置为用户usr模式。
       4.系统sys模式 vs 管理svc模式
       首先,sys模式和usr模式相比,所用的寄存器组,都是一样的,但是增加了一些访问一些在usr模式下不能访问的资源。而svc模式本身就属于特权模式,本身就可以访问那些受控资源,而且,比sys模式还多了些自己模式下的影子寄存器,所以,相对sys模式来说,可以访问资源的能力相同,但是拥有更多的硬件资源。
2. 初始化硬件:关看门狗、设置时钟
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
	ldr     r0, =pWTCON
	mov     r1, #0x0
	str     r1, [r0]


	/*
	 * mask all IRQs by setting all bits in the INTMR - default
	 */
	mov	r1, #0xffffffff
	ldr	r0, =INTMSK
	str	r1, [r0]
# if defined(CONFIG_S3C2410)
	ldr	r1, =0x3ff
	ldr	r0, =INTSUBMSK
	str	r1, [r0]
# elif defined(CONFIG_S3C2440)
	ldr	r1, =0x7fff
	ldr	r0, =INTSUBMSK
	str	r1, [r0]
# endif
2. 初始化CPU
	bl	cpu_init_crit                                                                               cpu_init_crit:
	/*
	 * flush v4 I/D caches
	 */
	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
	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
	mcr	p15, 0, r0, c1, c0, 0


	/*
	 * 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.
	 */
	mov	ip, lr
	bl	lowlevel_init
	mov	lr, ip
	mov	pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
MCR的用法简介                                                                                                   MCR{<cond>} <p>,< opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}                                                                              • <cond>
          指令执行的条件码.当<cond>忽略时指令为无条件执行。
          • <opcode_1>
          协处理器将执行的操作的操作码。对于CP15协处理器来说,<opcode_1>永远为0b000,当<opcode_1>不为0b000时,该指令操作结果不可预知。
         • <Rd>
          作为源寄存器的ARM寄存器,其值将被传送到协处理器寄存器中
        • <CRn>
          作为目标寄存器的协处理器寄存器,其编号可能是C0,C1,…,C15。
         <CRm>和<opcode_2>两者组合决定对协处理器寄存器进行所需要的操作,如果没有指定,则将为<CRm>为C0,opcode_2为0                                                                                                                                                                                             C7   Any  data  written  to  this  location  will  cause  the  selected  cache  to  be flushed.
           I  表示指令寄存器   D表示数据寄存器
  <CRm>和<opcode_2>
C7 - 0 :Flush I + D
    C5 - 0     :Flush I
    C6 - 0    :Flush D
    C6 - 1    :Flush D single Virtual address
    CA - 1    :Clean D entry  Virtual address
    CA - 4    :drain write buf.
             C8   Any  data  written  to  this  location  will  cause  the  selected  TLB  flush operation
          I  表示指令寄存器   D表示数据寄存器
  <CRm>和<opcode_2>
    C7 - 0    :Flush I + D
    C5 - 0     :Flush I
    C6 - 0    :Flush D
    C6 - 1    :Flush D single Virtual address

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


	bl clock_init

3.从定位   
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     clear_bss


ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot            */


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值