Linux/Linux_Device_Drivers

MTD (Memory Technology Devices)

Roien 2015. 3. 10.
반응형

MTD (Memory Technology Devices)

USER SPACE


             ^        ^             ^
             |        |             |
\-------------+--------+-------------+------------
KERNEL SPACE |        |             |
             |        |             |
             v        v             |
        +------------------------+  |
        | VFS (Virtual FS) layer |  |
        +------------------------+  |
                    ^                   |
                    |                   |
                    v                   |
+-----------------+         |
| Individual FS.s |         |
+-----------------+         |
        ^                   +---------------+
        |                                   |
        v                                   v
+---------------------+---------+-------+--------+
| mtdblock, FTL, NFTL | mtdchar | JFFS2 | YAFFS2 | USER MODULES    -----+
+---------------------+---------+-------+--------+                      |
        ^                          ^                                    |
        |                          |                                    |
        v                          v                                    |
    +-------+                +-----------+                              | <-- MTD Layer
    | NAND  | <------------> | MTD Core  |                              |
    | CHIP  |                +----+------+                              |
    | DRV.S |                     |                                     |
    +--+----+          +----------+-------+                             |
       |               v                  v                             |
       |            +----------+       +-------+                        |
       |            | NOR CHIP |       | Map   | DRIVER MODULES    -----+
       |            | DRV.S    |       | DRV.S |
       |            +-----+----+       +-+-----+
                   |                  | Prove        | I/O
                   v                  v              v
    ---------------+------------------+--------------+------------
                   |                  |              |
                   v                  v              |
               NAND DEVICE         NOR DEVICE  <-----+
+---------------------+
| nand\_crash\_dump.c |
+-----+---------------+
          | get\_mtd\_device\_nm("nand.dump")
          |
          v
+------------+
| mtdcore.c  | managing struct mtd\_info \*mtd\_table\[MAX\_MTD\_DEVICES\];
+-----+------+
      |  
      | +-----------+
      | | mtdpart.c |
      | +-----------+
      |   ^
          |   | add\_mtd\_device (mtd <-- this) --> add\_one\_partition
          |   |   (add MTD with the MTD partition information - partition info. contains start offset in the NAND)
          v   |
+---------+--+      it is registerd to MTD
| imx\_nfc.c  |  <-- CONTROLLING NAND HAL DRIVER      @ imx\_nfc\_init : platform\_driver\_register(&imx\_nfc\_driver)
+-----+------+      (MODULE)        \-> imx\_nfc\_probe, \_\_exit\_p(imx\_nfc\_remove), imx\_nfc\_suspend, imx\_nfc\_resume
      | \- @ imx\_nfc\_probe HAL init is called
      |
      +------------------+
      | nand\_scan        |
      |  ...             |
      v                  v
+-------------+    +-----+------+
| nand\_base.c |    | mxc\_nand.c |  <-- NAND PHYSICAL DRIVER (providing HAL functions)
+-------------+    +-----+------+      (MODULE)

template method

class for mxc_nand.c

 @ mxc\_nand.c static struct platform\_driver mxcnd\_driver = {

  mxc\_nd\_init .driver = { .name = DRIVER\_NAME, }, ...};

  platform\_driver\_probe(&mxcnd\_driver, mxcnd\_probe); <-- when registering a driver, the device for it is searched throughout BUS

+- platform_driver_register(drv)

+- driver_register(&drv->driver)

+- driver_find(drv->name, drv->bus); <-- find driver with .name = DRIVER_NAME from bus (if found, then in wrong situation)

| +- kset_find_obj(bus->p->drivers_kset, name);

+- bus_add_driver(drv); <-- add to bus

mtd.h

mxc_dataflash.c

imx_nfc.c (drivers/mtd/nand/) imx_nfc_data -> struct mtd_info mtd; <-- MTD

-> struct nand_chip nand; <-- about LOW LEVEL IO functions (using NAND HAL functions)

USING MTD

mxc_nd.c

mxc_nd2.c

nand_bbt.c (drivers/mtd/nand/)

nand_ecc.c (drivers/mtd/nand/)

* Bad block check

mtd->block_isbad

(= part_block_isbad) @ mtdpart.c

part->master->block_isbad

(= nand_block_isbad) @ nand_base.c

nand_block_checkbad

chip->block_bad

nand_isbad_bbt <-- res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; <-- 0 or 1 or 2 (0 means no bad block)

addr = blocknum * dump_nand_data->mtd->erasesize; // erasesize = one NAND block size

dump_nand_data->mtd->block_isbad(dump_nand_data->mtd, addr);

nand_block_checkbad(mtd, offs, 1, 0); // offs is in BYTE UNIT

* Initialization BBT

nand_scan_bbt @ nand_bbt.c

bbt = kalloc

mark_bbt_region

// CHECK BBT IS AT A GIVEN PAGE

read_abs_bbts <==== READ BBT HERE

scan_read_raw mtd->read_oob @ (loff_t)td->pages[0] << this->page_shift

or

search_read_bbts <==== READ BBT HERE

search_bbt

scan_read_raw mtd->read_oob @ (startblock + dir * block) << this->bbt_erase_shif

check_pattern

// IF BBT IS AT A GIVEN PAGE, THEN CREATE BB nand_scan_bbt

check_create

for chips

create_bbt (Create the table in memory by scanning the chip(s), device)

for all blocks

// GET BAD BLOCK INFO (WITH THE BBT DATA READ FROM read_abs_bbts or search_read_bbts)

scan_block_full

scan_read_raw

mtd->read_oob

for page length

or

scan_block_fast

// IF BAD BLOCK (THEN SET BITS)

this->bbt[i >> 3] |= 0x03 << (i & 0x6);

반응형

댓글