s3c6410 uboot代码分析
部端口的基地址,0x13的二进制为0x10011,0x10011的意思为256M,代表映射的
大小为256M,0x10010为128M。假如你没开MMU,PHY和Peri port映射的地址将相同。通过下面的内容后,我们知道我们原来uboot
代码是放置到0x57e00000的,现在便只能通过0x57e00000+0x70000000虚拟地址来访问uboot起始地址了。
使用C15的方法是:
1.Opcode_1 set to 0
2.CRn set to c15
3.CRm set to c2
4.Opcode_2 set to 4
还有问题请参考arm1176jzfs芯片手册
*/
--------------------
/* Peri port setup */
ldrr0, =0x70000000
orrr0, r0, #0x13
mcrp15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
--------------------
/*
下面是一条跳转指令,代码这里不贴,但是其中的代码很重要,在lowlevel.S中实现比如说点亮LED灯、关闭watchdog、关闭中断、系统
时钟初始、nand flash初始化、内存控制器初始化。不过说实在的,去仔细分析这些初始化的过程,对于你对如何控制硬件有很大的帮
助,对于这个函数,所要说的东西太多,会在后面的文章中单独分析它,现在先知道功能就好,没有它代码无法启动。
*/
--------------------
bllowlevel_init
--------------------
/*跳转出来以后,继续执行下面的代码,下面的代码是判断程序是否已经在ram中了,在的话就不拷贝,直接跳转到after_copy了,否则
继续执行下面的代码*/
--------------------
ldrr0, =0xff000fff
bicr1, pc, r0/* r0 <- current base addr of code */
ldrr2, _TEXT_PHY_BASE/* r1 <- original base addr in ram */
bicr2, r2, r0/* r0 <- current base addr of code */
cmp r1, r2 /* compare r0, r1 */
beq after_copy/* r0 == r1 then skip flash copy */
--------------------
/*
下面代码通过函数copy_from_nand函数把代码拷贝到ram中。steppingstone只能拷贝4KB,我们需要把所有的代码搬运到内存中哦
我们知道s3c6410可以通过SD、onenand、nand启动,但是我们这里做了简化,先只从nand启动,以后会再增加SD卡启动
copy_from_nand代码也在start.S中,做了修改以适合大页访问,如有需要请留言告知,将添加copy_from_nand代码分析
*/
--------------------
#ifdef CONFIG_BOOT_NAND
movr0, #0x1000
blcopy_from_nand
#endif
--------------------
/*SD卡启动方式,这个宏我没有定义,先保留吧*/
--------------------
#ifdef CONFIG_BOOT_MOVINAND
ldrsp, _TEXT_PHY_BASE
blmovi_bl2_copy
bafter_copy
#endif
--------------------
/*这里我啥都没做*/
after_copy:
/*
打开MMU功能
协处理器c3的作用是存储的保护和控制,用在MMU中为内存的域访问控制
c3为32位寄存器,每两位为一个访问控制特权,0x00代表没有访问权限,这时候访问将失效;0x01为客户类型,将根据
地址变换条目中的访问控制位决定是否允许特定内存访问;0x10是保留的,暂时没有使用,0x11为管理者权限,不考虑
地址变换条目中的权限控制位,将不会访问内存失效。
ldrr5, =0x0000ffff
mcrp15, 0, r5, c3, c0, 0,代码的含义为设置高8个域无访问权限,低8个域为管理者权限。
接着下面通过mcrp15, 0, r1, c2, c0, 0指令给c2赋值,c2用于保存页表基地址。所谓页表基地址即是虚实转换的内存页表的首地址。
这里r1的值赋值给了c2,r1的值为0x57exxxxx,c2高14位是储存页表的基地址
最后代码很简单,打开MMU。
*/
--------------------
#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldrr5, =0x0000ffff
mcrp15, 0, r5, c3, c0, 0@ load domain access register
/* Set the TTB register */
ldrr0, _mmu_table_base
ldrr1, =CFG_PHY_UBOOT_BASE
ldrr2, =0xfff00000
bicr0, r0, r2
orrr1, r0, r1
mcrp15, 0, r1, c2, c0, 0
/* Enable the MMU */
mmu_on:
mrcp15, 0, r0, c1, c0, 0
orrr0, r0, #1/* Set CR_M to enable MMU */
mcrp15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif
--------------------
/*
堆栈初始化代码,我们在这里定义了CONFIG_MEMORY_UPPER_CODE
sp的值为0xC7FFFFE8
*/
--------------------
skip_hw_init:
/* Set up the stack */
stack_setup:
#ifdef CONFIG_MEMORY_UPPER_CODE
ldrsp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
#else
ldrr0, _TEXT_BASE/* upper 128 KiB: relocated uboot */
subr0, r0, #CFG_MALLOC_LEN/* malloc area */
subr0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
subr0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
subsp, r0, #12/* leave 3 words for abort-stack */
#endif
--------------------
/*清零BSS段内容为0 */
--------------------
clear_bss:
ldrr0, _bss_start/* find start of bss segment */
ldrr1, _bss_end/* stop here */
mov r2, #0x00000000/* clear */
s3c6410uboot代码分 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)