免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1063 | 回复: 0
打印 上一主题 下一主题

MTD驱动介绍---要做jffs2文件系统的看一下 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-13 21:35 |只看该作者 |倒序浏览

                MTD驱动介绍
by good02xaut

本文所认为的MTD 驱动是针对NOR FLASH设备的驱动。目的是为以后建立jffs文件系统。NOR flash有2中接口:CFI和JEDEC。不同厂商的FLASH采用的接口不一定一致,
因此要参考datasheet中对FLASH的介绍。比如SST39VF160 使用的就是JEDEC标准。
而MTD提供的接口:
                jedec_probe
        cfi_probe
        amd_flah
        map_ram
        map_rom
        map_absent
这些接口的实现可以查看drivers/mtd/chips目录

下面看一个MTD驱动的启动信息:
       SnapGear flash probe(0xf0000000,2097152,2): 200000 at f0000000    CFI: Found no Flash device at location zero    Found: Toshiba TC58FVB160    number of JEDEC chips: 1    Creating 7 MTD partitions on "Flash":    0x00000000-0x00004000 : "Bootloader"    0x00004000-0x00006000 : "Bootargs"    0x00006000-0x00008000 : "MAC"    0x00010000-0x00020000 : "Config"    0x00008000-0x00010000 : "Spare"    0x00020000-0x00200000 : "Image"    0x00000000-0x00200000 : "Flash"
