编写hello驱动模块probe_linux_module.c时,需要写以下的结构体。
struct platform_driver hello_driver = {
.probe = hello_probe,
.remove = hello_remove,
.shutdown = hello_shutdown,
.suspend = hello_suspend,
.resume = hello_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
};
在驱动进行注册时会调用 platform_driver_register(&hello_driver),此时把以上的结构体传入这个注册函数。
在linux的kernel源码中查看得到一下的函数platform_driver_register这个函数的实现:
/**
* platform_driver_register - register a driver for platform-level devices
* @drv: platform driver structure
*/
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type;
if (drv->probe)
drv->driver.probe = platform_drv_probe;
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver);
}
结构体里的probe、remove、shutdown、suspend、resume都是函数,最终会在这个platform_driver_register注册函数注册的时候,通过结构体生成的实例,也就是hello_driver调用那几个函数进行一些操作。
在控制台输入:
insmod /mnt/udisk/4412/probe_linux_module.ko
出现以下信心表示驱动注册成功:
[root@iTOP-4412]# insmod /mnt/udisk/4412/probe_linux_module.ko
[ 7003.925932]
[ 7003.925952] Hello World enter!
[ 7003.929684] initialized
[ 7003.933116] DriverState is 0
分析一下init初始化函数和probe函数:
static int hello_init(void)
{
int DriverState;
printk(KERN_EMERG "\n Hello World enter! \n");
DriverState = platform_driver_register(&hello_driver);
printk(KERN_EMERG"\t DriverState is %d\n",DriverState);
return 0;
}
static int hello_probe(struct platform_device *pdv){
printk(KERN_EMERG "\tinitialized\n");
return 0;
}
结果可以发现:
1、module_init(hello_init)触发hello_init函数。
2、接着hello_init触发platform_driver_register函数。
3、platform_driver_register触发hello_probe函数。
至此,驱动注册完成。
[root@iTOP-4412]# lsmod
probe_linux_module 1464 0 - Live 0xbf000000
[root@iTOP-4412]#
[root@iTOP-4412]# rmmod probe_linux_module
可能会出现一下情况,无法卸载驱动:
[root@iTOP-4412]# rmmod probe_linux_module
rmmod: can't change directory to '/lib/modules': No such file or directory
解决方法:
执行 “mkdir lib/modules/xxx” 指令,xxx 是执行 uname -r 指令后查询的内核版本号。
此时执行 rmmod hello,就会卸载成功。
解决方法来源:https://www.cnblogs.com/lialong1st/p/7763531.html
卸载时控制台打印:
[root@iTOP-4412]# rmmod probe_linux_module
[ 630.652158]
[ 630.652175] Hello World exit!
[ 630.655473] hello_remove
1、先执行module_exit(hello_exit);函数。
2、跳入static void hello_exit(void)函数。
3、执行platform_driver_unregister(&hello_driver); 函数。
4、调用hello_driver结构体里面的remove函数。
在我感觉看来这probe、remove、shutdown、suspend、resume都像是回调函数,函数名在结构体中注册声明,然后整个结构体注册到平台文件中,也就是platform_driver_register这个函数。注册成功直接就能在特定情况下触发这些函数。
Tips:各位看官,看着这些函数名是不是很熟悉,各种实时的RTOS和Android、.NET等等操作系统,都有emove、shutdown、suspend、resume这些类似的函数,安卓里面的就是安卓生命周期函数。所以很多操作系统只要熟练一个或者两个也和学习编程一样,学习效率会提高很多!