smdkc100之u-boot 2010.03代码的分析1

来源:互联网 发布:vscode配置go 编辑:程序博客网 时间:2024/06/11 10:03

以下用以记录uboot 2010.03代码的分析过程,目标是smdkc100本文参考了网上有关s3c6410开发板有关源码的分析,在此感谢无私奉献,如有错误,欢迎指正。

强调,内容与三星原厂提供的uboot-2010.03有更改的地方,因为外接外设的区别,特别是nand_flash、外接网卡芯片和LCD芯片

以下纯代码情景分析,请结合uboot的功能结构图和内存分布图查看代码,这样会更加容易理解。




                                                功能结构图(上图)        

                  uboot内存分布图(上图)

 

1.start.s代码分析(第一阶段)

/* 以下是具有arm特色的异常向量表,为中断异常准备 */

--------------------

.globl _start
_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

_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

--------------------

 

/* 当发生中断异常时,pc会跳转到.word的后面地址处处理异常,

   undefined异常由arm核译码单元检测,并触发未定义指令异常请求,硬件设置pc的值为0x4,强制程序从内存0x4地址执行指令;

   0x8存放软件中断处理指令,arm中使用swi指令时触发软件中断,硬件设置PC的值为0x8,同时进入系统模式,多用在系统库的编写;

   prefetch异常,预取指中止异常,导致正在取的指令无法正常取出,这里需要注意流水线造成的pc值 ;

   data中止,无法获取数据,产生的原因有可能是内存未准备好、内存无读或写权限等一些原因产生的异常;

   0x14暂时未使用;

   0x18提供系统硬件中断跳转接口,一般我们的处理器都会引出很多的外部中断线,在这里能做的就是判断系统中断线产生的中断,注册中断,初始化中断,调用中断函数等等;

   0x1c地址为_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
_pad:
 .word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:

 .balignl 16,0xdeadbeef

--------------------

 

/* u-boot 执行总共需要二次搬移,第一次是 iROM 固化的代码搬移 nand flash 的前 16k  iRAM 中去运行,第二次是iRAM  16K 代码执行会把 nand flash 中的 u-boot 搬移到链接地址也就是 0x34800000 .

   _TEXT_BASE标号所代表的是uboot代码的运行地址,对于FS_S5PC100系统来说,如果nand flash启动方式,系统会把nand flash里面前16KB的内容映射到引导镜像区,即0x0地址,但是我们需要把uboot代码放到我们的SDRAM,原因是我们代码里面需要对变量做更改并且增加代码执行效率等

   下面代码的含义是定义uboot程序执行的运行地址,值为0x34800000.word后面的值TEXT_BASE在编译的时候,

   通过向编译器传递参数获得,-DTEXT_BASE方式向编译器传递宏参,在编译的时候可以注意下编译的时候都会指定它的值,值得定义在

   config.mk中,Makefile会包含它。

*/

--------------------

_TEXT_BASE:
 .word TEXT_BASE

--------------------

 

/* 

uboot里面会开启MMU,下面是在MMU开启前uboot在内存存放的真实物理地址,值为0x34800000。强调一下,我们做的开发板的SDRAMDMC1上,即访问物理内存的实际物理地址从0x30000000开始,SDRAM的大小为256M,正好是一个DMC1,所以内存的访问地址就是0x30000000-0x40000000之间了。

*/

--------------------

.globl _armboot_start
_armboot_start:
 .word _start

--------------------

 

/* 

   下面的代码__bss_start的值是在u-boot.lds脚本里面定义的,虽然没给值,但是你要知道文件的大小和位置是由编译器指定的,那么还需要我们告诉它值吗?所以没值胜有值啦,由编译时编译器决定它们的值

 */

--------------------

.globl _bss_start
_bss_start:
 .word __bss_start

.globl _bss_end
_bss_end:
 .word _end

--------------------

 

/* 

   uboot开始执行的第二条代码处即在这里了,下面的代码使得cpu的模式为管理模式,如果想使得为cpu为管理模式,需要保证cpsr寄存器的最低5位为10011,下面是把0xd3的值赋值给cpsr0xd31101 0011,最高两位置1的意思为关闭中断和快中断,这是为了防止代码正在执行时,产生外部中断,导致程序跳转到异常向量表而无法正常按顺序执行。5位为0的意思是cpu的状态为arm状态,如果是1cpu进入thumb态,thumb态处理16位指令代码和数据。 

*/

--------------------

reset:

 mrs r0,cpsr
 bic r0,r0,#0x1f
 orr r0,r0,#0xd3
 msr cpsr,r0

--------------------

 

/*下面宏没有定义,所以代码不执行*/

#if (CONFIG_OMAP34XX)

/* Copy vectors to mask ROM indirect addr */

adrr0, _start@ r0 <- current position of code

addr0, r0, #4@ skip reset vector

movr2, #64@ r2 <- size to copy

addr2, r0, r2@ r2 <- source end address

movr1, #SRAM_OFFSET0@ build vect addr

movr3, #SRAM_OFFSET1

addr1, r1, r3

movr3, #SRAM_OFFSET2

addr1, r1, r3

next:

ldmiar0!, {r3 - r10}@ copy from source address [r0]

stmiar1!, {r3 - r10}@ copy to   target address [r1]

cmpr0, r2@ until source end address [r2]

bnenext@ loop until equal */

#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)

/* No need to copy/exec the clock code - DPLL adjust already done

 * in NAND/oneNAND Boot.

 */

blcpy_clk_code@ put dpll adjust code behind vectors

#endif /* NAND Boot */

#endif

/* 以下标号所在处的代码比较多,将做逐步分析,这段代码主要的工作也就是改了一些硬件寄存器和内存初始化工作 */

--------------------

cpu_init_crit:

--------------------

 /*
  指令的含义为刷新指令和数据缓存。mcr的意思是把arm寄存器的值赋值给coprocesser寄存器,拿第一条指令来说,p15代表协处理器,0为一定的值,指令中0b0000四位来表示,现在无具体作用,如果不是0则结果未知,后面的r0是即将写入c7目标寄存器中的值,后面还有个c7所代表的意思为额外操作码,如果不是c0,则表示的是同一个寄存器的不同物理寄存器,因为同一个寄存器的名字并不代码通一个物理内存,我们在学rpsr的时候应该知道这点,最后的0提供附加信息,用于区分同一寄存器的不同物理寄存器,如无附加信息,请保持为0值,否则结果不可预测

 下面三行代码不难看出,c7c8的值被清为0,为什么要清为零呢,你需要去看Cortex-A8_Technical_Reference_Manual_r3p2.pdf芯片手册了,其中是有说明的,不再累述,如下图:


  */

--------------------
 /*

 * Invalidate L1 I/D

 */

movr0, #0@ set up for MCR

mcrp15, 0, r0, c8, c7, 0@ invalidate TLBs

mcrp15, 0, r0, c7, c5, 0@ invalidate icache

--------------------

 /*
查看芯片手册,因为以下改的内容是协处理器c1,那么你就该去查c1是用来干什么的。查看得知,是控制寄存器,查看手册Cortex-A8_Technical_Reference_Manual_r3p2.pdf,其中13,02位为 VCAMV位是对高端异常向量表的支持,如果选择0异常向量表为0x00000000-0x0000001c,如果选择1异常向量表就是FFFF0000-FFFF001c;接下来再分析下下面的指令含义bic r0, r0, #0x00000007 @ clear bits 7, 2:0(B--- -CAM) B位为0表示支持小little-endian1表示支持big-endian格式的系统内存CAM为第三位,M0代表禁止MMU,反之打开,A代表地址对齐检查,0代表禁止,C代表指令数据cache控制,0为禁止

 orr r0, r0, #0x00000002 @ set bit 2 (A) Align 这段指令打开地址对齐检查了,这是应该的O(∩_∩)O~,后面又设置12位为1,含义是如果数据cache和指令cache是分开的话,这里面置1的含义将会打开指令缓存

*/

--------------------
 /*

 * disable MMU stuff and caches

 */

mrcp15, 0, r0, c1, c0, 0

bicr0, r0, #0x00002000@ clear bits 13 (--V-)

bicr0, r0, #0x00000007@ clear bits 2:0 (-CAM)

orrr0, r0, #0x00000002@ set bit 1 (--A-) Align

orrr0, r0, #0x00000800@ set bit 12 (Z---) BTB

mcrp15, 0, r0, c1, c0, 0

--------------------

 

/* 

寄存器C1详细信息如下:

  

********************************我是分割线1128*******************************

代码较多,后续我会跟进,敬请期待
原创粉丝点击