data/attach/1907/yxdl802vivuv1b5997xzeppnhymedapa.jpg
重新烧录,启动,发现可以正常执行,然后卡死在DRAM之后,还打印出了一个O,这个O看起来挺熟悉的,开机时候打印的那个O?一下子就想到,我们虽然自己移植的那个重定位代码(拷贝BL2到内存中),但原版代码中应该也有一份,要将它移除。
首先定位到DRAM是由
board.c中的
board_init_f函数调用
display_dram_config打印出,
board_init_f函数被
crt0.S中的
_main中被调用,看到这里可以很明显的看出,调用完board_init_f之后就开始执行代码重定位了。那么,将这段代码屏蔽掉,应该就能解决上述问题。
再往下看代码,发现一个小细节问题,调用了
coloured_LED_init和
red_led_on,我们开发板应该没有什么彩 {MOD}led吧,屏蔽掉就可以了,防止出问题。
编译完后,再次启动,问题解决,进入了命令行,但是还是有一些问题还需要修改。
首先可以看到
cpu打印出来的时钟不对,其次就是sdhci应该是
nand初始化失败了吧,这里我为了验证猜想,使用了uboot提供的mmc操作命令,读取nand中的某块数据出来,但结果显示有问题。
目前就开始着手解决这两个问题吧。
Cpu时钟的初始化在2014.10版中的
lowlevel_init.S中有写,但是并未被调用。这里可以分析下到底都做了些啥。
汇编不常用,细节就不写了,大致就是读取CPU的id号,来判断是S5PV100还是V110,我们的芯片是s5pv210,寄存器和110是相同的。Review完代码后,我们发现开头对cpu的判断会在
system_clock_init中用到,那么我们就将100相关的代码删除,留下有用的代码就好了。
代码处理完后,就需要对时钟相关的寄存器进行配置了,这里我偷懒了,直接在网上看到别人写的帖子,觉得不错,直接用他的数据好了。
参考:
http://blog.csdn.net/u010346967/article/details/46461255他这里设置的时钟是datasheet推荐的,和我之前移植三星版本的uboot一致。
system_clock_init:
/* Check S5PC100 */
ldr r0, =0xE010C000 @ S5PC110_PWR_CFG
/* Set OSC_FREQ value */
ldr r1, =0xf
str r1, [r0, #0x100] @ S5PC110_OSC_FREQ
/* Set MTC_STABLE value */
ldr r1, =0xffffffff
str r1, [r0, #0x110] @ S5PC110_MTC_STABLE
/* Set CLAMP_STABLE value */
ldr r1, =0x3ff03ff
str r1, [r0, #0x114] @ S5PC110_CLAMP_STABLE
首先将
PWR_CFG寄存器的地址放入r0寄存器,大致就是为了方便下面三个寄存器的设置,这三个寄存器分别为
OSC_FREQ、MTC_STABLE、CLAMP_STABLE,查了数据手册,并不是很理解这几个寄存器是设置啥的,而这个章节讲的是cpu的电源模式。
ldr r0, =S5PC110_CLOCK_BASE @ 0xE0100000
/* Set Clock divider */
ldr r1, =0x14131330 @ 1:1:4:4, 1:4:5
str r1, [r0, #0x300]
ldr r1, =0x11110111 @ UART[3210]: MMC[3210]
str r1, [r0, #0x310]
/* Set Lock Time */
ldr r1, =0x2cf @ Locktime : 30us
str r1, [r0, #0x000] @ S5PC110_APLL_LOCK
ldr r1, =0xe10 @ Locktime : 0xe10 = 3600
str r1, [r0, #0x008] @ S5PC110_MPLL_LOCK
str r1, [r0, #0x010] @ S5PC110_EPLL_LOCK
str r1, [r0, #0x020] @ S5PC110_VPLL_LOCK
/* S5PC110_APLL_CON */
ldr r1, =0x80C80601 @ 800MHz
str r1, [r0, #0x100]
/* S5PC110_MPLL_CON */
ldr r1, =0x829B0C01 @ 667MHz
str r1, [r0, #0x108]
/* S5PC110_EPLL_CON */
ldr r1, =0x80600602 @ 96MHz VSEL 0 P 6 M 96 S 2
str r1, [r0, #0x110]
/* S5PC110_VPLL_CON */
ldr r1, =0x806C0603 @ 54MHz
str r1, [r0, #0x120]
/* Set Source Clock */
ldr r1, =0x10001111 @ A, M, E, VPLL Muxing
str r1, [r0, #0x200] @ S5PC1XX_CLK_SRC0
上述这段代码参考:
http://blog.csdn.net/u010346967/article/details/46461255
/* OneDRAM(DMC0) clock setting */
ldr r1, =0x01000000 @ ONEDRAM_SEL[25:24] 1 SCLKMPLL
str r1, [r0, #0x218] @ S5PC110_CLK_SRC6
ldr r1, =0x30000000 @ ONEDRAM_RATIO[31:28] 3 + 1
str r1, [r0, #0x318] @ S5PC110_CLK_DIV6
oneDRAM,开发板中没有,可以删除。
/* XCLKOUT = XUSBXTI 24MHz */
add r2, r0, #0xE000 @ S5PC110_OTHERS
ldr r1, [r2]
orr r1, r1, #(0x3 << 8) @ CLKOUT[9:8] 3 XUSBXTI
str r1, [r2]
/* CLK_IP0 */
ldr r1, =0x8fefeeb @ DMC[1:0] PDMA0[3] IMEM[5]
str r1, [r0, #0x460] @ S5PC110_CLK_IP0
/* CLK_IP1 */
ldr r1, =0xe9fdf0f9 @ FIMD[0] USBOTG[16]
@ NANDXL[24]
str r1, [r0, #0x464] @ S5PC110_CLK_IP1
/* CLK_IP2 */
ldr r1, =0xf75f7fc @ CORESIGHT[8] MODEM[9]
@ HOSTIF[10] HSMMC0[16]
@ HSMMC2[18] VIC[27:24]
str r1, [r0, #0x468] @ S5PC110_CLK_IP2
/* CLK_IP3 */
ldr r1, =0x8eff038c @ I2C[8:6]
@ SYSTIMER[16] UART0[17]
@ UART1[18] UART2[19]
@ UART3[20] WDT[22]
@ PWM[23] GPIO[26] SYSCON[27]
str r1, [r0, #0x46c] @ S5PC110_CLK_IP3
/* CLK_IP4 */
ldr r1, =0xfffffff1 @ CHIP_ID[0] TZPC[8:5]
str r1, [r0, #0x470] @ S5PC110_CLK_IP3
/* wait at least 200us to stablize all clock */
mov r2, #0x10000
1: subs r2, r2, #1
bne 1b
这部分应该就是和一些内部外设相关的时钟开启这类的,先放着不管。 修改完时钟相关的寄存器后,在
lowlevel_int中执行
system_clock_init。
理论上是不会有太大问题,但是为了验证是否正确,我移植了三星版本的一个打印各时钟频率的函数,移植完后,发现没有太大的问题。而且之前mmc初始化失败的问题也被解决了,但是只是没有初始化失败的log而已,所以还是要对mmc进行验证下。
首先先测试一下,是否能够对环境变量进行保存,环境变量会在代码中保存一份,如果存储设备不存在环境变量的话,就会先调用这份代码中的环境变量,因此我们先对这份环境变量进行更改。
开机后在uboot命令行中输入pri,结果打印出一堆参数,然后通过这些参数定位到X210.h中,接下来就是修改这些环境变量。
将没用的环境变量屏蔽掉,再次烧录sd卡并启动,打印环境变量,嗯,整洁多了。
之后set一个环境变量,并保存,重启后,发现环境变量存在,因此可以证明nand是可以使用的,当然,我们还可以直接对mmc read/write进行读写测试,写入一些数据,再读取出来,如果正确也可以说明mmc可以使用。
Nand、Mmc这类设备的兼容性比较强,移植uboot的时候,大多数都是不需要过多的修改就能使用了。