uboot第2阶段nand的初始化分析
发布时间:2020-12-15 18:14:18 所属栏目:百科 来源:网络整理
导读:在第二阶段中: #if (CONFIG_COMMANDS CFG_CMD_NAND)puts ("NAND: "); //在uboot启动时打印的nand_init();/* go init the NAND */#endif 从上面代码可以看到要对nand进行初始化,需要加入CFG_CMD_NAND的支持。 方法: 在boardshanl2440shanl2440.h中,加入
在第二阶段中: #if (CONFIG_COMMANDS & CFG_CMD_NAND) puts ("NAND: "); //在uboot启动时打印的 nand_init(); /* go init the NAND */ #endif从上面代码可以看到要对nand进行初始化,需要加入CFG_CMD_NAND的支持。 方法: 在boardshanl2440shanl2440.h中,加入: #define CONFIG_COMMANDS void nand_init(void) { int i; unsigned int size = 0; for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {//#define CFG_MAX_NAND_DEVICE ? ? 1 ? 设置nand的芯片有几个。 nand_init_chip(&nand_info[i],&nand_chip[i],base_address[i]);//对nand进行初始化 size += nand_info[i].size;//获取到nand chip的容量 if (nand_curr_device == -1) nand_curr_device = i; } printf("%lu MiBn",size / (1024 * 1024)); //在终端上打印的:NAND: 256 MiB就是这句话 #ifdef CFG_NAND_SELECT_DEVICE /* * Select the chip in the board/cpu specific driver */ board_nand_select_device(nand_info[nand_curr_device].priv,nand_curr_device); #endif } 接着往下看: nand_init_chip static void nand_init_chip(struct mtd_info *mtd,struct nand_chip *nand,ulong base_addr) { mtd->priv = nand;//将nand_chip付接到mtd_info上 nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;//设置读写的io地址,base-adddr为0, board_nand_init(nand); if (nand_scan(mtd,1) == 0) { if (!mtd->name) mtd->name = (char *)default_nand_name; } else mtd->name = NULL; }这里面有两个重要的函数: board_nand_init和nand_scan void board_nand_init(struct nand_chip *chip) { S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND(); s3c24x0_nand_inithw();//初始化时序和使能nand控制器 chip->IO_ADDR_R = (void *)&s3c2440nand->NFDATA; chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA; chip->hwcontrol = s3c2440_nand_hwcontrol;//硬件指定的控制 chip->dev_ready = s3c2440_nand_devready;//nand设备的状态 chip->select_chip = s3c2440_nand_select_chip;//片选 chip->options = 0; chip->eccmode = NAND_ECC_SOFT;//ecc的模式 } static void s3c24x0_nand_inithw(void) { S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND(); #define TACLS 0 #define TWRPH0 2 #define TWRPH1 0 /* Set flash memory timing */ s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); /* Initialize ECC,enable chip select,NAND flash controller enable */ s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0); }2.nand_scan函数对nand_chip结构体进一步填充,不何具体平台有关的代码: int nand_scan (struct mtd_info *mtd,int maxchips) { int i,j,nand_maf_id,nand_dev_id,busw; struct nand_chip *this = mtd->priv; /* Get buswidth to select the correct functions*/ busw = this->options & NAND_BUSWIDTH_16; //busw == 0 /* check for proper chip_delay setup,set 20us if not */ if (!this->chip_delay) this->chip_delay = 20;//设置传输数据到寄存器中的芯片延时 /* check,if a user supplied command function given */ if (this->cmdfunc == NULL) this->cmdfunc = nand_command;//设置nand的命令 /* check,if a user supplied wait function given */ if (this->waitfunc == NULL) this->waitfunc = nand_wait;//设置nand等待 if (!this->select_chip) this->select_chip = nand_select_chip;//使用的s3c2440_nand_select_chip if (!this->write_byte) this->write_byte = busw ? nand_write_byte16 : nand_write_byte; //nand_write_byte if (!this->read_byte) this->read_byte = busw ? nand_read_byte16 : nand_read_byte;//nand_read_byte if (!this->write_word) this->write_word = nand_write_word; if (!this->read_word) this->read_word = nand_read_word; if (!this->block_bad) this->block_bad = nand_block_bad; if (!this->block_markbad) this->block_markbad = nand_default_block_markbad; if (!this->write_buf) this->write_buf = busw ? nand_write_buf16 : nand_write_buf;//nand_write_buf if (!this->read_buf) this->read_buf = busw ? nand_read_buf16 : nand_read_buf;//nand_read_buf if (!this->verify_buf) this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;//nand_verify_buf if (!this->scan_bbt) this->scan_bbt = nand_default_bbt; /* Select the device */ this->select_chip(mtd,0);//使用的s3c2440_nand_select_chip /* Send the command for reading device ID 读取nand的设备id*/ this->cmdfunc (mtd,NAND_CMD_READID,0x00,-1); /* Read manufacturer and device IDs */ nand_maf_id = this->read_byte(mtd); nand_dev_id = this->read_byte(mtd); /* Print and store flash device information */ for (i = 0; nand_flash_ids[i].name != NULL; i++) { if (nand_dev_id != nand_flash_ids[i].id) continue; if (!mtd->name) mtd->name = nand_flash_ids[i].name; this->chipsize = nand_flash_ids[i].chipsize << 20;//获取nand芯片的容量 。。。 }在这个函数里面读取nand的id,获取nand的容量等等 nandflash的相关信息在在includelinuxmtdNand_ids.h中定义,这个文件中国有各种不同厂商的nand,每个nand的选项包含设备的名字,设备的工厂id,页大小,以M为单位的芯片的大小,块擦除的大小,可选项 struct nand_flash_dev nand_flash_ids[] = { {"NAND 1MiB 5V 8-bit",0x6e,256,1,0x1000,0},{"NAND 2MiB 5V 8-bit",0x64,2,{"NAND 4MiB 5V 8-bit",0x6b,512,4,0x2000,{"NAND 1MiB 3,3V 8-bit",0xe8,0xec,{"NAND 2MiB 3,0xea,{"NAND 4MiB 3,0xd5,0xe3,0xe5,{"NAND 8MiB 3,0xd6,8,{"NAND 8MiB 1,8V 8-bit",0x39,0xe6,8V 16-bit",0x49,NAND_BUSWIDTH_16},3V 16-bit",0x59,{"NAND 16MiB 1,0x33,16,0x4000,{"NAND 16MiB 3,0x73,0x43,0x53,{"NAND 32MiB 1,0x35,32,{"NAND 32MiB 3,0x75,0x45,0x55,{"NAND 64MiB 1,0x36,64,{"NAND 64MiB 3,0x76,0x46,0x56,{"NAND 128MiB 1,0x78,128,{"NAND 128MiB 3,0x79,0x72,0x74,{"NAND 256MiB 3,0x71,{"NAND 512MiB 3,0xDC,/* These are the new chips with large page size. The pagesize * and the erasesize is determined from the extended id bytes */ /* 1 Gigabit */ {"NAND 128MiB 1,0xA1,NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},0xF1,0xB1,NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},0xC1,/* 2 Gigabit */ {"NAND 256MiB 1,0xAA,0xDA,{"NAND 256MiB 1,0xBA,0xCA,/* 4 Gigabit */ {"NAND 512MiB 1,0xAC,{"NAND 512MiB 1,0xBC,0xCC,/* 8 Gigabit */ {"NAND 1GiB 1,0xA3,1024,{"NAND 1GiB 3,0xD3,{"NAND 1GiB 1,0xB3,0xC3,/* 16 Gigabit */ {"NAND 2GiB 1,0xA5,2048,{"NAND 2GiB 3,0xD5,{"NAND 2GiB 1,0xB5,0xC5,/* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte,as those chips have an array of 4 page planes * 1 block = 2 pages,but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5,2 + 6,3 + 7 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go * There are more speed improvements for reads and writes possible,but not implemented now */ {"AND 128MiB 3,0x01,NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY},{NULL,} }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |