File Systems (FatFS, LittleFS)
Relevant source files
The following files were used as context for generating this wiki page:
The File System subsystem in Zephyr provides a modular and layered framework for integrating various storage backends, most notably FatFS and LittleFS. It is categorized as an OS Service, sitting between high-level application services and the low-level kernel and platform drivers. This system is designed to provide generic I/O APIs that abstract the underlying implementation of specific file systems, allowing developers to switch between FAT-based storage or flash-optimized LittleFS without altering application-level code.
The architecture emphasizes safety and security, adhering to modular design principles that encapsulate file system logic to prevent repercussions on safety-critical kernel components. By utilizing the project's flexible configuration system (Kconfig), specific file system implementations can be enabled or disabled based on resource requirements and the intended security profile of the device.
Sources: doc/security/security-overview.rst:224-230, doc/safety/safety_overview.rst:115-120, doc/safety/safety_overview.rst:150-155
System Architecture
The file system subsystem follows a Layered Architecture Model, a structure highly recommended by safety standards such as IEC 61508. This model organizes modules with similar functionality into distinct layers, ensuring that the Virtual File System (VFS) provides a consistent interface while specific drivers handle the unique data structures of FatFS or LittleFS.
Architectural Layers
- Application Services Interface: Provides the public APIs for file operations (e.g., open, read, write, mount).
- OS Services (VFS): The generic implementation layer that routes calls to the appropriate file system driver based on the mount point.
- File System Drivers: Encapsulated modules for FatFS and LittleFS that manage volume structures and file allocation tables.
- Hardware Abstraction / Drivers: Low-level platform drivers that interface with physical storage media like SD cards or internal flash.
The diagram illustrates how the File System serves as a modular bridge between application requests and hardware-specific drivers.
Sources: doc/security/security-overview.rst:224-230, doc/safety/safety_overview.rst:115-125
Component Encapsulation and Configuration
A core principle of the Zephyr architecture is the use of Encapsulated Components. This ensures that the file system subsystem is isolated from other non-safety-relevant or safety-relevant components.
- Modularity: Individual file systems (FatFS, LittleFS) are treated as encapsulated single functionalities.
- Kconfig Integration: Zephyr uses Kconfig to manage this modularity. If a specific file system functionality is deemed unacceptable for a high-safety environment (e.g., due to dynamic memory requirements), it can be entirely disabled via configuration.
- Resource Management: Each file system driver manages its own internal state and buffers, adhering to the "Economy of Mechanism" principle by keeping the design as simple and small as practical.
| Feature | Description | Implementation File |
|---|---|---|
| FatFS | Standard FAT file system support, often used for removable media (SD cards). | subsys/fs/fat_fs.c |
| LittleFS | A fail-safe file system designed for microcontrollers and flash memory. | subsys/fs/littlefs_fs.c |
| VFS Core | The generic logic that handles mounting and path resolution. | subsys/fs/fs.c |
Sources: doc/safety/safety_overview.rst:140-155, doc/security/secure-coding.rst:45-50
Security and Execution Protection
The file system subsystem is subject to several security principles defined in the project's secure coding guidelines:
Protection Principles
- Least Privilege: File system threads and access mechanisms are designed to operate with the smallest possible subset of permissions required for the task.
- Execution Protection: The system implements Memory Separation and Stack Protection. Stack guards detect and trap potential overruns during complex file system operations, while memory attributes ensure that threads only access memory regions assigned to their specific file operations.
- Fail-safe Defaults: Access decisions are restricted by default. File system services must be explicitly enabled and authenticated if specific protection schemes are active.
Data Flow for Secure Access
When an application requests a file operation, the system follows a mediation path to ensure safety and security constraints are met:
This flow demonstrates the mediation required before a file operation is executed by the driver.
Sources: doc/security/secure-coding.rst:55-80, doc/security/security-overview.rst:100-115
Safety Requirements and Quality
To reach an auditable code base (IEC 61508 SIL 3 / SC 3), the file system subsystem must conform to strict quality goals. While the file system itself is often a non-safety-critical component, it must be developed using a process that prevents systematic errors from affecting the rest of the system.
- Requirements Tracing: Each functional aspect of the FS (mounting, writing, formatting) must be traceable back to high-level system requirements to ensure it behaves exactly as specified.
- Static Analysis: The code for FatFS, LittleFS, and the VFS core undergoes regular static analysis (e.g., Coverity) to eliminate common vulnerabilities and coding errors.
- Test Coverage: The goal for safety-relevant parts of the architecture is 100% structural test coverage (entry points, statements, and branches). Any defensive code that cannot be reached must be explicitly justified in the documentation.
Sources: doc/safety/safety_overview.rst:55-75, doc/safety/safety_overview.rst:90-105, doc/safety/safety_requirements.rst:15-30
Conclusion
The File System subsystem (encompassing FatFS and LittleFS) is a highly configurable, modular component of the Zephyr RTOS. By leveraging a layered architecture and Virtual File System (VFS) abstraction, it provides flexible storage options while maintaining rigorous security and safety standards. Its integration with Kconfig allows developers to tailor the subsystem to specific hardware constraints and safety integrity levels, ensuring that storage operations do not compromise the overall stability of the system.