21、Bootloader(5)---Uboot的移植

一、移植准备

1. U-Boot源码下载地址

  http://sourceforge.net/project/u-boot

  ftp://ftp.denx.de/pub/u-boot/

U-BOOT邮件列表下载:

  http://lists.sourceforge.net/lists/listinfo/u-boot-users/

DENX相关的网站:

  http://www.denx.de/re/DPLG.html

2. 源码文件的删除

二、U-Boot移植过程

1. 修改Makefile文件

   依照1897和1880,增加1882和1883两行,如下图所示:

    arm:表示现在用的CPU的架构就是ARM体系结构

    arm920t:指这是CPU的内核类型,它对应于cpu/arm920t

    smdk2410:这是开发板的型号,它的目录在board/smdk2410目录下,在这

              里可以命名自己的开发板,如我的是lwj2440

    s3c24x0:表示开发板上的CPU是啥

2. 建立自己的开发板

(1)进入源码u-boot-1.1.6目录下,将board/smdk2410目录复制为lwj2440

      cp -rf board/smdk2410  board/lwj2440

(2)修改board/lwj2440目录下的smdk2410.c为lwj2440.c

   mv  board/lwj2440/smdk2410.c   board/lwj2440/lwj2440.c

3. 建立自己的配置文件

在include/configs目录下建立一个配置文件lwj2440.h,将include/configs/smdk2410.h直接复制为lwj2440.h

      cp include/configs/smdk2410.h  include/configs/lwj2440.h

4. 修改Makefile

    修改board/lwj2440/Makefile,把原来的28行改为第29行的内容

  

5. 修改交叉编译工具的路径

在顶层Makefile中原始内容如下:

  

   当不修改时,此时用默认的交叉编译工具,我的是EABI4.4.3

  当想换其它交叉编译工具时,修改第128行,比如我想用3.4.5的,修改如下:

   

6. 编译并测试

   进入u-boot-1.1.6目录

   # make distclean

   # make lwj2440_config

   # make all

   如果没有错误,则会生成u-boot.bin文件、U-Boot文件、U-Boot.srec文件

   u-boot.bin:二进制可执行文件,可以直接烧入ROM、NOR FLASH的文件

   U-Boot:ELF格式的可执行文件

   U-Boot.srec:Motorola S-Record格式的可执行文件

  

   如果想编译时产生u-boot的反汇编代码,在顶层Makefile中查找u-boot.bin那一行:

 

修改如下所示:

   即在原来代码上添加了 $(obj)u-boot.dis

 

三、增加对S3C2440的支持

1.修改SDRAM配置

   SDRAM的初始化在U-Boot的第一阶段完成,就是在board/lwj2440/lowlevel_init.S文件中设置存储控制器

   进入board/lwj2440/lowlevel_init.S,修改54和58行,如下所示:

  

     再次进行修改第126行:

            #define REFCNT  1113 

                        /*period=15.6us,HCLK=60Mhz,(2048+1-15.6*60)*/

     改为如下所示:

            #define REFCNT 0x4f4 

                  /*period=7.8125us,HCLK=100Mhz,(2048+1-7.8125*100)*/

2.修改时钟配置

   对于S3C2440开发板,将FCLK设为400Mhz,分频率比为FCLK:HCLK:PCLK=1:4:8,而且将UPLL设为48Mhz,即UCLK为48Mhz

(1) 首先屏蔽掉原来S3C2410的时钟设置,修改cpu/arm920t目录下的start.S文件,大概148,其修改如下所示:

                                   

(2) 然后重新配置时钟,修改board/lwj2440/lwj2440.c文件中的board_init函数(68行),同时在第33行增加一些声明,如下所示修改:

   添加的声明:

上图针对S3C2410、S3C2440分别定义了MPLL、UPLL寄存器的值,开发板输入时钟为12MHZ(在include/configs/lwj2440.h中的宏CONFIG_SYS_CLK_FREQ中定义)

 

board_init函数的修改如下:                                                                         

 int board_init (void)                                                                          

