热度 13
2015-9-22 14:49
788 次阅读|
0 个评论
board_init_r() arch\arm\lib\board.c nand_init() driver\mtd\nand.c nand_init_chip () driver\mtd\nand.c nand-IO_ADDR_R = nand-IO_ADDR_W = (void __iomem *)base_addr; base_addr是nand控制器寄存器的起始地址,定义如下 #define NAND_BASE (0x04000000) include\configs\tq3358.h board_nand_init () driver\mnt\nand\ti81xx_nand.c 设置nand_chip结构体,提供底层造成函数。 nand-IO_ADDR_R = (void __iomem *)gpmc_cfg-cs .nand_dat; nand-IO_ADDR_W = (void __iomem *)gpmc_cfg-cs .nand_cmd; gpmc_cdg-cs 应该是nand控制器寄存器地址,nand_dat应该是数据寄存器, nand_cmd是命令寄存器。 nand-cmd_ctrl = ti81xx_nand_hwcontrol; ti81xx_nand_hwcontrol() driver\mn\nand\ti81xx_nand.c 实现nandflash 发地址,发命令,片选操作 nand-dev_ready = ti81xx_spl_dev_ready; driver\mn\nand\ti81xx_nand.c 实现nandflash忙状态判断 nand_scan () driver\mn\nand\nand_base.c nand_scan_ident() nand_set_defaults() 为nand_chips提供默认的底层函数 if (!chip-select_chip) 提供默认的片选函数 chip-select_chip = nand_select_chip; if (chip-cmdfunc == NULL) 提供默认的发命令函数 chip-cmdfunc = nand_command; nand_command有4个参数,mtd_info,命令,列地址,行地址 因此他可以发命令和地址,他的内部实际是调用nand-cmd_ctrl 即ti81xx_nand_hwcontrol() nand_get_flash_type() 获取nandflash的信息。 chip-select_chip(mtd, 0); 选中芯片 chip-cmdfunc(mtd, NAND_CMD_RESET, -1, -1); 发复位命令 chip-cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); 读ID命令 *maf_id = chip-read_byte(mtd); 读厂家ID *dev_id = chip-read_byte(mtd); 读芯片ID for (; type-name != NULL; type++) if (*dev_id == type-id) break; 去nand_flash_ids(driver/mtd/nand/nand_ids.c) 这个数组里找到对应的芯片信息。 chip-chipsize = (uint64_t)type-chipsize 20; 将芯片容量左移20位后放到chip-chipsize中。 add_mtd_device() 将构造好的mtd_info结构体添加到链表中。 实际真正需要自己实现的函数是 select_chip dev_ready cmd_ctrl 读写之前给IO_ADDR_R何IO_ADDR_W赋值 gpmc_cfg-cs .nand_cmd gpmc_cfg-cs .nand_adr gpmc_cfg-cs .nand_dat 分区部分 mtdparts_init common/cmd_mtdparts.c parse_mtdids mtd_device_validate get_mtd_info get_mtd_device_nm drivers/mtd/mtdcore.c ------------------------------------------------------------------------------------------------------ static int parse_mtdids(const char *const ids) 构造mtdids结构体,并添加到链表中,其中包含flash的大小 ------------------------------------------------------------------------------------------------------ int mtd_device_validate(u8 type, u8 num, u32 *size) if (get_mtd_info(type, num, mtd)) return 1; *size = mtd-size; 得到mtd_info和flash的大小,size是u32类型的,因此将无法存储4G的nand尺寸,4G是2的32次方。 ------------------------------------------------------------------------------------------------------ static int get_mtd_info(u8 type, u8 num, struct mtd_info **mtd) *mtd = get_mtd_device_nm(mtd_dev); 得到mtd_info ------------------------------------------------------------------------------------------------------ struct mtd_info *get_mtd_device_nm(const char *name) for (i = 0; i MAX_MTD_DEVICES; i++) { if (mtd_table !strcmp(name, mtd_table -name)) { mtd = mtd_table ; break; } } 到mtd_info数组中查找mtd_info ------------------------------------------------------------------------------------------------------ 主要改了uboot的几个地方来支持4G nand 1. nand_flash_ids结构体数组增加4g nand的id号。 2. 修改页尺寸,块尺寸,OOB尺寸 3. 修改分区大小,分区大小必须是块尺寸的倍数 4. 将涉及到存储nand大小的变量都修改为unsigned long long,因为4G是2的32次方,unsigned int放不下。 TQ335X+7寸屏套装:http://www.embedsky.com/index.php?s=/Product/show/id/49.html