原创 -boot-1.3.4 移植到S3C2440 (带有某些解析)2

2014-9-4 11:31 1037 12 12 分类: MCU/ 嵌入式

 

5. 修改board/qljt/qljt2440/lowlevel_init.S文件
    依照开发板的内存区的配置情况, 修改board/qljt/qljt2440/lowlevel_init.S文件,:
......
/* REFRESH parameter 下面这6个配置都可以参考s3c2440A datasheet P210的REFRESH寄存器 */
#define REFEN             0x1    /* Refresh enable */
#define TREFMD             0x0    /* CBR(CAS before RAS)/Auto refresh */
#define Trp             0x01    /* 3clk 这个值可以参考本版子上的SDRAM的datasheet*/
#define Trc             0x3    /* 也就是SDRAM datasheet里面的Tsrc 7clk 本来这个地方是Trc,但从lowlevel_init.S里面的调用来看,应该是寄存器REFRESH
的Tsrc才对,好多地方都没有改过来,我我觉得只是个名字而已,不影响结果
注意:如果这里改了,那么下面这句中的Trc也要改为相应的Tsrc:
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)*/
#define Tchr             0x2    /* 3clk,这个从lowlevel_init.S里面的调用来看是属于REFRESH的保留位,不知道为什
么还要给他赋值*/
#define REFCNT    1259 /*这个值的算法参考s3c2440A datasheet P210的Refresh Counter */
 
/*下面不厌其烦地解析一下lowlevel_init.S这个原文件*/
 
#define BWSCON  0x48000000
……
#define Tchr                      0x2   /* 3clk */
#define REFCNT                        0x0459
/**************************************/
/*1.要知道上面这些配置的最终会被用到下面SMRDATA 这个数据池里面,所以必须要明白SMRDATA 这个数据池是用
来干什么的,SMRDATA 后面每一个.word 后面防止的数据都是将要写入BWSCON 开始的寄存器的,总共有13个.work ,它们后面放置的值将会分别别写入0x48000000、0x48000004、0x48000008…一直到0x48000030共13个寄存器。 */
/*2.上面那些配置的值是怎样决定的呢,详细请参考s3c2440A和你所用SDRAM的datasheet。细心找总是能找到的。*/
/*3.而上面的那些配置值最终是通过下面lowlevel_init后面的这段函数写到寄存器里面的,下面对该段函数逐一分析:*/
_TEXT_BASE:
         .word         TEXT_BASE
 
.globl lowlevel_init
lowlevel_init:
         /* memory control configuration */
         /* make r0 relative the current location so that it */
         /* reads SMRDATA out of FLASH rather than memory ! */
         ldr     r0, =SMRDATA
         ldr    r1, _TEXT_BASE
     sub   r0, r0, r1        /*其实明白了前三条语句这段程序就不难懂了,归根到底就是为什么将SMRDATA 的值减
去_TEXT_BASE的值?原因是这样的:我们使用的是从nandflash boot的方式,目前程序
仍然在4K-bytes ‘Steppingstone’(这里为什么突然冒出个Steppingstone’,这个就是我前面提到从nand flash 引导的方法,但不知道名字,后来重新看s3c2440A  datasheet的nand flash那一章的开头才知道)上面运行,在SMRDATA后面的的内容仍然在Steppingstone里面。但是SMRDATA的值是相对于_TEXT_BASE 值的地址,而且_TEXT_BASE 是放置u-boot的开始地方,所以用SMRDATA-_TEXT_BASE 就可以得到SMRDATA后面内容在Steppingstone里面相对于地址0x00000000的放置的所在地方(相对于0x00的地址值)。*/
/*从这三条语句可以看出前人为了实现从nand flash启动可谓费尽心思啊!*/
         ldr    r1, =BWSCON        /* Bus Width Status Controller */
         add     r2, r0, #13*4  /*总共13个寄存器*/