{                                                                                                

 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();                        

S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();                                           

                                                                                               

/* set up the I/O ports */                                                                 

    gpio->GPACON = 0x007FFFFF;                                                                

    gpio->GPBCON = 0x00044555;                                                               

    gpio->GPBUP = 0x000007FF;                                                              

    gpio->GPCCON = 0xAAAAAAAA;                                                                 

    gpio->GPCUP = 0x0000FFFF;                                                                

    gpio->GPDCON = 0xAAAAAAAA;                                                                       

    gpio->GPDUP = 0x0000FFFF;                                                                            

    gpio->GPECON = 0xAAAAAAAA;                                                                               

    gpio->GPEUP = 0x0000FFFF;                                                                      

    gpio->GPFCON = 0x000055AA;                                                                    

    gpio->GPFUP = 0x000000FF;                                                                  

    gpio->GPGCON = 0xFF95FFBA;                                                                       

    gpio->GPGUP = 0x0000FFFF;                                                                    

    gpio->GPHCON = 0x002AFAAA;                                                                   

    gpio->GPHUP = 0x000007FF;                                                                         

                                                                                             

 /* support both of S3C2410 and S3C2440*/

 if((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))                            

  {                                                                                             

     /* FCLK:HCLK:PCLK = 1:2:4 */                                                               

     clk_power->CLKDIV = S3C2410_CLKDIV;                                                            

                                                                                                    

     /* change for asynchronous bus mod*/                                                                    

     __asm__( "mrc  p15, 0, r1, c1, c0, 0\n"   /* read ctrl register*/                             

              "orr  r1, r1, #0xc0000000\n"     /* Asynchronous */                               

               "mcr  p15, 0, r1, c1, c0, 0\n"   /* write ctrl register*/                             

               :::"r1"                                                                              

             );                                                                                

                                                                                                 

      /* set PLL lock time*/                                                                   

      clk_power->LOCKTIME = 0xFFFFFFFF;                                                           

                                                                                                 

      /* configure MPLL*/                                                                       

      clk_power->MPLLCON = S3C2410_MPLL_200MHZ;                                                

                                                                                                 

      /* some delay between MPLL and UPLL*/                                                       

      delay(4000);                                                                              

                                                                                                        

/*configure UPLL*/                                                                          

      clk_power->UPLLCON = S3C2410_UPLL_48MHZ;                                                   

                                                                                                         

      /* have a delay again */                                                                   

      delay(8000);                                                                                   

                                                                                                        

      /* arch number of SMDK2410-Board */                                                                      

      gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;                                                          

    }                                                                                           

    else                                                                                                        

    {                                                                                                         

       /* FCLK:HCLK:PCLK = 1:4:8 */                                                               

       clk_power->CLKDIV = S3C2440_CLKDIV;                                                                                

                                                                                                       

       /* change for asynchronous bus mod*/                                                            

       __asm__( "mrc  p15, 0, r1, c1, c0, 0\n"   /* read ctrl register*/                               

                "orr  r1, r1, #0xc0000000\n"     /* Asynchronous */                              

                "mcr  p15, 0, r1, c1, c0, 0\n"   /* write ctrl register*/                                    

                 :::"r1"                                                                           

               );                                                                                             

                                                                                              

       /* set PLL lock time*/                                                                  

       clk_power->LOCKTIME = 0xFFFFFFFF;                                                     

                                                                                                

       /* configure MPLL*/                                                                      

       clk_power->MPLLCON = S3C2440_MPLL_400MHZ;                                                  

                                                                                                

       /* some delay between MPLL and UPLL*/                                                          

       delay(4000);                                                                             

                                                                                             

       /*configure UPLL*/                                                                         

       clk_power->UPLLCON = S3C2440_UPLL_48MHZ;                                                 

                                                                                                      

       /* have a delay again */                                                                  

       delay(8000);                                                                            

                                                                                              

       /* arch number of SMDK2410-Board */                                                        

       gd->bd->bi_arch_number = MACH_TYPE_S3C2440;                                                              

                                                                                                                  

     }                                                                                          

                                                                                                

 /* adress of boot parameters */                                                                        

gd->bd->bi_boot_params = 0x30000100;                                                           

                                                                                                    

icache_enable();                                                                             

dcache_enable();                                                                               

                                                                                                                                  

return 0;                                                                                     

}

(3)获取系统时钟的函数需要针对S3C2410、S3C2440的不同进行修改(get_PCLK)

    在后面设置串口波特率时需要获得系统时钟,就是在U-Boot的第二阶段,lib_arm/board.c中start_armboot函数调用serial_init函数初始化串口时,会调用get_PCLK函数 ,在cpu/arm920t/s3c2440/speed.c中定义,与它相关的还有get_HCLK、get_PLLCLK函数

     前面的程序board_init函数在识别出S3C2410或S3C2440后,设置机器ID:gd->bd->bi_arch_number,后面的函数可以通过它来分辨是S3C2410还是S3C2440。

 

