I’ve been working through John Madieu’s Book on Linux Device Driver Development. When typing in the Sample code for the Platform device, I got a Segmentation fault registering the device (insmod).
I started with the example code for registering the platform_driver:
static struct platform_driver mctp_pcc_driver = {
.probe = mctp_pcc_driver_probe,
.remove = mctp_pcc_driver_remove,
};
static int __init mctp_pcc_mod_init(void)
{
int rc = 0;
printk(KERN_INFO "initializing MCTP over PCC\n");
rc = platform_driver_register(&mctp_pcc_driver);
return rc;
}
The stack trace in the Kernel Oops showed that there was string compare happening in the platform_driver_register call. Looking at other Kernel modules code, I noticed that it set the .driver { .name } value. This change worked:
static struct platform_driver mctp_pcc_driver = {
.probe = mctp_pcc_driver_probe,
.remove = mctp_pcc_driver_remove,
.driver = {
.name = "mctp_pcc",
}
};
Once I made this change, I can insmod the module, and check to see that the system sees the driver:
# find /sys/ -name mctp_pcc
/sys/kernel/btf/mctp_pcc
/sys/kernel/debug/printk/index/mctp_pcc
/sys/bus/platform/drivers/mctp_pcc
/sys/module/mctp_pcc
And rmmod-ing the module removes these /sys entries.
If you go to the Book github site and check the code, you can he he fills out the structure with the owner value as well:
static struct platform_driver mypdrv = {
.probe = my_pdrv_probe,
.remove = my_pdrv_remove,
.driver = {
.name = "platform-dummy-char",
.owner = THIS_MODULE,
},
};
One other change I noticed when looking at his sample code is that he does not use an init or exit function for the module, but instead registers the driver with the single macro:
module_platform_driver(mypdrv);
Which I confirmed also creates and removes the /sys entries upon insmod/rmmod.