u-boot-2009.08在飞凌OK2440/FL2440上的移植(一)——让u-boot在内存中运行进来

经过十来天的折腾,终于实现了让u-boot-2009.08在OK2440上跑起来,并且移植了内核2.6.35.4,挂接NFS根文件系统成功。

这段时间一直在看网络上的各种相关资料,并重复的编译u-boot,编译内核。有时一个小问题就用上一个上午或者一个下午,最后终于完成了开发板上整个开发环境的搭建,故写此备忘录。


一、移植环境

· 主  机:VMWare--ubuntu12.04 

· 开发板:OK2440--RAM=64MB;nor flash=4M;nand flash=128M;kernel:linux-2.6.35.4.tar.gz;根文件系统:NFS挂接启动

· 编译器:arm-linux-gcc-4.3.2.tgz 

· u-boot:u-boot-2009.08.tar.bz2


二、u-boot移植步骤

1.以SMDK2410为模板,建立好开发板相关的文件,并利用交叉编译器编译生成.bin文件;

2.再修改相关时钟频率使之适应开发板硬件配置,让uboot能在ram中运行调试成功(即串口能打印数据);

3.修改norflash相关配置,使uboot能支持norfalsh的读写,附:uboot默认支持从norflash启动;

4.修改nandflash相关配置,使uboot能支持nandflash的读写;使uboot能从nand flash启动;

5.增加uboot的功能,如网络(此开发板是DM9000A)、USB等(这个功能没实现);

6.修改相应配置,使uboot能引导Linux系统启动;


三、让U-B00T在内存中运行起来

(一)创建板子文件夹

1.进入board/samsung目录,拷贝目录中的smdk2410文件夹放在当前目录下,并重命名为ok2440v3(这是板子配置文件夹);

2.进入ok2440v3,把文件smdk2410.c重命名为ok2440v3.c(uboot启动第二步执行的文件);打开Makefile,修改COBJS:= ok2440v3.o flash.o

(二)创建配置文件

进到include/configs目录下,找到配置文件smdk2410.h,将其拷贝并重命名为ok2440v3.h(uboot相关各种宏定义,关键文件);

(三)创建编译规则

打开顶层Makefile(注意是在根目录下),修改(红色部分):

1.添加编译板配置文件时用到的命令(即make ok2440v3_config ;注意@之前加的是tab,不是空格)

smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0

ok2440v3_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t ok2440v3 samsung s3c24x0

2.设置好交叉编译器路径(本人的交叉编译是放在根目录/4.3.2/bin下,注意安装好交叉编译器后要重启虚拟机使交叉编译器生效)

ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=/4.3.2/bin/arm-linux-
  
endif

(四)首次编译uboot

编译之前打开/include/configs/ok2440v3.h;增加宏定义

 #define CONFIG_SKIP_LOWLEVEL_INIT         1 

之所以增加这条是因为我们是在RAM中运行,不拷贝代码到ram中和不进行底层初始化;接着输入下面三条命令编译(注意返回到顶层目录):  

   1.make distclean //清空之前操作生成的各种文件

   2. make ok2440v3_config //生成配置文件

   3.make //编译.bin文件

若能成功编译出.bin文件,则说明交叉编译器没问题,初步移植也没问题,此时的.bin 文件只是基于smdk2410开发板的,在咱们的开发板是ok2440上不能适用的,所以在此基础上还要对相应的文件进行修改配置,例如要修改ok2440v3.c;ok2440v3.h等文件使其能支持本开发板,以上的步骤是很通用的。                                                                                                                                                        

在板子上运行飞凌制作好的u-boot,选择nor flash 启动方式,运行起来后选择0,通过DNW下载我们刚才生成的u-boot.bin(修改DNW配置,设置下载地 址为0x32000000,其中OK2440的DRAM空间是0x30000000~0x34000000,共64M);此时u-boot已在内存中运行起来了,但此时屏幕上并没有串口打印输出,因为s3c2440的时钟频率和s3c2410的是不一样的,咱们生成的u-boot.bin是基于后者的。接下来要修改时钟的频率让串口正常输出。

(五)让串口能正常输出打印信息

原来,2440与2410的一个重要的区别就是,在相同的外部时钟(12M)的情况下,默认得到的内部时钟FCLK/HCLK/PCLK是不一样的,而这些时钟会影响到口串口的波特率。关于FCLK/HCLK/PCLK,这篇博文写得不错:FCLK/HCLK/PCLK简介

1.u-boot中添加对S3C2440一些寄存器的支持、添加中断禁止部分和时钟设置部分。

