u-boot-2010.12移植到2440(二,移植在RAM中运行)

    技术2022-05-20  43

    http://my.chinaunix.net/space.php?uid=24319701&do=blog&id=131489 Smdk2410 可以编译通过之后,即可进入 2440 的移植了。 2440 2410 的资源差不多,主频和外设有点差别,所以我们就在 board/samsung/ 下以 smdk2410 为模板建立自己目标板的项目,取名叫 smdk2440 (代码中的修改用红色表示)

    一、首先建立目标板文件

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

    #cd smdk2440        //进入smdk2440目录

    #mv smdk2410.c smdk2440.c  //smdk2440下的smdk2410.c改名为smdk2440.c

    #cd ../../../         //回到u-boot根目录#cp include/configs/smdk2410.h include/configs/smdk2440.h //建立2440头文件#gedit board/samsung/smdk2440/Makefile   

    修改smdk2440Makefile的编译项,如下:

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

    老版本的uboot是需要修改顶层makefile文件

    在其中加入:

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

    但是新版本的文件组织结构有很大变化,需要在boards.cfg文件中smdk2410的下面增加类似的一条:

    smdk2440       arm         arm920t     -          samsung        s3c24x0

    然后,测试下编译情况:

    Make distclean

    Make smdk2440_ config

    Make all

    不幸,出现如下错误:

     

    board.c: In function 'board_init_f':

    board.c:279: error: 'CONFIG_SYS_TEXT_BASE' undeclared (first use in this function)

    board.c:279: error: (Each undeclared identifier is reported only once

    board.c:279: error: for each function it appears in.)

    make[1]: *** [board.o] 错误 1

    make[1]: 离开目录“/home/bsc/samba/u-boot-2010.12/arch/arm/lib”

    make: *** [arch/arm/lib/libarm.o] 错误 2

     

    这说明我们前面为了编译通过而增加的宏定义可能是有问题的,事实上我们可以在网上查到一个patch,可以解决这些问题。但是这里,为了深入了解问题所在,我们手动一点点来修改而不是直接打上patch

    include/configs/smdk2410.h include/configs/smdk2440.h 文件中删除上面添加的宏定义:

    #define CONFIG_SYS_SDRAM_BASE             0x00000000#define CONFIG_SYS_INIT_SP_ADDR              (CONFIG_SYS_TEXT_BASE - GENERATED_GBL_DATA_SIZE)

    添加如下宏定义(参考该patch

    #define CONFIG_SYS_SDRAM_BASE      PHYS_SDRAM_1

    #define CONFIG_SYS_INIT_SP_ADDR    (CONFIG_SYS_SDRAM_BASE + 0x1000 -   GENERATED_GBL_DATA_SIZE)

    然后再次编译,此次编译可以通过 至此我们建立起了目标板的框架,我们可以开始修改代码以适应我们的目标板。

    二、目标板u-boot的硬件设备初始化。

    1)入口代码分析

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

    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")OUTPUT_ARCH(arm)    //定义生成文件的目标平台是armENTRY(_start)       //定义程序的入口点是_startSECTIONS{    //其他一些代码段、数据段等分配    . = 0x00000000;    . = ALIGN(4);    .text :    {        cpu/arm920t/start.o    (.text)        *(.text)    }    ..................    ..................}

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

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

    从这个汇编代码可以看到程序又跳转到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启动代码的真正开始处。

    2)初始化代码修改

    start.S中注释掉LED相关代码:

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

           /*注释掉以下两行代码以便在内存中调试

    #ifndef CONFIG_SKIP_LOWLEVEL_INIT

           bl    cpu_init_crit

    #endif

    */

    或者在include/configs/smdk2440.h头文件中添加CONFIG_S3C2440

    #define CONFIG_SKIP_LOWLEVEL_INIT

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

    #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    */添加此宏

    #define CONFIG_SYS_CLK_FREQ    16934400/* the SMDK2440 has 16MHz input clock  by bsc */

     

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

    #ifdef CONFIG_S3C24X0

           /* 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

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

           ldr   r1, =0x7fff

           ldr   r0, =INTSUBMSK

           str    r1, [r0]

    # endif

     

    # if defined(CONFIG_S3C2440)   //添加s3c2440的时钟部分

     

    #define MPLLCON   0x4C000004   //系统主频配置寄存器基地址

    #define UPLLCON   0x4C000008   //USB时钟频率配置寄存器基地址

    #define CAMDIVN      0x4C000018

     

           ldr  r0,  = CAMDIVN

           mov  r1,  #0

           str  r1,  [r0]

            

               ldr  r0, = CLKDIVN          //设置分频系数FCLK:HCLK:PCLK = 1:3:6

               ldr  r1,  = 0x7

               str  r1, [r0]

     

           ldr  r0, =MPLLCON  //设置系统主频为405MHz

           ldr  r1, =0x6e031  //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分

           str  r1, [r0]

          

           ldr  r0, =UPLLCON  //设置USB时钟频率为48MHz

           ldr  r1, =0x3c042  //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分

           str  r1, [r0]

    # else //其他开发板的时钟部分,这里就不用管了,我们现在是做2440

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

           /* default FCLK is 120 MHz ! */

           ldr   r0, =CLKDIVN

           mov r1, #3

           str    r1, [r0]

    #endif     /* CONFIG_S3C2440 */

    #endif     /* CONFIG_S3C24X0 */

     

    S3C2440的时钟部分除了在start.S中添加外,还要在board/samsung/smdk2440/smdk2440.c修改或添加部分代码,如下:

    #define FCLK_SPEED 2       //设置默认等于2by bsc 2010-2-22 20:49

    #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    0x6e     //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置

    #define M_PDIV    0x3

    #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    0x3c   //这三个值根据S3C2440芯片手册“PLL VALUE SELECTION TABLE”部分进行设置

    #define U_M_PDIV    0x4

    #define U_M_SDIV    0x2

    #endif

     

    修改/* arch number of SMDK2440-Board */

           gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;

    dram_initvoid)函数中添加gd->ram_size初始化(此句比较重要):

    gd->ram_size = PHYS_SDRAM_1_SIZE; /*add by bsc 2011/2/21 20:14:46*/

    修改board/samsung/smdk2440/config.mk

    CONFIG_SYS_TEXT_BASE = 0x33000000/*0x3f800000改为0x33000000 以便内存中调试*/

    修改完毕后我们再重新编译u-boot,然后再下载到RAM中运行测试。tftp 0x33000000 u-boot.bin

    go 0x33000000

    结果终端有输出信息并且出现类似Shell的命令行,这说明这一部分移植完成。如果有其他问题可以在include/configs/smdk2440.h头文件中添加DEBUG宏用于调试。


    最新回复(0)