0:
         ldr     r3, [r0], #4
         str     r3, [r1], #4
         cmp     r2, r0
         bne     0b
 
         /* everything is fine now */
         mov  pc, lr
 
         .ltorg         /*数据缓冲池,上网可以查得资料*/
/* the literal pools origin */
 
SMRDATA:
   ……  
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0xb2
    .word 0x30       /*需要注意的是CAS Latency的值在这里直接配置*/
.word 0x30
/*===========================================================
到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误
===========================================================*/
 
6 修改/board/qljt/qljt2440/qljt2440.c,修改这个文件主要针对下面两点:
(1) GPIO的控制
(2) PLL,毕竟s3c2410跟s3c2440不同
修改其对GPIO和PLL的配置(请参阅SBC2440的硬件说明和2440芯片手册): ......
#elif FCLK_SPEED==1 /* Fout = 405MHz */
//#define M_MDIV 0x5c
//#define M_PDIV 0x4
//#define M_SDIV 0x0
#define M_MDIV 0x7f
#define M_PDIV 0x2
#define M_SDIV 0x1
#elif USB_CLOCK==1
//#define U_M_MDIV 0x48
//#define U_M_PDIV 0x3
#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2
......
/* set up the I/O ports */
gpio->GPACON = 0x007FFFFF;
// gpio->GPFCON = 0x000055AA;
gpio->GPFCON = 0x5500; /*for LED*/
......
/* arch number of S3C2440 -Board */
gd->bd->bi_arch_number = MACH_TYPE_S3C2440 ;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
gpio->GPFDAT = 0xbf; /*for LED*/
//int board_init (void)设置完成后,LED1和LED2会亮起!
return 0;
}
/*===========================================================
到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误
===========================================================*/
 
7. 为了实现NAND Flash的读写,再次修改/include/configs/qljt2440.h
......
/*
 * High Level Configuration Options
 * (easy to change)
 */
#define CONFIG_ARM920T        1    /* This is an ARM920T Core    */
//#define    CONFIG_S3C2410       1   /* in a SAMSUNG S3C2410 SoC     */
//#define CONFIG_SBC2410X        1   /* on a friendly-arm SBC-2410X Board  */
 
#define    CONFIG_S3C2440        1  /* 在前面很多地方调用到CONFIG_S3C2440 ,他是在这里定义  */
#define CONFIG_qljt2440    1  /* 针对一些本开发板配置的宏控制*/
......
/***********************************************************
 * Command definition
 ***********************************************************/
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
#define CONFIG_CMD_PING    
#define CONFIG_CMD_NAND          
#define CONFIG_CMD_NET
#define CONFIG_CMD_ENV
 
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#define    CFG_LONGHELP                
/* undef to save memory        */
#define    CFG_PROMPT   "[qljt2440]#" /*这个就是你启动开发板后命令行显示的内容了*/
/*Monitor Command Prompt  */
#define    CFG_CBSIZE        256        
/* Console I/O Buffer Size    */
......
#define    CFG_LOAD_ADDR      0x30008000   /*以后linux kernel就要放在这里执行 */
 /* default load address    */
 
......
//#define CFG_ENV_IS_IN_FLASH       1 /这里的flash应该是指nor了,都不知道外国人为什么这么默认/
#define    CFG_ENV_IS_IN_NAND    1 /*定义这个宏的目的是为了调用nand flash类型的saveenv
因为还有其它类型存储器的saveenv,在u-boot中查看saveenv
的定义,有多少中定义就有多少种*/
/*在linux对nand flash分区的时候,给u-boot分配256k的空间(0~0x40000)
其中 u-boot.bin    [0x0~0x30000]  占192K
而   u-boot的参数 [0x30000~0x40000] 占64k
*/
#define CFG_ENV_OFFSET  0x30000         
#define CFG_ENV_SIZE         0x10000
/*注意:网上很多地方都有关于CONFIG_CMD_NAND 、CFG_NAND_LEGACY、drivers/mtd/nand/nand.c中的nand_init()函数以及board/qljt/qljt2440/qljt2440.c中的nand_init()函数这四个东西的关系,但大多说的不清不楚,我把它门的关系用表格一一列出来,请参考附录。*/
#define CFG_NAND_LEGACY                  1
/*----------------------------------------------------------------------
 * NAND flash settings
 */
