ARM-Linux驱动--MTD驱动分析(一)

发布者:science56最新更新时间:2016-04-26 来源: eefocus关键字:ARM-Linux驱动  MTD  驱动分析 手机看文章 扫描二维码
随时随地手机看文章
主机:Gentoo Linux 11.2 with linux kernel 3.0.6

硬件平台:FL2440(S3C2440)with linux kernel 2.6.35

MTD(memory technology device内存技术设备) 在硬件和文件系统层之间的提供了一个抽象的接口,MTD是用来访问内存设备(如:ROM、flash)的中间层,它将内存设备的共有特性抽取出来,从而使增加新的内存设备驱动程序变得更简单。MTD的源代码都在/drivers/mtd目录中。

MTD中间层细分为四层,按从上到下依次为:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。MTD中间层层次结构图如下:

 

从上图可以看出,原始设备是MTD字符设备和MTD块设备的抽象。

MTD设备层、MTD原始设备层和Flash硬件驱动层之间的接口关系如下图:

下面首先分析下MTD原始层设备

1、mtd_info数据结构

 

  1. struct mtd_info {  
  2.     u_char type;//内存技术类型,例如MTD_RAM,MTD_ROM,MTD_NORFLASH,MTD_NAND_FLASH,MTD_PEROM等  
  3.     uint32_t flags;//标志位  
  4.     uint64_t size;   // Total size of the MTD//MTD设备的大小  
  5.   
  6.     /* "Major" erase size for the device. Naïve users may take this 
  7.      * to be the only erase size available, or may use the more detailed 
  8.      * information below if they desire 
  9.      */  
  10.     uint32_t erasesize;//最小的擦除块大小  
  11.     /* Minimal writable flash unit size. In case of NOR flash it is 1 (even 
  12.      * though individual bits can be cleared), in case of NAND flash it is 
  13.      * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR 
  14.      * it is of ECC block size, etc. It is illegal to have writesize = 0. 
  15.      * Any driver registering a struct mtd_info must ensure a writesize of 
  16.      * 1 or larger. 
  17.      */  
  18.     uint32_t writesize;//编程块大小  
  19.   
  20.     uint32_t oobsize;   // Amount of OOB data per block (e.g. 16)//oob(Out of band)块大小  
  21.     uint32_t oobavail;  // Available OOB bytes per block//每块的可用的oob字节  
  22.   
  23.     /* 
  24.      * If erasesize is a power of 2 then the shift is stored in 
  25.      * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize. 
  26.      */  
  27.     unsigned int erasesize_shift;  
  28.     unsigned int writesize_shift;  
  29.     /* Masks based on erasesize_shift and writesize_shift */  
  30.     unsigned int erasesize_mask;  
  31.     unsigned int writesize_mask;  
  32.   
  33.     // Kernel-only stuff starts here.  
  34.     const char *name;  
  35.     int index;  
  36.   
  37.     /* ecc layout structure pointer - read only ! */  
  38.     struct nand_ecclayout *ecclayout;//eec布局结构  
  39.   
  40.     /* Data for variable erase regions. If numeraseregions is zero, 
  41.      * it means that the whole device has erasesize as given above. 
  42.      */  
  43.     int numeraseregions;//擦除区域个数,通常为1  
  44.     struct mtd_erase_region_info *eraseregions;//擦除区域的区域信息地址  
  45.   
  46.     /* 
  47.      * Erase is an asynchronous operation.  Device drivers are supposed 
  48.      * to call instr->callback() whenever the operation completes, even 
  49.      * if it completes with a failure. 
  50.      * Callers are supposed to pass a callback function and wait for it 
  51.      * to be called before writing to the block. 
  52.      */  
  53.     int (*erase) (struct mtd_info *mtd, struct erase_info *instr);//函数指针,erase函数的功能是将一个erase_info加入擦除队列  
  54.   
  55.     /* This stuff for eXecute-In-Place */  
  56.     /* phys is optional and may be set to NULL */  
  57.     int (*point) (struct mtd_info *mtd, loff_t from, size_t len,  
  58.             size_t *retlen, void **virt, resource_size_t *phys);//point函数功能是允许片内执行(XIP)  
  59.   
  60.     /* We probably shouldn't allow XIP if the unpoint isn't a NULL */  
  61.     void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);//unpoint函数与point函数相反,是禁止片内执行(XIP)  
  62.   
  63.     /* Allow NOMMU mmap() to directly map the device (if not NULL) 
  64.      * - return the address to which the offset maps 
  65.      * - return -ENOSYS to indicate refusal to do the mapping 
  66.      */  
  67.     //如果不是NULL,则允许无MMU单元的地址映射,返回偏移地址  
  68.     unsigned long (*get_unmapped_area) (struct mtd_info *mtd,  
  69.                         unsigned long len,  
  70.                         unsigned long offset,  
  71.                         unsigned long flags);  
  72.   
  73.     /* Backing device capabilities for this device 
  74.      * - provides mmap capabilities 
  75.      */  
  76.     struct backing_dev_info *backing_dev_info;  
  77.   
  78.     //MTD设备的读写函数  
  79.     int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);  
  80.     int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);  
  81.   
  82.     /* In blackbox flight recorder like scenarios we want to make successful 
  83.        writes in interrupt context. panic_write() is only intended to be 
  84.        called when its known the kernel is about to panic and we need the 
  85.        write to succeed. Since the kernel is not going to be running for much 
  86.        longer, this function can break locks and delay to ensure the write 
  87.        succeeds (but not sleep). */  
  88.   
  89.     int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);  
  90.       
  91.     //用于MTD设备的OBB数据读写  
  92.     int (*read_oob) (struct mtd_info *mtd, loff_t from,  
  93.              struct mtd_oob_ops *ops);  
  94.     int (*write_oob) (struct mtd_info *mtd, loff_t to,  
  95.              struct mtd_oob_ops *ops);  
  96.   
  97.     /* 
  98.      * Methods to access the protection register area, present in some 
  99.      * flash devices. The user data is one time programmable but the 
  100.      * factory data is read only. 
  101.      */  
  102.     int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);  
  103.     int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);  
  104.     int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);  
  105.     int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);  
  106.     int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);  
  107.     int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);  
  108.   
  109.     /* kvec-based read/write methods. 
  110.        NB: The 'count' parameter is the number of _vectors_, each of 
  111.        which contains an (ofs, len) tuple. 
  112.     */  
  113.     int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);  
  114.   
  115.     /* Sync */  
  116.     //MTD设备的同步函数  
  117.     void (*sync) (struct mtd_info *mtd);  
  118.   
  119.     /* Chip-supported device locking */  
  120.     //芯片的加锁和解锁  
  121.     int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);  
  122.     int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);  
  123.   
  124.     /* Power Management functions */  
  125.     //支持电源管理函数  
  126.     int (*suspend) (struct mtd_info *mtd);  
  127.     void (*resume) (struct mtd_info *mtd);  
  128.   
  129.     /* Bad block management functions */  
  130.     //坏块管理函数  
  131.     int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);  
  132.     int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);  
  133.   
  134.     struct notifier_block reboot_notifier;  /* default mode before reboot */  
  135.   
  136.     /* ECC status information */  
  137.     struct mtd_ecc_stats ecc_stats;//ECC状态信息  
  138.     /* Subpage shift (NAND) */  
  139.     int subpage_sft;  
  140.   
  141.     void *priv;//私有数据指针  
  142.   
  143.     struct module *owner;  
  144.     struct device dev;  
  145.     int usecount;//记录用户的个数  
  146.   
  147.     /* If the driver is something smart, like UBI, it may need to maintain 
  148.      * its own reference counting. The below functions are only for driver. 
  149.      * The driver may register its callbacks. These callbacks are not 
  150.      * supposed to be called by MTD users */  
  151.     //驱动回调函数  
  152.     int (*get_device) (struct mtd_info *mtd);  
  153.     void (*put_device) (struct mtd_info *mtd);  
  154. };  

