zoukankan      html  css  js  c++  java
  • 移植属于自己的6410开发板的UBoot

    学习了几个月的关于嵌入式相关的知识,之前一直觉得自己能力不够,去研究uboot很有难度,现在通过几个月的学习,再去研究uboot应该可以理解了,于是就开始自己的移植之旅!

           首先在网上搜索关于6410uboot的移植的相关信息,资料有点少,都是关于2410的,偶然看到一篇关于《基于OK6410的u-boot2010.03移植过程》的文章,原来已经有朋友移植成功了的,我们就得参照一下,站在巨人的肩膀上嘛。我就详细的把我移植的过程及其中遇到的问题说说:

    准备阶段:

          主机环境:Ubuntu11.10

          目标机:  飞凌-OK6410-A

          编译环境:arm-linux-gcc-4.3.2

          源码下载:ftp://ftp.denx.de/pub/u-boot/

           下载u-boot-2010.03(本来想追求最新的,但这以后的版本跟这以前的就不同了,所以先把老版本弄清楚吧),我下载到桌面;

    #tar xvf u-boot-2010.03.tar.bz2

    #ls

           你看到大多目录跟Linux源码结构很像,分析步骤跟分析linux源码差不多,我们先编译体验一下,同时验证一下能否编译通过;

    #cd u-boot-2010.03

    #make smdk6400_config

    #make

    #ls

    在文件夹根目录下生成u-boot.bin文件,这就是我们要下载到开发板上的可执行文件。

    源码修改阶段:

          进入u-boot-2010.03/board/samsung,建立smdk6410文件夹,把smdk6400内的所有文件复制到smdk6410中,进smdk6410中将smdk6400.c改为smdk6410.c。(6400与6410大体是一样的);

    #cd board/samsung

    #mkdir smdk6410

    #cp smdk6400/* smdk6410/

    #mv smdk6410/smdk6400.c smdk6410/smdk6410.c

         进入u-boot-2010.03/include/asm-arm/arch-s3c64xx,复制s3c6400.h并改为s3c6410.h

    #cd ../../include/asm-arm/arch-s3c64xx

    #cp s3c6400.h s3c6410.h

         进入根目录,打开Makefile,找到下面的代码:

    smdk6400_noUSB_config \
    smdk6400_config : unconfig
    @mkdir-p$(obj)include$(obj)board/samsung/smdk6400
    @mkdir-p$(obj)nand_spl/board/samsung/smdk6400
    @echo"#defineCONFIG_NAND_U_BOOT">$(obj)include/config.h
    @if[-z"$(findstringsmdk6400_noUSB_config,$@)"];then \
    echo"RAM_TEXT=0x57e00000">>$(obj)board/samsung/smdk6400/config.tmp;\
    $(MKCONFIG)$(@:_config=)armarm1176smdk6400samsungs3c64xx; \
    else \
    echo"RAM_TEXT=0xc7e00000">>$(obj)board/samsung/smdk6400/config.tmp;\
    $(MKCONFIG)$(@:_noUSB_config=)armarm1176smdk6400samsungs3c64xx;\
    fi
    @echo"CONFIG_NAND_U_BOOT=y">>$(obj)include/config.mk

         上面是6400的配置文件,将里面的6400都改为6410;

    smdk6410_noUSB_config \
    smdk6410_config : unconfig
    @mkdir-p$(obj)include$(obj)board/samsung/smdk6410
    @mkdir-p$(obj)nand_spl/board/samsung/smdk6410
    @echo"#defineCONFIG_NAND_U_BOOT">$(obj)include/config.h
    @if[-z"$(findstringsmdk6410_noUSB_config,$@)"];then \
    echo"RAM_TEXT=0x57e00000">>$(obj)board/samsung/smdk6410/config.tmp;\
    $(MKCONFIG)$(@:_config=)armarm1176smdk6410samsungs3c64xx; \
    else \
    echo"RAM_TEXT=0xc7e00000">>$(obj)board/samsung/smdk6410/config.tmp;\
    $(MKCONFIG)$(@:_noUSB_config=)armarm1176smdk6410samsungs3c64xx;\

         进入u-boot-2010.03/board/samsung/smdk6410,编辑smdk6410,把#include <asm/arch/s3c6400.h> 改为 #include <asm/arch/s3c6410.h

         下面就要修改启动代码cpu/arm1176/start.S

    第一处修改:

    #ifndef CONFIG_NAND_SPL
    /*
     * flush v4 I/D caches
     */
    mov r0, #0
    mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
    mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
    /*
     * disable MMU stuff and caches//////////////////////////////////////////////////////////////////////////////////////////
     */
    mrc p15, 0, r0, c1, c0, 0
    bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
    bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
    orr r0, r0, #0x00000002 @ set bit 2 (A) Align
    orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
    mcr p15, 0, r0, c1, c0, 0//从后面拷贝过来的
    ///////////////////////////////以下的注释掉
    
    /* Prepare to disable the MMU */
    //adr r1, mmu_disable_phys
    /* We presume we're within the first 1024 bytes */
    //and r1, r1, #0x3fc
    //ldr r2, _TEXT_PHY_BASE
    //ldr r3, =0xfff00000
    //and r2, r2, r3
    //orr r2, r2, r1
    //b mmu_disable
    //.align 5
    /* Run in a single cache-line */
    //mmu_disable:
    // mcr p15, 0, r0, c1, c0, 0
    // nop
    // nop
    // mov pc, r2
    /////////////////////////////////////////////////////////////////////////////////////////////////////  
    
    

    第二处修改:

    bl lowlevel_init /* go setup pll,mux,memory */  之后
    
    
    /* when we already run in ram, we don't need to relocate U-Boot.////////////////////////////////////////////////////////////////////
    * and actually, memory controller must be configured before U-Boot
    * is running in ram.
    */
     ldr r0, =0xff000fff
     bic r1, pc, r0  /* r0 <- current base addr of code */
     ldr r2, _TEXT_BASE  /* r1 <- original base addr in ram */
     bic r2, r2, r0  /* r0 <- current base addr of code */
     cmp     r1, r2                  /* compare r0, r1                  */
     beq      after_copy  /* r0 == r1 then skip flash copy   */
    #ifdef CONFIG_BOOT_NAND
      mov r0, #0x1000
     bl copy_from_nand
    #endif 
    after_copy://///////////////////////////////////////////////////////////////////////////////////////////////
    #ifdef CONFIG_ENABLE_MMU   
    

    上面的修改是判断到底是从Nand Flash启动还是RAM启动;

    1.如果是从nandflash中启动,那么PC的值一定在4K之内。那么执行完bicr1,pc,r0 之后,r1为0。_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0 之后,r2为0x00e00000,那么不相等,则不跳转,下面应该就是copy_from_nand。
    2.如果是从ram中启动,那么PC的值为0xx7e00000。那么执行完bicr1,pc,r0 之后,r1为0x00e00000。_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0 之后,r2为0x00e00000,那么相等,跳转到after_copy,也就是不需要copy。承接上面分析,如果没有完成copy,则接下来就是copy_from_nand。

    第三处修改:

    #ifndef CONFIG_NAND_SPL
    /*
     * we assume that cache operation is done before. (eg. cleanup_before_linux())
     * actually, we don't need to do anything about cache if not use d-cache in
     * U-Boot. So, in this function we clean only MMU. by scsuh
     *
     * void theLastJump(void *kernel, int arch_num, uint boot_params);
     */
    #ifdef CONFIG_ENABLE_MMU
     .globl theLastJump
    theLastJump:  
    之前加上以下语句
    
    /*
     * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
     * r0: size to be compared
     * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
     *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    .globl copy_from_nand
    
    copy_from_nand:
      mov r10, lr  /* save return address */
    
      mov r9, r0
     /* get ready to call C functions */  
    
    
    ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */
     sub sp, sp, #12
     mov fp, #0   /* no previous 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  /* all is OK */
      mov pc, lr
    copy_failed:
      nop   /* copy from nand failed */
       
    b copy_failed
    compare_failed:
     nop   /* compare failed */
     b compare_failed   
    

          接着进入u-boot-2010.03/include/configs编辑smdk6410.h,添加下面的宏定义;

    1.

    #definevirt_to_phys(x) virt_to_phy_smdk6410(x)

    2.

    #defineCONFIG_SYS_PROMPT "SMDK6410#" /*MonitorCommandPrompt */
    这里的”SMDK6410”可以自己修改,这就是你进入uboot的命令模式的#前面的文字。
    3.
    //#definePHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */
    #definePHYS_SDRAM_1_SIZE 0x10000000 /*256MBinBank#1 */
    修改SDRAM内存为256M的。
    4.
    /*NANDconfiguration*/
    #defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1))
    #defineNAND_ENABLE_CE()(NFCONT_REG&=~(1<<1))
    #defineNF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)
    这里的定义是后面写nand_cp.c要用到的宏定义
    5.
    /*
    *Architecturemagicandmachinetype
    */
    //#define MACH_TYPE 1270/*smdk6400ID*/
    #defineMACH_TYPE 1626/*smdk6410ID*/
    6410的ID号;
    6.
    /*
    *Sizeofmalloc()pool
    */
    //#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+1024*1024)
    #defineCONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+512*1024)
    #defineCONFIG_SYS_GBL_DATA_SIZE 128 /*sizeinbytesforinitialdata*/
    修改内存大小;
    7.
    #defineCONFIG_BOOTDELAY 3
    修改bootdelay延迟时间
    8.
    //#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x7e00000)
    /*126MBinDRAM*/
    #defineCONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x9e00000)
    /*256MBinDRAM*/
    修改SDROM大小;
    9.
    /*the PWMTImer4usesacounterof15625for10ms,soweneed*/
    /*ittowrap100times (total1562500)toget1sec.*/
    //#define CONFIG_SYS_HZ 1000 //atPCLK50MHz
    #defineCONFIG_SYS_HZ 1562500
    时钟修改;
    10.
    //#define CONFIG_STACKSIZE 0x40000 /*regularstack256KB*/
    #defineCONFIG_STACKSIZE 0x80000 /*regularstack512KB*/
    堆栈大小修改;
    11.
    //#define PHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */
    #definePHYS_SDRAM_1_SIZE0x10000000 /*256MBinBank#1 */
    Nand Flash每块大小修改;
    12.
    //#define CONFIG_ENV_SIZE 0x4000 /*TotalSizeofEnvironmentSector*/
    #defineCONFIG_ENV_SIZE 0x80000 /*TotalSizeofEnvironmentSector*/
    Total Size of Environment Sector修改;
    13.
    //#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x60000 0x1c0000;"\
    //"bootm0x50018000"
    #define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x100000 0x500000;"\
    "bootm0x50018000"
    CONFIG_BOOTCOMMAND修改
    14.
    #defineCONFIG_ENV_OFFSET 0x0080000
    CONFIG_ENV_OFFSET修改
    15.
    //#define CONFIG_SYS_NAND_PAGE_SIZE 2048
    #defineCONFIG_SYS_NAND_PAGE_SIZE 4096
    Nand Flash每一页大小的修改
    16.
    /*NANDchipblocksize */
    //#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
    #defineCONFIG_SYS_NAND_BLOCK_SIZE (512*1024)
    Nand Flash每一块大小的修改
    17.
    /*NANDchippageperblockcount */
    //#define CONFIG_SYS_NAND_PAGE_COUNT 64
    #defineCONFIG_SYS_NAND_PAGE_COUNT 128
    校验位修改
    并将里面的所有6400替换为6410
     
       接下来在u-boot-2010.03/cpu/arm1176/下面新建一个nand_cp.c文件,代码如下:
    #include<common.h>
    #ifdefCONFIG_S3C64XX
    #include<asm/io.h>
    #include<linux/mtd/nand.h>
    #include<asm/arch/s3c6410.h>
    staticintnandll_read_page(uchar*buf,ulongaddr,intlarge_block)
    {
    inti;
    intpage_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;
    /*WriteAddress*/
    NFADDR_REG=0;
    if(large_block)
    NFADDR_REG=0;
    NFADDR_REG=(addr)&0xff;
    NFADDR_REG=(addr>>8)&0xff;
    NFADDR_REG=(addr>>16)&0xff;
    /*
    #defineNFCMD_REG
    __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
    #defineELFIN_NAND_BASE 0x70200000
    #defineNFCMMD_OFFSET 0x08
    NFCMD_REG=(*( (volatileu32*) (0x70200008) ))
    NFCMMD 0x70200008 NANDFlash命令设置寄存器0
    #define NAND_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=(*( (volatileu32*) (0x70200028) ))
    NFSTAT 0x70200028 NANDFlash操作状态寄存器
    */
    NF_TRANSRnB();
    /*forcompatibility(2460).u32cannotbeused.byscsuh*/
    for(i=0;i<page_size;i++)
    {
    *buf++=NFDATA8_REG;
    }
    /*
    #defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1))
    #defineNFCONT_REG
    __REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
    #define__REG(x) (*((volatileu32*)(x)))
    #defineELFIN_NAND_BASE 0x70200000
    #defineNFCONT_OFFSET 0x04
    */
    NAND_DISABLE_CE();
    return0;
    }
    staticintnandll_read_blocks(ulongdst_addr,ulongsize,int large_block)
    {
    uchar*buf=(uchar*)dst_addr;
    inti;
    uintpage_shift=9;
    if(large_block==1)
    page_shift=11;
    /*Readpages*/
    if(large_block==2)
    page_shift=12;
    if(large_block==2)
    {
    /*Readpages*/
    for(i=0;i<4;i++,buf+=(1<<(page_shift-1)))
    {
    nandll_read_page(buf,i,large_block);
    }
    /*Readpages*/
    /* 0x3c000 = 111100000000000000 */
    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);
    }
    }
    return0;
    }
    intcopy_uboot_to_ram(void)
    {
    intlarge_block =0;
    inti;
    vu_charid;
    /*
    #defineNAND_ENABLE_CE() (NFCONT_REG&=~(1<<1))
    #defineNFCONT_REG
    __REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
    #define__REG(x) (*((volatileu32*)(x)))
    #defineELFIN_NAND_BASE 0x70200000
    #defineNFCONT_OFFSET 0x04
    NFCONT_REG=(*( (volatileu32*) (0x70200004) ))
    NFCONT0x70200004 读/写NANDFlash控制寄存器
    [0]1:NANDFlash控制器使能
    */
    NAND_ENABLE_CE();
    /*
    #defineNFCMD_REG
    __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
    #defineELFIN_NAND_BASE 0x70200000
    #defineNFCMMD_OFFSET 0x08
    NFCMD_REG=(*( (volatileu32*) (0x70200008) ))
    NFCMMD 0x70200008 NANDFlash命令设置寄存器0
    #defineNAND_CMD_READID 0x90
    */
    NFCMD_REG=NAND_CMD_READID;
    *
    #defineNFADDR_REG
    __REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
    #defineELFIN_NAND_BASE 0x70200000
    #defineNFADDR_OFFSET 0x0C
    NFADDR_REG =(*( (volatileu32*) (0x7020000C) ))
    NFADDR0x7020000C NANDFlash地址设置寄存器
    */
    NFADDR_REG= 0x00;
    /*
    #define NFDATA8_REG
    __REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
    #define__REGb(x) (*(vu_char*)(x))
    NFDATA8_REG = (*( (vu_char*) (0x70200010) ))
    NFDATA0x70200010 读/写NANDFlash数据寄存器
    NANDFlash 读/烧写数据值用于I/O
    */
    /*waitforawhile*/
    for(i=0;i<200;i++);
    id=NFDATA8_REG;
    id=NFDATA8_REG;
    if(id>0x80)
    large_block=1;
    if(id ==0xd5)
    large_block=2;
    /*readNANDBlock.
    *128KB->240KBbecauseofU-Bootsizeincrease.byscsuh
    *So,read0x3c000bytesnot0x20000(128KB).
    */
    /*
    #define CONFIG_SYS_PHY_UBOOT_BASE
    (CONFIG_SYS_SDRAM_BASE+0x07e00000)
    #define CONFIG_SYS_SDRAM_BASE 0x50000000
    CONFIG_SYS_PHY_UBOOT_BASE= 0x57e00000
    0x3c000 = 1M
    */
    returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,0x3c000,large_block);
    }
    #endif
     
       修改u-boot-2010.03/cpu/arm1176/Makefile,在COBJS = cpu.o后面加nand_cp.o
    COBJS	= cpu.o nand_cp.o
       修改u-boot-2010.03/board/samsung/smdk6410/u-boot-nand.lds,添加nand_cp.o 如下:
    {
    cpu/arm1176/start.o (.text)
    cpu/arm1176/s3c64xx/cpu_init.o (.text)
    board/samsung/smdk6410/lowlevel_init.o (.text)
    cpu/arm1176/nand_cp.o(.text)
    lib_arm/board.o (.text)
    *(.text)
    }
       修改u-boot-2010.03/cpu/arm1176/u-boot.lds,添加nand_cp.o,如下:
    {
    cpu/arm1176/start.o(.text)
    cpu/arm1176/s3c64xx/cpu_init.o (.text)
    board/samsung/smdk6410/lowlevel_init.o (.text)
    cpu/arm1176/nand_cp.o(.text)
    lib_arm/board.o (.text)
    *(.text)
    }
       进入u-boot-2010.03/nand_spl/board/samsung,复制一个smdk6410,修改Makefile,作如下修改:
    COBJS =nand_boot.onand_ecc.os3c64xx.onand_cp.o
    在下面代码
    #fromSoCdirectory
    $(obj)cpu_init.S:
    @rm-f$@
    @ln-s$(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S$@
    之后添加
    $(obj)nand_cp.c:
    @rm-f$@
    @ln-s$(TOPDIR)/cpu/arm1176/nand_cp.c$@
       修改u-boot-2010.03/board/samsung/smdk6410/lowlevel_init.S,修改/*LEDononly#8*/LED灯的测试代码,将所有灯点亮,修改为:
    /* LED on only #8 */
    	
    ldr	r0, =ELFIN_GPIO_BASE
    	
    ldr	r1, =0x0001111
    	
    str	r1, [r0, #GPMCON_OFFSET]
    
    
    	
    ldr	r1, 0x000aaa
    	
    str	r1, [r0, #GPNPUD_OFFSET]
    
    
    	
    ldr	r1, =0x0000	
    str	r1, [r0, #GPNDAT_OFFSET]
    配置,编译,生成u-boot.bin,下到开发板上如下所示:
    U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410
    
    
    
    CPU:     S3C6400@533MHz
             
    Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 
    
    Board:   SMDK6410
    
    DRAM:  256 MB
    
    Flash:  0 kB
    
    NAND:  No oob scheme define for oobsize 32
     
    2048 MiB
    
    *** Warning - bad CRC, using default environment                                
                                                                    
    In:serial 
                                                              
    Out:serial  
                                                             
    Err:serial 
                                                              
    Net:cs8900  
                                                            
    Hit any key to stop autoboot:  0 
    
    板子上的4盏LED全亮!
    这就完成了u-boot移植的第一步。
     
    网卡DM9000移植:
       在u-boot-2010.03/include/configs/smdk6410.h中将CS8900的宏定义注释掉:
    //#define CONFIG_NET_MULTI
    //#define CONFIG_CS8900 /*wehaveaCS8900on-board*/
    //#define CONFIG_CS8900_BASE 0x18800300
    //#define CONFIG_CS8900_BUS16 /*followthe Linuxdriver*/
    然后添加DM9000网卡的宏定义:
    #defineCONFIG_NET_MULTI 1
    #defineCONFIG_DM9000_NO_SROM 1
    #defineCONFIG_dm9000
    #defineCONFIG_DRIVER_DM9000 1
    #defineCONFIG_DM9000_BASE 0x18800300
    #defineDM9000_IO CONFIG_DM9000_BASE
    #defineDM9000_DATA (CONFIG_DM9000_BASE+4)
    #defineCONFIG_DM9000_USE_16BIT
    #defineCONFIG_ETHADDR 00:40:5c:26:0a:5b
    #defineCONFIG_NETMASK 255.255.255.0
    #defineCONFIG_IPADDR 192.168.1.20
    #defineCONFIG_SERVERIP 192.168.1.10
    #defineCONFIG_GATEWAYIP 192.168.1.1
    //#define CONFIG_DM9000_DEBUG
    上面的IP和网关、子网掩码等根据自己的具体情况进行修改。接着打开u-boot-2010.03/net/eth.c,并且进入到函数inteth_initialize(bd_t*bis)中,在:
    #ifdefined(CONFIG_DB64460)|| defined(CONFIG_P3Mx)
    mv6446x_eth_initialize(bis);
    #endif

    后面添加:

    同样在u-boot-2010.03/net/net.c,
    1.将
    #defineARP_TIMEOUT 5000UL /*MillisecondsbeforetryingARPagain*/
    修改为
    #defineARP_TIMEOUT 5 /*MillisecondsbeforetryingARPagain*/

    2. 将

    if((t-NetArpWaitTimerStart)>ARP_TIMEOUT)

    修改为

    if((t-NetArpWaitTimerStart)>ARP_TIMEOUT*CONFIG_SYS_HZ

    3. 将

    NetSetTimeout(10000UL,PingTimeout);

    修改为

    NetSetTimeout(10*CONFIG_SYS_HZ,PingTimeout);

    接着进入u-boot-2010.03/net/tftp.c,找到void TftpStart(void)函数,用#if0 #endif注释掉下面的程序:

    #if0
    /*
    *Allowthe usertochooseTFTPblocksizeandtimeout
    *TFTPprotocolhasaminimaltimeoutof1second.
    */
    if((ep=getenv("tftpblocksize"))!=NULL)
    TftpBlkSizeOption=simple_strtol(ep,NULL,10);
    if((ep=getenv("tftptimeout"))!=NULL)
    TftpTimeoutMSecs=simple_strtol(ep,NULL,10);
    if(TftpTimeoutMSecs<1000){
    printf("TFTPtimeout(%ldms)toolow,"
    "setminimum=1000ms\n",
    TftpTimeoutMSecs);
    TftpTimeoutMSecs=1000;
    }
    debug("TFTPblocksize=%i,timeout=%ldms\n",
    TftpBlkSizeOption,TftpTimeoutMSecs);
    #endif

    再编译,下载,运行情况如下:

    U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410
    
    
    
    CPU:     S3C6400@533MHz
             
    Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 
    
    Board:   SMDK6410
    
    DRAM:  256 MB
    
    Flash:  0 kB
    
    NAND:  No oob scheme define for oobsize 32
     
    2048 MiB
    
    *** Warning - bad CRC, using default environment                                
                                                                                    
    
    In:    serial                                                                   
    
    Out:   serial                                                                   
    
    Err:   serial   
                                                                    
    Net:   dm9000                                                                  
     
    
    Hit any key to stop autoboot:  0 
    

    Nandflash读写:

    nandflash的控制都是这个套路,因为这就是硬件协议,先使能芯片->发送命令->发送地址序列->读或写数据寄存器->判断准备就绪状态->禁止芯片,这是对nand flash操作的大体过程,根据发送命令的不同还有些区别。

       进入u-boot-2010.03/driver/mtd/nand/,修改nand_ids.c,作如下修改:

    //{"NAND 2GiB3,3V8-bit",0xD5,0,2048,0,LP_OPTIONS},
    {"NAND2GiB3,3V8-bit", 0xD5,4096,2048,512*1024,LP_OPTIONS},

    编译下载,运行如下:

    U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410
    
    
    
    CPU:     S3C6400@533MHz
             
    Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 
    
    Board:   SMDK6410
    
    DRAM:  256 MB
    
    Flash:  0 kB
    
    NAND:  raise: Signal # 8 caught
    
    raise: Signal # 8 caught
    
    raise: Signal # 8 caught
    
    2048 MiB
    
    *** Warning - bad CRC, using default environment                                
                                                                                    
    
    In:    serial                                                                   
    
    Out:   serial                                                                   
    
    Err:   serial 
                                                                      
    Net:   dm9000                                                                  
     
    
    Hit any key to stop autoboot:  0 

    在NAND: 后面出现raise: Signal # 8 caught这些信息,虽然不影响运行,但是确实是一个BUG,花了一天的时间在网上查了一下,都是关于2410的,偶然在网上看到一位朋友也是碰到同样的问题,修改跟移植2410的一样处理,我试了,

    修改/cpu/arm/arm1176/s3c64xx/timer.c,
    imer_load_val用gd->timer_rate_hz替代;
    timer_clk用gd->tbl替代;
    timestamp用gd->timer_reset_value替代;
    lastdec用gd->lastinc替代。

    编译的时候出现gd_t这个结构体根本就没有timer_rate_hz这几个成员变量,可能是版本的原因,在论坛上求助说修改lib_arm/eabi_compact.c,直接将printf("raise: Signal # %d caught\n", signum);注释掉,至今我是这样解决的,不影响启动。修改后启动如下:

    U-Boot 2010.03 ( 8��月 04 2012 - 21:49:40) for SMDK6410
    
    
    
    CPU:     S3C6400@533MHz
             
    Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode) 
    
    Board:   SMDK6410
    
    DRAM:  256 MB
    
    Flash:  0 kB
    
    NAND:  2048 MiB
    
    *** Warning - bad CRC, using default environment                                
                                                                                    
    
    In:    serial                                                                   
    
    Out:   serial                                                                   
    
    Err:   serial  
                                                                     
    Net:   dm9000                                                                  
     
    
    Hit any key to stop autoboot:  0 

    这下正常了!

    添加自己的命令:

        boot有许多指令,nandinfo,set 等等。现在我们来给u-boot添加我们想要的指令。

    U-Boot的每一个命令都是通过U_Boot_CMD宏定义的。这个宏在include/command.h头文件中定义,每一个命令定义一个cmd_tbl_t结构体。

    这样每一个U-Boot命令有一个结构体来描述。结构体包含的成员变量:命令名称、最大参数个数、重复数、命令执行函数、用法、帮助。

    从控制台输入的命令是由common/command.c中的程序解释执行的。(这就是我要找的)find_cmd()负责匹配输入的命令,从列表中找出对应的命令结构体。

    基于U-Boot命令的基本框架,来分析一下简单的icache操作命令,就可以知道添加新命令的方法。

    (1)定义CACHE命令。在include/cmd_confdefs.h中定义了所有U-Boot命令的标志位。

    如果有更多的命令,也要在这里添加定义。

    (2)实现CACHE命令的操作函数。下面是common/cmd_cache.c文件中icache命令部分的代码。

    U-Boot的命令都是通过结构体__U_Boot_cmd_##name来描述的。根据U_Boot_CMD在include/command.h中的两行定义可以明白。

    还有,不要忘了在common/Makefile中添加编译的目标文件。

    (3)打开CONFIG_COMMANDS选项的命令标志位。这个程序文件开头有#if语句需要预处理是否包含这个命令函数。CONFIG_COMMANDS选项在开发板的配置文件中定义。例如:SMDK2410平台在include/configs/smdk2410.h中有如下定义。

    按照这3步,就可以添加新的U-Boot命令。

     

    这下我们就知道怎样添加自己的Uboot命令了,下面我以添加info命令为例:

    1. 进入u-boot-2010.03/commom文件夹,新建cmd_info.c文件。代码如下:

    #include<common.h>
    #include<command.h>
    int do_info(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[])
    {
    printf("u-boot is made by lixiaoming!\n");
    return0;
    }
    U_BOOT_CMD(info,CONFIG_SYS_MAXARGS,1,do_info,"usageinfo", "helpinfo");
    

    2. 然后在common/Makefile 中 的#command 添 加 如 下 内 容 :

    COBJS-$(CONFIG_CMD_INFO)+=cmd_hello.o

    3. 在u-boot-2010.03/include/config_cmd_default.h中添加CONFIG_CMD_INFO命令,同时也在config_cmd_all.c中定义

    这下编译,下载,运行进入uboot命令模式后输入:info,就会显示信息了;

    SMDK6410# info
    u-boot is made by lixiaoming!

     

    内核引导:

    由于uboot只能引导uImage,因此需要把编译成的zImage转换成uImage,先进入u-boot根目录下,把tools/下mkimage复制到主机的/bin目录下,然后进入到linux-3.0.4/下输入指令:make uImage。

    #defineCONFIG_BOOTARGS "root=/dev/mtdblock2 rootfstype=yaffs2 console=ttySAC0,115200"

    是在smdk6410.h里面。这要根据linux内核mach-ok6410.c中的:

    staticstructmtd_partitionok6410_nand_part[]={
    {
    .name ="Bootloader",
    .offset =0,
    .size =(1*SZ_1M),
    .mask_flags =MTD_CAP_NANDFLASH,
    },
    {
    .name ="Kernel",
    .offset =(1*SZ_1M),
    .size =(5*SZ_1M),
    .mask_flags =MTD_CAP_NANDFLASH,
    },
    {
    .name ="User",
    .offset =(6*SZ_1M),
    .size =(120*SZ_1M),
    },
    {
    .name ="FileSystem",
    .offset =MTDPART_OFS_APPEND,
    .size =MTDPART_SIZ_FULL,
    }
    };

    上面主要是对MTD进行分区,可以自己分配,不过一定要把Uboot与内核结合起来。

      到此,自己的6410开发板的Uboot基本移植成功,现在自己可以添加命令了,后面的就可以添加启动后进入主菜单实现下载等功能的命令,在后面的几天我也移植了Linux3.0.4内核到开发板上,成功运行,并移植支持yaff2文件系统的读写,再后面自己制作文件系统镜像,成功运行完整的嵌入式系统!

    在移植的过程中感谢网上朋友的无私分享,我也记录一下自己的移植工程,与大家一起共同进步,有一天可以成为嵌入式牛人!

    参照文章:

    宁静致远的文章《基于OK6410的u-boot2010.03移植过程》 (http://wenku.baidu.com/view/ae78a00390c69ec3d5bb75ce.html?st=1

    懒惰人的懒惰事 (http://hi.baidu.com/shangyefeng/item/4df893ee978c5e245b2d646f

  • 相关阅读:
    Android中Context具体解释 ---- 你所不知道的Context
    JDK6、Oracle11g、Weblogic10 For Linux64Bit安装部署说明
    matplotlib 可视化 —— 定制 matplotlib
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    指数函数的研究
    指数函数的研究
    指数分布的研究
  • 原文地址:https://www.cnblogs.com/lixiaoming90/p/2633151.html
Copyright © 2011-2022 走看看