遇顺境,处之淡然;遇逆境,处之泰然
分类: LINUX
2012-03-10 19:34:30
u-boot-2010.06在mini2440上的移植(一)---建立mini2440工程环境
移植环境
1,主机环境:VMware7.1.4 + Ubuntu10.04
2,编译环境:arm-linux-gcc v4.3.2
3,开发板:mini2440,2M nor flash,256M nand flash,DM9000网卡。
4,u-boot版本:u-boot-2010.06
注:修改或添加的地方都用红色表示
移植步骤
(一)到U-boot的官方FTP下载u-boot的源码
(二)到工作目录(/home/jason/working)下解压u-boot-2010.06.tar.bz2
$ tar jxvf u-boot-2010.06.tar.bz2
(三)进入u-boot的根目录,并修改Makefile
$ cd u-boot-2010.06/
$ gedit Makefile
(1) 搜索CROSS_COMPILE,修改交叉编译工具链
159 CROSS_COMPILE ?= arm-linux-
(2)搜索smdk2410,并仿照它建立自己开发板的配置选项
mini2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 jason s3c24x0
然后保存。
*说明:
arm :CPU的架构(ARCH)
arm920t:CPU的类型
mini2440 :对应在board目录下建立新的开发板项目的目录
jason:新开发板项目目录的上级目录,如直接在board下建立新的开发板项目的目录,则这里就为NULL
s3c24x0:CPU型号
*注意:编译选项格式的第二行要用Tab键开始,否则编译会出错。
(四)建立mini2440开发板的板子目录文件
(1)复制smdk2410的板子目录文件为mini2440
$ mkdir -p board/jason
$ cd board/jason/
$ cp -rf ../samsung/smdk2410/ mini2440
(2)重命名smdk2410.c为mini2440.c
$ mv smdk2410.c mini2440.c
(3)修改对应的Makefile文件
COBJS := mini2440.o flash.o
SOBJS := lowlevel_init.o
(五)在根目录下定位到include/configs,建立mini2440开发板的配置头文件
将smdk2410.h复制并粘贴到当前目录下,将其重命名成mini2440.h
$ cp include/configs/smdk2410.h include/configs/mini2440.h
(六)修改开发板终端中命令行提示符
用gedit打开include/configs/mini2440.h头文件,定位到117行,其中的 "SMDK2410 # " 就是开发板在终端中显示的提示符,现在将其改为 "[u-boot@MINI2440]# " ,如下所示
#define CONFIG_SYS_PROMPT "[u-boot@MINI2440] # " /* Monitor Command Prompt */
(七)注释掉不需要的LED代码
(1)$ gedit arch/arm/cpu/arm920t/start.S
//这两行是AT91RM9200DK开发板的LED初始化,注释掉
// bl coloured_LED_init
// bl red_LED_on
(2)$ gedit arch/arm/lib/board.c
删除不需要的指示进度LED功能
#if 0
/************************************************************************
* Coloured LED functionality
…………………………
void blue_LED_off(void) __attribute__((weak, alias("__blue_LED_off")));
#endif
(八)在include/configs/mini2440.h头文件中添加宏定义
#define CONFIG_S3C2440 1 /* specifically a SAMSUNG S3C2440 SoC */
#define CONFIG_MINI2440 1 /* FriendlyARM Mini2440 */
(九)修改lowlevel_init.S 文件
$ gedit board/jason/mini2440/lowlevel_init.S
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
#if defined(CONFIG_S3C2440)
#define Trp 0x2 /* 4clk */
#define REFCNT 1012
#else
#define Trp 0x0 /* 2clk */
#define REFCNT 1113
#endif
修改lowlevel_init.S的一个小bug,使得无法使用J-Link下载到内存直接运行
ldr r0, =SMRDATA
//ldr r1, _TEXT_BASE
ldr r1, =lowlevel_init
sub r0, r0, r1
adr r3, lowlevel_init /* r3 <- current position of code */
add r0, r0, r3
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
(十)增加对S3C2440一些寄存器的支持,添加中断禁止部分和时钟设置部分
(1) $ gedit arch/arm/cpu/arm920t/start.S
#ifdef CONFIG_S3C24X0
/* turn off the watchdog */
…………..
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
# if defined(CONFIG_S3C2440) //添加s3c2440的中断禁止部分
ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK寄存器有15位可用
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
# if defined(CONFIG_S3C2440) //添加s3c2440的时钟部分
#define MPLLCON 0x4C000004 //系统主频配置寄存器基地址
#define UPLLCON 0x4C000008 //USB时钟频率配置寄存器基地址
ldr r0, =CLKDIVN //设置分频系数FCLK:HCLK:PCLK = 1:4:8
mov r1, #5
str r1, [r0]
ldr r0, =MPLLCON //设置系统主频为405MHz
ldr r1, =0x7F021 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分
str r1, [r0]
ldr r0, =UPLLCON //设置USB时钟频率为48MHz
ldr r1, =0x38022 //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分
str r1, [r0]
# else //其他开发板的时钟部分,这里就不用管了,我们现在是做2440的
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
#endif /* CONFIG_S3C24X0 */
(2) $ gedit board/jason/mini2440/mini2440.c
#define FCLK_SPEED 2 //设置默认等于2,即下面红色代码部分有效
#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV 0xC3
#define M_PDIV 0x4
#define M_SDIV 0x1
#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
#define M_MDIV 0xA1
#define M_PDIV 0x3
#define M_SDIV 0x1
#elif FCLK_SPEED==2 /* Fout = 405MHz */
#define M_MDIV 0x7F //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
#define USB_CLOCK 2 //设置默认等于2,即下面红色代码部分有效
#if USB_CLOCK==0
#define U_M_MDIV 0xA1
#define U_M_PDIV 0x3
#define U_M_SDIV 0x1
#elif USB_CLOCK==1
#define U_M_MDIV 0x48
#define U_M_PDIV 0x3
#define U_M_SDIV 0x2
#elif USB_CLOCK==2 /* Fout = 48MHz */
#define U_M_MDIV 0x38 //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2
#endif
(3) $ gedit arch/arm/cpu/arm920t/s3c24x0/speed.c //根据设置的分频系数FCLK:HCLK:PCLK = 1:4:8修改获取时钟频率的函数
static ulong get_PLLCLK(int pllreg)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
……………………..
s = r & 0x3;
#if defined(CONFIG_S3C2440)
if(pllreg == MPLL)
{ //参考S3C2440芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2s)
return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));
}
#endif
return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
}
/* return HCLK frequency */
ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
#if defined(CONFIG_S3C2440)
return(get_FCLK()/4);
#endif
return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
}
(十一) 借用S3C2410的代码
(1)修改s3c24x0_cpu.h
$ gedit arch/arm/include/asm/arch-s3c24x0/s3c24x0_cpu.h
#elif defined CONFIG_S3C2410 || defined CONFIG_S3C2440
#include
(2)修改s3c24x0.h
$ gedit arch/arm/include/asm/arch-s3c24x0/s3c24x0.h
分别定位到81、91、95、106、144、400行,将“#ifdef CONFIG_S3C2410”改为
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
然后在下面结构中加入2440 的NAND FLASH 的数据结构成员CAMDIVN定义
struct s3c24x0_clock_power {
u32 LOCKTIME;
u32 MPLLCON;
u32 UPLLCON;
u32 CLKCON;
u32 CLKSLOW;
u32 CLKDIVN;
#if defined (CONFIG_S3C2440)
u32 CAMDIVN; //for mini2440
#endif
};
这个结构是用来封装时钟寄存器的,我们要在其中增加一项CAMDIVN寄存器是2410所没有的,而2440在配置时钟的时候又必须用到,看名字我们就知道是用来配置CAMERA时钟的,也就是配置摄像头的时钟的。
(3)修改timer.c
$ gedit arch/arm/cpu/arm920t/s3c24x0/timer.c
#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
tbclk = timer_load_val * 100;
#elif defined(CONFIG_SBC2410X) || \
defined(CONFIG_SMDK2410) || \
defined(CONFIG_MINI2440) || \
defined(CONFIG_VCMA9)
tbclk = CONFIG_SYS_HZ;
#else
(十二) 现在编译u-boot,在根目录下会生成一个u-boot.bin文件。然后我们利用mini2440原有的supervivi把u-boot.bin下载到RAM中运行测试(注意:我们使用supervivi进行下载时已经对CPU、RAM进行了初始化,所以我们在u-boot中要屏蔽掉对CPU、RAM的初始化),如下
用gedit打开cpu/arm920t/start.S,定位到如下代码
//#ifndef CONFIG_SKIP_LOWLEVEL_INIT
// bl cpu_init_crit
//#endif
(十三) 测试编译能否成功
回到U-Boot主目录
$ make distclean
$ make mini2440_config
Configuring for mini2440 board...
$ make
(十四) 从运行结果图看