2、mtd_part结构体信息

 

  1. /* Our partition linked list */  
  2. static LIST_HEAD(mtd_partitions);//分区链表  
 
  1. /* Our partition node structure */  
  2. //分区结构信息  
  3. struct mtd_part {  
  4.     struct mtd_info mtd;//mtd_info数据结构,会被加入mtd_table中  
  5.     struct mtd_info *master;//该分区的主分区  
  6.     uint64_t offset;//该分区的偏移地址  
  7.     struct list_head list;//分区链表  
  8. };  

3、mtd_partition描述mtd具体分区结构

 

  1. /* 
  2.  * Partition definition structure: 
  3.  * 
  4.  * An array of struct partition is passed along with a MTD object to 
  5.  * add_mtd_partitions() to create them. 
  6.  * 
  7.  * For each partition, these fields are available: 
  8.  * name: string that will be used to label the partition's MTD device. 
  9.  * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition 
  10.  *  will extend to the end of the master MTD device. 
  11.  * offset: absolute starting position within the master MTD device; if 
  12.  *  defined as MTDPART_OFS_APPEND, the partition will start where the 
  13.  *  previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. 
  14.  * mask_flags: contains flags that have to be masked (removed) from the 
  15.  *  master MTD flag set for the corresponding MTD partition. 
  16.  *  For example, to force a read-only partition, simply adding 
  17.  *  MTD_WRITEABLE to the mask_flags will do the trick. 
  18.  * 
  19.  * Note: writeable partitions require their size and offset be 
  20.  * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). 
  21.  */  
  22.   
  23. struct mtd_partition {  
  24.     char *name;         /* identifier string 分区名*/  
  25.     uint64_t size;          /* partition size 分区大小*/  
  26.     uint64_t offset;        /* offset within the master MTD space 偏移地址*/  
  27.     uint32_t mask_flags;        /* master MTD flags to mask out for this partition */  
  28.     struct nand_ecclayout *ecclayout;   /* out of band layout for this partition (NAND only)*/  
  29. };  

