Chinaunix首页 | 论坛 | 博客
  • 博客访问: 344901
  • 博文数量: 92
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 960
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-21 19:38
文章分类

全部博文(92)

文章存档

2010年(71)

2009年(21)

我的朋友

分类: 嵌入式

2010-04-06 17:19:48

U-boot移植 NAND

虽然失败了但还是要祭奠一下,我的努力!!

http://bamv.spaces.live.com/blog/cns!569B6B5EA6A99B9E!276.entry(汇编这块讲的很仔细)

(分析了nand nand_legacy

 

要注意的几点:

1.       drivers/ 目录下因为原来的nand nand_legacy 是小页NAND,而我的开发板是大页NAND的,所以需重新导入。另外将nand_flash.c 加入cpu/arm920t/s3c24x0,将nand.h加入include/

2.       include/s3c2410.h include/s3c24x0.h 是关联的

3.       board/  include/configs/ 是关联的 可以全删只保留 TX2440 & TX2440.h

 

首先在配置文件include/configs/TX2440.h的宏CONFIG_COMMANDS中增加CFG_CMD_NAND (大概在82)

编译,出现nand.c的错误和警告

解决:在include/configs/TX2440.h的最后面增加3个宏:

/*NAND flash settings*/

#define CFG_NAND_BASE        0      //无实际意义:基地址,在board_nand_init中重新定义

#define CFG_MAX_NAND_DEVICE     1   //NAND Flash设备数目为1

#define NAND_MAX_CHIPS          1   //每个NAND设备由1NADN芯片组成

修改配置文件后再编译,只有一个错误了“board_nand_init”函数未定义

 

board_nand_init需要自己编写,在cpu/arm920t/s3c24x0下新建nand_flash.c

编写之前,需要针对S3C2440 NAND Flash定义一些数据结构和函数

include/s3c24x0.h增加(不是替换)S3C2440_NAND数据结构(168行)

/* NAND FLASH (see S3C2440 manual chapter 6) */

typedef struct {

       S3C24X0_REG32  NFCONF;

       S3C24X0_REG32  NFCONT;

       S3C24X0_REG32  NFCMD;

       S3C24X0_REG32  NFADDR;

       S3C24X0_REG32  NFDATA;

    S3C24X0_REG32  NFMECCD0;

    S3C24X0_REG32  NFMECCD1;

    S3C24X0_REG32  NFSECCD;

       S3C24X0_REG32  NFSTAT;

    S3C24X0_REG32  NFESTAT0;

    S3C24X0_REG32  NFESTAT1;

    S3C24X0_REG32  NFMECC0;

    S3C24X0_REG32  NFMECC1;

    S3C24X0_REG32  NFSECC;

       S3C24X0_REG32  NFSBLK;

    S3C24X0_REG32  NFEBLK;

} /*__attribute__((__packed__))*/ S3C2440_NAND;

 

include/s3c2410.h中仿照S3C2410_GetBase_NAND函数(96行)

定义2440的函数:

static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)

{

       return (S3C2440_NAND * const)S3C2410_NAND_BASE;

}

 

cpu/arm920t/s3c24x0/nand_flash.c中添加代码,是从Linux-2.6.13/drivers/mtd/nand/s3c2410.c中移植过来的,代码略。

 

修改cpu/arm920t/s3c24x0/Makefile

COBJS  =  加上一项nand_flash.o

 

出现的错误,是交叉工具编辑链的问题,如有知道可交流,别的嵌入式问题也可以,QQ 1217866355

-Map u-boot.map -o u-boot

arm-linux-ld: ERROR: /usr/local/arm/3.3.2/lib/gcc-lib/arm-linux/3.3.2/libgcc.a(_udivdi3.oS) uses hardware FP, whereas u-boot uses software FP

File in wrong format: failed to merge target specific data of file /usr/local/arm/3.3.2/lib/gcc-lib/arm-linux/3.3.2/libgcc.a(_udivdi3.oS)

arm-linux-ld: ERROR: /usr/local/arm/3.3.2/lib/gcc-lib/arm-linux/3.3.2/libgcc.a(_clz.oS) uses hardware FP, whereas u-boot uses software FP

File in wrong format: failed to merge target specific data of file /usr/local/arm/3.3.2/lib/gcc-lib/arm-linux/3.3.2/libgcc.a(_clz.oS)

make: *** [u-boot] Error 1

 

编译后生成uboot镜像,但这里注意,现在还不支持NAND FLASH启动,只能烧到NOR FLASH中。要支持NAND FLASH启动,要修改cpu/arm920t/start.S,还要编写nand启动函数.

