Hacker News new | ask | show | jobs
by nrclark 1776 days ago
A semi-related question: do kernel modules play nicely with device-tree instantiations?

Like let's say I wanted to instantiate an I2C with a custom driver in my device-tree. Can I put the controller's driver in a kernel module that lives in /lib/modules? Or do I need to compile it into the kernel?

4 comments

Yes, it'll work but device trees are still a little less dynamic than modules, which can be loaded and unloaded, and reconfigured at will. Device Trees still apparently have issues with dynamic reconfiguration. I think branches can be safely added, but removal is still problematic. This apparently is being worked on, so eventually it'll work, I understand.
yes ive done this recently with both spi and i2c. it works with modules, the hardest part for me was finding the right way to create the device tree so eg, my module got the spi bus over spidev. same with i2cdev if you are not using userspace
Yep. The device tree and kernel modules are actually two seperate concepts - the former is just a data structure that describes the hardware for a system and the latter is a way of delivering the drivers independently of the kernel.

Just make sure to run `depmod -a` after copying it into /lib/modules.

nice! I wasn't sure exactly how the ordering happens between (kernel loads the device-tree) and (kernel scans /lib/modules for stuff to autoload).
There is (or can be) some overlap between the two.

As an example, you may want to create a kernel module that can be configured through the device tree (e.g. binds to an arbitrary SPI/I2C bus, requires hardware-specific config). You can add a node for your module to the device tree and assign it a "compatible" property, which is just an arbitrary string you define to represent your module. If you then make your module export the same string using the MODULE_DEVICE_TABLE macro, the kernel will figure out that your module is the one that implements that node in the device tree, and it will call your module's probe callback to initialize the module, passing in the context from the device tree node (e.g. you can get a reference to the SPI/I2C bus hosting your device).

As I understand it, this is the standard way to implement drivers for devices that sit on buses that don't support automatic detection (e.g. not PCIe / USB).

I just did that recently you can load a kernel module the driver will start working and the device will appear (if compatibility is setup correctly). You can remove the module and the device will stop and be removed from /dev.