关键字:ARM-Linux驱动  MTD  驱动分析 引用地址:ARM-Linux驱动--MTD驱动分析(一)

上一篇:ARM-Linux驱动--MTD驱动分析(二)
下一篇:ARM-Linux移植攻略--yaffs2 Partially written block xxx detected 问题解决

推荐阅读最新更新时间:2024-03-16 14:51

S3C2440 (4.3寸)LCD驱动程序之层次分析(十六)
在上一节LCD层次分析时,得出写个LCD驱动入口函数,需要以下4步: 1)分配一个fb_info结构体:framebuffer_alloc(); 2)设置fb_info; 3)设置硬件相关的操作; 4)使能LCD,并注册fb_info:register_framebuffer(); 本节需要用到的函数: 函数dma_alloc_writecombine():(分配显存) void * dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);//分配DMA缓存区给现存 //返回值为:申请到
[单片机]
S3C2440 (4.3寸)LCD<font color='red'>驱动</font>程序之层次<font color='red'>分析</font>(十六)
Mini2440 DM9000 驱动分析(二)
在真正的开始分析dm9000 driver的probe之前,首先来看看dm9000 驱动中几个十分重要的结构 1、dm9000_driver static struct platform_driver dm9000_driver = { .driver = { .name = dm9000 , .owner = THIS_MODULE, .pm = &dm9000_drv_pm_ops, }, .probe = dm9000_probe, .remove = __devexit_p(dm9000_drv_remove), }; dm9000_driver是platform_driver结构体变量,其中
[单片机]
基于S3c2440的I2C驱动与测试程序追踪交叉分析
VMware虚拟机+Fedora10, 硬件平台TQ2440, 内核2.6.30.4 对应的驱动程序豁然开朗, 然后自己添加了一些dev_dbg后, 对于不理解的地方也有了一定的参考提示, 记录下来与大家分享。 测试程序如下: /*i2c_test.c * hongtao_liu */ #include #include #include #include #include #include #include #include #define I2C_RETRIES 0x0701 #define I2C_ TI MEOUT 0x0702 #define I2C_RDWR 0x0707 /*********定义struct i
[单片机]
1W大功率LED驱动电源电路分析
  大功率发光二极管比日光灯具有更高的发光效率和使用寿命。人们应根据实际使用方式另外加装散热器。目前,国产3W发白光的LED零售价为15元,但由于3W大功率LED质量还不够可靠,暂不宜使用。5W大功率LED只有进口货,每只售价高达60元,仅适用于特殊要求的灯光工程之中,最适合人们家里作照明用的就是国产1W发光二极管。   鉴于大功率发光二极管工作电压仅为3V,通过全桥整流将220V交流电变成直流电,在全桥上的电压降约为1.8V,只驱动一只发光二极管工作的电能利用效率仅为60%。必须把3只以上发光二极管串联起来工作,才能使总的电能利用效率超过80%。   根据3基色合成白光原理,将红、绿、蓝3只1W大功率发光二极管串联起来工作
