zoukankan      html  css  js  c++  java
  • 基于mini2440的uboot移植(一)

    一.移植环境

    虚拟机:ubuntu12.04

    uboot源码:u-boot-2008.10.tar.bz2

    交叉编译:arm-linux-gcc-4.4.3

    简单的记录下编译uboot的过程,要想具体了解uboot的工作原理,可以查看韦东山对uboot这部分的讲解,红色部分为修改部分

    二.移植步骤

    1.将uboot源码复制到ubuntu下的自己定义的文件夹,并解压tar jxvf u-boot-2008.10.tar.bz2

    2.选择要移植的开发板,我们要准备将uboot移植到mini2440上,s3c2440开发板的cpu为arm920t,smdk2410开发板的cpu也为arm920t,所以我们选择smdk2410作为模板进行移植

    3.首先将u-boot-2008.10/board下面的smdk2410 这个文件夹复制成一个自己定义的文件,放在board目录下:

    cp -rf smdk2410 mini2440

    进入mini2440目录,将smdk.c重命名为mini2440.c,与建立的文件夹名字相符

    进入u-boot-2008.10/include/configs目录下,为你的开发板建立一个头文件,以smdk2410.h为模板

    cp  smdk2410.h   mini2440.h

    4. 在顶层Makefile中为开发板添加新的配置选项

    smdk2410_config : unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
    mini2440_config :   unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x0
    
    CROSS_COMPILE = arm-linux-     //指定交叉编译环境

    这部分代码时为mini2440添加配置选项,当我们运行make mini2440_config时,执行的就是这句语句

    在mini2440文件夹中修改目标文件

    COBJS:= mini2440.o flash.o

    到这里我们可以编译我们新建的mini2440开发板了

    make mini2440_config   配置mini2440

    执行这个步骤,打印出

    Configuring for mini2440 board...

    执行make

    在执行的过程中,会报错,具体的错误忘了,当时忘记截图了,如果报错的话,你找到报错的源文件,并将报错的语句全都注释掉,报错的话主要是因为硬件初始化的led与mini2440 然后进行make,编译成功的话会在目录下生成uboot.bin文件。  

     5. 修改u-boot-2008.10/cpu/arm920t/start.s,添加中断设置部分和时钟初始化部分

    (1)修改编译条件,使其支持mini2440

    136 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    137     /* turn off the watchdog */

    (2)添加硬件初始化的相关寄存器

    150 /*add by mini2440*/
    151 #define CLK_CTL_BASE 0X4C000000    //基地址
    152 #define MDIV_405 0X7F << 12       //主频为405mhz
    153 #define PSDIV_405 0X21
    154 #define UPLL_MDIV_48 0x38 << 12    //usb频率为48mhz
    155 #define UPLL_PSDIV_48 0x22

    上述寄存器的定义根据s3c2440的datasheet来确定的,时钟的基地址:0X4C000000

    S3C2440共有两个PLL,一个是MPLL,一个是UPLL。MPLL用于CPU及其他外围器件,UPLL用于USB。用于产生FCLK, HCLK, PCLK三种频率,这三种频率分别有不同的用途: 
    FCLK是CPU提供的时钟信号。 
    HCLK是为AHB总线提供的时钟信号, Advanced High-performance Bus,主要用于高速外设,比如内存控制器,中断控制器,LCD控制器, DMA 等。 

    PCLK是为APB总线提供的时钟信号,Advanced Peripherals Bus,主要用于低速外设,比如看门狗,UART控制器, IIS, I2C, SDI/MMC, GPIO,RTC and SPI等。

    由datasheet可知,MDIV位于寄存器的12-19位,PDIV位于寄存器的4-9位和SDIV位于0-1位。

    系统时钟的主频为405mhz,usb的频率为48mhz,查表可知MDIV,SDIV,PDIV的值

    (3)修改s3c2440中断禁止部分

    169 # if defined(CONFIG_S3C2410)
    170     ldr r1, =0x3ff
    171     ldr r0, =INTSUBMSK
    172     str r1, [r0]
    173 # endif
    174 
    175 
    176 /*add for mini2440 ,15bit INTSUBMSK*/
    177 # if defined(CONFIG_S3C2440)
    178     ldr r1, =0x7fff
    179     ldr r0, =INTSUBMSK
    180     str r1, [r0]
    181 # endif

    (4)修改时钟分频,FLCK:HCLK:PCLK = 1:4:8

    # if defined(CONFIG_S3C2440)
    185     /* FCLK:HCLK:PLCK = 1:4:8 */
    186     ldr r0, =CLKDIVN
    187     mov r1, #5       //根据下面的datasheet,CLKDIVN的值应为5
    188     str r1, [r0]
    189 
    190     mrc p15,0,r1,c1,c0,0 /*read ctrl regester*/   //读取协处理器中寄存器的数据到arm处理器中
    191     orr r1,r1,#0xc0000000                     //设置为异步总线模式
    192     mcr p15,0,r1,c1,c0,0 /*write ctrl regester*/
    193 
    194     mov r1, #CLK_CTL_BASE    //0x4c000000
    195 
    196     mov r2, #UPLL_MDIV_48   //配置upll
    197     add r2, r2, #UPLL_PSDIV_48
    198     str r2, [r1,#0x08]    //UPLLCON的地址为:0x4c000008
    199 
    200     mov r2, #MDIV_405   //配置mpll
    201     add r2, r2, #PSDIV_405 
    202     str r2, [r1, #0x04]    //MPLLCON的地址为:0x4c000004
    
    204 # else
    205     /* FCLK:HCLK:PCLK = 1:2:4 */
    206     /* default FCLK is 120 MHz ! */
    207     ldr r0, =CLKDIVN
    208     mov r1, #3
    209     str r1, [r0]
    210 #endif

    (6)修改u-boot-2008.10/cpu/arm920t/s3c24x0/interrupts.c支持mini2440

     32 #include <common.h>
     33 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
     34 
     35 #include <arm920t.h>
     36 #if defined(CONFIG_S3C2400)
     37 #include <s3c2400.h>
     38 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
     39 #include <s3c2410.h>
     40 #endif
    
    
    
    177 #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
    178     tbclk = timer_load_val * 100;
    179 #elif defined(CONFIG_SBC2410X) || 
    180       defined(CONFIG_SMDK2410) || 
    181       defined(CONFIG_MINI2440) || 
    182       defined(CONFIG_VCMA9)
    183     tbclk = CFG_HZ;
    184 #else
    185 #   error "tbclk not configured"
    186 #endif

    (7)修改u-boot-2008.10/cpu/arm920t/s3c24x0/speed.c的内容

     32 #include <common.h>
     33 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) ||defined (CONFIG_S3C2440) || defined (CONFIG_TRAB)
     34 
     35 #if defined(CONFIG_S3C2400)
     36 #include <s3c2400.h>
     37 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
     38 #include <s3c2410.h>
     39 #endif

    修改get_pllclk函数

     66     m = ((r & 0xFF000) >> 12) + 8;
     67     p = ((r & 0x003F0) >> 4) + 2;
     68     s = r & 0x3;
     69 
     70  #if defined(CONFIG_S3C2440)
     71     if(pllreg == MPLL)
     72        return((CONFIG_SYS_CLK_FREQ * m * 2)/ (p << s));
     73        else if(pllreg == UPLL)
     74  #endif
     75     return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
     76 77 

    这段代码根据datasheet上的计算公式来修改

    修改get_hclk函数,使其支持mini2440

     85 ulong get_HCLK(void)
     86 {
     87     S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
     88 #if defined(CONFIG_S3C2440)
     89     if(clk_power->CLKDIVN & 0X6)    // 与0x6与CKDIVN与得到HDIVN的值 
     90        {
     91          if((clk_power->CLKDIVN & 0X6) == 2)    //HDIVN 为01b时
     92               return(get_FCLK()/2);  
     93          if((clk_power->CLKDIVN & 0X6) == 6)    //HDIVN 为11b时
     94               return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);  //与0x100与得到CAMDIVA[9]的值,并返回get_fclk()
     95          if((clk_power->CLKDIVN & 0X6) == 4)                                       //HDIVN 为10b时
     96               return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);   //与0x200与得到CAMDIVN[8]的值,并返回get_flck()
     97           return(get_FCLK());
     98        }
     99     else
    100           return(get_FCLK());
    101 #else
    102     return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
    103 #endif
    104 }

    (8)修改/u-boot-2008.10/board/mini2440/mini2440.c

    修改mpll和upll的配置

     33 #define FCLK_SPEED 1
     34 
     35 #if FCLK_SPEED==0       /* Fout = 203MHz, Fin = 12MHz for Audio */
     36 #define M_MDIV  0xC3
     37 #define M_PDIV  0x4
     38 #define M_SDIV  0x1
     39 #elif FCLK_SPEED==1     /* Fout = 202.8MHz */
     40 #define M_MDIV  0xA1
     41 #define M_PDIV  0x3
     42 #define M_SDIV  0x1
     43 
     44 #if defined(CONFIG_S3C2440)
     45 /*fout = 405MHZ*/
     46 #define M_MDIV 0x7f
     47 #define M_PDIV 0x2
     48 #define M_SDIV 0x1
     49 #endif
     50 
     51 #endif
     54 #define USB_CLOCK 1
     55 
     56 #if USB_CLOCK==0
     57 #define U_M_MDIV    0xA1
     58 #define U_M_PDIV    0x3
     59 #define U_M_SDIV    0x1
     60 #elif USB_CLOCK==1
     61 #define U_M_MDIV    0x48
     62 #define U_M_PDIV    0x3
     63 
     64 #if defined(CONFIG_S3C2440)
     65 #define U_M_MDIV 0x38
     66 #define U_M_PDIV 0x2
     67 #endif
     68 
     69 #define U_M_SDIV    0x2
     70 #endif

    (9)修改u-boot-2008.10/cpu/arm920t/s3c24x0/serial.c

     21 #include <common.h>
     22 #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_S3C2440) || defined (CONFIG_TRAB)
     23 
     24 #if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
     25 #include <s3c2400.h>
     26 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
     27 #include <s3c2410.h>
     28 #endif

    (10)修改u-boot-2008.10/includes/s3c24x0.h

    添加CAMDIVN寄存器的定义,注意一定要加对位置,是在S3C24X0_CLOCK_POWER这个结构体中不然编译时会报错,

     122 typedef struct {
     123     S3C24X0_REG32   LOCKTIME;
     124     S3C24X0_REG32   MPLLCON;
     125     S3C24X0_REG32   UPLLCON;
     126     S3C24X0_REG32   CLKCON;
     127     S3C24X0_REG32   CLKSLOW;
     128     S3C24X0_REG32   CLKDIVN;
     129 #if defined(CONFIG_S3C2440)
     130     S3C24X0_REG32   CAMDIVN;
     131 #endif
     132 
     133 } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;

    (11)修改u-boot-2008.10/drivers/rtc/s3c24x0_rtc.c

     31 #if (defined(CONFIG_CMD_DATE))
     32 
     33 #if defined(CONFIG_S3C2400)
     34 #include <s3c2400.h>
     35 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
     36 #include <s3c2410.h>
     37 #endif

    6.修改mini2440的机器id  /includes/asm-arm/mach-types.h

    1860 #define MACH_TYPE_MINI2440             1999

    7.修改borad/mini2440.c  使其borad在引导内核时能够引导mini2440

    122     /* arch number of SMDK2410-Board */
    123     /*gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;*/
    124 
    125     /* arch number of MINI2440-Board */
    126     gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

    8.修改include/configs/mini2440.h

    添加对s3c2440的宏定义

     36 #define CONFIG_ARM920T      1   /* This is an ARM920T Core  */
     37 #define CONFIG_S3C2440      1   /* in a SAMSUNG S3C2440 SoC     */
     38 #define CONFIG_MINI2440     1   /* on a SAMSUNG MINI2440 Board  */

    修改到这里,可以进行编译了,执行

    make mini_config

    make

    生成uboot.bin文件

    利用jlink将bin文件下载到开发板中,具体下载方法参照网上的

    存在两个问题,flash显示错误,以及CRC检验警告,对于flash的显示,需要具体修改源码,添加其对mini2440flash芯片的支持

    而对于crc警告是由于产生新的环境变量,输入saveenv就能保存新的环境变量,之后就没有warning了。

    接下来要实现对norflash和DM9000网卡芯片的支持

    参考说明:

    本文参考了snowboy9859的博客http://blog.chinaunix.net/uid-24919665-id-435489.html  感谢!

  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/rwzhou/p/3675730.html
Copyright © 2011-2022 走看看