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

6.    实现NAND flash 的读写,再次修改/include/configs/gt2440.h

这里主要是定义了两个宏和屏蔽了原来的宏,修改

/*
 * High Level Configuration Options
 * (easy to change)
 */
#defineCONFIG_ARM920T        1    /* This isan 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_GT2440    1  /* 针对一些本开发板配置的宏控制*/
......
/***********************************************************
 * Command definition
 ***********************************************************/

#define CONFIG_CMD_DHCP

#define CONFIG_CMD_ELF

#define CONFIG_CMD_PING 

#define CONFIG_CMD_NAND       /*这个宏和CFG_CMD_LEGACY控制调用nand_init()的地方(是在nand.c还是gt2440.c)问题*/

#define CONFIG_CMD_NET                  /*在board.c里得到调用,判断是否使用net*/

#define CONFIG_CMD_ENV                 /*环境变量相关的宏*/


#define    CFG_LONGHELP              
/* undef to save memory        */

#define    CFG_PROMPT   "[GT2440]#" /*这个就 是你启动开发板后命令行显示的内容了*/
/*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分配384k的空间(0~0x60000)

其中 u-boot.bin    [0x0~0x40000]  占256K

而   u-boot的参数 [0x40000~0x60000] 占128k

*/
#defineCFG_ENV_OFFSET  0x40000    /*这个宏是表示环境变量在nandflash里的偏移

这里要注意,这个宏必须是nand flash block size的整数倍,例如这里我的是64*2048 = 0x20000,所以这宏必须为这个的整数倍,否则操作是会提示:N AND 256MiB 3,3V 8-bit: MTD Erase failure: -22 */

#define CFG_ENV_SIZE           0x20000 /*环境变量的长度*/

/*注意:网上很多地方都有关于CONFIG_CMD_NAND 、CFG_NAND_LEGACY、drivers/mtd/nand/nand.c中的nand_init()函数以及board/gt2440/GT2440.c中的nand_init()函数这四个东西的关系,他们就是一些宏,在不同的文件中有宏关系,从而实现调用不同的nand_init(),有兴趣可以跟踪一下,附录有他们调用的关系,这里笔者定义了CFG_NAND_LEGACY和CONFIG_CMD_NAND,所以调用的是gt2440.c的nand_init()函数,现在有没有?当然没有,要自己写,下一步骤就是修改这个*/

/*----------------------------------------------------------------------
 * 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

#define LARGE_NAND_FLASH              1     //原因是笔者这使用的是大容量nand为2K每页

#ifndef LARGE_NAND_FLASH
 /* 支持的最大Nand Flash数据 */
#define SECTORSIZE 512
/* 1页的大小 */
#define NAND_SECTOR_SIZE SECTORSIZE      

#define NAND_BLOCK_MASK (SECTORSIZE-1)              /*本flash一个block的大小-1*/
/* 页掩码 */
#defineADDR_COLUMN 1 /*意思是你所用的nandflash的Column地址占多少个字节*/
/* 一个字节的Column地址 */

#define ADDR_PAGE 3 /*意思是你所用的nandflash的(row)page地址占多少个字节*/
/* 3字节的页块地址!!!!!*/
#define ADDR_COLUMN_PAGE 4 /*意思是你所用的nandflash的column地址+page地址共占多少个字节*/
/* 总共4字节的页块地址!!!!! */

#else

 /* 支持的最大Nand Flash数据 */
#defineSECTORSIZE 2048
/* 1页的大小 */
#define NAND_SECTOR_SIZE SECTORSIZE      

#define NAND_BLOCK_MASK (SECTORSIZE-1)              /*本flash一个block的大小-1*/
/* 页掩码 */
#define ADDR_COLUMN 2
/* 一个字节的Column地址 */

#define ADDR_PAGE 3

#define ADDR_COLUMN_PAGE    5

#endif


#defineNAND_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()

*/ /*由于我们这次的移植是使用cpu/arm920t/s3c24x0/nand.c,这文件里也有定义需要的函数,不过是以NFADDR这种格式出现的,不过宏没多大关系,这样移植性也好点*/

#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写校验打开下面宏定义*/
#defineCONFIG_MTD_NAND_VERIFY_WRITE 1
......

#endif    /* __CONFIG_H */

 

7.    修改cpu/arm920t/s3c24x0/Nand.c

#define NF_BASE      0x4e000000

#ifdefined(CONFIG_S3C2410)

#defineNFCONF  __REGi(NF_BASE + 0x0)

#defineNFCMD  __REGb(NF_BASE + 0x4)

#defineNFADDR  __REGb(NF_BASE + 0x8)

