歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux下的nandflash驅動分析(3)——基於S3C6410平台

在上一篇中probe函數中的一個很重要的函數nand_scan函數,現在來說另外一個很重要的函數add_mtd_partitions函數,add_mtd_partitions()會對每一個新建分區建立一個新的mtd_part 結構體,將其加入mtd_ partitions中,並調用add_mtd_device()將此分區作為MTD設備加入mtd_table。成功時返回0,如果分配mtd_part時內存不足,則返回-ENOMEM。

相關閱讀:

Linux下的nandflash驅動分析(1)——基於S3C6410平台 http://www.linuxidc.com/Linux/2012-05/61439.htm

Linux下的nandflash驅動分析(2)——基於S3C6410平台 http://www.linuxidc.com/Linux/2012-05/61544.htm

Linux下的nandflash驅動分析(3)——基於S3C6410平台 http://www.linuxidc.com/Linux/2012-05/61545.htm

1、在說這個函數前,先說下,與這有關的結構體struct mtd_part和struct mtd_partition結構體,如下所示:

mtd_part結構體用於描述分區,其mtd_info結構體成員用於描述本分區

/* Our partition node structure */
struct mtd_part {
struct mtd_info mtd;  分區的信息(大部分由其master決定
struct mtd_info *master;  該分區的主分區
u_int32_t offset;  該分區的偏移地址
int index;  分區號
struct list_head list;
int registered;
};

/*
 * Partition definition structure:
 *
 * An array of struct partition is passed along with a MTD object to
 * add_mtd_partitions() to create them.
 *
 * For each partition, these fields are available:
 * name: string that will be used to label the partition's MTD device.
 * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
 * will extend to the end of the master MTD device.
 * offset: absolute starting position within the master MTD device; if
 * defined as MTDPART_OFS_APPEND, the partition will start where the
 * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
 * mask_flags: contains flags that have to be masked (removed) from the
 * master MTD flag set for the corresponding MTD partition.
 * For example, to force a read-only partition, simply adding
 * MTD_WRITEABLE to the mask_flags will do the trick.
 *
 * Note: writeable partitions require their size and offset be
 * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
 */


struct mtd_partition {
char *name; /* identifier string */  標識字符串
u_int32_t size;/* partition size */   分區大小
u_int32_t offset;/* offset within the master MTD space */   主MTD空間內的偏移
u_int32_t mask_flags;/* master MTD flags to mask out for this partition */
struct nand_ecclayout *ecclayout;/* out of band layout for this partition (NAND only)*/
struct mtd_info **mtdp;/* pointer to store the MTD object */
};

現在來看下6410中的定義:

struct mtd_partition s3c_partition_info[] = {
        {
                .name = "Bootloader",
                .offset = 0,
                .size = (256*SZ_1K),
                .mask_flags = MTD_CAP_NANDFLASH,
        },
        {
                .name = "Kernel",
                .offset = (256*SZ_1K),
                .size = (4*SZ_1M) - (256*SZ_1K),
                .mask_flags = MTD_CAP_NANDFLASH,
        },
#if defined(CONFIG_SPLIT_ROOT_FILESYSTEM)
        {
                .name = "Rootfs",
                .offset = (4*SZ_1M),
               // .size = (512*SZ_1M),//(48*SZ_1M),
.size = (80*SZ_1M),//(48*SZ_1M),
        },
#endif
        {
                .name = "File System",
                .offset = MTDPART_OFS_APPEND,
                .size = MTDPART_SIZ_FULL,
        }
};


struct s3c_nand_mtd_info s3c_nand_mtd_part_info = {
.chip_nr = 1,
.mtd_part_nr = ARRAY_SIZE(s3c_partition_info),
.partition = s3c_partition_info,
};

2、下面來看add_mtd_partitions函數,源碼如下:

/*
 * This function, given a master MTD object and a partition table, creates
 * and registers slave MTD objects which are bound to the master according to
 * the partition definitions.  
 * (Q: should we register the master MTD object as well?)
 */
int add_mtd_partitions(struct mtd_info *master,
      const struct mtd_partition *parts,
      int nbparts)
{
struct mtd_part *slave;
u_int32_t cur_offset = 0;
int i;


printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);


for (i = 0; i < nbparts; i++) {  主要就是這個循環體,應該是分別添加每個struct mtd_partition結構
slave = add_one_partition(master, parts + i, i, cur_offset);
if (!slave)
return -ENOMEM;
cur_offset = slave->offset + slave->mtd.size;
}


return 0;
}

Copyright © Linux教程網 All Rights Reserved