Linux NVMe驱动中core.c与pci.c的module_init差异及疑问
module_init() Entries? Great question! This is a classic example of the Linux kernel's modular, layered driver design—let me break it down clearly for you:
1. nvme_core_init in core.c: The Universal NVMe Infrastructure
This entry point initializes the core NVMe protocol layer—the part that's common to all NVMe devices, regardless of how they connect to the system (PCIe, NVMe over Fabrics, etc.). Think of it as the "backend" that handles:
- Setting up sysfs interfaces for NVMe device management
- Managing NVMe namespaces, queues, and command processing logic
- Implementing core NVMe protocol behaviors that apply to every type of NVMe device
- Registering helper functions that hardware-specific drivers can use
It doesn't talk directly to hardware—its job is to provide a reusable foundation for any bus-specific NVMe driver to build on.
2. nvme_init in pci.c: The PCIe-Specific NVMe Driver
This entry point is for the PCIe bus adapter layer—the code that bridges the core NVMe logic to physical PCIe-based NVMe drives. Its responsibilities include:
- Probing the PCIe bus to detect NVMe devices
- Configuring PCIe-specific hardware settings (like BAR mappings, interrupts, and DMA)
- Linking detected PCIe NVMe devices to the core NVMe infrastructure (so the core can handle protocol commands)
- Handling PCIe-specific power management and error recovery
In short, this is the part that talks directly to your PCIe NVMe hardware, while leveraging all the generic code from the core module.
Why Split the Driver This Way?
The dual entry points exist for a few key reasons:
- Modularity & Reusability: If you ever work with NVMe over Fabrics (like NVMe over TCP/RDMA), there's a separate
nvme-fabrics.komodule with its ownmodule_init. It reuses all the core logic fromnvme-core.kowithout having to rewrite protocol handling code. - Clean Separation of Concerns: The core layer focuses on the NVMe protocol standard, while the PCIe layer focuses on PCIe bus specifics. This makes the codebase easier to maintain, debug, and extend.
- Independent Loading: While in practice these modules are often loaded together, the design allows you to load the core infrastructure first, then add bus-specific drivers as needed (useful for testing or specialized setups).
To put it simply: nvme-core is the brains of the NVMe implementation, and nvme (the PCIe module) is the hands that interact with the physical hardware.
内容的提问来源于stack exchange,提问作者user3094631

