zoukankan      html  css  js  c++  java
  • uboot在s3c2440上的移植(1)

    一、移植环境

    • 主  机:VMWare--Fedora 9
    • 开发板:Mini2440--64MB Nand,Kernel:2.6.30.4
    • 编译器:arm-linux-gcc-4.3.2.tgz
    • u-boot:u-boot-2009.08.tar.bz2

    二、移植步骤

    本次移植的功能特点包括:

    • 支持Nand Flash读写
    • 支持从Nor/Nand Flash启动
    • 支持CS8900或者DM9000网卡 
    • 支持Yaffs文件系统 
    • 支持USB下载(还未实现)

    1. 了解u-boot主要的目录结构和启动流程,如下图。

     
     
     
        u-bootstage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;
        u-bootstage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。
        各个部分的流程图如下:
     
     
     
    2. 建立自己的开发板项目并测试编译。
       目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。
     
    1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440

    #tar -jxvf u-boot-2009.08.tar.bz2    //解压源码
    #cd u-boot-2009.08/board/samsung/    //进入目录
    #mkdir my2440                        //创建my2440文件夹

     
    2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改

    #cp -rf smdk2410/* my2440/   //将2410下所有的代码复制到2440下

    #cd my2440                   //进入my2440目录

    #mv smdk2410.c my2440.c      //将my2440下的smdk2410.c改名为my2440.c

    #cd ../../../                //回到u-boot根目录
    #cp include/configs/smdk2410.h include/configs/my2440.h //建立2440头文件
    #gedit board/samsung/my2440/Makefile   //修改my2440下Makefile的编译项,如下:

    COBJS    := my2440.o flash.o  //因在my2440下我们将smdk2410.c改名为my2440.c

    3)修改u-boot跟目录下的Makefile文件。查找到smdk2410_config的地方,在他下面按照smdk2410_config的格式建立my2440_config的编译选项,另外还要指定交叉编译器

    #gedit Makefile

    CROSS_COMPILE ?= arm-linux-        //指定交叉编译器为arm-linux-gcc

     

    smdk2410_config    :    unconfig   //2410编译选项格式
        @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0

     

    my2440_config    :    unconfig     //2440编译选项格式
        @$(MKCONFIG) $(@:_config=) arm arm920t my2440 samsung s3c24x0

     

    *说明:arm    :CPU的架构(ARCH)

           arm920t:CPU的类型

           my2440 :对应在board目录下建立新的开发板项目的目录

           samsung:新开发板项目目录的上级目录,如直接在board下建立新的开发板项目的目录,则这里就为NULL

           s3c24x0:CPU型号

    *注意:编译选项格式的第二行要用Tab键开始,否则编译会出错

    4)测试编译新建的my2440开发板项目

    #make my2440_config //如果出现Configuring for my2440 board...则表示设置正确

    #make //编译后在根目录下会出现u-boot.bin文件,则u-boot移植的第一步就算完成了

    到此为止,u-boot对自己的my2440开发板还没有任何用处,以上的移植只是搭建了一个my2440开发板u-boot的框架,要使其功能实现,还要根据my2440开发板的具体资源情况来对u-boot源码进行修改。

    3. 根据u-boot启动流程图的步骤来分析或者修改添加u-boot源码,使之适合my2440开发板(注:修改或添加的地方都用红色表示)。

    1)my2440开发板u-boot的stage1入口点分析。
    一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等分配情况等。那么我们的my2440开发板u-boot的这个链接文件就是cpu/arm920t/u-boot.lds,打开该文件部分代码如下:

    知道了程序的入口点是_start,那么我们就打开my2440开发板u-boot第一个要运行的程序cpu/arm920t/start.S(即u-boot的stage1部分),查找到_start的位置如下:

    从这个汇编代码可以看到程序又跳转到start_code处开始执行,那么再查找到start_code处的代码如下:

    /*
     * the actual start code
     */

    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  //此处两行是对AT91RM9200DK开发板上的LED进行初始化的
        bl red_LED_on

     

    由此可以看到,start_code处才是u-boot启动代码的真正开始处。以上就是u-boot的stage1入口的过程。

    2)my2440开发板u-boot的stage1阶段的硬件设备初始化。
    由于在u-boot启动代码处有两行是AT91RM9200DK的LED初始代码,但我们my2440上的LED资源与该开发板的不一致,所以我们要删除或屏蔽该处代码,再加上my2440的LED驱动代码(注:添加my2440 LED功能只是用于表示u-boot运行的状态,给调试带来方便,可将该段代码放到任何你想调试的地方),代码如下:

        /*bl coloured_LED_init  //这两行是AT91RM9200DK开发板的LED初始化,注释掉
        bl red_LED_on*/

     

    #if defined(CONFIG_S3C2440)  //区别与其他开发板

    //根据mini2440原理图可知LED分别由S3C2440的PB5、6、7、8口来控制,以下是PB端口寄存器基地址(查2440的DataSheet得知)
    #define GPBCON 0x56000010

    #define GPBDAT 0x56000014
    #define GPBUP  0x56000018    

        //以下对寄存器的操作参照S3C2440的DataSheet进行操作
        ldr r0, =GPBUP
        ldr r1, =0x7FF    //即:二进制11111111111,关闭PB口上拉
        str r1, [r0]

        ldr r0, =GPBCON   //配置PB5、6、7、8为输出口,对应PBCON寄存器的第10-17位
        ldr r1, =0x154FD  //即:二进制010101010011111101
        str r1, [r0]

        ldr r0, =GPBDAT
        ldr r1, =0x1C0    //即:二进制111000000,PB5设为低电平,6、7、8为高电平
        str r1, [r0]
     

    #endif

    //此段代码使u-boot启动后,点亮开发板上的LED1,LED2、LED3、LED4不亮

    include/configs/my2440.h头文件中添加CONFIG_S3C2440宏

    #gedit 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)
        {   //参考S3C2440芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2s)
            return((CONFIG_SYS_CLK_FREQ * m * 2) / (<< 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,然后再下载到RAM中运行测试。结果终端有输出信息并且出现类似Shell的命令行,这说明这一部分移植完成。示意图如下: 

     

    #gedit include/configs/my2440.h

    #define CONFIG_ARM920T        1    /* This is an ARM920T Core     */
    #define CONFIG_S3C2410        1    /* in a SAMSUNG S3C2410 SoC    */
    #define CONFIG_SMDK2410       1    /* on a SAMSUNG SMDK2410 Board */
    #define CONFIG_S3C2440        1    /* in a SAMSUNG S3C2440 SoC    */

    现在编译u-boot,在根目录下会生成一个u-boot.bin文件。然后我们利用mini2440原有的supervivi把u-boot.bin下载到RAM中运行测试(注意:我们使用supervivi进行下载时已经对CPU、RAM进行了初始化,所以我们在u-boot中要屏蔽掉对CPU、RAM的初始化),如下:

    /*#ifndef CONFIG_SKIP_LOWLEVEL_INIT //在start.S文件中屏蔽u-boot对CPU、RAM的初始化
       bl cpu_init_crit
    #endif*/

    #make my2440_config

    #make

    下载运行后可以看到开发板上的LED灯第一了亮了,其他三个熄灭,测试结果符合上面的要求。终端运行结果如下:

    #gedit cpu/arm920t/start.S

    .globl _start
    _start: b       start_code    //将程序的执行跳转到start_code处

    #gedit cpu/arm920t/u-boot.lds

    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
    OUTPUT_ARCH(arm)    
    //定义生成文件的目标平台是arm
    ENTRY(_start)       
    //定义程序的入口点是_start

    SECTIONS
    {
        
    //其他一些代码段、数据段等分配
        . = 0x00000000;

        . = ALIGN(4);
        .text :
        {
            cpu/arm920t/start.o    (.text)
            *(.text)
        }
        ..................
        ..................
    }

    3)在u-boot中添加对S3C2440一些寄存器的支持、添加中断禁止部分和时钟设置部分
    由于2410和2440的寄存器及地址大部分是一致的,所以这里就直接在2410的基础上再加上对2440的支持即可,代码如下:

    #gedit cpu/arm920t/start.S

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

    # if defined(CONFIG_S3C2400)
    # define pWTCON     0x15300000
    # define INTMSK     0x14400008    /* Interupt-Controller base addresses */
    # define CLKDIVN    0x14800014    /* clock divisor register */
    #else  //下面2410和2440的寄存器地址是一致的
    # define pWTCON     0x53000000
    # define INTMSK     0x4A000008    /* Interupt-Controller base addresses */
    # define INTSUBMSK  0x4A00001C
    # define CLKDIVN    0x4C000014    /* clock divisor register */
    # endif

        ldr  r0, =pWTCON
        mov  r1, #0x0
        str  r1, [r0]

        /*
         * mask all IRQs by setting all bits in the INTMR - default
         */
        mov  r1, #0xffffffff
        ldr  r0, =INTMSK
        str  r1, [r0]
    # 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的时钟部分# endif
    #endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_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:*/
        /* default FCLK is 120 MHz ! */
      

        ldr  r0, =CLKDIVN
        mov  r1, #3
        str  r1, [r0]

    S3C2440的时钟部分除了在start.S中添加外,还要分别在board/samsung/my2440/my2440.c和cpu/arm920t/s3c24x0/speed.c中修改或添加部分代码,如下:

    #gedit board/samsung/my2440/my2440.c //设置主频和USB时钟频率参数与start.S中的一致

    #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

  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/80scd/p/5869334.html
Copyright © 2011-2022 走看看