原创 TQ335X UBOOT分析(nand部分)

2015-9-22 14:49 785 13 13 分类: MCU/ 嵌入式

  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[cs].nand_dat;

  nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;

  gpmc_cdg->cs[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[cs].nand_cmd

  gpmc_cfg->cs[cs].nand_adr

  gpmc_cfg->cs[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

文章评论0条评论)

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