精华内容
下载资源
问答
  • 本篇文章我们主要说明向mtd设备驱动模型的架构及相应的数据结构,我们从数据结构入手,即可以较好的理解mtd设备驱动模型的架构,以便我们能较好的理解mtd设备驱动模。 本篇主要包括如下几个部分: 一、mtd设备...

          本篇文章我们主要说明向mtd设备驱动模型的架构及相应的数据结构,我们从数据结构入手,即可以较好的理解mtd设备驱动模型的架构,以便我们能较好的理解mtd设备驱动模。

     

    本篇主要包括如下几个部分:

    一、mtd设备驱动模型的架构说明

     

    二、mtd设备驱动相关的数据结构说明

     

     

    一、mtd设备驱动模型的架构说明

           为了方便我们认识mtd设备驱动模型,此处我们先说明mtd设备驱动模型的架构(即mtd设备驱动模型与外部模块间的联系,包括接口、数据结构之间的关联),在我们对mtd设备驱动模型架构有一个感性认识的基础上,我们再分析mtd设备驱动模型相关的数据结构。

     

         我们mtd驱动模型对上层的抽象以及对下层的抽象,都进行一一详细说明,如下为mtd设备驱动模型的架构,针对mtd设备驱动模型而言,主要包括接口抽象层、数据结构关联两部分。下面分别进行说明。

     

    接口抽象层

    1. 针对接口抽象层,对于上层主要包括mtd_read、mtd_write、get_mtd_device、mtd_erase等接口。这些接口是对上层的抽象,主要供mtd 字符设备、mtd 块设备以及相应的闪存文件系统调用;
    2. mtd对下也做了抽象,为了能兼容nor flash、nandflash等闪存驱动,mtd也做了相应的抽象,而这些接口主要在struct mtd_info类型结构体中定义,主要包括_erase、_read、_write、_block_isbad、_block_markbad等接口;这些接口由具体闪存类型相关的驱动去实现,如针对nandflash驱动而言,这些接口即为nand_erase、nand_read、nand_write、nand_block_isbad、nand_block_markbad;而针对nor flash(cfi标准的norflash),则接口为cfi_amdstd_erase_varsize、cfi_amdstd_write_words、cfi_amdstd_read、cfi_amdstd_sync、cfi_amdstd_suspend、cfi_amdstd_resume等。

    数据结构关联

    针对mtd设备驱动层,主要涉及struct mtd_partition、struct mtd_part、struct mtd_info这几个主要的数据结构。

    1. struct mtd_partition用于进行闪存芯片的分区定义,针对不支持设备树的内核,则一般在开发板对应的板级文件中定义该结构体类型变量的定义,用于说明本芯片的分区情况;针对支持设备树的内核,一般在设备树文件中定义分区信息,然后在芯片对应的驱动文件中解析该分区定义;
    2. struct mtd_part,主要由mtd设备驱动模型内部使用的分区信息,该结构体中包括本分区对应的struct mtd_info类型的变量以及指向master mtd_info的指针。系统中所有已注册的struct mtd_part变量,均链接至链表mtd_partitions上。一般针对闪存芯片的操作接口(如mtd_info->_erase/_read/_write等),均在master mtd_info中定义。而在mtd_erase、mtd_read、mtd_write等对上层的接口中,根据传递的struct mtd_info类型变量,获取到对应的struct mtd_part类型变量,从而调用master mtd_info中对应的_erase、_read、_write等接口。
    3. struct mtd_info,该结构体是mtd设备驱动模型最主要的数据结构,通过该数据结构,对上完成与mtd接口层的关联;对下完成与具体类型闪存芯片驱动的关联(如针对nand flash controller driver,则通过mtd_info->priv=nand_chip,完成与nandflash controller driver的关联;针对nor flash,则同样通过mtd_info->priv=map_info完成关联;而针对其他类型的芯片,则同样是通过mtd_info->priv的关联),通过该结构体中的_erase、_read、_write等函数指针,完成针对下层设备驱动操作接口的抽象,完成对下层设备驱动接口的抽象模型的建立。

     

     

    二、mtd设备驱动相关的数据结构说明

    struct mtd_partition

          在上面已经说了,该结构体主要用于定义分区的大小、偏移位置、是否只读等功能的结构体,请具体定义如下。请记住,该数据结构类型变量的定义一般在板级文件或者在flash设备驱动文件进行mtd_info分区的注册时使用。属于mtd设备驱动模型对外的数据结构。

     

     

    struct mtd_part

    该结构体用于mtd设备驱动模型内部进行mtd设备分区所用,该数据结构类型变量不对外部开放。系统中所有已注册的mtd分区设备,均链接至全局链表mtd_partitions上。

     

     

    struct mtd_info

     

    该数据结构为mtd设备驱动模型的关键,其定义的变量也比较多,下面我们从几个方面进行说明,并联合其他数据结构,说明其中的关联;

    1. 定义mtd设备类型、总大小、写单位、擦除单位、index等等信息;
    2. 抽象的闪存芯片的操作接口(读写擦除等接口)
    3. 提供priv指针,指向该mtd设备的私有信息,若mtd设备需要特殊的处理相关的变量,则可以将该priv指向对应的内存,如针对nandflash controller驱动而言,则通过该priv指针实现nand_chip与mtd_info的关联;
    4. 定义struct device类型的变量,将该mtd_info设备与linux设备驱动模型关联,该结构体实现如下几个功能:
      1. 可通过该变量实现mtd设备与mtd class的关联;
      2. 当调用device_register等接口将该变量注册至linux设备驱动模型中时,则通过netlink向应用层发送device add的uevent,而应用层的udev/mdev则在接收到该事件后,则进行该mtd_info设备对应的mtd字符设备与块设备文件的创建(通过mknod,而mtd设备字符设备与块设备相关的初始化接口已在系统初始化时完成主设备的注册)

     

     

     

            以上即为mtd设备驱动模型相关的说明。针对mtd设备驱动模型而言,其完成了对上层xxxfs、mtd字符设备、块设备的接口抽象;对下完成了针对闪存芯片的操作接口的抽象,并且借助struct device完成与linux设备驱动模型模块的关联,并以此完成mtd设备对应的字符设备、块设备的创建。基于此我们也知道mtd设备注册大概完成哪些功能:

     

    1. 首先进行闪存芯片驱动的初始化,完成该闪存芯片对应master mtd_info的初始化与赋值(包括芯片对应的参数、接口的赋值等);
    2. 在闪存芯片驱动的probe接口中,完成针对各分区对应的mtd_part、mtd_Info的初始化与注册操作,主要包括对mtd_info类型的变量进行赋值与初始化操作,包括write_size、erase_size、size等赋值、对闪存芯片操作接口的赋值(_read、_write、_erase等接口);
    3. 并完成mtd_info对应的strcut device类型变量的注册,并借助注册完成mtd_info对应字符设备、块设备文件节点的创建;
    4. 将该mtd_info对应的分区变量注册到链表mtd_partitions中。

     

     

          以上即为本次内容的主要内容,主要说明mtd设备驱动模型对应的架构抽象以及数据结构的说明。同时说明了mtd设备的注册流程。下一章主要介绍mtd设备驱动模型中上下层接口间的关联。

    展开全文
  • MTD技术设备驱动框架

    2014-01-16 16:48:59
    MTD技术设备驱动框架,深入分析linux MTD技术设备的原理,列出直观框架图
  • linux mtd设备使用

    千次阅读 2019-03-20 11:17:34
    mtd-physmap 问题 开机启动打印, jffs2: Write of 109 bytes at 0x0160f61c failed. returned -5, retlen 108 jffs2: Write of 109 bytes at 0x0160f68c failed. returned -5, retlen 108 jffs2: Write of ...

    作者

    QQ群:852283276
    微信:arm80x86
    微信公众号:青儿创客基地
    B站:主页 https://space.bilibili.com/208826118

    参考

    mtd-physmap
    General MTD documentation

    问题

    开机启动打印,

    jffs2: Write of 109 bytes at 0x0160f61c failed. returned -5, retlen 108
    jffs2: Write of 109 bytes at 0x0160f68c failed. returned -5, retlen 108
    jffs2: Write of 45 bytes at 0x0160f784 failed. returned -5, retlen 44
    jffs2: Write of 45 bytes at 0x0160f7b4 failed. returned -5, retlen 44
    jffs2: Write of 77 bytes at 0x0160f828 failed. returned -5, retlen 76
    jffs2: Write of 77 bytes at 0x0160f878 failed. returned -5, retlen 76
    

    写flash打印,

    root@t2080rdb:~# fw_setenv flag 1
    MTD erase error on /dev/mtd6: Input/output error
    Error: can't write fw_env to flash
    

    其中Input/output error就是代表returned -5

    分析

    用户层发起ioctl传到驱动drivers\mtd\mtdchar.c

    mtdchar_ioctl
    

    cfi-flash对应驱动代码为drivers\mtd\maps\physmap_of.c

    Nor Flash设备树

    CFI or JEDEC memory-mapped NOR flash, MTD-RAM (NVRAM…)

    Flash chips (Memory Technology Devices) are often used for solid state file systems on embedded devices.

    • compatible : should contain the specific model of mtd chip(s) used, if known, followed by either “cfi-flash”, “jedec-flash”, “mtd-ram” or “mtd-rom”.
    • reg : Address range(s) of the mtd chip(s) It’s possible to (optionally) define multiple “reg” tuples so that non-identical chips can be described in one node.
    • bank-width : Width (in bytes) of the bank. Equal to the device width times the number of interleaved chips.
    • device-width : (optional) Width of a single mtd chip. If omitted, assumed to be equal to ‘bank-width’.
    • #address-cells, #size-cells : Must be present if the device has sub-nodes representing partitions (see below). In this case both #address-cells and #size-cells must be equal to 1.
    • no-unaligned-direct-access: boolean to disable the default direct mapping of the flash. On some platforms (e.g. MPC5200) a direct 1:1 mapping may cause problems with JFFS2 usage, as the local bus (LPB) doesn’t support unaligned accesses as implemented in the JFFS2 code via memcpy(). By defining “no-unaligned-direct-access”, the flash will not be exposed directly to the MTD users (e.g. JFFS2) any more.
    • linux,mtd-name: allow to specify the mtd name for retro capability with physmap-flash drivers as boot loader pass the mtd partition via the old device name physmap-flash.
    • use-advanced-sector-protection: boolean to enable support for the advanced sector protection (Spansion: PPB - Persistent Protection Bits) locking.
    • addr-gpios : (optional) List of GPIO descriptors that will be used to address the MSBs address lines. The order goes from LSB to MSB.

    For JEDEC compatible devices, the following additional properties are defined:

    • vendor-id : Contains the flash chip’s vendor id (1 byte).
    • device-id : Contains the flash chip’s device id (1 byte).

    For ROM compatible devices (and ROM fallback from cfi-flash), the following additional (optional) property is defined:

    • erase-size : The chip’s physical erase block size in bytes.

    The device tree may optionally contain endianness property. little-endian or big-endian : It Represents the endianness that should be used by the controller to properly read/write data from/to the flash. If this property is missing, the endianness is chosen by the system (potentially based on extra configuration options).
    The device tree may optionally contain sub-nodes describing partitions of the address space. See partition.txt for more detail.
    Example:

    	flash@ff000000 {
    		compatible = "amd,am29lv128ml", "cfi-flash";
    		reg = <ff000000 01000000>;
    		bank-width = <4>;
    		device-width = <1>;
    		#address-cells = <1>;
    		#size-cells = <1>;
    		fs@0 {
    			label = "fs";
    			reg = <0 f80000>;
    		};
    		firmware@f80000 {
    			label ="firmware";
    			reg = <f80000 80000>;
    			read-only;
    		};
    	};
    

    Here an example with multiple “reg” tuples:

    	flash@f0000000,0 {
    		#address-cells = <1>;
    		#size-cells = <1>;
    		compatible = "intel,PC48F4400P0VB", "cfi-flash";
    		reg = <0 0x00000000 0x02000000
    		       0 0x02000000 0x02000000>;
    		bank-width = <2>;
    		partition@0 {
    			label = "test-part1";
    			reg = <0 0x04000000>;
    		};
    	};
    

    An example using SRAM:

    	sram@2,0 {
    		compatible = "samsung,k6f1616u6a", "mtd-ram";
    		reg = <2 0 0x00200000>;
    		bank-width = <2>;
    	};
    

    分区的描述,

    Representing flash partitions in devicetree
    Partitions can be represented by sub-nodes of an mtd device. This can be used on platforms which have strong conventions about which portions of a flash are used for what purposes, but which don't use an on-flash partition table such as RedBoot. NOTE: if the sub-node has a compatible string, then it is not a partition.
    #address-cells & #size-cells must both be present in the mtd device. There are two valid values for both: <1>: for partitions that require a single 32-bit cell to represent their size/address (aka the value is below 4 GiB) <2>: for partitions that require two 32-bit cells to represent their size/address (aka the value is 4 GiB or greater).
    Required properties:
    - reg : The partition's offset and size within the mtd bank.
    Optional properties:
    - label : The label / name for this partition.  If omitted, the label is taken from the node name (excluding the unit address).
    - read-only : This parameter, if present, is a hint to Linux that this partition should only be mounted read-only. This is usually used for flash partitions containing early-boot firmware images or data which should not be clobbered.
    Examples:
    flash@0 { #address-cells = <1>;
    	#size-cells = <1>;
    	partition@0 { label = "u-boot";
    		reg = <0x0000000 0x100000>;
    		read-only; };
    	uimage@100000 { reg = <0x0100000 0x200000>; }; };
    flash@1 { #address-cells = <1>;
    	#size-cells = <2>;
    	/* a 4 GiB partition */
    	partition@0 { label = "filesystem";
    		reg = <0x00000000 0x1 0x00000000>; }; };
    flash@2 { #address-cells = <2>;
    	#size-cells = <2>;
    	/* an 8 GiB partition */
    	partition@0 { label = "filesystem #1";
    		reg = <0x0 0x00000000 0x2 0x00000000>; };
    	/* a 4 GiB partition */
    	partition@200000000 { label = "filesystem #2";
    		reg = <0x2 0x00000000 0x1 0x00000000>; }; }; 
    

    测试

    root@zynq:~# cat /proc/mtd
    dev:    size   erasesize  name
    mtd0: 000c0000 00001000 "boot"
    mtd1: 00020000 00001000 "bootenv"
    mtd2: 00020000 00001000 "bootenvredund"
    mtd3: 01300000 00001000 "pl"
    mtd4: 00c00000 00001000 "kernel"
    
    展开全文
  • 硬件环境: 飞凌OK6410,256MB DDR,2GB NAND Flash、 NAND Flash...一、 MTD 设备驱动。1、先来简单介绍一下MTDLinux 系统中, 提供了MTD(Memory Technology Device , 内存技术设备)系统来建立 Flash 针对 Linux ...

    硬件环境: 飞凌OK6410,256MB DDR,2GB NAND Flash、   NAND Flash 型号:K9G8G08U9A   、     分析源码:Linux 2.6.36.2 内核源码。

    一、 MTD 设备驱动。

    1、先来简单介绍一下MTD

    在Linux 系统中, 提供了MTD(Memory Technology Device , 内存技术设备)系统来建立 Flash 针对 Linux 的系统、抽象的接口, MTD 将文件系统 与 底层的Flash

    存储器进行了隔离, 使 Flash 驱动工程师 无需关心Flash 作为字符设备和 块 设备与 LInux内核的接口。

    2、在引入MTD 后Linux 系统中的Flash  设备及接口可分为4层, 从上到下依次是:设备节点、MTD 设备层、MTD原始设备层 和 硬件驱动层。  这 4 层的作用定义如下:

    1-> 硬件驱动层: Flash 硬件驱动层负责 Flash 硬件设备的读、写、擦除, LInux MTD 设备的 NOR Flash 芯片驱动位于 drivers/mtd/chips 子目录下,  NAND Flash

    的驱动程序则 位于 drivers/mtd/nand 子目录下。

    2->MTD 原始设备层: MTD原始设备层由两部分组成, 一部分是MTD 原始设备的通用代码, 另一部分是各个特定 Flash 的数据,例如分区。

    3->MTD设备层: 基于MTD 原始设备,Linux 系统可以定义出 MTD 的块设备的结构(主设备号 31) 和 字符设备 (设备号 90) ,构成MTD 设备层, MTD 字符设备定义

    在mtdchar.c 中实现,MTD 块设备则是定义在一个描述MTD 块设备的结构 mtdblk_dev ,并声明了一个名为 mtdblks 的指针数组,这个数组 中的每个mtdblk_dev

    和 mtd_table 中的每一个mtd_info 一一对应。

    4->设备节点: 通过mknod 在/dev 子目录下建立MTD字符设备节点 和 块设备节点,用户通过访问此此设备节点即可访问 MTD 字符设备和块设备。

    3、分析Linux MTD 系统接口 mtd_info 结构体代码分析  此结构体定义在 ./include/linux/mtd/mtd.h 中

    关键词词解析:

    XIP :XIP eXecute In Place,即芯片内执行,指应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。flash内执行

    是指nor flash 不需要初始化,可以直接在flash内执行代码。但往往只执行部分代码,比如初始化RAM.

    OOB :Out Of Brower 传输层协议使用带外数据(out-of-band,OOB)来发送一些重要的数据,如果通信一方有重要的数据需要通知对方时,协议能够将这些数据

    快速地发送到对方.为了发送这些数据

    iovec-base : iovec 结构体基础。struct iovec定义了一个向量元素。通常,这个结构用作一个多元素的数组。对于每一个传输的元素,指针成员iov_base指向

    一个缓冲区,这个缓冲区是存放的是readv所接收的数据或是writev将要发送的数据。成员iov_len在各种情况下分别确定了接收的最大长度以及实际写入的长度。

    Sync : 函数, 函数说明:此函数负责将系统缓冲区的内容写回磁盘,以确保数据同步。

    structmtd_info {

    u_char type;// 内存技术的类型

    uint32_t flags;// 标志位

    uint64_t size;// Total size of the MTD 、mtd 设备的大小

    /* "Major" erase size for the device. Na茂ve users may take this

    * to be the only erase size available, or may use the more detailed

    * information below if they desire

    */

    uint32_t erasesize;// 主要的擦除块大小 erase size of main block

    /* Minimal writable flash unit size. In case of NOR flash it is 1 (even

    * though individual bits can be cleared), in case of NAND flash it is

    * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR

    * it is of ECC block size, etc. It is illegal to have writesize = 0.

    * Any driver registering a struct mtd_info must ensure a writesize of

    * 1 or larger.

    */

    uint32_t writesize;// 最小的可写单元的字节数

    uint32_t oobsize;// Amount of OOB data per block (e.g. 16) OOB 字节数

    uint32_t oobavail;// Available OOB bytes per block   可用OBB 字节数

    /*

    * If erasesize is a power of 2 then the shift is stored in

    * erasesize_shift otherwise erasesize_shift is zero. Ditto writesize.

    */

    unsignedinterasesize_shift;

    unsignedintwritesize_shift;

    /* Masks based on erasesize_shift and writesize_shift */

    unsignedinterasesize_mask;

    unsignedintwritesize_mask;

    // Kernel-only stuff starts here.

    constchar*name;

    intindex;

    /* ecc layout structure pointer - read only ! */

    structnand_ecclayout *ecclayout;// ECC 布局结构体指针

    /* Data for variable erase regions. If numeraseregions is zero,

    * it means that the whole device has erasesize as given above.

    */

    intnumeraseregions;// 不同的erasesize 的区域   数目通常是1

    structmtd_erase_region_info *eraseregions;

    /*

    * Erase is an asynchronous operation.  Device drivers are supposed

    * to call instr->callback() whenever the operation completes, even

    * if it completes with a failure.

    * Callers are supposed to pass a callback function and wait for it

    * to be called before writing to the block.

    */

    int(*erase) (structmtd_info *mtd,structerase_info *instr);

    /* This stuff for eXecute-In-Place */

    /* phys is optional and may be set to NULL */

    int(*point) (structmtd_info *mtd, loff_t from,size_tlen,// 针对 eXecute-In- Place

    size_t*retlen,void**virt, resource_size_t *phys);

    /* We probably shouldn't allow XIP if the unpoint isn't a NULL */

    void(*unpoint) (structmtd_info *mtd, loff_t from,size_tlen);// 如果unpoint 为空,不允许 XIP

    /* Allow NOMMU mmap() to directly map the device (if not NULL)

    * - return the address to which the offset maps

    * - return -ENOSYS to indicate refusal to do the mapping

    */

    unsignedlong(*get_unmapped_area) (structmtd_info *mtd,

    unsignedlonglen,

    unsignedlongoffset,

    unsignedlongflags);

    /* Backing device capabilities for this device

    * - provides mmap capabilities

    */

    structbacking_dev_info *backing_dev_info;

    int(*read) (structmtd_info *mtd, loff_t from,size_tlen,size_t*retlen, u_char *buf);// 读 flash

    int(*write) (structmtd_info *mtd, loff_t to,size_tlen,size_t*retlen,constu_char *buf);// 写 flash

    /* In blackbox flight recorder like scenarios we want to make successful

    writes in interrupt context. panic_write() is only intended to be

    called when its known the kernel is about to panic and we need the

    write to succeed. Since the kernel is not going to be running for much

    longer, this function can break locks and delay to ensure the write

    succeeds (but not sleep). */

    int(*panic_write) (structmtd_info *mtd, loff_t to,size_tlen,size_t*retlen,constu_char *buf);// Kernel panic 时序读写

    int(*read_oob) (structmtd_info *mtd, loff_t from,// 读 out-of-band

    structmtd_oob_ops *ops);

    int(*write_oob) (structmtd_info *mtd, loff_t to,// 写 out-of-band

    structmtd_oob_ops *ops);

    /*

    * Methods to access the protection register area, present in some

    * flash devices. The user data is one time programmable but the

    * factory data is read only.

    */

    int(*get_fact_prot_info) (structmtd_info *mtd,structotp_info *buf,size_tlen);

    int(*read_fact_prot_reg) (structmtd_info *mtd, loff_t from,size_tlen,size_t*retlen, u_char *buf);

    int(*get_user_prot_info) (structmtd_info *mtd,structotp_info *buf,size_tlen);

    int(*read_user_prot_reg) (structmtd_info *mtd, loff_t from,size_tlen,size_t*retlen, u_char *buf);

    int(*write_user_prot_reg) (structmtd_info *mtd, loff_t from,size_tlen,size_t*retlen, u_char *buf);

    int(*lock_user_prot_reg) (structmtd_info *mtd, loff_t from,size_tlen);

    /* kvec-based read/write methods.

    NB: The 'count' parameter is the number of _vectors_, each of

    which contains an (ofs, len) tuple.

    */

    int(*writev) (structmtd_info *mtd,conststructkvec *vecs, unsignedlongcount, loff_t to,size_t*retlen);// iovec-based 读写函数

    /* Sync */

    void(*sync) (structmtd_info *mtd);// Sync

    /* Chip-supported device locking */

    int(*lock) (structmtd_info *mtd, loff_t ofs, uint64_t len);// 设备锁

    int(*unlock) (structmtd_info *mtd, loff_t ofs, uint64_t len);

    int(*is_locked) (structmtd_info *mtd, loff_t ofs, uint64_t len);

    /* Power Management functions */

    int(*suspend) (structmtd_info *mtd);// 电源管理函数

    void(*resume) (structmtd_info *mtd);

    /* Bad block management functions */

    int(*block_isbad) (structmtd_info *mtd, loff_t ofs);// 坏块管理函数

    int(*block_markbad) (structmtd_info *mtd, loff_t ofs);

    structnotifier_block reboot_notifier;/* default mode before reboot */

    /* ECC status information */

    structmtd_ecc_stats ecc_stats;

    /* Subpage shift (NAND) */

    intsubpage_sft;

    void*priv;// 私有函数

    structmodule *owner;

    structdevice dev;

    intusecount;

    /* If the driver is something smart, like UBI, it may need to maintain

    * its own reference counting. The below functions are only for driver.

    * The driver may register its callbacks. These callbacks are not

    * supposed to be called by MTD users */

    int(*get_device) (structmtd_info *mtd);

    void(*put_device) (structmtd_info *mtd);

    };

    mtd_info 中的 read(). write(). read_oob(). write_oob(). erase() 是 MTD 设备驱动主要实现的函数。在在后面我将要介绍的nand flahs 驱动中几乎看不到mtd_info

    的成员函数(也就是说这些函数对于Flash 芯片来说是透明的),这是因为在Linux MTD 下层实现了针对 NOR、NAND Flsh 的同游mtd_info 成员函数。

    Flash 驱动中使用如下两个函数来注册 和注销MTD 设备:

    int add_mtd_device(struct mtd_info *mtd);

    int del_mtd_device (struct mtd_info *mtd)0b1331709591d260c1c78e86d0c51c18.png

    展开全文
  • MTD设备驱动详解

    千次阅读 2017-11-04 21:22:49
    MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源...

    MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源代码在/drivers/mtd子目录下。CFI接口的MTD设备分为四层(从设备节点直到底层硬件驱动),这四层从上到下依次是:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。

      MTD原始设备描述   所有组成MTD原始设备的Flash芯片必须是同类型(无论是interleave还是地址相连),在描述MTD原始设备数据结构中采用同一结构描述组成Flash芯片。每个MTD原始设备有一个mtd_info结构,其中的priv指针指向一个map_info结构,map_info结构中的fldrv_priv指向一个cfi_private结构,cfi_private结构的cfiq指针指向一个cfi_ident结构,chips指针指向一个flchip结构的数组。其中mtd_info、map_info和cfi_private结构用于描述MTD原始设备,因为组成MTD原始设备的NOR型Flash相同,cfi_ident结构用于描述Flash芯片信息;而flchip结构用于描述每个Flash芯片专有信息。  根文件系统   文件系统   字符设备节点   MTD字符设备   MTD块设备   MTD原始设备   FLASH硬件驱动   块设备节点   一、Flash硬件驱动层:硬件驱动层负责在init时驱动Flash硬件,Linux MTD设备的NOR Flash芯片驱动遵循CFI接口标准,其驱动程序位于drivers/mtd/chips子目录下。NAND型Flash的驱动程序则位于/drivers/mtd/nand子目录下  二、MTD原始设备:原始设备层有两部分组成,一部分是MTD原始设备的通用代码,另一部分是各个特定的Flash的数据,例如分区。  用于描述MTD原始设备的数据结构是mtd_info,这其中定义了大量的关于MTD的数据和操作函数。mtd_table(mtdcore.c)则是所有MTD原始设备的列表,mtd_part(mtd_part.c)是用于表示MTD原始设备分区的结构,其中包含了mtd_info,因为每一个分区都是被看成一个MTD原始设备加在mtd_table中的,mtd_part.mtd_info中的大部分数据都从该分区的主分区mtd_part->master中获得。  在drivers/mtd/maps/子目录下存放的是特定的flash的数据,每一个文件都描述了一块板子上的flash。其中调用add_mtd_device()、del_mtd_device()建立/删除 mtd_info结构并将其加入/删除mtd_table(或者调用add_mtd_partition()、del_mtd_partition() (mtdpart.c)建立/删除mtd_part结构并将mtd_part.mtd_info加入/删除mtd_table 中)。   三、MTD设备层:基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。MTD字符设备的定义在mtdchar.c中实现,通过注册一系列file operation函数(lseek、open、close、read、write)。MTD块设备则是定义了一个描述MTD块设备的结构 mtdblk_dev,并声明了一个名为mtdblks的指针数组,这数组中的每一个mtdblk_dev和mtd_table中的每一个 mtd_info一一对应。   四、设备节点:通过mknod在/dev子目录下建立MTD字符设备节点(主设备号为90)和MTD块设备节点(主设备号为31),通过访问此设备节点即可访问MTD字符设备和块设备。  五、根文件系统:在Bootloader中将JFFS(或JFFS2)的文件系统映像jffs.image(或jffs2.img)烧到flash的某一个分区中,在/arch/arm/mach-your/arch.c文件的 your_fixup函数中将该分区作为根文件系统挂载。  六、文件系统:内核启动后,通过mount 命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。  设备层和原始设备层的函数调用关系(红色部分需要我们实现):   一个MTD原始设备可以通过mtd_part分割成数个MTD原始设备注册进 mtd_table,mtd_table中的每个MTD原始设备都可以被注册成一个MTD设备,其中字符设备的主设备号为90,次设备号为0、2、4、 6…(奇数次设备号为只读设备),块设备的主设备号为31,次设备号为0、1、2、3…  mtd_notifier mtd_notifier   字符设备 mtd_fops 块设备 mtd_fops   (mtdchar.c) (mtdblock.c) mtdblks   设备层   register_mtd_user()   get_mtd_device()   unregister_mtd_user()   put_mtd_device()   erase_info   mtd_notifiers   mtd_table   mtd_info   mtd_part   (mtdcore.c)   (mtdpart.c)   Your Flash   (your-flash.c)   add_mtd_partitions()   del_mtd_partitions()   原始设备层 add_mtd_device()   del_mtd_device()   mtd_partition   NOR型Flash芯片驱动与MTD原始设备   所有的NOR型Flash的驱动(探测probe)程序都放在 drivers/mtd/chips下,一个MTD原始设备可以由一块或者数块相同的Flash芯片组成。假设由4块devicetype为x8的 Flash,每块大小为8M,interleave为2,起始地址为0x01000000,地址相连,则构成一个MTD原始设备(0x01000000-0x03000000),其中两块interleave成一个chip,其地址从0x01000000到0x02000000,另两块interleave成一个chip,其地址从0x02000000到0x03000000。  请注意,所有组成一个MTD原始设备的Flash芯片必须是同类型的(无论是interleave还是地址相连),在描述MTD原始设备的数据结构中也只是采用了同一个结构来描述组成它的Flash芯片。  0x03000000   0x02000000   0x01000000   每个MTD原始设备都有一个mtd_info 结构,其中的priv指针指向一个map_info结构,map_info结构中的fldrv_priv指向一个cfi_private结构,cfi_private结构的cfiq指针指向一个cfi_ident结构,chips指针指向一个flchip结构的数组。其中mtd_info、 map_info和cfi_private结构用于描述MTD原始设备;因为组成MTD原始设备的NOR型Flash相同,cfi_ident结构用于描述Flash芯片的信息;而flchip结构用于描述每个Flash芯片的专有信息(比如说起始地址)
    展开全文
  • 原标题:嵌入式Linux驱动设备MTD技术详解MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层...
  • MTD设备知识分享 块设备驱动设备驱动的引入 1. 简单字符驱动程序思想 ​ 当应用程序的 open,read,write 等函数要操作“硬件”时,自然引入了“驱动程序”的概念,最简单的方式是 APP 调用 open 时,驱动...
  • Linux内核MTD驱动程序与SD卡驱动程序flash闪存设备和SD插卡设备是嵌入式设备用到的主要存储设备,它们相当于PC机的硬盘。在嵌入设备特别是手持设备中,flash闪存是焊接在嵌入设备主板上的flash闪存芯片。在嵌入设备...
  • Linux下读写FLASH驱动——MTD设备分析

    千次阅读 2018-05-04 15:23:58
    最近在学习驱动读写flash的代码部分。经历了可笑的过程:开始我知道flash用通过spi口来读写。所以就到了driver/spi 下面看相关代码。发现有个spidev.c里面有read/write/ioctl等函数。而且还有一个davinci_spi_master...
  • Linux MTD介绍

    2021-05-11 14:28:38
    1. 介绍MTD,即Memory Technology Device,值得是内存技术设备字符设备和块设备的区别在于前者只能被顺序读写,后者可以随机访问;同时,两者读写数据的基本单元不同字符设备: 以字节为基本单位,在Linux中,字符...
  • Linux MTD架构下的nand flash驱动详解

    千次阅读 2019-04-23 17:45:12
    有了前面的基础(Nandflash详解:https://blog.csdn.net/Golden_Chen/article/details/89470673),我们就可以研究MTD下的nand驱动了,我这里用的是jz4780grus开发板,我将以下面几个部分做一个介绍...
  • 最近几天为了熟悉linux的驱动开发,我选择了其MTD驱动做了一些研究。我能找到的文章中我觉得有些部分不够细致,所以我还是自己写了一部分分析,希望对别人也能有所帮助,也做为自己的一个备忘,。蓝色文字的部分是从...
  • 转:...1. /dev/mtdN 是Linux 中的MTD架构中,系统自己实现的mtd分区所对应的字符设备,其里面添加了一些ioctl,支持很多命令,如MEMGETINFO,MEMERASE等。 而mtd-util中的flash_eraseall等工
  • linuxMTD驱动

    千次阅读 2016-02-16 21:58:02
    因为之前不是很了解文件系统,所以要探究一下mtd来加深一下印象。
  • linux mtd 驱动

    2009-04-24 02:09:54
    这是关于linuxmtd代码分析的文档
  • 浅析linuxmtd设备onenand存储器的分区和节点创建流程及yaffs2文件系统挂载在arch/arm/mach-pxa/luther.c这个产品平台文件中,即:MACHINE_START(LUTHER, "luther").phys_io = 0x40000000,.boot_params = 0xa0000100...
  • 第八章LinuxMTD驱动上章回顾LinuxMTD驱动第8章预习检查本章目标掌握LinuxMTD驱动层结构掌握NOR Flash或NAND Flash驱动程序的移植、开发了解Flash文件系统本章结构LinuxMTD驱动Linux MTD 系统层次Linux MTD...
  • Linux mtd system

    2021-05-10 03:16:28
    题图:gratisographyLinux mtd systemMTD(Memory Technology Device),内存技术设备Linux的存储设备中的一个子系统。其设计此系统的目的是,对于内存类的设备,提供一个抽象层,一个接口,使得对于硬件驱动设计者来...
  • 之前文章分析了MTD的框架与NANDFLASH的驱动,NORFLASH也是MTD设备的一种,他的驱动和NANDFLASH差不多,也是内核帮我们完成了NOR操作协议层,内核提供的协议层接口是map_info结构体,我们要写一个新的NOR驱动就只需要...
  • Linux mtd 驱动

    2017-05-23 15:13:56
    转载于:... MTD,Memory Technology Device即内存技术设备,在Linux内核中,引入MTD层为NOR FLASH和NAND FLASH设备提供统一接口。MTD将文件系统与底层FLASH存储器进行了隔离。 如上图所示,MT
  • Linux MTD系统剖析(转载+总结)

    万次阅读 2018-06-05 19:59:43
    MTD,Memory Technology Device即内存技术设备,在Linux内核中,引入MTD层为NOR FLASH和NAND FLASH设备提供统一接口。MTD将文件系统与底层FLASH存储器进行了隔离。 如上图所示,MTD设备通常可分为四层,从上到下...
  • 本文介绍了Linux系统下MTD/CFI驱动以及一些编程要点。
  • linux内核MTD分区

    2021-05-12 02:47:26
    linux内核MTD分区 (30页) 本资源...19.90 积分MTD 设备驱动 和 NAND Flash 驱动程序分析硬件环境: 飞凌OK6410,256MB DDR,2GB NAND Flash、 NAND Flash 型号:K9G8G08U9A 、 分析源码:Linux 2.6.36.2 内核源码。...
  • 压缩包 : linux设备驱动开发详解光盘源码.rar 列表19/busybox源代码/busybox-1.2.1.tar.bz219/MTD工具/mtd-utils-1.0.0.tar.gz19/nand驱动范例/s3c2410.c19/nor驱动范例/s3c2410nor.c19/yaffs&yaffs2源代码/...
  • 首先贴上ubi的一个网站,上面对ubi 文件系统由很详细的说明:http://www.linux-mtd.infradead.org/faq/ubifs.html#L_empty_file整理一下mtd和ubi的关系,出自其他博客:...
  •  本书是linux设备驱动程序开发领域的权威著作。全书基于2.6内核,不仅透彻讲解了基本概念和技术,更深入探讨了其他书没有涵盖或浅尝辄止的许多重要主题和关键难点,如pcmcia、i2c和usb等外部总线以及视频、音频、...
  • 原始设备mtdcore.c 硬件驱动层 /mtd/nand/下 nand_base.c nand通用接口; 分rawnand;onenand,spinand; 只是接口不同而已指令解析系统都是一样的。 raw nand驱动字符设备接口 来看字符设备访问nandflash的流程图...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,840
精华内容 4,336
关键字:

linuxmtd设备驱动

linux 订阅