In embedded Linux systems, storage and file systems are the core links for data interaction between the kernel and user space. Whether it is an SD card, NAND/NOR Flash, or eMMC, understanding the Linux storage subsystem, driver mechanisms, and file system management not only helps ensure stable system operation but also enhances performance and reduces boot latency. This article will comprehensively analyze embedded Linux storage management practices from Overview of Embedded Storage, Block Devices and Driver Mechanisms, File System Types and Selection, Mounting and Rootfs Construction, Performance Tuning Practices to Debugging Techniques.
1. Overview of Embedded Storage Systems
The storage architecture of embedded devices typically includes:
-
On-chip Memory: such as SRAM and ROM, which have small capacity and fast speed
-
External Flash: such as NAND/NOR, used for storing code and data
-
Block Storage Devices: SD cards, eMMC, SSDs, etc.
-
Memory File System (tmpfs): RAM disk for temporary data
The Linux kernel abstracts storage devices through the block device layer and provides a unified access interface through the file system, enabling data management from hardware to user space.
1. Differences Between Block Devices and Character Devices
| Feature | Character Device | Block Device |
|---|---|---|
| Access Method | Byte Stream | Blocks (sector) |
| Typical Devices | UART, GPIO | SD card, eMMC, NAND |
| Data Caching | Minimal | Kernel Page Cache |
| File System Dependency | None | Must mount a file system |
Storage access in embedded systems is almost entirely through the block device interface, so understanding the block device layer is a prerequisite for file system management.
2. Block Device Driver Mechanisms
Block device drivers are the core of interaction between the kernel and storage hardware. Common driver types used in embedded platforms include:
1. Structure of Block Device Drivers
Each block device driver mainly includes:
-
Request Queue: The kernel manages I/O requests through the queue
-
Low-level Operation Functions (block_device_operations): Implementing read/write/ioctl interfaces
-
Device Registration: Calling
<span>register_blkdev()</span>to register the device number
Example:
static struct block_device_operations mybdev_fops = {
.owner = THIS_MODULE,
.open = mybdev_open,
.release = mybdev_release,
.ioctl = mybdev_ioctl,
};
static int __init mybdev_init(void) {
major = register_blkdev(0, "myblock");
mybdev_queue = blk_init_queue(mybdev_request, &mybdev_lock);
return 0;
}
2. Request Handling
The driver receives kernel I/O requests through the request queue:
static void mybdev_request(struct request_queue *q) {
struct request *req;
while ((req = blk_fetch_request(q)) != NULL) {
// Perform read/write operations
blk_end_request_all(req, 0);
}
}
In embedded systems, properly configuring queue length and I/O scheduling strategies can significantly enhance storage performance.
3. Embedded Flash Drivers
1. NAND Flash Driver
NAND Flash requires the use of the MTD (Memory Technology Device) Subsystem. Key steps include:
-
Registering the MTD device
-
Providing read/write/erase operations
-
Configuring ECC (Error Correction Code) mechanisms
Example:
static struct mtd_info my_nand = {
.name = "my_nand",
.size = 128 * 1024 * 1024,
.erasesize = 128 * 1024,
.writesize = 2048,
.read = my_nand_read,
.write = my_nand_write,
.erase = my_nand_erase,
};
2. NOR Flash Driver
-
Mapping register space through
<span>map_flash</span> -
Typically used for storing code, supporting XIP (execute-in-place)
-
Can be used with MTD or directly mount a file system
4. File System Types and Selection
Common file systems used in embedded systems include:
| File System | Features | Applicable Scenarios |
|---|---|---|
| ext4 | Journaled file system, mature and stable | SD cards, eMMC |
| UBIFS | Designed for NAND, supports wear-leveling | NAND Flash |
| JFFS2 | Older NAND, average performance | Small capacity NAND |
| tmpfs | RAM disk, fast | Temporary data, cache |
| VFAT | Cross-platform compatibility | External SD cards |
1. File System Mounting Methods
mount -t ext4 /dev/mmcblk0p2 /mnt/rootfs
-
<span>-t</span>specifies the file system type -
<span>root=</span>kernel parameter specifies the rootfs device
2. Rootfs Construction
Common methods include:
-
Buildroot / Yocto Build: Automatically generates rootfs
-
Manual Creation: Copying BusyBox tools and necessary directories
-
Compressed Images: Using initramfs or squashfs to reduce storage usage
5. Storage Performance Tuning
Embedded systems are sensitive to storage performance, and tuning strategies include:
-
Block Device Layer Optimization
-
Adjusting I/O scheduling strategies:
<span>noop</span>,<span>deadline</span>,<span>cfq</span> -
Adjusting request queue length
File System Layer Optimization
-
Disabling unnecessary logging (ext4 mount parameter
<span>data=writeback</span>) -
Using appropriate mount options:
<span>noatime</span>,<span>nodiratime</span> -
Using UBIFS instead of JFFS2 for NAND to improve write performance
Boot Acceleration
-
Using initramfs to cache the root file system
-
Delaying the loading of non-critical services
-
Simplifying file system content to reduce mount time
Example mount parameters:
mount -t ext4 -o noatime,nodiratime,data=writeback /dev/mmcblk0p2 /mnt/rootfs
6. Debugging and Practical Techniques
1. Driver Debugging
-
Using
<span>dmesg</span>to view MTD or block device initialization logs -
Early printk outputs NAND/SD initialization status
-
Using
<span>cat /proc/mounts</span>and<span>df -h</span>to check mount status
2. Storage Performance Analysis
-
<span>iostat</span>and<span>blktrace</span>to analyze I/O performance -
<span>ftrace</span>to trace kernel block layer scheduling -
NAND Flash can be tested for erase/write speed and ECC status using
<span>nandtest</span>
3. Rootfs Construction and Compression
-
Using
<span>initramfs</span>or<span>squashfs</span>to compress the file system and improve loading speed -
Using BusyBox to build a minimal command set to save storage space
-
Using partition alignment on SD cards or eMMC to improve access efficiency
7. Embedded Storage Case Studies
1. SD Card Boot
-
Bootloader initializes the SD card controller
-
The kernel mounts ext4 Rootfs
-
Optimized mount parameters:
<span>noatime,data=writeback</span> -
Testing boot speed and I/O performance to ensure stability
2. NAND Flash System
-
Using UBIFS file system
-
Hardware or software ECC verification
-
Using compressed images for root file system mounting
-
Regular garbage collection to extend NAND lifespan
3. eMMC High-Performance Applications
-
Using ext4 or f2fs file systems
-
Aligning partitions to erase block sizes to improve performance
-
Using DMA to enhance I/O bandwidth
-
Adjusting I/O scheduling strategies to ensure responsiveness under multitasking
8. Conclusion
This article systematically introduces embedded Linux file systems and storage management practices:
-
Storage architecture and block device abstraction
-
MTD, NAND, NOR driver mechanisms
-
File system types, mounting methods, and Rootfs construction
-
Storage performance tuning strategies and debugging techniques
-
Practical case studies covering common platforms like SD cards, NAND, and eMMC
Through this article, developers can establish a comprehensive understanding of embedded system storage management, laying a solid foundation for system stability, boot optimization, and performance enhancement.
#Embedded Panorama Series #Linux Kernel Architecture #Performance Tuning Practices