新闻  |   论坛  |   博客  |   在线研讨会
U-Boot
mayer | 2009-07-10 19:58:23    阅读:2898   发布文章

U-Boot

 

U-Boot移植过程
① 获得发布的最新版本U-Boot源码,与Linux内核源码类似,也是 bzip2的压缩格式。可从U-Boot的官方网站http://sourceforge.net/projects/U-Boot上获得;
② 阅读相关文档,主要是U-Boot源码根目录下的README文档和U-Boot官方网站的DULG(The DENX U-Boot and Linux Guide)文档http://www.denx.de/twiki/bin/view/DULG/Manual。尤其是DULG文档,从如何安装建立交叉开发环境和解决U-Boot移植中常见问题都一一给出详尽的说明;
③ 订阅U-Boot用户邮件列表http://lists.sourceforge.net/lists/listinfo/u-boot-users。在移植U-Boot过程中遇有问题,在参考相关文

下载:

         http://sourceforge.net/projects/U-Boot

解压

              进入目录

            $ rm -f u-boot
        $ bunzip2 < u-boot-0.4.5.tar.bz2 | tar xf -
        $ ln -s u-boot-0.4.5 u-boot
        $ cd u-boot

移植:

一、在顶层Makefile中为开发板添加新的配置选项

       smdk2410_config   :       unconfig

              @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

    参考上面2行,添加下面2行。

       real2410_config   :       unconfig

              @./mkconfig $(@:_config=) arm arm920t real2410 NULL s3c24x0

 

二、在board中创建一个新目录real2410存放开发板相关的代码,并且添加文     件。

    cp rf board/smdk2410 board/real2410

    #cd board/real2410

    #mv smdk2410.c real2410.c

 

三、修改board/real2410/Makefile
    将28行的
  OBJS    := smdk2410.o flash.o
    改为       OBJS    := real2410.o flash.o

 

四、修改board/real2410/flash.c 参考board/dave/common/flash.c

      #define CMD_ERASE_BLOCK 0x0050

       #elif defined(CONFIG_SST_39VF1601)

                     (SST_MANUFACT & FLASH_VENDMASK) |

                     (SST_ID_xF1601 & FLASH_TYPEMASK);

    在int flash_erase (flash_info_t * info, int s_first, int s_last)

       #if defined(CONFIG_SST_39VF1601) /* Ali + */

                     *addr = CMD_ERASE_BLOCK;

       #else

                     *addr = CMD_ERASE_CONFIRM;

       #endif

    在volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)

       #if defined(CONFIG_SST_39VF1601) /* Ali + */

              MEM_FLASH_ADDR1 = CMD_PROGRAM;

       #else

              MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;

             *addr = CMD_PROGRAM;

       #endif

 

五、为开发板添加新的配置文件

    $cp include/configs/smdk2410.h  include/configs/real2410.h

       修改include/configs/real2410.h

      #define CONFIG_SST_39VF1601        1

       //#define CONFIG_AMD_LV400          1    

       #ifdef CONFIG_SST_39VF1601

              #define PHYS_FLASH_SIZE        0x00200000 /* 2MB */

              #define CFG_MAX_FLASH_SECT   (35)

              #define CFG_ENV_ADDR           (CFG_FLASH_BASE + 0x1F0000)  

       #endif

 

六、$ make real2410_config

          $ make

     生成u-boot(elf映像)和u-boot.bin

        

七、支持NAND FLASH读写