#defineNFDATA  __REGb(NF_BASE + 0xc)

#defineNFSTAT  __REGb(NF_BASE + 0x10)

#defineNFECC0  __REGb(NF_BASE + 0x14)

#defineNFECC1  __REGb(NF_BASE + 0x15)

#defineNFECC2  __REGb(NF_BASE + 0x16)

#define S3C2410_NFCONF_EN          (1<<15)

#defineS3C2410_NFCONF_512BYTE     (1<<14)

#defineS3C2410_NFCONF_4STEP       (1<<13)

#defineS3C2410_NFCONF_INITECC     (1<<12)

#defineS3C2410_NFCONF_nFCE        (1<<11)

#defineS3C2410_NFCONF_TACLS(x)    ((x)<<8)

#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)

#defineS3C2410_NFCONF_TWRPH1(x)   ((x)<<0)

#elifdefined(CONFIG_S3C2440)

#defineNFCONF  __REGi(NF_BASE + 0x0)

#defineNFCONT  __REGi(NF_BASE + 0x4)

#defineNFCMD  __REGb(NF_BASE + 0x8)

#defineNFADDR  __REGb(NF_BASE + 0xc)

#defineNFDATA  __REGb(NF_BASE + 0x10)

#defineNFMECCD0 __REGi(NF_BASE + 0x14)

#defineNFMECCD1 __REGi(NF_BASE + 0x18)

#defineNFSECCD  __REGi(NF_BASE + 0x1C)

#defineNFSTAT  __REGb(NF_BASE + 0x20)

#defineNFSTAT0  __REGi(NF_BASE + 0x24)

#define NFSTAT1  __REGi(NF_BASE + 0x28)

#defineNFMECC0  __REGi(NF_BASE + 0x2C)

#defineNFMECC1  __REGi(NF_BASE + 0x30)

#defineNFSECC  __REGi(NF_BASE + 0x34)

#defineNFSBLK  __REGi(NF_BASE + 0x38)

#defineNFEBLK  __REGi(NF_BASE + 0x3c)

#defineS3C2440_NFCONT_nCE (1<<1)

#defineS3C2440_ADDR_NALE 0x0c

#defineS3C2440_ADDR_NCLE 0x08

#endif

static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)

{

       struct nand_chip *chip =mtd->priv;

 

       DEBUGN("hwcontrol():0x%02x: ", cmd);

 

#if defined(CONFIG_S3C2410)

 switch (cmd) {

 case NAND_CTL_SETNCE:

  NFCONF &=~S3C2410_NFCONF_nFCE;

 DEBUGN("NFCONF=0x%08x\n", NFCONF);

  break;

 case NAND_CTL_CLRNCE:

  NFCONF |= S3C2410_NFCONF_nFCE;

 DEBUGN("NFCONF=0x%08x\n", NFCONF);

  break;

 case NAND_CTL_SETALE:

  chip->IO_ADDR_W = NF_BASE +0x8;

  DEBUGN("SETALE\n");

  break;

 case NAND_CTL_SETCLE:

  chip->IO_ADDR_W = NF_BASE +0x4;

  DEBUGN("SETCLE\n");

  break;

 default:

  chip->IO_ADDR_W = NF_BASE +0xc;

  break;

 }

#elif defined(CONFIG_S3C2440)

 switch (cmd) {

 case NAND_CTL_SETNCE:

  NFCONF &=~S3C2440_NFCONT_nCE;

 DEBUGN("NFCONF=0x%08x\n", NFCONF);

  break;

 case NAND_CTL_CLRNCE:

  NFCONF |= S3C2440_NFCONT_nCE;

 DEBUGN("NFCONF=0x%08x\n", NFCONF);

  break;

 case NAND_CTL_SETALE:

  chip->IO_ADDR_W = NF_BASE +S3C2440_ADDR_NALE;

  DEBUGN("SETALE\n");

  break;

 case NAND_CTL_SETCLE:

  chip->IO_ADDR_W = NF_BASE +S3C2440_ADDR_NCLE;

  DEBUGN("SETCLE\n");

  break;

 default:

  chip->IO_ADDR_W = NF_BASE +0x10; //注意是0x10

  break;

 }

#endif

 

       return;

}

intboard_nand_init(struct nand_chip *nand)