cpu/arm920t/s3c2440/speed.c 中修改如下所示:

1) 在第40添加一行,如下所示:

  

   这样才可以使用gd变量

2) 修改get_PLLCLK函数(第54行)

修改原因:S3C2410和S3C2440的MPLL、UPLL计算公式不一样,如下所示:                      

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;                                                                            

                                                                                                        

    /* support both of S3C2410 and S3C2440*/                                                               

    if(gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)                                                   

         return ((CONFIG_SYS_CLK_FREQ * m) / (p << s));                                                        

    else                                                                                          

         return ((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));  /* S3C2440*/                                      

                                                                                                

}   

3)修改get_HCLK、get_PCLK函数(第84行开始)

                                                                                                       

/* for s3c2440*/                                                                               

#define S3C2440_CLKDIVN_PDIVN         (1<<0)                                                       

#define S3C2440_CLKDIVN_HDIVN_MASK    (3<<1)                                                     

#define S3C2440_CLKDIVN_HDIVN_1       (0<<1)                                                    

#define S3C2440_CLKDIVN_HDIVN_2       (1<<1)                                                

#define S3C2440_CLKDIVN_HDIVN_4_8     (2<<1)                                                     

#define S3C2440_CLKDIVN_HDIVN_3_6     (3<<1)                                                       

#define S3C2440_CLKDIVN_UCLK          (1<<3)                                                      

                                                                                                

#define S3C2440_CAMDIVN_CAMCLK_MASK   (0xf<<0)                                                  

#define S3C2440_CAMDIVN_CAMCLK_SEL    (1<<4)                                                    

#define S3C2440_CAMDIVN_HCLK3_HALF    (1<<8)                                                

#define S3C2440_CAMDIVN_HCLK4_HALF    (1<<9)                                                  

#define S3C2440_CAMDIVN_DVSEN         (1<<12)                                                  

                                                                                              

/* return HCLK frequency */                                                                

ulong get_HCLK(void)                                                                               

{                                                                                                

 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();                                           

    unsigned long clkdiv;                                                                                 

    unsigned long camdiv;                                                                      

    int hdiv = 1;                                                                                                    

                                                                                                   

/* support both of S3C2410 and S3C2440*/                                                              

    if(gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)                                                                      

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

get_FCLK());                                                                                                        

    else                                                                                                

    {       clkdiv = clk_power->CLKDIVN;                                                          

            camdiv = clk_power->CAMDIVN;                                                             

                                                                                                                       

            /* caculate clock scalings */                                                        

            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;                                                                     

            }                                                                                                 

                                                                                                          

            return get_FCLK() / hdiv;                                                                  

     }                                                                                                

}                                                                                                

                                                                                           

/* return PCLK frequency */                                                                         

ulong get_PCLK(void)                                                                                     

{                                                                                                           

 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();                     

    unsigned long clkdiv;                                                                     

    unsigned long camdiv;                                                                    

    int hdiv = 1;                                                                            

                                                                                              

    /* support both of S3C2410 and S3C2440*/                                                    

    if(gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)                                                  

           return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 :                                           

get_HCLK());                                                                                                  

    else                                                                                       

    {       clkdiv = clk_power->CLKDIVN;                                                       

            camdiv = clk_power->CAMDIVN;                                                      

                                                                                                   

            /* caculate clock scalings */                                                    

            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;                                                                     

            }                                                                                          

                                                                                                      

       return get_FCLK() /hdiv/((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2:1);                          

     }                                                                                                     

}

(4)在“include/s3c24x0.h”中重新定义S3C24X0_CLOCK_POWER结构体

    在s3c24x0.h中的S3C24X0_CLOCK_POWER结构体中增加如下两行:129和130

    

   到这时,时钟部分基本上做好了,为了方便调试,可以利用开发板自带的UBOOT烧写到内存中运行

(5)便于调试UBOOT的修改

    修改“cpu/arm920t/start.S”文件的第162行:                                                    

                                                       

    修改“boar/lwj2440/config.mk”文件的第25行:                                               

  #TEST_BASE = 0x33F80000                                                                    

   TEST_BASE = 0x33000000   

 

待续。。。。。。。。。。。。。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值