在u-boot-1.1.6根目录下Makefile,根据smdk2410修改。增加mini2440项。
mini2440_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x0
NULL指的是Vendor,也就是制造商,这里增NULL就可以直接在board下面加mini2440的目录了。
cp -r /board/smdk2410 /board/mini2440
cp /include/configs/smdk2410.h /include/configs/mini2440.h
记得将mini2440下的Makefile和smdk2410.c修改成mini2440的。
这个时候你就可以使用make mini2440_config来配置了。
接着改一下mini2440.h配置文件吧。
#define CONFIG_S3C2440 1
#define CONFIG_MINI2440 1
记得把提示符也改一下哦。免得出现SMDK2410 #多不爽。
开始修改吧。
/cpu/arm920t/start.S
在系统重启后,2440会从0地址开始执行程序。这个就是放u-boot的地方了。
现在还不太会,所以只好借用一下jtag将u-boot直接烧写到BANK 0的NOR FLASH里了。
我使用的是Hjtag,注意一下,从mini2440官网下载配置文件哦!
重启之后,cpu进入SVC32模式,这些都是2440芯片手册没有提过的,你应该看ARM920T的手册。
里面内容蛮多的。这是我要努力的方向。
/*******************************************************************************
cpu/arm920t/start.S
关看门狗,这里2440和2410寄存器是一样的,借用一下了。
elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
这里就定义了WTCON INTMSK INTSUBMSK CLKDIVN
我想在系统上电时就将时钟频率FCLK调到405MHz这是三星推荐的值。分频调成1:4:8。
将cpu调成异步模式,这样arm920t核心就会运动在405MHz下了,不然运行在HCLK下。
重新加入2440的代码。
#if defined(CONFIG_S3C2440)
关闭看门狗
ldr r0,=pWTCON
mov r1,#0x0
str r1,[r0]
屏蔽2440的所有中断
mov r1,#0xffffffff
ldr r0,=INTMSK
str r1,[r0]
ldr r1,=0x7fff
ldr r0,=INTSUBMSK
str r1,[r0]
这个是设置时钟了因为没有使用USB功能,UPLLCON就不设置了。
#define MPLLCON 0x4C000004
#define MDIV_405 0x7f<<12
#define PSDIV_405 0x21
将分频调成1:4:8,HCLK还和CAMDIVN有关,看看2440手册,重启时CAMDIVN的值。
ldr r0,=CLKDIVN
mov r1,#5
str r1,[r0]
这里将arm920t调成异步模式。
mrc p15,0,r1,c1,c0,0
orr r1,r1,#0xC0000000
mcr p15,0,r1,c1,c0,0
这个是有技巧的,直接mov r1,#7f021会出错,这和arm指令相关
ldr r0,=MPLLCON
mov r1,#MDIV_405
add r1,r1,#PSDIV_405
str r1,[r0]
#endif /* defined(CONFIG_S3C2440) */
***************************************************************************/
/***************************************************************************
/board/mini2440/lowlevel_init.S
在start.S里,要调用lowlevel_init.S,在这时将与开发板相关的BWSCON设置好。
这里最重要的是设置好SDRAM所在的BANK6设置好。然后就可以使用SDRAM了。
也就是REFRESH寄存器里[10:0]位Refresh counter值
Refresh count = 2^11+1-100*7.8125=1267.75
这里的100是HCLK的值100MHz,7.8125uS是mini2440板上的内存刷新频率。
因此修改如下
#define REFCNT 1268
这个时候u-boot就可以顺便将自己移动到0x33F80000了,所謂的TEXT_BASE
**********************************************************************/
/**********************************************************************
程序会跳入lib_arm/board.c继续执行。
在这里有一个init_fnc_t *init_sequence[],这个结构很难看懂,好像是函数指针数组吧。
然后就可以一个一个地进行初始化了。
**********************************************************************/
/**********************************************************************
/board/mini2440/mini2440.c
第二个初始化函数就在这里了,board_init这个与开发板相关的。
痛快地将与时钟MPLLCON和UPLLCON删掉吧,因为在start.S里已经设置好了。
对了这里有个
#include
将它改成2440吧,将include里的s3c2410.h复制一份到s3c2440.h
这里我还没有改GPIO设置,等用到时候再来改吧。
gd->bd->bi_arch_number
这个还是借用一个这个值吧,和将来要移植的linux有关,linux现在已经支持
mini2440了,应该也分配了这个号吧。
gd->bd->bi_params
放置了启动linux内核参数的地址。
**********************************************************************/
/**********************************************************************
/cpu/arm920t/s3c24x0/serial.c
串口是开发中的很重要的环节,2410和2440在UART这个功能模块上没什么区别
但是UART是要用时钟的,2440主频比2410主频要高。
这里serial_init调用了serial_setbrg
这个函数会通过get_PCLK来得到PCLK值,这个值对设置波特率很重要。
**********************************************************************/
/**********************************************************************
cpu/arm920t/s3c24x0/speed.c
2440和2410的主频计算方式不一样
所以在get_PLLCLK里修改
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
#elif defined(CONFIG_S3C2440)
return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
#endif
为了保持修改后的代码还能让其它开发板使用,这样改了。
最主要的是修改get_HCLK这里体现了2440和2410不一样的地方。
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
ulong get_HCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
}
#elif defined(CONFIG_S3C2440)
ulong get_HCLK(void)
{
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
unsigned long clkdiv;
unsigned long camdiv;
int hdiv=1;
clkdiv=clk_power->CLKDIVN;
camdiv=clk_power->CAMDIVN;
switch(clkdiv & S3C2440_CLKDIVN_HDIVN_MASK){
case S3C2440_CLKDIVN_HDIVN_1:
hdiv=1;
break;
case S3C2440_CLKDIVN_HDIVN_2:
hdiv=2;
break;
case S3C2440_CLKDIVN_HDIVN_4_8:
hdiv=(camdiv&S3C2440_CAMDIVN_HCLK4_HALF)?8:4;
break;
case S3C2440_CLKDIVN_HDIVN_3_6:
hdiv=(camdiv&S3C2440_CAMDIVN_HCLK3_HALF)?6:3;
break;
default:
break;
}
return get_FCLK()/hdiv;
}
#endif
这里就用到了CAMDIVN,上面的代码完全复制了韦东山的代码,这应该是用于个人用途吧。
参考一下2440的芯片手册,就可以懂这个switch,case在找分频比hdiv。
get_PCLK不用修改,这个是和2410一样的。
**********************************************************************/
/**********************************************************************
串口搞定之后你就可以编译了,在编译中查找错误吧,因为你用了CONFIG_S3C2440
很多文件都要这个定义,把CONFIG_S3C2410的相关的改一下。
make mini2440_config
make all
他说S3C24X0_GPIO这个数据结构有问题,没有成员
原来在S3C24X0.h里没有定义2440的。看着2440芯片手册改吧。
rtc/s3c24x0_rtc.c
cpu/arm920t/s3c24x0/interrupts.c
注意get_tbclk出错 加上defined(CONFIG_MINI2440)
cpu/arm920t/s3c24x0/serial.c
cpu/arm920t/s3c24x0/speed.c
提示找不到CAMDIVN,在include/s3c24x0.h里加。
如果你没有错了,说明你走出了U-boot移植的第一步。
**********************************************************************/