MTD, Memory Technology Device, is a memory technology device. In the Linux kernel, the MTD layer is introduced to provide a unified interface for NOR FLASH and NAND FLASH devices. MTD isolates the file system from the underlying FLASH memory.
As shown in the figure above, MTD devices can usually be divided into four layers, from top to bottom: device node, MTD device layer, MTD original device layer, and hardware driver layer.
Flash hardware driver layer: The Flash hardware driver layer is responsible for the read, write and erase operations of the Flash hardware. The driver of the Nand Flash chip of the MTD device is in the drivers/mtd/nand/ subdirectory, and the Nor Flash chip driver is in the drivers/mtd/chips/ subdirectory.
MTD original device layer: The data structure used to describe the MTD original device is mtd_info, which defines a large amount of data and operation functions about MTD. Among them, mtdcore.c: MTD original device interface related implementation, mtdpart.c: MTD partition interface related implementation.
MTD device layer: Based on the MTD original device, the Linux system can define MTD block devices (major device number 31) and character devices (device number 90). Among them, mtdchar.c: MTD character device interface related implementation, mtdblock.c: MTD block device interface related implementation.
Device node: Create an MTD block device node (major device number 31) and an MTD character device node (major device number 90) in the /dev subdirectory through mknod. You can access the MTD character device and block device by accessing this device node.
MTD data structure:
1. The Linux kernel uses the mtd_info structure to represent the MTD raw device, which defines a lot of data and operation functions about MTD (as will be seen later). All mtd_info structures are stored in the mtd_table structure data. In /drivers/mtd/mtdcore.c:
struct mtd_info *mtd_table[MAX_MTD_DEVICES];
2. The Linux kernel uses the mtd_part structure to represent partitions, where the mtd_info structure members are used to describe the partition. Most members are determined by its master partition mtd_part->master, and various functions also point to the corresponding functions of the master partition.
struct mtd_part {
struct mtd_info mtd; /* Partition information, mostly determined by the master*/
struct mtd_info *master; /* master partition of the partition*/
uint64_t offset; /* Partition offset address*/
int index; /* Partition number (this field does not exist after Linux 3.0) */
struct list_head list; /* Link mtd_part into a linked list mtd_partitons */
int registered;
};
The main members of the mtd_info structure put important data in the front and less important data in the back for easy observation.
struct mtd_info {
u_char type; /* MTD type, including MTD_NORFLASH, MTD_NANDFLASH, etc. (refer to mtd-abi.h) */
uint32_t flags; /* MTD attribute flags, MTD_WRITEABLE, MTD_NO_ERASE, etc. (see mtd-abi.h) */
uint64_t size; /* size of mtd device*/
uint32_t erasesize; /* The erase unit size of the MTD device, for NandFlash it is the size of the Block*/
uint32_t writesize; /* Write size, bytes for norFlash, one page for nandFlash*/
uint32_t oobsize; /* OOB bytes*/
uint32_t oobavail; /* Number of available OOB bytes */
unsigned int erasesize_shift; /* default is 0, not important */
unsigned int writesize_shift; /* default is 0, not important*/
unsigned int erasesize_mask; /* default is 1, not important*/
unsigned int writesize_mask; /* Default is 1, not important*/
const char *name; /* name, not important*/
int index; /* index number, not important*/
int numeraseregions; /* usually 1 */
struct mtd_erase_region_info *eraseregions; /* Variable erase region*/
void *priv; /* Device private data pointer, for NandFlash it refers to the nand_chip structure*/
struct module *owner; /* Usually set to THIS_MODULE */
/* Erase function */
int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
/* Read and write flash functions*/
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
/* Read and write Flash functions with oob*/
int (*read_oob) (struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops);
int (*write_oob) (struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops);
int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
/* Sync */
void (*sync) (struct mtd_info *mtd);
/* Chip-supported device locking */
int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
/* Power management function */
int (*suspend) (struct mtd_info *mtd);
void (*resume) (struct mtd_info *mtd);
/* Bad block management function*/
int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
unsigned long (*get_unmapped_area) (struct mtd_info *mtd,
unsigned long len,
unsigned long offset,
unsigned long flags);
struct backing_dev_info *backing_dev_info;
struct notifier_block reboot_notifier; /* default mode before reboot */
/* ECC status information */
struct mtd_ecc_stats ecc_stats;
int subpage_sft;
struct device dev;
int usecount;
int (*get_device) (struct mtd_info *mtd);
void (*put_device) (struct mtd_info *mtd);
};
The read(), write(), read_oob(), write_oob(), and erase() functions in the mtd_info structure are the main functions that the MTD device driver needs to implement. Fortunately, Linux experts have helped us implement a set of mtd_info member functions suitable for most FLASH devices.
If the MTD device has only one partition, use the following two functions to register and unregister the MTD device.
int add_mtd_device(struct mtd_info *mtd)
int del_mtd_device (struct mtd_info *mtd)
If the MTD device has other partitions, use the following two functions to register and unregister the MTD device.
int add_mtd_partitions(struct mtd_info *master,const struct mtd_partition *parts,int nbparts)
int del_mtd_partitions(struct mtd_info *master)
The mtd_partition structure represents the partition information
struct mtd_partition {
char *name; /* Partition name, such as TQ2440_Board_uboot, TQ2440_Board_kernel, TQ2440_Board_yaffs2 */
uint64_t size; /* Partition size*/
uint64_t offset; /* Partition offset value*/
uint32_t mask_flags; /* Mask flag, not important*/
struct nand_ecclayout *ecclayout; /* OOB layout */
struct mtd_info **mtdp; /* pointer to store the MTD object */
};
Among them, the nand_ecclayout structure is:
struct nand_ecclayout {
__u32 eccbytes; /* Number of ECC bytes */
__u32 eccpos[64]; /* ECC checksum is stored in the OOB area*/
__u32 oobavail;
/* Number of available OOB bytes in addition to the ECC checksum*/
struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
};
For more information about the nand_ecclayout structure instance, please refer to the nand_oob_8, nand_oob_16, and nand_oob_64 instances in drivers/mtd/nand/nand_base.c.
MTD device layer:
MTD character device interface:
/drivers/mtd/mtdchar.c file implements the MTD character device interface, through which you can directly access the Flash device. Like the previous character driver, you can read and write Flash through open(), read(), write(), and ioctl() in the file_operations structure. You can get Flash device information, erase Flash, read and write NAND OOB, get OOB layout, and check NAND bad blocks through a series of IOCTL commands (MEMGETINFO, MEMERASE, MEMREADOOB, MEMWRITEOOB, MEMGETBADBLOCK IOCRL)
MTD block device interface:
The /drivers/mtd/mtdblock.c file implements the MTD block device interface. The main principle is to map the data in the erase block of Flash in the memory, then modify it, and finally erase the block on Flash and write the mapped block in the memory to the Flash block. The whole process is called the read/modify/erase/rewrite cycle. However, this is unsafe. When the following operation sequence occurs, read/modify/erase/poweroff, the data of this block will be lost.
MTD hardware driver layer:
The Linux kernel implements a general NAND driver (/driver/mtd/nand/nand_base.c) under the MTD layer, so the chip-level NAND driver no longer needs to implement member functions such as read(), write(), read_oob(), and write_oob() in the mtd_info structure.
MTD uses nand_chip to represent a NAND FLASH chip. This structure contains a series of underlying mechanisms such as Nand Flash address information, read and write methods, ECC mode, hardware control, etc.
struct nand_chip {
void __iomem *IO_ADDR_R; /* Read 8-bit I/O line address*/
void __iomem *IO_ADDR_W; /* Write 8-bit I/O line address*/
/* Read a byte from the chip */
uint8_t (*read_byte)(struct mtd_info *mtd);
Previous article:OK6410 DMA bare metal summary
Next article:Analysis of Linux serial port driver
Recommended ReadingLatest update time:2024-11-16 09:30
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Analysis of the advantages and disadvantages of crystal resonators and crystal oscillators
- 【Domestic chip】69P21 from Sinowin Electronics
- ON Semiconductor RSL10 Technical Features, Toolkits, Case Studies and Other Documents
- Is there a camera that works with the F746GDISCOVERY development board?
- Sub-library: Summary of official Chinese technical documents of accelerometers
- Re-study the comparator of MSP430
- Filter capacitor value after bridge rectification
- Please look at this circuit, why is the output signal like this, the DC operating point is fine
- Three-phase watt-hour meter transformer wiring
- How to export the sensor data on sensorile?