[电源管理]
1W大功率LED<font color='red'>驱动</font>电源电路<font color='red'>分析</font>
驱动关键技术分析驱动系统结构及原理
电机驱动低速高扭、扭矩波动小,因此悬置布置时不用追求高的解耦率,重点考虑限位、抗扭作用; 从外特性上对比来看,电机驱动相比内燃机驱动,扭矩响应速度快、峰值扭矩作用区间宽,在特殊路况下容易出现动态冲击事件,产品的耐久、强度需要特殊考虑; 传统车工作转速区间比较集中,而新能源车相对较宽,需要在很宽的转速范围内考虑共振等NVH问题。
[嵌入式]
电<font color='red'>驱动</font>关键技术<font color='red'>分析</font> 电<font color='red'>驱动</font>系统结构及原理
电动汽车驱动方式优缺点技术分析
电动汽车相对传统汽车具有能量转换效率高、噪声小、零排放等优点,同时由于电动机的带载性和宽调速特性,可去掉离合器和变速箱等机械装置,使结构简化,维护、保养方便。在当今能源、环境双重问题的推动下,世界主要汽车生产国都以前所未有的力度发展电动汽车产业,科研人员对电动汽车的研发也获得了绝佳机遇。因此,电动汽车正在开创汽车产业的新格局,它将成为汽车工业发展的主要方向。 驱动电机作为电动汽车的核心部件,其好坏对电动汽车的动力性、经济性、安全性都有重要影响。但汽车驱动电机有别于其它工业电机,电机驱动系统不仅受汽车结构尺寸的影响,同时还要满足复杂工况下的运行条件。因此,除了要求驱动电机效率高、质量小、功率密度大、尺寸小、可靠性好及成本低的特点
[嵌入式]
电动汽车<font color='red'>驱动</font>方式优缺点技术<font color='red'>分析</font>
MapPtrToProcess 用法 WINCE驱动分析3
以使用下面的应用程序代码测试这个driver,使用evc编译。 #include windows.h #include Windev.h #include stdio.h #include "objbase.h" #include "initguid.h" #include "foo.h" //char data1 ; int  WinMain(void) {     HANDLE hnd;     COPY_STRUCT cs ;     int i;     //static char data1 ;   auto char data1 ;     auto char
[嵌入式]
Teledyne LeCroy 发布电机驱动分析
在8通道、12bit高精度示波器上的针对三相电机驱动的功率分析能力 Chestnut Ridge, NY, February 4, 2015 -力科(Teledyne LeCroy)发布了MDA800系列电机驱动分析仪(MDA),该设备将三相功率分析仪的静态(稳态)计算能力,独特的动态三相电源和电机的机械分析功能与高带宽(1 GHz)的控制系统结合为一台仪器。 电机驱动器分析仪(MDA)搭载于HDO8000示波器平台上。该平台标配8个输入通道(16个数字通道可选),拥有12位垂直分辨率,2.5 GS/ s的实时采样率,高达1 GHz的带宽和高达250 Mpts的单通道采集存储。拥有一整套完整的串行触
[测试测量]
Teledyne LeCroy 发布电机<font color='red'>驱动</font><font color='red'>分析</font>仪
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved