Boot 1.3.4到GT2440(第二版2.0)(5)

11.  为了在uboot里显示你现在的nand的大小,修改include/linux/mtd/nand_ids.h的结构体nand_flash_ids   /*这个结构体是为了在初始化nand时,用读到的id和这里面匹配,如果有就输出该nand的信息*/

注意:根据朋友小子 提醒,其实不用添加这一步的,而是在drivers/mtd/nand/nand_ids.h里已经有定义了,可以去看一下,这里也不删这段了,就当是告诉这结构体每一位的作用

static struct nand_flash_dev nand_flash_ids[] = {

....../*结构体nand_flash_dev 在doc2000.h中定义*/

/*厂家 型号,生产商编号,本模块的编号,总共容纳地址的位数,存储页字节数是否为256 ,地址需要多少字节数减一(行列地址总共) ,擦除1个block的大小,是否为16位总线*/
    {"Samsung KM29N16000",NAND_MFR_SAMSUNG, 0x64, 21,1, 2, 0x1000, 0},
   {"Samsung K9F2G08U0B",   NAND_MFR_SAMSUNG, 0xDA, 28, 0, 4, 0x10000, 0},
   {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000, 0},
......

};

       其中"SamsungK9F2G08U0B"是nand的名字,无关紧要

       NAND_MFR_SAMSUNG是该nand的makercode 三星的是0xec

       0xDA是本模块的编号,也就是device code,笔者的为0xda

       28是你的芯片总共容纳的地址位数,也就是有效的地址位数,这个地方控制你显示的大小的。

0, 即是否为256字节一页,笔者的为2048一页,所以为0

0x10000为擦除1个block的大小,简单来说就是一个block的大小,本flash为1block= 64*1page = 64*2048 = 0x20000

1为是否16位总线,笔者的为8位

 

12. 修改lib_arm中的board.c添加几个debug信息,即点几个灯

#include<common.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
#include <version.h>
#include <net.h>

 

......

 

static intdisplay_banner (void)
{      

        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

        gpio->GPFBDAT =0x7f8e; 

//在串口初始化和console初始化完成,串口输出信息之前,LED1、LED2、LED3会亮起!

   printf ("\n\n%s\n\n", version_string);
    debug ("U-Boot code: %08lX -> %08lX  BSS: ->%08lX\n",
           _armboot_start,_bss_start, _bss_end);
    printf("U-Boot code: %08lX -> %08lX  BSS: ->%08lX\n",   
       _armboot_start, _bss_start, _bss_end);     
#ifdef CONFIG_MODEM_SUPPORT
    debug ("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
    debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);
    debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif

    return (0);
}

 

......

voidstart_armboot (void)

{

        init_fnc_t **init_fnc_ptr;

        char *s;

#ifndefCFG_NO_FLASH

        ulong size;

#endif

#ifdefined(CONFIG_VFD) || defined(CONFIG_LCD)

        unsigned long addr;

#endif

        S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

......

        gpio->GPFDAT = 0x7f0e; 

//在进入命令提示符之前,四个LED会同时亮起!

        /* main_loop() can return to retry autoboot, if so just run it again. */

        for (;;) {

                  main_loop ();

        }

 

        /* NOTREACHED - no way out of command loop except booting */

}

/*到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误*/

       15. 修改nor flash写入功能的代码,因为AMD与SST写时序有差别,所以要修改

在board/gt2440/flash.c里

//#define CMD_ERASE_CONFIRM 0x00000030

#define CMD_ERASE_CONFIRM    0x00000050

#if defined(CONFIG_SST_VF1601)

#define MEM_FLASH_ADDR1              (*(volatileu16 *)(CFG_FLASH_BASE + (0x00005555 << 1)))

#define MEM_FLASH_ADDR2              (*(volatileu16 *)(CFG_FLASH_BASE + (0x00002AAA << 1)))

#else

#define MEM_FLASH_ADDR1              (*(volatileu16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))

#define MEM_FLASH_ADDR2              (*(volatileu16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))

#endif                        

 

#elif defined(CONFIG_AMD_LV800)

                                                 (AMD_MANUFACT& FLASH_VENDMASK) |

                                                 (AMD_ID_LV800B& FLASH_TYPEMASK);

#elif defined(CONFIG_SST_VF1601)

                                                 (SST_MANUFACT& FLASH_VENDMASK) |

                                                 (SST_ID_xF1601& FLASH_TYPEMASK);

#else

#error "Unknown flash configured"

#ifndef CONFIG_SST_VF1601

                                          ……

                                                        flash_info[i].start[j] =

                                                               flashbase+ (j - 3) * MAIN_SECT_SIZE;

                                                 }

#else

                                                        flash_info[i].start[j]=

                                                               flashbase+ (j) * MAIN_SECT_SIZE;

#endif

void flash_print_info (flash_info_t * info)

case (SST_MANUFACT & FLASH_VENDMASK):

                                          printf("SST:");

                                          break;

……

case (SST_ID_xF1601 & FLASH_TYPEMASK):

                                          printf("1xSST39VF1601(2MB)\n");

                                          break;

int flash_erase (flash_info_t * info, ints_first, int s_last)

……

#ifdef CONFIG_SST_VF1601

                                          if((info->flash_id & FLASH_VENDMASK) !=

                                                 (SST_MANUFACT& FLASH_VENDMASK)) {

                                                               returnERR_UNKNOWN_FLASH_VENDOR;

                                          }

#else

if ((info->flash_id & FLASH_VENDMASK)!=

                                        (AMD_MANUFACT & FLASH_VENDMASK)) {

                                          returnERR_UNKNOWN_FLASH_VENDOR;

                                    }

#endif

int flash_erase (flash_info_t * info, ints_first, int s_last)

#if 0

                                                 /*wait until flash is ready */

                                                 chip= 0;

 

                                                 do{

                                                        result= *addr;

 

                                                        /*check timeout */

                                                        if(get_timer_masked () >

                                                            CFG_FLASH_ERASE_TOUT) {

                                                               MEM_FLASH_ADDR1= CMD_READ_ARRAY;

                                                               chip= TMO;

                                                               break;

                                                        }

 

                                                        if(!chip

                                                            && (result & 0xFFFF) &BIT_ERASE_DONE)

                                                               chip= READY;

 

                                                        if(!chip

                                                            && (result & 0xFFFF) &BIT_PROGRAM_ERROR)

                                                               chip= ERR;

 

                                                 }while (!chip);

 

                                                 MEM_FLASH_ADDR1= CMD_READ_ARRAY;

 

                                                 if(chip == ERR) {

                                                        rc= ERR_PROG_ERROR;

                                                        gotooutahere;

                                                 }

                                                 if(chip == TMO) {

                                                        rc= ERR_TIMOUT;

                                                        gotooutahere;

                                                 }

 

                                                 printf("ok.\n");

                                          }else {   /* it was protected */

 

                                                 printf("protected!\n");

                                          }

                                    }

#endif

/**********************************************/

/*wait until flash is ready*/

                                          while(1){

                                                 unsignedshort i;

                                                 i=  *((volatile unsigned short *)addr)& 0x40;

                                                 if(i!= (*((volatile unsigned short *)addr) & 0x40))

                                                                continue;

                                                 if((*((volatileunsigned short *)addr)) & 0x80)

                                                               break;

                                          }

                                          printf("ok.\n");

                                         }else {   /* it was protected */

                                                         printf ("protected!\n");

                                          }

                                    }

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

……

//                                 MEM_FLASH_ADDR1= CMD_UNLOCK_BYPASS;

//                                 *addr= CMD_PROGRAM;

                                    MEM_FLASH_ADDR1 = CMD_PROGRAM;

#if 0

                                    /* wait until flash is ready */

                                    chip= 0;

                                    do{

                                          ……

 

                                    *addr= CMD_READ_ARRAY;

 

                                    if(chip == ERR || *addr != data)

                                          rc= ERR_PROG_ERROR;

#endif

                                    /*waituntil flash is ready*/

                                    while(1){

                                          unsignedshort i = *(volatile unsigned short *)addr & 0x40;

                                         if(i !=(*(volatile unsigned short *)addr & 0x40))  //D6 == D6

                    continue;

      if((*(volatile unsigned short *)addr & 0x80) == (data & 0x80)){

                    rc = ERR_OK;

                    break;     //D7 == D7

                            }

在include/configs/gt2440.h加上:

#define CONFIG_SST_VF1601        1

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE            0x00080000/* 512KB */

#define CFG_MAX_FLASH_SECT    (11) /* max number ofsectors on one chip */

#define CFG_ENV_ADDR        (CFG_FLASH_BASE+ 0x070000) /* addr of environment */

#endif

 

#ifdef CONFIG_SST_VF1601

#define PHYS_FLASH_SIZE            0x00200000/* 2M */

#define CFG_MAX_FLASH_SECT    (512)      /* max number ofsectors on one chip */

#define CFG_ENV_ADDR        (CFG_NAND_BASE + CFG_ENV_OFFSET) /* addrof environment */

#endif

13、支持yaffs根文件系统的烧写(可选)

       因为在开发过程中,烧写yaffs根文件系统还是有需要的,但是1.3.4又不支持yaffs的烧写,所以就要手动移植。Yaffs根文件系统主要特点是烧写时第一块是不烧内容的,也就跳过第一块,所以在移植时会在相应的结构体里加入skipfirstblk这个成员。

1.首先在common/cmd_nand.c的496行附近加入

"nandread.yaffs     - addr off|partitionsize\n"

"nandwrite.yaffs    - addr off|partition size- read/write `size' bytes starting\n"

这两行主要是起提示作用的。

在349附近加入

#ifdefined(ENABLE_CMD_NAND_YAFFS)

 

                     } else if ( s != NULL&&

 

                            (!strcmp(s, ".yaffs") ||!strcmp(s, ".yaffs1"))){

 

                            if (read) {

 

                                   /* read */

 

                                  nand_read_options_t opts;

 

                                  memset(&opts, 0, sizeof(opts));

 

                                   opts.buffer= (u_char*) addr;

 

                                   opts.length= size;

 

                                   opts.offset= off;

 

                                   opts.readoob= 1;

 

                                   opts.quiet      = quiet;

 

                                   ret =nand_read_opts(nand, &opts);

 

                            } else {

 

                                   /* write */

 

                                   nand_write_options_topts;

 

                                  memset(&opts, 0, sizeof(opts));

 

                                   opts.buffer= (u_char*) addr;

 

                                   opts.length= size;

 

                                   opts.offset= off;

 

                       //opts.noecc = 1;

 

                                   opts.pad =0;

 

                                  opts.writeoob = 1;

 

                                  opts.blockalign = 1;

 

                                   opts.quiet      = quiet;

 

                                  opts.autoplace = 1;

 

                                   if (s[6] =='1')

 

                                         opts.forceyaffs = 1;

 

#ifdefined(ENABLE_CMD_NAND_YAFFS_SKIPFB)

 

                                   opts.skipfirstblk = 1;

 

#endif

 

                                   ret =nand_write_opts(nand, &opts);

 

                            }

 

#endif

/*add to useyaffs*/

2.在include/command.h

加入

#defineENABLE_CMD_NAND_YAFFS               1

#define ENABLE_CMD_NAND_YAFFS_SKIPFB        1

#defineCFG_NAND_YAFFS1_NEW_OOB_LAYOUT      0

3.在include/nand.h里的nand_write_options结构体加入

       u_char *buffer;           /*memory block containing image to write */

       ulong length;            /*number of bytes to write */

       ulong offset;              /*start address in NAND */

       int quiet;             /*don't display progress messages */

       int autoplace;            /*if true use auto oob layout */

       int forcejffs2;             /*force jffs2 oob layout */

       int forceyaffs;            /*force yaffs oob layout */

       int noecc;            /*write without ecc */

       int writeoob;              /*image contains oob data */

       int pad;        /* pad topage size */

       int blockalign;           /*1|2|4 set multiple of eraseblocks

                             *to align to */

       int skipfirstblk;//add to use yaffs

};

14、yaffs2根文件系统制作

       在说制作时,先要说说制作的工具,首先,内核要支持yaffs根文件系统,就要去打补丁,先到yaffs官网上下载

其中的mkyaffs2image这个工具是有点不正常的,不支持2K的nand,要上网去搜补丁,主要是制作根文件映像时,oob区域不一样导致。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzxyg.html