①修改include/configs/real2410.h

    #define rNFCONF (*(volatile unsigned int *)0x4e000000)

    #define rNFCMD (*(volatile unsigned char *)0x4e000004)

    #define rNFADDR (*(volatile unsigned char *)0x4e000008)

    #define rNFDATA (*(volatile unsigned char *)0x4e00000c)

    #define rNFSTAT (*(volatile unsigned int *)0x4e000010)

    #define rNFECC (*(volatile unsigned int *)0x4e000014)

    #define rNFECC0 (*(volatile unsigned char *)0x4e000014)

    #define rNFECC1 (*(volatile unsigned char *)0x4e000015)

    #define rNFECC2 (*(volatile unsigned char *)0x4e000016)

 

    在CONFIG_COMMANDS中, 打开CFG_CMD_NAND选项.

 

    #if(CONFIG_COMMANDS&CFG_CMD_NAND)

    #define CFG_NAND_BASE   0x4E000000

    #define CFG_NAND_LEGACY 1

    #define CFG_MAX_NAND_DEVICE 1

                                                                                     

    #define SECTORSIZE 512

    //#define NAND_SECTOR_SIZE SECTORSIZE

    //#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE-1)

    #define ADDR_COLUMN             1

    #define ADDR_PAGE               3

    #define ADDR_COLUMN_PAGE        4

                                                                                      

    #define NAND_ChipID_UNKNOWN     0x00

    #define NAND_MAX_FLOORS         1

    #define NAND_MAX_CHIPS          1

                                                                                     

    #define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}

    #define NAND_DISABLE_CE(nand) {rNFCONF|=(1<<11);}

    #define NAND_ENABLE_CE(nand)  {rNFCONF&=~(1<<11);}

                                                                                     

    #define WRITE_NAND_COMMAND(d,adr) do {rNFCMD=d;}while(0)

    #define WRITE_NAND_ADDRESS(d,adr) do {rNFADDR=d;}while(0)

    #define WRITE_NAND(d,adr) do {rNFDATA=d;}while(0)

    #define READ_NAND(adr) (rNFDATA)

    /*the following functions are NOP's because S3C24x0 handle this in    hardware*/

    #define NAND_CTL_CLRALE(nandptr)

    #define NAND_CTL_SETALE(nandptr)

    #define NAND_CTL_CLRCLE(nandptr)

    #define NAND_CTL_SETCLE(nandptr)

                                                                                     

    #define CONFIG_MTD_NAND_VERIFY_WRITE 1

    //#define CONFIG_MTD_NAND_ECC_JFFS2 1

                                                                                     

    #endif //(CONFIG_COMMANDS&CFG_CMD_NAND)

 

②加入自己的Nand Flash芯片型号

    在include/linux/mtd/ nand_ids.h中的对如下结构体赋值进行修改:

    static struct nand_flash_dev nand_flash_ids[] = {

    ......

    {"Samsung K9F1208U0B", NAND_MFR_SAMSUNG, 0x76, 26, 0, 4, 0x4000, 0},

         .......

    }

 

③编写自己的Nand Flash初始化函数

 

    在board/real2410/real2410.c中加入nand_init()函数.

    void nand_reset(void)

    {

        int i;

        rNFCONF=0xf830;

        rNFCONF&=~(1<<11);

        rNFCMD=0xff;

        for(i=0;i<10;i++);

        while(!(rNFSTAT&(1<<0)));

        rNFCONF|=(1<<11);

    }

   

    void nand_init(void)

    {

       /* 初始化Nand Flash控制器, 以及Nand Flash 芯片 */

       nand_reset();

       /* 调用nand_probe()来检测芯片类型 */

       printf ("%4lu MB\n", nand_probe(CFG_NAND_BASE) >> 20);

    }

 

④  make

 

 

 

       在board/real2410加入NAND Flash读函数,建立nand_read.c, (copy from vivi)

修改include/configs/real2410.h

#define CONFIG_S3C2410_NAND_BOOT 1

#ifdef CONFIG_S3C2410_NAND_BOOT
       #define STACK_BASE    0x33f00000
       #define STACK_SIZE    0x8000
       #define UBOOT_RAM_BASE    0x33f80000
       /* NAND Flash Controller */
       #define NAND_CTL_BASE            0x4E000000
       #define bINT_CTL(Nb)        __REG(INT_CTL_BASE + (Nb))
       /* Offset */
       #define oNFCONF               0x00
       #define oNFCMD                0x04
       #define oNFADDR               0x08
       #define oNFDATA               0x0c
       #define oNFSTAT               0x10
       #define oNFECC                0x14

#endif


修改cpu/arm920t/start.S文件
ldr pc, _start_armboot之前加入:
#ifdef CONFIG_S3C2410_NAND_BOOT
  bl    copy_myself
 
  @ jump to ram
  ldr   r1, =on_the_ram
  add  pc, r1, #0
  nop
  nop
  1:    b     1b          @ infinite loop
 
on_the_ram:
#endif

_start_armboot: .word start_armboot之后加入:
#ifdef CONFIG_S3C2410_NAND_BOOT
copy_myself:
  mov r10, lr
