Chinaunix首页 | 论坛 | 博客
  • 博客访问: 35105
  • 博文数量: 9
  • 博客积分: 128
  • 博客等级: 入伍新兵
  • 技术积分: 142
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-21 11:28
文章分类
文章存档

2015年(3)

2012年(6)

我的朋友

分类: 嵌入式

2012-03-25 15:05:35

记录一下我的移植过程,参考了韦东山的书,他的书真的写得很好。
在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移植的第一步。
**********************************************************************/





阅读(2399) | 评论(1) | 转发(3) |
给主人留下些什么吧!~~

farewellbuaa2012-03-26 20:50:16

夏冰软件: 博主写的不错,支持一下.....
多谢支持啦