图中显示共有7个分区,实际只有6个,最后的flash代表整块分区。
分区的描述采用:offset-offset+size  
该flash位于CPU地址空间的0xf0000000---0xf0200000
若要实现SST39VF160的MTD驱动,只需添加drivers/mtd/chips/里面的实现文件即可。
/****************************************************************************/
/*
* Flash memory access on uClinux ARMSYS board
* modified by Sam Fei
* Copyright (C) ENSEIRB 2003, Patrice Kadionik
*/
/****************************************************************************/
/*
*
* Normal mappings of chips in physical memory
*/
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#define WINDOW_ADDR  0x0000000
#define WINDOW_ADDR2 0x0200000
#define WINDOW_SIZE   0x200000
#define WINDOW_SIZE2  0x200000
#define BUSWIDTH 2
//#define MY_FLASH2
static struct mtd_info *mymtd;
#ifdef MY_FLASH2
static struct mtd_info *mymtd2;
#endif
__u8 armsys_read8(struct map_info *map, unsigned long ofs)
{
return __raw_readb(map->map_priv_1 + ofs);
}
__u16 armsys_read16(struct map_info *map, unsigned long ofs)
{
return __raw_readw(map->map_priv_1 + ofs);
}
__u32 armsys_read32(struct map_info *map, unsigned long ofs)
{
return __raw_readl(map->map_priv_1 + ofs);
}
void armsys_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
_memcpy_fromio(to, map->map_priv_1 + from, len);
}
void armsys_write8(struct map_info *map, __u8 d, unsigned long adr)
{
__raw_writeb(d, map->map_priv_1 + adr);
mb();
}
void armsys_write16(struct map_info *map, __u16 d, unsigned long adr)
{
__raw_writew(d, map->map_priv_1 + adr);
mb();
}
void armsys_write32(struct map_info *map, __u32 d, unsigned long adr)
{
__raw_writel(d, map->map_priv_1 + adr);
mb();
}
void armsys_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
_memcpy_toio(map->map_priv_1 + to, from, len);
}
struct map_info armsys_map = {
name: "SAMFEI flash device",
size: WINDOW_SIZE,
buswidth: BUSWIDTH,
read8: armsys_read8,
read16: armsys_read16,
read32: armsys_read32,
copy_from: armsys_copy_from,
write8: armsys_write8,
write16: armsys_write16,
write32: armsys_write32,
copy_to: armsys_copy_to
};
#ifdef MY_FLASH2
struct map_info armsys_map2 = {
name: "SAMFEI flash device 2",
size: WINDOW_SIZE2,
buswidth: BUSWIDTH,
read8: armsys_read8,
read16: armsys_read16,
read32: armsys_read32,
copy_from: armsys_copy_from,
write8: armsys_write8,
write16: armsys_write16,
write32: armsys_write32,
copy_to: armsys_copy_to
};
#endif
/*
* MTD 'PARTITIONING' STUFF
*/
#ifdef MY_FLASH2
static struct mtd_partition armsys_partitions2[] = {
        {
                name: "data (2M)",
                size: 0x200000,
                offset: 0x0
        }
};
#endif
static struct mtd_partition armsys_partitions[] = {
        {
                name: "test (1M)",
                size: 0x100000,
                offset: 0x100000
        }
};
int __init init_armsys(void)
{
int ret;
        printk(KERN_NOTICE "armsys flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
armsys_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
#if 0
if (!armsys_map.map_priv_1) {
  printk("Failed to ioremap\n");
  return -EIO;
}
printk(KERN_NOTICE "map_prive_1=%x\n", armsys_map.map_priv_1);
#endif
//mymtd = do_map_probe("cfi_probe", &armsys_map);
//mymtd = do_map_probe("jedec_probe", &armsys_map);
mymtd = do_map_probe("amd_flash", &armsys_map);
if (mymtd) {
        printk(KERN_NOTICE "armsys flash device: regions=%d\n", mymtd->numeraseregions);
  mymtd->module = THIS_MODULE;
  mymtd->erasesize = 0x10000;
  ret = add_mtd_partitions(mymtd, armsys_partitions,
       sizeof(armsys_partitions) /
       sizeof(struct mtd_partition));
  printk("ret = %d\n", ret);
}
iounmap((void *)armsys_map.map_priv_1);
#ifdef MY_FLASH2
        printk(KERN_NOTICE "armsys flash device 2: %x at %x\n", WINDOW_SIZE2, WINDOW_ADDR2);
armsys_map2.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR2, WINDOW_SIZE2);
if (!armsys_map2.map_priv_1) {
  printk("Failed to ioremap\n");
  return -EIO;
}
//mymtd2 = do_map_probe("cfi_probe", &armsys_map2);
mymtd2 = do_map_probe("jedec_probe", &armsys_map2);
if (mymtd2) {
        printk(KERN_NOTICE "armsys flash device2: regions=%d\n", mymtd->numeraseregions);
  mymtd2->module = THIS_MODULE;
  mymtd2->erasesize = 0x10000;
  return add_mtd_partitions(mymtd2, armsys_partitions2,
       sizeof(armsys_partitions2) /
       sizeof(struct mtd_partition));
}
iounmap((void *)armsys_map2.map_priv_1);
#endif
return -ENXIO;
}
static void __exit cleanup_armsys(void)
{
if (mymtd) {
  del_mtd_partitions(mymtd);
  map_destroy(mymtd);
}
if (armsys_map.map_priv_1) {
  iounmap((void *)armsys_map.map_priv_1);
  armsys_map.map_priv_1 = 0;
}
#ifdef MY_FLASH2
if (mymtd2) {
  del_mtd_partitions(mymtd2);
  map_destroy(mymtd2);
}
if (armsys_map2.map_priv_1) {
  iounmap((void *)armsys_map2.map_priv_1);
  armsys_map2.map_priv_1 = 0;
}
#endif
}
module_init(init_armsys);
module_exit(cleanup_armsys);
/****************************************************************************/
/*
* Flash memory access on uClinux SnapGear like devices
* Copyright (C) 2001-2002, David McCullough
*/
/****************************************************************************/
默认情况下,MTDBLOCK主设备号为31,与BLKMEM的主设备号冲突,因此 修改\mtd\mtd.h中 MTD BLOCK MAJOR的值为30。
接着应添加MTD设备节点到/dev目录中。
   其中字符设备的主设备号为90,次设备号为0、2、4、6...(奇数次设备号为只读设备),块设备的主设备号为30,次设备号为0、1、2、3。如下:
mtd0,c,90,0
mtd1,c,90,1
mtd2,c,90,2
mtdblock0,b,30,0
mtdblock1,b,30,1
mtd-block2,b,30,2
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/40912/showart_320691.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP