原创 U-Boot

2009-7-2 11:19 1771 3 3 分类: MCU/ 嵌入式

U-Boot移植过程
获得发布的最新版本U-Boot源码,与Linux内核源码类似,也是 bzip2的压缩格式。可从U-Boot的官方网站http://sourceforge.net/projects/U-Boot上获得;
阅读相关文档,主要是U-Boot源码根目录下的README文档和U-Boot官方网站的DULGThe 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过程中遇有问题,在参考相关文<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


下载:


         http://sourceforge.net/projects/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-bootelf映像)和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启动模式,重启即可

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

zhujun74_602010376 2013-2-19 17:11

肯定是好东西,似乎主要是处理器架构和存储器的内容,U-Boot烧写地址怎么确定的呢?

用户190536 2009-4-21 17:46

同意楼上,我邮箱xiyuweiyanxia@163.com。最近做毕设,博主最好帮我发一份FPGA设计的整套过程代码及原理图。自己实在是有点搞不懂。谢谢了。

用户1601871 2009-4-19 04:19

看不到插图,能否发一个?谢谢了! g007zhao@gmail.com
相关推荐阅读
用户1271976 2009-07-02 11:18
ViVi
head.s     config.h(包含autoconf.h)---autoconf.h(配置选项)              linkage.h-(链接相关)              mach...
用户1271976 2009-07-02 11:11
通信接口
并行接口:是指8位数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,容易出错。(1)SPP 标准工作模式。SPP 数据是半双工单向传输的,...
用户1271976 2009-07-02 11:06
安装VMware
安装VMware Workstation<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&g...
用户1271976 2009-04-02 14:33
USB体系结构
USB总线接口层:物理连接、电气信号环境、信息包传输机制;主机一方由USB主控制器和根集线器组成,而USB方则由设备中的USB接口组成。USB设备层:由主机方的USB系统软件和设备方的USB设备逻辑视...
用户1271976 2009-02-09 13:28
USB基础知识
 USB的重要关键字:1、端点:位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有惟一的确定地址,有不同的传输特性(如输入端点、输出端点、配置端点、批量传输端点)2...
EE直播间
更多
我要评论
1
3
关闭 站长推荐上一条 /3 下一条