本次移植目标是将u-boot-2010.09移植到FL2440上,并在SDRAM中运行,结果是关闭蜂鸣器,打开板子上的四个LED,把控制台名称改为ZHW_FL2440#
搭建移植框架
1.下载u-boot-2010.09.tar.bz2
地址:http://download.csdn.net/detail/u013752202/9458077
2.解压并进入解压后的目录,修改boards.cfg,增加对fl2440开发板的支持。
3.在board目录下新建一个fl2440目录,并把board/samsung/smdk2410/目录下的所有文件都拷贝到新建的fl2440目录下面。
4.修改fl2440目录下的Makefile,把smdk2410.o 改成fl2440.o
5.把include/configs/smdk2410.h复制一份为include/configs/fl2440.h
cp include/configs/smdk2410.hinclude/configs/fl2440.h
6.编译
上面的步骤以smdk2410为模板,搭建了移植u-boot到fl2440开发板的软件框架。现在编译看是否能够编译成功。执行下面的命令:
如果出现类似uses hardware FP, whereasu-boot uses software FP这样的报错,那么说明当前交叉编译器支持的是硬浮点运算,应换成支持软浮点运算的编译器重新编译。
经过测试,cross-3.4.1.tar.bz2编译报错,arm-linux-gcc-4.4.3.tar.gz和arm-linux-gcc-4.5.1.tar.gz编译通过。其中u-boot.bin就是目标文件。
CPU和SDRAM初始化
打开arch/arm/cpu/arm920t/start.S
1.删除AT91RM9200使用的LED代码。
2.修改编译条件支持s3c2440,修改寄存器地址定义,修改 CPU频率初始化设置
添加代码:
# defineCLK_CTL_BASE 0x4C000000
# defineMDIV_405 0x7f<<12
# definePSDIV_405 0x21 /*set s3c2440 MPLL 405MHZ*/
# defineMDIV_200 0xa1<<12
# definePSDIV_200 0x31 /*set s3c2410 MPLL 200MHZ*/
3.修改中断禁止部分
添加代码:
#if defined(CONFIG_S3C2440)
ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
4.修改时钟设置(2440的主频为405MHz),紧接着上面一步,在其后添加代码:
#if defined(CONFIG_S3C2440)
/* FCLK:HCLK:PCLK = 1:4:8 */
/* default FCLK is 405 MHz ! */
ldr r0, =CLKDIVN
mov r1, #5
str r1, [r0]
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000 //asynchronous
mcr p15, 0, r1, c1, c0, 0
mov r1, #CLK_CTL_BASE
mov r2, #MDIV_405
add r2, r2, #PSDIV_405
str r2, [r1, #0x04] //MPLLCON
#else
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000 //asynchronous
mcr p15, 0, r1, c1, c0, 0
/* cpu clock is 200MHZ*/
mov r1, #CLK_CTL_BASE
mov r2, #MDIV_200
add r2, r2, #PSDIV_200
str r2, [r1, #0x04] //MPLLCON
#else
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000 //asynchronous
mcr p15, 0, r1, c1, c0, 0
/* cpu clock is 200MHZ*/
mov r1, #CLK_CTL_BASE
mov r2, #MDIV_200
add r2, r2, #PSDIV_200
str r2, [r1, #0x04] //MPLLCON
#endif
5.修改SDRAM的REFRESH刷新周期,修改board/fl2440/lowlevel_init.S文件
找到下面四个宏,并修改:
6.修改S3C2440在C语言中要使用的寄存器,把include/asm/arch-s3c24x0/s3c24x0.h中的#ifdef CONFIG_S3C2410全部改为#if defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440),(81、91、95、106、144、400行)。在154行附近添加S3C2440的NAND FLASH 寄存器定义和CAMDIVN定义。
/* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) */
/* (see S3C2410 manual chapter 7) */
struct s3c24x0_clock_power {
u32 LOCKTIME;
u32 MPLLCON;
u32 UPLLCON;
u32 CLKCON;
u32 CLKSLOW;
u32 CLKDIVN;
#if defined (CONFIG_S3C2440)
u32 CAMDIVN;
#endif
};
#if defined(CONFIG_S3C2410)
/* NAND FLASH (see S3C2410 manual chapter 6) */
struct s3c2410_nand {
u32 NFCONF;
u32 NFCMD;
u32 NFADDR;
u32 NFDATA;
u32 NFSTAT;
u32 NFECC;
};
#endif
#if defined(CONFIG_S3C2440)
/* NAND FLASH (see S3C2440 manual chapter 6) */
struct s3c2410_nand {
u32 NFCONF;
u32 NFCONT;
u32 NFCMD;
u32 NFADDR;
u32 NFDATA;
u32 NFMECCD0;
u32 NFMECCD1;
u32 NFSECCD;
u32 NFSTAT;
u32 NFESTAT0;
u32 NFESTAT1;
u32 NFMECC0;
u32 NFMECC1;
u32 NFSECC;
u32 NFSBLK;
u32 NFEBLK;
};
#endif
7
.修改
include/asm/arch/s3c24x0_cpu.h
第
23
行
#if defined(CONFIG_S3C2400)
#include <s3c2400.h>
#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
#include <s3c2410.h>
8
.在
arch/arm/cpu/arm920t/s3c24x0/timer.c
的
184
行添加
defined(CONFIG_VCMA9) || \
defined(CONFIG_FL2440)
9.修改arch/arm/cpu/arm920t/s3c24x0/speed.c
由于S3C2410和S3C2440的MPLL、UPLL计算公式不一样,所以get_PLLCLK函数需要修改,在66行添加。
#if defined(CONFIG_S3C2440)
if(pllreg == MPLL)
return (CONFIG_SYS_CLK_FREQ * m * 2) / (p << s);
else if(pllreg == UPLL)
#endif
return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
由于S3C2410和S3C2440的设置方法也不一样,所以get_HCLK函数也需要修改。
ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
#if defined(CONFIG_S3C2440)
if (readl(&clk_power->CLKDIVN) & 0x6)
{
if ((readl(&clk_power->CLKDIVN) & 0x6)==2) return(get_FCLK()/2);
if ((readl(&clk_power->CLKDIVN) & 0x6)==6) return((readl(&clk_power->CAMDIVN) & 0x100) ? get_FCLK()/6 : get_FCLK()/3);
if ((readl(&clk_power->CLKDIVN) & 0x6)==4) return((readl(&clk_power->CAMDIVN) & 0x200) ? get_FCLK()/8 : get_FCLK()/4);
return(get_FCLK());
}
else return(get_FCLK());
#else
return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
#endif
}
10.修改drivers/i2c/s3c24x0_i2c.c,其原来的位置/cpu/arm920t/s3c24x0/i2c.c,在第60、79、131、140、166行:
将
“#ifdef CONFIG_S3C2410”
改为
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
11.修改common/serial.c,在第71行
将
#elif defined(CONFIG_S3C2410)
改为
#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
把160行改为
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
修改include/serial.h在49行添加
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
12.修改include/configs/fl2440.h文件中第38行,39行。
把
#define CONFIG_S3C2410 1 /* specifically a SAMSUNG S3C2410 SoC */
#define CONFIG_SMDK24101 /* on a SAMSUNG SMDK2410 Board */
改为
#define CONFIG_S3C2440 1 /* specifically a SAMSUNG S3C2440 SoC */
#define CONFIG_FL2440 1 /* on a SAMSUNG FL2440Board */13.打开全部LED,关闭蜂鸣器。
在board/fl2440/fl2440.c的int board_init (void)函数中添加代码:
gpio->GPBUP=0x7FF;
gpio->GPBCON=0x1117FD;
gpio->GPBDAT=0X0;
14.修改u-boot打印输出的终端名称。
在include/configs/fl2440.h修改宏定义CONFIG_SYS_PROMPT为"ZHW_FL2440 #",这样uboot运行的时候,控制台名称显示为ZHW_FL2440 #
编译并下载到SDRAM进行测试
s3c2440A片上有4K的RAM是不需要进行初始化的,上电后程序最先执行者4K的RAM里面的程序,如果程序的二进制文件小于4K那么可以直接烧写到RAM中运行,但是u-boot编译生产的u-boot.bin有400多K,所以只能放到外部的SDRAM中。SDRAM是要先初始化才能访问的,所以我们要先再前4K的RAM中烧写一段SDRAM的初始化程序(2440Init.bin)并运行,然后再把pc指针的值指向SDRAM的入口地址(0x33f80000),再运行就是u-boot程序了。
由于SDRAM的初始化是靠前4K RAM的单独代码完成的,所以u-boot中不需要再进行初始化,
在include/configs/fl2440.h文件中添加:
#define CONFIG_SKIP_LOWLEVEL_INIT 1
重新make。
u-boot.bin烧写到内存运行的具体的操作方式是:
打开J-link Commander,依次执行下面命令:
speed 12000
loadbin d:\share\2440Init.bin 0x40000000
h
setpc 0x40000000
g
loadbin d:\share\u-boot.bin 0x33f80000
h
setpc 0x33f80000
g
这是SDRAM程序为二进制文件的时候,如果是用飞凌提供的2440Init.axf。那么步骤稍有区别
要先打开AXD把2440Init.axf烧进去,点击运行,然后再打开J-link Commander,依次执行下面命令:
speed 12000
loadbin d:\share\u-boot.bin 0x33f80000
h
setpc 0x33f80000
g
如果需要将u-boot.bin烧进Nand flash中运行,则上面跳过SDRAM的宏要去掉,再修改相关文件编译一个Nand flash版本的u-boot.bin,然后按照上面的步骤先把RAM版本的u-boot.bin在RAM中运行起来,然后再通过烧写Nand flash的命令吧新的u-boot.bin烧写到Nand flash中。
执行结果如下: