本节中实现的目标是代码在Nor flash上面可以运行,串口输出正常信息。
1. 代码前期调试
因为刚开始不能使用串口,因此使用LED来辅助调试程序
在start.S中禁止中断后line83后加入
/**************************
init LED
**************************/
ldr r0, =0x56000050
ldr r1, =0x1500
str r1, [r0]
ldr r0, =0x56000054
ldr r1, =0xAF
str r1, [r0]
2. 设置时钟
紧接着,加入时钟初始化代码
ldr r0, =0x4c000014
// mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
str r1, [r0]
/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */
orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */
/* MPLLCON = S3C2440_MPLL_200MHZ */
ldr r0, =0x4c000004
ldr r1, =S3C2440_MPLL_400MHZ
str r1, [r0]
/* 启动ICACHE */
mrc p15, 0, r0, c1, c0, 0 @ read control reg
orr r0, r0, #(1<<12)
mcr p15, 0, r0, c1, c0, 0 @ write it back
时钟初始化中,必须加入
ldr r0, =0x4c000014
mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8
str r1, [r0]
以确定时钟源,刚开始自己没加,程序不能跑到__main中,折腾了很久,也是自己对时钟初始化这部分不太熟悉
3. 修改board/samsung/smdk2440/lowlevel_init.S
修改初始化内存控制其的寄存器值
SMRDATA:
.long 0x22011110 //BWSCON
.long 0x00000700 //BANKCON0
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
.long 0x00000700 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
.long 0x008C04F4 // REFRESH
.long 0x000000B1 //BANKSIZE
.long 0x00000030 //MRSRB6
.long 0x00000030 //MRSRB7
4. 在代码任意位置可以加入代码,使用LED调试
GPF4—-GPF6三个LED
ldr r0, =0x56000054
ldr r1, =0xEF
str r1, [r0]
5. 修改board\samsung\smdk2440\smdk2440.c
在__main函数调用的函数序列init_sequence_f中调用board_early_init_f中,含有对时钟重新初始化的语句,因为之前在start.s文件中我们已经对其时钟进行初始化,因此在这没有必要重新初始化,注释掉以下语句
#if 0
/* to reduce PLL lock time, adjust the LOCKTIME register */
writel(0xFFFFFF, &clk_power->locktime);
/* configure MPLL */
writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
&clk_power->mpllcon);
/* some delay between MPLL and UPLL */
pll_delay(4000);
#endif
还有之前初始化了LED用于调试,此处又对GPIO进行了初始化,去掉其中对gpfcon的操作
//writel(0x000055AA, &gpio->gpfcon);
6. 初始化串口
串口的初始化在序列init_sequence_r中的initr_serial中
在函数注册到终端后,在函数_serial_setbrg()中调用了get_PCLK(),
而get_PCLK()又调用了get_HCLK(),里面用到了CONFIG_S3C2440的宏。
因此修改include\configs\smdk2440.h
将
#define CONFIG_S3C2410
改为
#define CONFIG_S3C2440
7. 保存后重新编译
8. 验证结果
使用oflash将开发板自带的uboot烧录到Nor flash, 然后再用uboot烧录编译后的新uboot
因为重新编译后的uboot空间超出了之前的分区,因此使用以下命令烧录
q退出当前菜单
usb 1 30000000进入USB dnw接收状态
使用USB发送新的uboot二进制文件
protect off all
erase 0 7ffff
cp.b 30000000 0 80000
重启开发板之后就可以看到串口有输出了。
本文详细介绍了在JZ2440平台上移植uboot 2016.11的过程中,如何通过LED调试代码、设置时钟、修改内存控制器寄存器、初始化串口,并最终验证串口输出正常的过程。
2904

被折叠的 条评论
为什么被折叠?



