TQ335X UBOOT分析(nand部分)

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_RIO_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[i] && !strcmp(name, mtd_table[i]->name)) {
            mtd = mtd_table[i];
            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放不下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值