经过前面的配置,编译分析。选择可以开始进入移植篇了。
其实我在想,是先出移植篇呢还是先出分析篇。因为这两者息息相关。整个uboot的启动流程懂了,那么移植也就不那么无从下手了。
我手上的板子是S3C6410的,如果一直对S3C6400 进行分析,那会不会影响到读者的分析。。
最终我决定,分析移植一起进行更新,,一般我会先出分析帖,然后再出教程帖。间隔应该不会特别长时间。
最近我同学说了,说我的帖子不够正式,没有转载说明,没有版权说明,,以后慢慢补上吧。
下面开始 分析篇(一)-----start.S
-----------------------------
使用环境
PC: ubuntu 11.04
kernel: 2.6.32-28-generic
corss: arm-linux-gcc 4.3.2
arm: s3c6410
-----------------------------
作者: LvApp
联系方式:
[email protected]
一切版权均有作者所有,欢迎转载,请指明出处,如何修改请与本人联系,谢谢
今天,我们正式进入了uboot启动代码的分析,从上一次分析的makefile中,关于lds的说明,可以知道为什么要从这个文件开始,要是忘记了,可以去复习下。
u-boot2010.03 配置编译目标分析
u-boot2010.03 Makefile分析
这里就不细说了,arm上电启动执行的第一条语句就是在这个start.S中。
由于代码比较长,依旧采取边帖代码边分析的方式
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
*
*************************************************************************
*/
.globl _start
_start: b reset
#ifndef CONFIG_NAND_SPL
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 */
#else
. = _start + 64
#endif
首先进入的就是arm的异常项量表,这对于有过裸机开发的人应该不陌生,如果不了解这个,这里我就不多说,因为这不是这次的主题,可以去查阅相关资料,其实arm的中断入口地址就是在这里指定的
_start: b reset 这就是arm执行的第一条代码,直接通过跳转,进入到了
reset地址处
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr /* 把cpsr 放到r0 中 */
bic r0, r0, #0x3f /* 清 0x3f 对应位 11 1111 为0 */
orr r0, r0, #0xd3 /* 或上 1011 0011 模式设置为SRC32 禁止中断和快速中断*/
msr cpsr, r0
此处就是arm执行的第二条语句,将arm设置为
src模式,并禁止了中断以及快速中断。可以查看s3c6410数据手册,查看
cpsr寄存器的作用
下面开始初始化cpu了,这部分是关于协处理器的,我也不是很懂,想具体了解的人,可以去看协处理器手册
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
cpu_init_crit:
/*
* When booting from NAND - it has definitely been a reset, so, no need
* to flush caches and disable the MMU
*/
#ifndef CONFIG_NAND_SPL
/*
* 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
/* Prepare to disable the MMU */
adr r1, mmu_disable_phys
/* We presume we're within the first 1024 bytes */
and r1, r1, #0x3fc
ldr r2, _TEXT_PHY_BASE
ldr r3, =0xfff00000
and r2, r2, r3
orr r2, r2, r1
b mmu_disable
.align 5
/* Run in a single cache-line */
mmu_disable:
mcr p15, 0, r0, c1, c0, 0 /* 禁止MMU就是这一句了,没必要判断那么多,其实只要把这句话移到上面,直接禁止了就好了。反正现在就是要关掉对吧 */
nop
nop
mov pc, r2
#endif
/* 设置MMC映射地址,如果MMU开启,那么地址将被映射到0x70000000起始位置 0x13 为256MB 查看arm1176jzfs */
mmu_disable_phys:
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M (0x70000000 - 0x7fffffff)
这里就是根据你的外部的内存大小来设置的,我这里是256MB,所以设置为0x13具体的数值根据arm1176jzfs手册可以查看到,s3c6410的核心就是arm1176
下面这个就相对来说比较重要了,很比较复杂。我这里就先留个脚印,回头下一篇细细的分析
/*
* Go setup Memory and board specific bits prior to relocation.
*/
bl lowlevel_init /* go setup pll,mux,memory */
注释也说了,是初始化 pll mux memory 之类的,对于cpu的工作频率就是在这里设置的
继续分析
after_copy: /* 注意这里噢。。有个after_copy,移植篇的时候,会在这里加上适当的代码 */
#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldr r5, =0x0000ffff
mcr p15, 0, r5, c3, c0, 0 /* load domain access register */
/* Set the TTB register */
ldr r0, _mmu_table_base
ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE
ldr r2, =0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15, 0, r1, c2, c0, 0
/* Enable the MMU */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #1 /* Set CR_M to enable MMU */
/* Prepare to enable the MMU */
adr r1, skip_hw_init
and r1, r1, #0x3fc
ldr r2, _TEXT_BASE
ldr r3, =0xfff00000
and r2, r2, r3
orr r2, r2, r1
b mmu_enable
.align 5
/* Run in a single cache-line */
mmu_enable:
mcr p15, 0, r0, c1, c0, 0
nop
nop
mov pc, r2
#endif
这段代码主要是是否启动mmu的,一般都不开启,直接跳过就好了。
Ps:看到那个
after_copy了没?之前分析的时候,没说过要copy对不对?很奇怪吧。。。其实不然,看了下面的代码,你会发现,下面就剩下设置栈,clear bss以及启动第二阶段的部分了
也就是说,uboot 如果是从nand启动的,那么选择的pc指针还在 stepping stone内,而该区域只有4K的大小,有点小了。。。而对于nor flash启动的,以及其它media都有类似的问题,
不是速度慢就是没法直接执行代码,都需要将代码拷贝到ram中去。
移植的一个问题就出来了,在这里 添加拷贝代码。。
skip_hw_init:
/* Set up the stack */
stack_setup:
ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */
sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
sub sp, r0, #12 /* leave 3 words for abort-stack */
这一部分是设置栈,而栈设置的位置在哪呢?
CONFIG_SYS_UBOOT_BASE 在
include/configs/xxx.h中定义,此处我的是
s3c6400.h 打开该文件,还是别关了,经常要看这个里面是不是定义了什么宏的
/* NAND U-Boot load and start address */
#define CONFIG_SYS_SDRAM_BASE 0x50000000
#define CONFIG_SYS_MAPPED_RAM_BASE CONFIG_SYS_SDRAM_BASE
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_MAPPED_RAM_BASE + 0x07e00000)
最终这个
CONFIG_SYS_UBOOT_BASE = 0x50000000 + 0x07e00000 为什么后面要加上0x07e00000(126MB) 其实uboot在将自己拷贝到内存中的时候,会放到内存最大值往下2MB的位置,这里呢,uboot
默认就以为自己是128MB了。往下就是126MB的位置了,该值可以根据实际情况而改变,一般不改也没事的
#define CONFIG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 1024 * 1024)
CONFIG_SYS_MALLOC_LEN = 0x4000 + 1024*1024
#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes for initial data */
最终
sp = 0x50000000 + 0x07e00000 - (0x4000 + 1024*1024) - 128 - 12
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0 /* clear */
clbss_l:
str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
这一段就是
clear_bss 固定清为0 由此可知bss也不是天生就是0,也是人为的原因
#ifndef CONFIG_NAND_SPL
ldr pc, _start_armboot
_start_armboot:
.word start_armboot
#else
b nand_boot
/* .word nand_boot*/
#endif
进入最后一部分,就是一个
ldr pc,_start_armboot 这个地址最终会保存
start_armboot,启动第二阶段
finish.
thanks a lot.