• 基于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  感谢!

  • 相关阅读:
    C#
    Excel 中大量图片如何快速导出? 转载自:http://www.zhihu.com/question/20800948
    IE的F12开发人员工具不显示 转载自:http://blog.csdn.net/longyulu/article/details/8749705
    firefox ie 比较 relative path
    fiddler save files
    selenium3加载浏览器
    Linux安装PHP
    客户端级别的渲染分析工具 dynaTrace
    前端性能分析:分析百度和sogou
    Linux vi的基本操作
  • 原文地址:https://www.cnblogs.com/rwzhou/p/3675730.html
Copyright © 2020-2023  润新知