#if defined (CONFIG_CMD_NAND)
#define CFG_NAND_BASE 0x4E000000     /*这个鬼东西在drivers/mtd/nand/nand.c中被调用,它
是NAND控制寄存器的基地址*/
/* NandFlash控制器在SFR区起始寄存器地址 */
#define CFG_MAX_NAND_DEVICE 1
 /* 支持的最在Nand Flash数据 */
#define SECTORSIZE 512 
/* 1页的大小 */
#define NAND_SECTOR_SIZE SECTORSIZE /*这两个东西好像也是多余的,备用吧,在次文章搜一下
就知道其它用到的地方也有定义*/
#define NAND_BLOCK_MASK 511         /*本flash一个block的大小-1*/
/* 页掩码 */
#define ADDR_COLUMN 1 /*意思是你所用的nandflash的Column地址占多少个字节*/
/* 一个字节的Column地址 */
#define ADDR_PAGE 3 /*意思是你所用的nandflash的(row)page地址占多少个字节*/
/* 3字节的页块地址!!!!!*/
#define ADDR_COLUMN_PAGE 4 /*意思是你所用的nandflash的column地址+page地址共占多少个字节*/
/* 总共4字节的页块地址!!!!! */
#define NAND_ChipID_UNKNOWN 0x00 
/* 未知芯片的ID号 */
#define NAND_MAX_FLOORS 1           /*怎样算一floor*/
#define NAND_MAX_CHIPS 1
/* Nand Flash命令层底层接口函数 */
#define rNFCONF (*(volatile unsigned int *)0x4e000000)
#define rNFCONT (*(volatile unsigned int *)0x4e000004)
#define rNFCMD (*(volatile unsigned char *)0x4e000008)
#define rNFADDR (*(volatile unsigned char *)0x4e00000c)
#define rNFDATA (*(volatile unsigned char *)0x4e000010)
#define rNFSTAT (*(volatile unsigned int *)0x4e000020)
#define rNFECC (*(volatile unsigned int *)0x4e00002c)
/*下面部分内容是修改的*/
/* Nand Flash命令层底层接口函数 */
/*
#define NAND_WAIT_READY(nand)      NF_WaitRB()
#define NAND_DISABLE_CE(nand)        NF_SetCE(NFCE_HIGH)
#define NAND_ENABLE_CE(nand)         NF_SetCE(NFCE_LOW)
#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr)      NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr)    NF_Addr(d)
#define WRITE_NAND(d, adr)                 NF_Write(d)
#define READ_NAND(adr)                         NF_Read()
*/
#define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;}
#define WRITE_NAND(d, adr) {rNFDATA = d;}
#define READ_NAND(adr) (rNFDATA)
#define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}
#define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;}
#define WRITE_NAND_COMMANDW(d, adr)    NF_CmdW(d)
 
# if defined(CONFIG_S3C2440)
#define NAND_DISABLE_CE(nand) {rNFCONT |= (1<<1);}
#define NAND_ENABLE_CE(nand) {rNFCONT &= ~(1<<1);}
#endif
# if defined(CONFIG_S3C2410)
#define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}
#define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
#endif
 
/* 允许Nand Flash写校验 打开下面宏定义*/
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
......
#endif    /* __CONFIG_H */
8. 在/board/qljt/qljt2440/qljt2440.c文件的末尾添加对Nand Flash 的初始化函数(在后面Nand Flash的操作都要用到)
#if defined(CONFIG_CMD_NAND) /*大概在145行*/
typedef enum {
    NFCE_LOW,
    NFCE_HIGH
} NFCE_STATE;
 