@ reset NAND
  mov r1, #NAND_CTL_BASE
  ldr   r2, =0xf830           @ initial value
  str   r2, [r1, #oNFCONF]
  ldr   r2, [r1, #oNFCONF]
  bic  r2, r2, #0x800              @ enable chip
  str   r2, [r1, #oNFCONF]
  mov r2, #0xff         @ RESET command
  strb r2, [r1, #oNFCMD]
  mov r3, #0                   @ wait

1:add  r3, r3, #0x1
  cmp r3, #0xa
  blt   1b
2:ldr   r2, [r1, #oNFSTAT]      @ wait ready
  tst    r2, #0x1
  beq  2b
  ldr   r2, [r1, #oNFCONF]
  orr  r2, r2, #0x800              @ disable chip
  str   r2, [r1, #oNFCONF]

@ get read to call C functions (for nand_read())
  ldr   sp, DW_STACK_START       @ setup stack pointer
  mov fp, #0                    @ no previous frame, so fp="0"

@ copy vivi to RAM
  ldr   r0, =UBOOT_RAM_BASE
  mov     r1, #0x0
  mov r2, #0x20000
  bl    nand_read_ll
  tst    r0, #0x0
  beq  ok_nand_read

#ifdef CONFIG_DEBUG_LL
  bad_nand_read:
  ldr   r0, STR_FAIL
  ldr   r1, SerBase
  bl    PrintWord
1:b     1b          @ infinite loop
  #endif

ok_nand_read:
#ifdef CONFIG_DEBUG_LL
  ldr   r0, STR_OK
  ldr   r1, SerBase
  bl    PrintWord
#endif

@ verify
  mov r0, #0
  ldr   r1, =UBOOT_RAM_BASE
  mov r2, #0x400     @ 4 bytes * 1024 = 4K-bytes
go_next:
  ldr   r3, [r0], #4
  ldr   r4, [r1], #4
  teq   r3, r4
  bne  notmatch
  subs r2, r2, #4
  beq  done_nand_read
  bne  go_next

notmatch:
#ifdef CONFIG_DEBUG_LL
  sub  r0, r0, #4
  ldr   r1, SerBase
  bl    PrintHexWord
  ldr   r0, STR_FAIL
  ldr   r1, SerBase
  bl    PrintWord
#endif
1:b     1b
done_nand_read:
#ifdef CONFIG_DEBUG_LL
  ldr   r0, STR_OK
  ldr   r1, SerBase
  bl    PrintWord
#endif
  mov pc, r10
@ clear memory
@ r0: start address
@ r1: length
  mem_clear:
  mov r2, #0
  mov r3, r2
  mov r4, r2
  mov r5, r2
  mov r6, r2
  mov r7, r2
  mov r8, r2
  mov r9, r2

clear_loop:
  stmia      r0!, {r2-r9}
  subs r1, r1, #(8 * 4)
  bne  clear_loop
  mov pc, lr

#endif @ CONFIG_S3C2410_NAND_BOOT

在文件的最后加入:
   .align     2
DW_STACK_START:
 .word      STACK_BASE+STACK_SIZE-4



 

 

9. 支持nandflash读写

include/configs/yl2410.h添加CFG_CMD_NAND

编译,在cmd_nand.c产生很多错误,原因是yl2410根本就没有nandflash的驱动支持,如:

NAND_DISABLE_CE()

NAND_ENABLE_CE()

NAND_WAIT_READY()

WRITE_NAND_COMMAND()

WRITE_NAND_COMMANDW()

WRITE_NAND_ADDRESS()

WRITE_NAND()

这些函数的实现都很简单,参考at91rm9200dk.h,对nand的驱动支持全部添加在include/configs/yl2410.h

加载运行,nand write 0x32000000 0x20000 0x200 (nand flash512字节),报错,nand_write_page : Failed write verify 应该是sector(page)没擦除,nand erase 0x20000 0x200,出错,提示边界没对齐,查得资料获知,erase单位是一个block(16k)program单位是一个sector(512B),按要求先擦除后写入,正确

 

10. 支持nandflash启动

cpu/arm920t/start.S添加对nandflash重定位的支持,在board/yl2410/nand_boot.c添加对nandflash的初始化和读取操作,在nandflash启动时被start.s调用,注意nand_boot.c的所有代码以及被调用的代码不能超出4k,因为按nandflash启动模式,开始只有4k的运行空间。

编译获得u-boot.bin

Tftp 0x32000000 u-boot.bin (load u-boot.bin to 0x32000000)

Nand erase 0 0x20000 (erase nandflash first 128k)

Nand write 0x32000000 0 0x20000 (write u-boot.bin to nandflash)

设置跳线到nandflash启动模式,重启即可

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客