微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > s3c6410 uboot代码分析

s3c6410 uboot代码分析

时间:11-09 来源:互联网 点击:

部端口的基地址,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 */

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top