本节中实现的目标是代码在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
重启开发板之后就可以看到串口有输出了。