zoukankan      html  css  js  c++  java
  • [置顶] 0K6410学习之初步Uboot移植

    一个人跌跌撞撞终于来到了Uboot的移植,经过这几天对uboot源代码的分析,可以说得上是获益匪浅,也可以说收获不多吧,唉,知识实在是匮乏啊,Uboot代码中相当多的句子看不明白,很多都是猜测性的,或许我有生之年也写出那样的代码吧,不发牢骚了,开始今天的学习了。

    好吧,既然是Uboot的移植,那么我们首先搞清楚为什么要对Uboot进行移植呢?两个原因,uboot虽然名为通用的bootloader,但是这个通用得打上引号。每个人手上开发板的架构以及外设资源是不一样的,所以,我们需要对Uboot上的一些驱动程序等加以修改,称为板级移植,此为原因之一;同样根据我们使用的CPU不同,那么我们uboot上一些寄存器等也需要进行修改,称为片级移植,此为原因之二。

    恩,原因已经分稍稍分析了一下,那就开始uboot的移植吧!

    一、             移植前的准备

    1、  arm-linux-gcc4.3.2;2、u-boot-2010.03;3、OK6410开发板;redhat5.0;4、SD卡(用于烧写uboot,没网络啊!)。

    二、             第一步:删繁取简

    得到UBOOT后,将u-boot-2010.03.tar FZ到redhat中去,(为避免出现不必要的麻烦。个人建议一切操作在linux下面进行,好像xp下面的空格和linux下面的空格是不一样的,装个tools一切麻烦解决)解压后得到u-boot-2010.03。

    1、  进入u-boot-2010.03根目录下面的board文件夹,删除samsung之外的所有文件夹。

    2、  进入u-boot-2010.03.根目录下面的cpu文件夹  ,删除arm1176之外的所有文件夹。

    3、  进入u-boot-2010.03.根目录下面的include文件夹,删除以asm-开头的(一定要注意)除asm-arm、asm-generic之外的文件夹。

    4、  回到根目录下面,删除以lib_开头的出去lib_arm、lib_generic之外的文件夹。

    5、  进入 u-boot-2010.03\include\configs,删除 smdk6400.h以外的 其它的东西。

    6、  修改u-boot-2010.03下面的makefile,将CROSS_COMPILE ?=修改为CROSS_COMPILE?=arm-linux-,增添交叉编译工具链。

    7、  初步尝试 make smdk6400_config,然后执行make。编译完成后可以看到下面的信息。


    注意在第一步的过程中可能会出现如下问题


    这肯定的是你没有按步骤删除导致的,也就是删了一些不该删除得东西。初步编译后的uboot还是不能给我么开发板用的,下面就开始做一定修改。

    还有一点就是需要进入u-boot-2010.03根目录才能执行make。。我之前经常犯这种错误。。。

    三、             第二歩:对号入座

    先make distclean吧。

    1、  进入 u-boot-2010.03\board\samsung, 把除了 smdk6400 之外的文件夹删除, 同时建立一个文件夹 smdk6410, 把 smdk6400 文件夹里面的东西复制到smdk6410 文件夹中。进入 smdk6410 文件夹,将smdk6410文件夹下面所有文件中出现了6400的改为6410(保险起见)。

     

    2、  进入 u-boot-2010.03\include\asm-arm ,把除了 arch-s3c64xx 、proc-armv 之外的文件夹删除。进入 arch-s3c64xx,建立 s3c6410.h,将 s3c6400.h 文件里面的程序原原本本复制到s3c6410.h。同时将arch-s3c64xx文件夹下面所有出现了smdk6400的改为smdk6410。

     

    3、  进入u-boot-2010.03\nand_spl\board\samsung,建立smdk6410文件夹,同事把smdk6400中的内容FZ到smdk6410中去,接着把smdk6410中所有文件中出现了6400的地方改成6410。

     

    4、  进入u-boot-2010.03/include/configs,复制smdk6400.h,并且将副本改为smdk6410.h,同时里面出现了的6400全部改为6410.

     

    5、  进入u-boot-2010.03根目录的makefile文件,将里面的6400全部改为6410。

     

     

    6、  执行make smdk6410_config、make。这时候会出现下面的编译结果,唯一的区别就是6400变成了6410。但是还是不能用,完事之后,就开始深度修改吧,幸好之前分析了一下uboot源码,不然,真特么是“黑匣子”移植呀!

     

    四、             第三步:初步移植

    1、  打开start.S,之前已经分析了启动代码,现在就不细述,第一个修改地方,增加了一条协处理命令。


    2、  第二个代码修改的地方,用#if 0注释掉以下代码。


    3、  在bl lowlevel_init后面插入如下代码,判断启动方式。


    4、在 u-boot-2010.03\cpu\arm1176 下面新建一个 nand_cp.c 文件,c文件中的代码如下:

    #include<common.h>
    #ifdef CONFIG_S3C64XX
    #include<asm/io.h>
    #include<linux/mtd/nand.h>
    #include<asm/arch/s3c6410.h>
    static intnandll_read_page (uchar *buf, ulong addr, int large_block)
    {
    int i;
    int page_size = 512;
    /* 2K */
    if (large_block==1)
    page_size = 2048;
    /* 4K */
    if (large_block==2)
    page_size = 4096;
    NAND_ENABLE_CE();
    NFCMD_REG =NAND_CMD_READ0;
    /* Write Address */
    NFADDR_REG = 0;
    if (large_block)
    NFADDR_REG = 0;
    NFADDR_REG = (addr)& 0xff;
    NFADDR_REG = (addr>> 8) & 0xff;
    NFADDR_REG = (addr>> 16) & 0xff;
    /*
    #define NFCMD_REG
    __REG(ELFIN_NAND_BASE+ NFCMMD_OFFSET)
    #defineELFIN_NAND_BASE 0x70200000
    #define NFCMMD_OFFSET0x08
    NFCMD_REG = ( *((volatile u32 *) (0x70200008) ) )
    NFCMMD 0x70200008NAND Flash 命令设置寄存器 0
    #defineNAND_CMD_READSTART 0x30
    */
    if (large_block)
    NFCMD_REG =NAND_CMD_READSTART;
    /*
    define NF_TRANSRnB()
    do { while( !(NFSTAT_REG & (1 << 0) ) ); } while(0)
    #define NFSTAT_REG
    __REG(ELFIN_NAND_BASE+ NFSTAT_OFFSET)
    NFSTAT_REG = ( *((volatile u32 *) (0x70200028) ) )
    NFSTAT 0x70200028NAND Flash 操作状态寄存器
    */
    NF_TRANSRnB();
    /* forcompatibility(2460). u32 cannot be used. by scsuh */
    for(i=0; i <page_size; i++)
    {
    *buf++ = NFDATA8_REG;
    }
    /*
    #defineNAND_DISABLE_CE() (NFCONT_REG |= (1 << 1))
    #define NFCONT_REG
    __REG(ELFIN_NAND_BASE+ NFCONT_OFFSET)
    #define __REG(x)(*((volatile u32 *)(x)))
    #defineELFIN_NAND_BASE 0x70200000
    #define NFCONT_OFFSET0x04
    */
    NAND_DISABLE_CE();
    return 0;
    }
    static intnandll_read_blocks (ulong dst_addr, ulong size, int large_block)
    {
    uchar *buf = (uchar*)dst_addr;
    int i;
    uint page_shift = 9;
    if (large_block==1)
    page_shift = 11;
    /* Read pages */
    if(large_block==2)
    page_shift = 12;
    if(large_block == 2)
    {
    /* Read pages */
    for (i = 0; i < 4;i++, buf+=(1<<(page_shift-1)))
    {
    nandll_read_page(buf,i, large_block);
    }
    /* Read pages */
    /* 0x3c000 = 11 11000000 0000 0000 */
    for (i = 4; i <(0x3c000>>page_shift); i++, buf+=(1<<page_shift))
    {
    nandll_read_page(buf,i, large_block);
    }
    }
    else
    {
    for (i = 0; i <(0x3c000>>page_shift); i++, buf+=(1<<page_shift))
    {
    nandll_read_page(buf,i, large_block);
    }
    }
    return 0;
    }
    intcopy_uboot_to_ram(void)
    {
    int large_block = 0;
    int i;
    vu_char id;
    /*
    #defineNAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1))
    #define NFCONT_REG
    __REG(ELFIN_NAND_BASE+ NFCONT_OFFSET)
    #define __REG(x)(*((volatile u32 *)(x)))
    #defineELFIN_NAND_BASE 0x70200000
    #define NFCONT_OFFSET0x04
    NFCONT_REG = ( *((volatile u32 *) (0x70200004) ) )
    NFCONT 0x70200004 读/写 NAND Flash 控制寄存器
    [0]1:NAND Flash 控制器使能
    */
    NAND_ENABLE_CE();
    /*
    #define NFCMD_REG
    __REG(ELFIN_NAND_BASE+ NFCMMD_OFFSET)
    #defineELFIN_NAND_BASE 0x70200000
    #define NFCMMD_OFFSET0x08
    NFCMD_REG = ( *((volatile u32 *) (0x70200008) ) )
    NFCMMD 0x70200008NAND Flash 命令设置寄存器 0
    #defineNAND_CMD_READID 0x90
    */
    NFCMD_REG = NAND_CMD_READID;
    /*
    #define NFADDR_REG
    __REG(ELFIN_NAND_BASE+ NFADDR_OFFSET)
    #defineELFIN_NAND_BASE 0x70200000
    #define NFADDR_OFFSET0x0C
    NFADDR_REG = ( *((volatile u32 *) (0x7020000C) ) )
    NFADDR 0x7020000CNAND Flash 地址设置寄存器
    */
    NFADDR_REG = 0x00;
    /*
    #define NFDATA8_REG
    __REGb(ELFIN_NAND_BASE+ NFDATA_OFFSET)
    #define __REGb(x)(*(vu_char *)(x))
    NFDATA8_REG = ( *((vu_char *) (0x70200010) ) )
    NFDATA 0x70200010 读/写 NAND Flash 数据寄存器
    NAND Flash 读/烧写数据值用于 I/O
    */
    /* wait for a while*/
    for (i=0; i<200;i++);
    id = NFDATA8_REG;
    id = NFDATA8_REG;
    if (id > 0x80)
    large_block = 1;
    if(id == 0xd5)
    large_block = 2;
    /* read NAND Block.
    * 128KB ->240KBbecause of U-Boot size increase. by scsuh
    * So, read 0x3c000bytes not 0x20000(128KB).
    */
    /*
    #defineCONFIG_SYS_PHY_UBOOT_BASE
    (CONFIG_SYS_SDRAM_BASE+ 0x07e00000)
    #defineCONFIG_SYS_SDRAM_BASE 0x50000000
    CONFIG_SYS_PHY_UBOOT_BASE= 0x57e0 0000
    0x3 c000 = 1M
    */
    returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block);
    }
    #endif



    5、在 u-boot-2010.03\cpu\arm1176 的 makefile 中增加创建目标


    6、进入u-boot-2010.03\nand_spl\board\samsung \smdk6410,修改makefile中的内容,修改后如下。

    接下来就是


    7、在第二个#ifndef CONFIG_NAND_SPL后面增加如下代码,这里的顺序可不能搞错了,否则就会报错,如果编译过程中出现了未定义,那八成就是这里出问题了。

    /******************************************************************************************************************************/
    /* copy U-Boot toSDRAM and jump to ram (from NAND or OneNAND)
    * r0: size to becompared
    * Load 1'st 2blocksto RAM because U-boot's size is larger than 1block(128k) size
    */
    .globl copy_from_nand
    copy_from_nand:
    mov r10, lr /* savereturn address */
    mov r9, r0
    /* get ready to callC functions */
    ldr sp,_TEXT_PHY_BASE /* setup temp stack pointer */
    sub sp, sp, #12
    mov fp, #0 /* noprevious frame, so fp=0 */
    mov r9, #0x1000
    bl copy_uboot_to_ram
    3: tst r0, #0x0
    bne copy_failed
    ldr r0, =0x0c000000
    ldr r1,_TEXT_PHY_BASE
    1: ldr r3, [r0], #4
    ldr r4, [r1], #4
    teq r3, r4
    bne compare_failed /*not matched */
    subs r9, r9, #4
    bne 1b
    4: mov lr, r10 /* allis OK */
    mov pc, lr
    copy_failed:
    nop /* copy from nandfailed */
    b copy_failed
    compare_failed:
    nop /* compare failed*/
    b compare_failed
    /******************************************************************************************************************************/



    到这里为止,start.s中的修改初步完成了。

    7、  接下来就是对板子的配置进行修改了,这里面的一些东西和你板子的硬件资源密切相关,所以总得知道你板子的配置吧,这个就不多说了,打开u-boot-2010.03\include\configs \smdk6410.h文件查看吧,在新添加的nand_cp.c文件中含有3个宏没有定义,需要在这里定义,如下图示。


    8、  最后还需要修改链接脚本那!

    u-boot.lds和u-boot_nand.lds两个链接脚本中都需要做修改,路径分别为u-boot-2010.03 /CPU/ARM1176/uboot.lds, u-boot-2010.03/BOARD/SAMSUNG/SMDK6410/u-boot_nand.lds,修改内容如下:


    10、还是一样编译吧,make了,由于没有网络,不好检测网卡移植是否成功,所以网卡移植就先不说了,最后贴上串口上打印的信息如下:


    好了,一下又到了12点多了,不能再熬下去了,脸上长包啦~~~,这学期被这东西整的人不像人的,没办法啊,今天的总结就写到这里了,睡觉去。。。。            

  • 相关阅读:
    css3中-moz、-ms、-webkit 是什么意思
    自定义AppServer
    自定义AppSession
    分离Command
    创建简单的Telnet实例
    注册表权限设置
    centos root登录password 忘记解决的方法
    ajaxFileUpload+struts2实现多文件上传
    计算机图形学(二)输出图元_6_OpenGL曲线函数_2_中点画圆算法
    linux命令的别名alias,unalias
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2992130.html
Copyright © 2011-2022 走看看