cpu/arm920t/start.S(添加支持NAND flash

2410的启动代码可以在外部的NAND FLASH上执行,启动时,NAND FLASH的前4KB(地址为0x00000000OM[1:0]=0)将被装载到SDRAM中被称为Setppingstone的地址中,然后开始执行这段代码。启动以后,这4KB的空间可以做其他用途,start.S加入搬运代码如下:

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

#ifndef CONFIG_S3C2410_NAND_BOOT

relocate:                      /* relocate U-Boot to RAM      */

       adr  r0, _start              /* r0 <- current position of code   */

       ldr   r1, _TEXT_BASE         /* test if we run from flash or RAM */

       cmp     r0, r1                  /* don't reloc during debug         */

       beq     stack_setup

 

       ldr   r2, _armboot_start

       ldr   r3, _bss_start

       sub  r2, r3, r2              /* r2 <- size of armboot            */

       add  r2, r0, r2              /* r2 <- source end address         */

 

copy_loop:

       ldmia      r0!, {r3-r10}         /* copy from source address [r0]    */

       stmia      r1!, {r3-r10}         /* copy to   target address [r1]    */

       cmp r0, r2                    /* until source end addreee [r2]    */

       ble   copy_loop

#else /* NAND BOOT */

relocate:

copy_myself:

       @ reset NAND

       mov r1, #NAND_CTL_BASE

       ldr   r2, =0xf830           @ initial value enable

       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]

 

       /* stack setup */

       ldr   r0, _TEXT_BASE                /* upper 128 KiB: relocated uboot   */

       sub  r0, r0, #CFG_MALLOC_LEN            /* malloc area                      */

       sub  r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */

#ifdef CONFIG_USE_IRQ

       sub  r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

       sub  sp, r0, #12                   /* leave 3 words for abort-stack    */

 

       @ copy u-boot to RAM             

       ldr   r0, _TEXT_BASE         @ 设置第0参数: UBOOTRAM中的起始地址

       mov     r1, #0x0        @ 设置第1参数:NAND闪存的起始地址

       mov r2, #CFG_UBOOT_SIZE            @ 设置第2参数: U-BOOT的长度(128KB)

       bl    nand_read_ll        @ 调用nand_read_whole(),NAND闪存中的数据读入到RAM

 

       tst   r0, #0x0                              @ 如果函数的返回值为0,表示执行成功

       beq  ok_nand_read                    @ 执行内存比较,把RAM中的前4K内容与NAND闪存中的前4K内容进行比较, 如果完全相同, 则表示搬移成功

 

ok_nand_read:

       @ verify

       mov r0, #0

       ldr   r1, _TEXT_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:

1:    b     1b

done_nand_read:

#endif /* NAND_BOOT */

#endif     /* CONFIG_SKIP_RELOCATE_UBOOT */

 

其中,nand_reset ()nand_read_whole()被加在/board/wch2410/wch2410.c中。

支持U-BOOT命令设计
      
U-BOOT下对nand闪存的支持主要是在命令行下实现对nand闪存的操作。对nand闪存实现的命令为:nand info(打印nand Flash信息)nand device(显示某个nand闪存设备)nand read(读取nand闪存)nand write(nand闪存)nand erease(擦除nand闪存)nand bad(显示坏块)等。

       用到的主要数据结构有:struct nand_flash_devstruct nand_chip。前者包括主要的芯片型号、存储容量、设备IDI/O总线宽度等信息;后者是具体对NAND闪存进行操作时用到的信息。

a. 设置配置选项
      
修改/include/configs/wch2410.h,主要是在CONFIG_COMMANDS中打开CFG_CMD_NAND选项。定义NAND闪存控制器在SFR区中的起始寄存器地址、页面大小,定义NAND闪存命令层的底层接口函数等。

b. 加入NAND闪存芯片型号
      
/include/linux/mtd/ nand_ids.h中对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[] = {
......
{"Samsung K9F1208U0A", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
.......
                                                 }
这样对于该款NAND闪存芯片的操作才能正确执行。

c.
编写NAND闪存初始化函数
/board/wch2410/wch2410.c中加入nand_init()函数。
void nand_init(void)
{
/*
初始化NAND闪存控制器, 以及NAND闪存芯片 */
nand_reset();
/*
调用nand_probe()来检测芯片类型
*/
printf ("%4lu MB\n", nand_probe(CFG_NAND_BASE) >> 20);
}

该函数在启动时被start_armboot()调用。

阅读(1218) | 评论(0) | 转发(0) |
0

上一篇:U-boot 移植--NOR

下一篇:Linux 内核简介

给主人留下些什么吧!~~