Uboot移植记录
2011-9-14 V0.0.0
2012-1-2 V0.0.1
Tq2440开发板(S3C2440)
CentOs5.4开发环境
交叉编译工具4.3.3 天嵌科技提供
| 与硬件相关的寄存器 | ||
| 电源&时钟 | ||
| usart | ||
| 网卡驱动 | ||
| nand flash驱动 | ||
| usb等其他驱动 |
2.1 uboot的使用
2.2 S3C2440电源和时钟
Uboot 中默认的时钟设置时S3C2410,需要将其注释掉,并加入S3C2440的时钟设置。首先,简单了解一下S3C2440的时钟
Fin = 12.000000MHz<<输入时钟12M
FCLK = MPLL = MCLKCON *
Fin<<FCLK为“主时钟”,通过MPLL倍频而来。见图1: 
图1
其他时钟HCLK、PCLK通过分频器HDIVN和PDIVN而来。另外UCLK的时钟源同样为Fin,通过UPLLCON倍频到UCLK。MPLL的计算公式如下(UPLL也是类似的):
MPLL=(2\*m\*FIN)/(p\*2^s) where m=(MDIV+8), p=(PDIV+2), s="SDIV"
MPLLCON = ((0x5c<<12)|(0x01<<4)|(0x01))
MDIV PDIV SDIV
=>FCLK = 2\*(5c+8)\*12M/((1+2)\*2^1) = 400M
最后,配置FCLK:HCLK:PCLK = 1:4:8,
CLKDIVN = 0x5(0101b)。具体的bit如下图2 
图2
至于系统时钟为什么要配置为400,以及1:4:8的关系,暂时没有深究。根据uboot的注释,可能与所使用的SDRAM刷新频率有关系。
2.3 两个重要的时钟函数
在cpu920t3c24x0.c
2.3.1 get_HCLK()
根据图2的描述,HCLK的配置与CAMDIVN这个寄存器也(因为前面的CLKDIVN配置了1:4:8的关系,所以这里说“也”)有关,而在uboot的源码中没有提供这个寄存器,首先查看这个寄存器的地址,手动增加上去。它的地址为0x4C000018,
实际上,get_HCLK函数的原理是根据读取CAMDIVN和CLKDIVN里面的配置,再根据前面设置的FCLK来计算出HCLK的频率,下面的PCLK也是同样的原理。
2.3.2 get_PCLK()
请参考2.3.1最后一句话。
3.1 一些简单的设置
删除arch/下除arm以外的其他文件
$ rm -rf ls ./ | grep -v arm
删除arch/arm/cpu下除920t以外的其他文件
$ rm -rf ls ./ | grep -v 920t
删除board/除samsung外的文件
rm -rf ls ./ | grep -v samsung
删除board/samsung除smdk2410的文件。
rm -rf ls ./ | grep -v smdk2410
设置交叉编译(我用的是4.3.3),然后编译一下试试。
make smdk2410_config
make all
一切顺利的话会在当前目录下生成u-boot.bin。
3.2 修改时钟
arch/arm/cpu/arm920t/start.S,大约173行,修改原来的系统时钟配置:
/\*code modified by hooao 2012-01-04\*/
/\* FCLK:HCLK:PCLK = 1:4:8 \*/
/\* FCLK is 400 MHz ! \*/
ldr r0, =CLKDIVN
mov r1, #0x5
str r1, [r0]
/\* set MPLLCON\*/
ldr r0, =LOCKTIME
mov r1, #0xFFFFFF /\* Set LOCKTIME first \*/
str r1, [r0]
ldr r0, =UPLLCON /\* Set to 48MHz \*/
ldr r1, =0x38022 /\* ((0x38<<12)|(0x02<<4)|(0x02)) \*/
str r1, [r0]
delay\_fun:
ldr r3, =0xFF
sub r3, r3, #0x1
cmp r3,#0
beq delay\_fun /\* at least 7 nop between MPLL and UPLL \*/
ldr r0, =MPLLCON
ldr r1, =0x5C011 /\* (0x5c<<12)|(0x1<<4)|(0x1) \*/
str r1, [r0]
delay\_fun1:
ldr r3, =0xFF
sub r3, r3, #0x1
cmp r3,#0
beq delay\_fun1 /\* Some delay \*/
/\* set CAMDIVN bit[9]=0 then HCLK = FCLK/4 \*/
/\* Reset val is 0x00000000,so no need to modify it \*/
/\* code modify end \*/
3.3 修改两个函数
arch/arm/cpu/arm920t/s3c24x0/speed.c
可以看到这个版本已经支持S3C2440的时钟设置,因此只需要加入一个宏定义即可。(通过对CONFIG_S3C2440全局设置发现,会出现一些变量的重定义,因此此处只对get_HCLK函数释放CONFIG_S3C2440)
#define CONFIG\_S3C2440 /\* support s3c2440 archtecture \*/
/\* return HCLK frequency \*/
ulong get\_HCLK(void)
{
struct s3c24x0\_clock\_power \*clk\_power = s3c24x0\_get\_base\_clock\_power();
#ifdef CONFIG\_S3C2440
return get\_FCLK()/2;
#else
return (readl(&clk\_power->clkdivn) & 2) ? get\_FCLK() / 2 : get\_FCLK();
#endif
}
#undef CONFIG\_S3C2440
#undef CONFIG\_S3C2440
另外一个get_PCLK()可以不去动它。
3.4 一点修改
暂时注释掉nand部分的初始化。
board_init_r()里面对nand的操作注释掉。大约在475~508行。驱动部分暂时没时间去做,哪位有兴趣移植驱动(主要是nand & 网络)部分的可以向我索要word版(email:[email protected])。当然,是为了补充下这个文档。
3.5 试验
nm.w 0x56000014
56000014: 0600 ? 620 (led熄灭)
56000014: 0620 ? 600 (led点亮)
参考资料
U-boot-2011-06-rc3工作流程:
http://blog.chinaunix.net/space.php?uid=1718717&do=blog&id=599559