打开/include/configs/ok2440v3.h;增加宏定义,如下

#define	CONFIG_S3C2440		1	/* in a SAMSUNG S3C2440 SoC     */
打开 /cpu/arm920t/start.S(增加红色部分)

  • start_code:
    /*
    * set the cpu to SVC32 mode
    */
    mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0xd3
    msr cpsr,r0


     /*bl coloured_LED_init
    bl red_LED_on*/     //这是LED灯初始化将其屏蔽掉,因为我们OK2440V3上的LED资源与SMDK2410开发板的不一致

紧接着上面的语句,增加下面的语句,点亮LED0,在uboot运行时,我们会看到LED0亮

  • #define GPFCON  0x56000050 
 #define GPFDAT  0x56000054 
 #define GPFUP   0x56000058

    ldr    r0,=GPFUP              // 0:enable pull up ; 1:disable pull up 
     ldr    r1,=0xfffff87          //使能上拉F3-6
    str    r1,[r0] 

    ldr    r0,=GPFCON
    ldr    r1,=0xd57f            //将F3-6设为输出口
    str    r1,[r0] 

   ldr    r0,=GPFDAT
    ldr    r1,=0xf3             //点亮LED0 (不同的地方我们可以点亮不同的灯)
    str    r1,[r0] 


找到下面的语句,定位到该位置,修改相应部位,即增加红色部分。

  • #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)  
  •  mov  r1, #0xffffffff
     ldr    r0, =INTMSK
    str r1, [r0]
    # if defined(CONFIG_S3C2440)
    ldr r1, =0x7fff   //这里是屏蔽中断,S3C440用到了15位,所以把值设置成0x7fff
    ldr r0, =INTSUBMSK
    str r1, [r0]
    # endif    

    # if defined(CONFIG_S3C2440)
    #  define MPLLCON        0x4C000004 
    #  define UPLLCON        0x4C000008
            ldr r0, =CLKDIVN
    mov r1, #5                // FCLK:HCLK:PCLK = 1:4:8 
    str r1, [r0]

           ldr   r0, =MPLLCON     //写MPLL使pll生效,405MHz,(127<<12)+(2<<4)+(1)
           ldr   r1, =0x7F021
           str    r1, [r0]
                                
           ldr   r0, =UPLLCON    //USB时钟48MHz       (56<<12)+(2<<4)+(2)
           ldr   r1, =0x038022
           str    r1, [r0]

     # else

       /* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr    r0, =CLKDIVN
        mov    r1, #3     
str    r1, [r0]
     # endif

#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */


/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif


 打开 board/samsung/ok2440v3/ok2440v3.c

 将下面一段去掉

 #define FCLK_SPEED 1

 #ifFCLK_SPEED==0              /* Fout = 203MHz, Fin = 12MHz for Audio */
 #define M_MDIV  0xC3
 #define M_PDIV  0x4
 #define M_SDIV  0x1
 #elifFCLK_SPEED==1            /* Fout = 202.8MHz */
 #define M_MDIV  0xA1
 #define M_PDIV  0x3
 #define M_SDIV  0x1
 #endif
 #define USB_CLOCK 1

 #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
 #endif

用下面一段替换:

#define M_MDIV 0x7f
#define M_PDIV 0x2
#define M_SDIV 0x1

#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2

因为OK2440V3的晶振为12M,在芯片手册可以查到这些值,使得CPU频率为405M,USB时钟频率为48M.

打开cpu/arm920t/s3c24x0/speed.c;修改(根据设置的分频系数FCLK:HCLK:PCLK = 1:4:8修改获取时钟频率的函数):

  • static ulong get_PLLCLK(int pllreg)
    {
        S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
        ulong r, m, p, s;

        if (pllreg == MPLL)
    r = clk_power->MPLLCON;
        else if (pllreg == UPLL)
    r = clk_power->UPLLCON;
        else
    hang();

        m = ((r & 0xFF000) >> 12) + 8;
        p = ((r & 0x003F0) >> 4) + 2;
        s = r & 0x3;

    # if defined(CONFIG_S3C2440)
    if (pllreg == MPLL)
    {
    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)
    {
        S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    # if defined(CONFIG_S3C2440)
    return(get_FCLK()/4);
    # endif

        return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
    }

这样,时钟就设置好了,保存,重新生成u-boot.bin,下载到开发板运行,就可以看到串口打印信息了:


附:注意NDW的下载位置要设置为0x32000000,反正就是不能是0X30000000,我在这卡住了10几个小时。奇怪的是那会我是越挫越勇,没有放弃。

感谢网上的各位大牛,本博文主要参考:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值