{

 u_int32_t cfg;

 u_int8_t tacls, twrph0, twrph1;

 S3C24X0_CLOCK_POWER * const clk_power =S3C24X0_GetBase_CLOCK_POWER();

 DEBUGN("board_nand_init()\n");

 clk_power->CLKCON |= (1 << 4);

#if defined(CONFIG_S3C2410)

 /* initialize hardware */

 twrph0 = 3; twrph1 = 0; tacls = 0;

 cfg = S3C2410_NFCONF_EN;

 cfg |= S3C2410_NFCONF_TACLS(tacls- 1);

 cfg |=S3C2410_NFCONF_TWRPH0(twrph0 - 1);

 cfg |=S3C2410_NFCONF_TWRPH1(twrph1 - 1);

 NFCONF = cfg;

 /* initialize nand_chip datastructure */

 nand->IO_ADDR_R = nand->IO_ADDR_W= 0x4e00000c;

 /* read_buf and write_buf aredefault */

 /* read_byte and write_byte aredefault */

 /* hwcontrol always must beimplemented */

 nand->hwcontrol =s3c2410_hwcontrol;

 nand->dev_ready =s3c2410_dev_ready;

#ifdef CONFIG_S3C2410_NAND_HWECC

 nand->enable_hwecc =s3c2410_nand_enable_hwecc;

 nand->calculate_ecc =s3c2410_nand_calculate_ecc;

 nand->correct_data =s3c2410_nand_correct_data;

 nand->eccmode =NAND_ECC_HW3_512;

#else

 nand->eccmode = NAND_ECC_SOFT;

//nand->eccmode = NAND_ECC_NONE; /*这个ECC先去掉,否则你使用nand write命令和nand read会boot 不起内核*/

#endif

#ifdef CONFIG_S3C2410_NAND_BBT

 nand->options =NAND_USE_FLASH_BBT;

#else

 nand->options = 0;

#endif

#elif defined(CONFIG_S3C2440)

    twrph0 = 6; twrph1 = 2; tacls =0;

 cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);

 NFCONF = cfg;

 cfg =(1<<6)|(1<<4)|(0<<1)|(1<<0);

 NFCONT = cfg;

/* initialize nand_chip data structure */

 nand->IO_ADDR_R =nand->IO_ADDR_W = (void *)0x4e000010;

 /* read_buf and write_buf aredefault */

 /* read_byte and write_byte aredefault */

 /* hwcontrol always must beimplemented */

 nand->hwcontrol =s3c2410_hwcontrol;

 

 nand->dev_ready =s3c2410_dev_ready;

 

#ifdef CONFIG_S3C2440_NAND_HWECC

 nand->enable_hwecc =s3c2410_nand_enable_hwecc;

 nand->calculate_ecc = s3c2410_nand_calculate_ecc;

 nand->correct_data =s3c2410_nand_correct_data;

 nand->eccmode =NAND_ECC_HW3_512;

#else

 nand->eccmode = NAND_ECC_SOFT;

//nand->eccmode = NAND_ECC_NONE; /*这个ECC先去掉,否则你使用nand write命令和nand read会boot 不起内核*/

#endif

#ifdef CONFIG_S3C2440_NAND_BBT

 nand->options =NAND_USE_FLASH_BBT;

#else

 nand->options = 0;

#endif

#endif

 DEBUGN("end of nand_init\n");

 return 0;

}

#else

 error "U-Boot legacy NAND support notavailable for S3C2410"

#endif

#endif

/*到这里,编译是不能通过的,原因上一节中CONFIG_S3C2410这个宏定义被注释掉,下面要用CONFIG_S3C2440这个宏打开CONFIG_S3C2410所打开的内容*/

 

8.    在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;
/*这两个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

    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)   

  {

       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_GT2440)”,使得原来SBC2410X开发板的代码可以编译进来,

/cpu/arm920t/s3c24x0/interrupts.c文件的第181行: 

   #elif defined(CONFIG_SBC2410X) || \

      defined(CONFIG_SMDK2410) || \

      defined(CONFIG_VCMA9) || defined(CONFIG_GT2440)

       tbclk = CFG_HZ;  /*对于CFG_HZ 的值,结合uboot的说明和s3c2440datasheet就比较容易理解*/

#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)

 

9.    在/include/s3c24x0.h中加入2440 的NAND FLASH 寄存器定义和CAMDIVN定义:

typedefstruct {

              S3C24X0_REG32   LOCKTIME;

        S3C24X0_REG32   MPLLCON;

        S3C24X0_REG32   UPLLCON;

        S3C24X0_REG32   CLKCON;

        S3C24X0_REG32   CLKSLOW;

        S3C24X0_REG32   CLKDIVN;

        S3C24X0_REG32   CAMDIVN;

}S3C24X0_CLOCK_POWER;

......

#ifdefined(CONFIG_S3C2410)  //2410 的NAND FLASH 寄存器

typedefstruct {

        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

 

10.  修改/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> 
 

/*===========================================================

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

===========================================================*/

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

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