static inline void NF_Conf(u16 conf)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCONF = conf;
}
 
 
static inline void NF_Cmd(u8 cmd)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCMD = cmd;
}
 
static inline void NF_CmdW(u8 cmd)
{
    NF_Cmd(cmd);
    udelay(1);
}
 
static inline void NF_Addr(u8 addr)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFADDR = addr;
}
 
 
static inline void NF_WaitRB(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    while (!(nand->NFSTAT & (1<<0)));
}
 
static inline void NF_Write(u8 data)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFDATA = data;
}
 
static inline u8 NF_Read(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    return(nand->NFDATA);
}
 
static inline u32 NF_Read_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    return(nand->NFECC);
}
 
#if defined(CONFIG_S3C2440)
static inline void NF_Cont(u16 cont) 
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCONT = cont;
}
 
static inline void NF_SetCE(NFCE_STATE s)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    switch (s) {
    case NFCE_LOW:
        nand->NFCONT &= ~(1<<1);
        break;
    case NFCE_HIGH:
        nand->NFCONT |= (1<<1);
        break;
    }
}
 
static inline void NF_Init_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCONT |= (1<<4);
}
 
#else
static inline void NF_SetCE(NFCE_STATE s)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    switch (s) {
    case NFCE_LOW:
        nand->NFCONF &= ~(1<<11);
        break;
    case NFCE_HIGH:
        nand->NFCONF |= (1<<11);
        break;
    }
}
 
static inline void NF_Init_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCONF |= (1<<12);
}
#endif /*对应#if defined(CONFIG_S3C2440)*/
 
static inline void NF_Init(void)
{
#if 0
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
 
#if defined(CONFIG_S3C2440)
    NF_Conf((TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4));
    NF_Cont((0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0)); 
#else
    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
    /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
    /* 1 1 1 1, 1 xxx, r xxx, r xxx */
    /* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
#endif
    NF_Reset();
}
 
#endif
9. cpu\arm920t\s3c24x0\ Nand.c ,很多人说u-boot-1.3.4已经不支持CFG_NAND_LEGACY了,但其实还是支持的,定义了CFG_NAND_LEGACY后Nand.c要做如下修改:
#error "U-Boot legacy NAND support not available for S3C2410"
改成
// #error "U-Boot legacy NAND support not available for S3C2410"
/*===========================================================
到这里,编译是不能通过的,原因上一节中CONFIG_S3C2410这个宏定义被注释掉,下面要用CONFIG_S3C2440这个宏打开CONFIG_S3C2410所打开的内容===========================================================*/
 
10.  在S3C2440与s3c2410能够共用的文件中添加“CONFIG_S3C2440”,使得原来s3c2410的代码可以编译进来。
(1)/include/common.h文件的第492行:/*一些公用的常用函数,例如get_fclk()*/
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) || defined(CONFIG_S3C2440)
(2)/include/s3c24x0.h:文件的第85、95、99、110、148、404行:/*一些关于S3C2440寄存器的结构体*/
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
(3)/cpu/arm920t/s3c24x0/interrupts.c文件的第33行:/*主要把一些头文件包含进去*/
#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)
第38行:
#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
(4)/cpu/arm920t/s3c24x0/serial.c文件的第22行:/*主要把一些头文件包含进去*/
#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)
第26行:
#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
(5)/cpu/arm920t/s3c24x0/speed.c文件的第33行:
#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) || defined (CONFIG_S3C2440)
第37行:
#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
顺便修改源代码,以匹配s3c2440:
static ulong get_PLLCLK(int pllreg)
{
   ......
 
    m = ((r & 0xFF000) >> 12) + 8;
    p = ((r & 0x003F0) >> 4) + 2;
    s = r & 0x3;
//qljt  /*这两个PLL的算法参见S3C2440datasheet的254页*/
#if defined(CONFIG_S3C2440)
   if (pllreg == MPLL)
    return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s)); /* CONFIG_SYS_CLK_FREQ 在qljt2440.h中定义*/
    else if (pllreg == UPLL)
#endif
//qljt
    return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
}
......
/* return FCLK frequency */
ulong get_FCLK(void)
{
    return(get_PLLCLK(MPLL));
}
 
/* return HCLK frequency */
ulong get_HCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
 /*看看s3c2410与s3c2440的datasheet就知道s3c2440的HCLK可选择的值多很多*/
  if (clk_power->CLKDIVN & 0x6)   
  {/*这里注意:编译的时候发现CLKDIVN ,这个将会在12节解决*/
       if ((clk_power->CLKDIVN & 0x6)==2)        return(get_FCLK()/2);
if ((clk_power->CLKDIVN & 0x6)==6)        return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);         /*注意这里的CAMDIVN还没有被定义,在/include/s3c24x0.h中定义 */
      if ((clk_power->CLKDIVN & 0x6)==4)        return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);        
        return(get_FCLK());
 } 
 else   {
        return(get_FCLK());
     }
//    return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
}
......
(6)/cpu/arm920t/s3c24x0/usb_ohci.c文件的第45行:
#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
(7)drivers/rtc/s3c24x0_rtc.c文件的第35行:
#elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) 
(8)在文件中添加“defined(CONFIG_qljt2440)”,使得原来SBC2410X开发板的代码可以编译进来,
/cpu/arm920t/s3c24x0/interrupts.c文件的第181行: 
   #elif defined(CONFIG_SBC2410X) || \
      defined(CONFIG_SMDK2410) || \
      defined(CONFIG_VCMA9) || defined(CONFIG_qljt2440)
    tbclk = CFG_HZ;   /*对于CFG_HZ 的值,结合uboot的说明和s3c2440的datasheet就比较容易理解*/
#else
(9)/cpu/arm920t/s3c24x0/usb.c文件的第31行: 
#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
(10)/cpu/arm920t/s3c24x0/i2c.c文件的第35行: 
#elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
第66、85、142、150、174行:
将“#ifdef CONFIG_S3C2410”改为 
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
(11)drivers/usb/usb_ohci.c文件的第68行附近:
#if defined(CONFIG_ARM920T) || \
    defined(CONFIG_S3C2400) || \
    defined(CONFIG_S3C2410) || \
    defined(CONFIG_S3C2440) || \
    defined(CONFIG_440EP) || \
    defined(CONFIG_PCI_OHCI) || \
    defined(CONFIG_MPC5200)
11. 在/include/s3c24x0.h中加入2440 的NAND FLASH 寄存器定义和CAMDIVN定义:
typedef struct {
         S3C24X0_REG32   LOCKTIME;
         S3C24X0_REG32   MPLLCON;
         S3C24X0_REG32   UPLLCON;
         S3C24X0_REG32   CLKCON;
         S3C24X0_REG32   CLKSLOW;
         S3C24X0_REG32   CLKDIVN;
         S3C24X0_REG32   CAMDIVN;
} S3C24X0_CLOCK_POWER;
......
#if defined(CONFIG_S3C2410)  //2440 的NAND FLASH 寄存器
typedef struct {
         S3C24X0_REG32   NFCONF;
         S3C24X0_REG32   NFCMD;
         S3C24X0_REG32   NFADDR;
         S3C24X0_REG32   NFDATA;
         S3C24X0_REG32   NFSTAT;
         S3C24X0_REG32   NFECC;
} S3C2410_NAND;
#endif
#if defined (CONFIG_S3C2440)
typedef struct {
         S3C24X0_REG32   NFCONF;
         S3C24X0_REG32   NFCONT;
         S3C24X0_REG32   NFCMD;
         S3C24X0_REG32   NFADDR;
         S3C24X0_REG32   NFDATA;
         S3C24X0_REG32   NFMECC0;
         S3C24X0_REG32   NFMECC1;
         S3C24X0_REG32   NFSECC;
         S3C24X0_REG32   NFSTAT;
         S3C24X0_REG32   NFESTAT0;
         S3C24X0_REG32   NFESTAT1;
         S3C24X0_REG32   NFECC;
} S3C2410_NAND;
#endif
12. 修改/lib_arm中的board.c。 
......
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
#include <version.h>
#include <net.h>
#include <s3c2410.h> 
 
......
13. 修改common/env_nand.c 
......
#ifdef CONFIG_INFERNO
#error CONFIG_INFERNO not supported yet
#endif
 
int nand_legacy_rw (struct nand_chip* nand, int cmd,
        size_t start, size_t len,
        size_t * retlen, u_char * buf);
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean);
 
/* info for NAND chips, defined in drivers/nand/nand.c */
nand_info_t nand_info[CFG_MAX_NAND_DEVICE];
 
......
 
#else /* ! CFG_ENV_OFFSET_REDUND */
int saveenv(void)
{
    size_t total;
    int ret = 0;
    nand_erase_options_t nand_erase_options;
 
    nand_erase_options.length = CFG_ENV_RANGE;
    nand_erase_options.quiet = 0;
    nand_erase_options.jffs2 = 0;
    nand_erase_options.scrub = 0;
    nand_erase_options.offset = CFG_ENV_OFFSET;
 
    if (CFG_ENV_RANGE < CFG_ENV_SIZE)
        return 1;
    puts ("Erasing Nand...\n");
/*在248行附近*/
//    if (nand_erase_opts(&nand_info[0], &nand_erase_options))
  if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))           
    return 1;
    puts ("Writing to Nand... ");
    total = CFG_ENV_SIZE;
/*在254行附近*/
//    if (writeenv(CFG_ENV_OFFSET, (u_char *) env_ptr)) {
//        puts("FAILED!\n");
//        return 1;
//    }
ret = nand_legacy_rw(nand_dev_desc + 0,0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE,&total, (u_char*)env_ptr);
 if (ret || total != CFG_ENV_SIZE)
        return 1;
    puts ("done\n");
    return ret;
}
 
#else /* ! CFG_ENV_OFFSET_REDUND */
.......
/*
 * The legacy NAND code saved the environment in the first NAND device i.e.,
 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.
 */
void env_relocate_spec (void)
{
#if !defined(ENV_IS_EMBEDDED)
    size_t total;
    int ret;
 
    total = CFG_ENV_SIZE;
/*在360行附近*/
//    ret = readenv(CFG_ENV_OFFSET, (u_char *) env_ptr);
     ret = nand_legacy_rw(nand_dev_desc + 0, 0x01 | 0x02, CFG_ENV_OFFSET,CFG_ENV_SIZE, &total, (u_char*)env_ptr);/*edited by yaoyi 20090314,1.3.4是先进入到readenv,而非直接调用nand_legacy_rw。 因此干脆就不用到readenv了,直接注释掉,添加以上代码 */
    if (ret || total != CFG_ENV_SIZE)
        return use_default();
 
    if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
        return use_default();
#endif /* ! ENV_IS_EMBEDDED */
}
/*
u-boot运行至第二阶段进入start_armboot()函数。其中nand_init()函数是对nand flash的最初初始化函数。Nand_init()函数在两个文件中实现。其调用与CFG_NAND_LEGACY宏有关,如果没有定义这个宏,系统调用 drivers/nand/nand.c中的nand_init();否则调用自己在board/qljt/qljt2440/qljt2440.c中的nand_init()函数。这里我选择第二种方式。*/
14. 修改include/nand.h
 
.......
//#ifndef CFG_NAND_LEGACY 
#include <linux/mtd/compat.h> 
#include <linux/mtd/mtd.h> 
#include <linux/mtd/nand.h> 
.......
//#endif /* !CFG_NAND_LEGACY */
/*===========================================================
到这里,应该是可以编译通过的,否则就是编辑的时候出现了错误
===========================================================*/

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /2 下一条