Linux内核大讲堂(一)设备驱动的基石驱动模型(7)
终于快讲完了,这一节其实就是让上节我们所说的四大天王露下小脸。源码分析请自行完成吧。我建议大家可以试着先看一下代码,如果能看懂,那就把我写的那破玩意删掉,自已实现一遍,如果不能看懂,那马上回过去从第一小节重新看过,耐心,一定要有耐心,没耐心,啥都完了。帖上原码:
Makefile:
obj-m+=wwhs_bus.o
KERNELDIR=/opt/kernel/linux-2.6.38/linux-2.6.38.5
PWD:=$(shellpwd)
all:
make-C$(KERNELDIR)M=$(PWD)modules
clean:
rm-rf*.o**.ko**.mod.c*.cmd*.symvers.tmp_versions.*.cmd
wwhs_public.h:
#include<linux/module.h>
#include<linux/device.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/stat.h>
#include<linux/slab.h>
#include<linux/kobject.h>
#include<linux/klist.h>
#include<linux/kdev_t.h>
#include<linux/fs.h>
#include<linux/major.h>
#include<linux/kprobes.h>
#definewwhs_dbg(dbgbuf)printk(KERN_ERR"wwhs:%s\n",dbgbuf);
#include"../wwhs_public.h"
#defineWWHS_MAJOR83
voidwwhs_release(structdevice*dev)
{
printk(KERN_ERR"wwhs:dev:%sisrelease\n",dev->kobj.name);
}
structdevicewwhs_bus={
.init_name ="wwhs",
.release=wwhs_release,
};
staticstructdevicewwhs_dev={
.init_name ="wwhsled0",
.release=wwhs_release,
};
staticintwwhs_bus_match(structdevice*dev,structdevice_driver*drv)
{
intret=-1;
ret=strncmp(dev->kobj.name,drv->name,strlen(drv->name));
printk(KERN_ERR"wwhs:dev->kobj.name:%sdrv->name:%sret:%d\n",dev->kobj.name,drv->name,ret);
return!ret;
}
staticintwwhs_bus_probe(structdevice*dev)
{
intret=-1;
if(dev->driver->probe)
ret=dev->driver->probe(dev);
returnret;
}
staticstructbus_typewwhs_bus_type={
.name ="wwhs",
.match =wwhs_bus_match,
};
staticstructclass*wwhs_class;
staticintwwhs_bus_register()
{
intret=-1;
wwhs_bus.class=wwhs_class;
ret=device_register(&wwhs_bus);
if(ret)gotodevice_error;
ret=bus_register(&wwhs_bus_type);
if(ret)gotobus_error;
returnret;
bus_error:
device_unregister(&wwhs_bus);
device_error:
returnret;
}
staticvoidwwhs_bus_unregister()
{
device_unregister(&wwhs_bus);
bus_unregister(&wwhs_bus_type);
}
staticintwwhs_class_register(void)
{
wwhs_class=class_create(THIS_MODULE,"wwhsclass");
if(IS_ERR(wwhs_class)){
printk(KERN_ERR"wwhs:classcreateerror\n");
returnPTR_ERR(wwhs_class);
}
printk(KERN_ERR"wwhs:classcreatesuccess\n");
return0;
}
staticvoidwwhs_class_unregister()
{
class_destroy(wwhs_class);
}
staticintwwhs_device_register(structdevice*dev)
{
dev->devt=MKDEV(WWHS_MAJOR,1);
dev->bus=&wwhs_bus_type;
dev->parent=&wwhs_bus;
returndevice_register(dev);
}
staticvoidwwhs_device_unregister(structdevice*wwhs_dev)
{
device_unregister(wwhs_dev);
}
staticstructdevice_driverwwhs_drv={
.name="wwhsled",
};
staticwwhs_drv_probe(structdevice*dev)
{
printk(KERN_ERR"wwhs:dev:%sisprobe\n",dev->kobj.name);
return0;
}
staticwwhs_drv_remove(structdevice*dev)
{
printk(KERN_ERR"wwhs:dev:%sisremove\n",dev->kobj.name);
return0;
}
staticintwwhs_driver_register(structdevice_driver*wwhs_driver)
{
intret=-1;
wwhs_driver->bus=&wwhs_bus_type;
wwhs_driver->owner=THIS_MODULE;
wwhs_driver->probe=wwhs_drv_probe;
wwhs_driver->remove=wwhs_drv_remove;
ret=driver_register(wwhs_driver);
returnret;
}
staticvoidwwhs_driver_unregister(structdevice_driver*wwhs_driver)
{
driver_unregister(wwhs_driver);
}
staticint__initwwhs_init()
{
intret=-1;
ret=wwhs_class_register();
if(ret)gotoerror;
ret=wwhs_bus_register();
if(ret)gotoerror;
ret=wwhs_device_register(&wwhs_dev);
if(ret)gotobus_error;
ret=wwhs_driver_register(&wwhs_drv);
if(ret)gotodevice_error;
returnret;
device_error:
wwhs_device_unregister(&wwhs_dev);
bus_error:
wwhs_bus_unregister();
class_error:
wwhs_class_unregister();
error:
returnret;
}
staticvoid__exitwwhs_exit()
{
wwhs_device_unregister(&wwhs_dev);
wwhs_driver_unregister(&wwhs_drv);
wwhs_bus_unregister();
wwhs_class_unregister();
}
module_init(wwhs_init);
module_exit(wwhs_exit);
MODULE_AUTHOR("wwhs");
MODULE_DESCRIPTION("wwhs_bustest");
MODULE_LICENSE("GPL");
上面就是四大天王小露一下脸,至此,驱动模型的分析要告一段落了。如果根着看了的朋友,我相信肯定是有所收获的。谢谢各位。你们的支持是我前进的动力。^_^
设备驱动模型就先讲到这里了,如果大家有什么好的建议,请进:
http://blog.youkuaiyun.com/z2007b/archive/2011/05/19/6431791.aspx
这里提出来。你们想要了解的,才是我想写的,要不然我写一堆大家都不感兴趣的东西,就没有价值了。谢谢。
上面示例代码下载地址:
<!--EndFragment-->
本文深入浅出地介绍了Linux内核中的设备驱动模型,并通过具体示例代码展示了四大核心组件的作用及其实现方式。


被折叠的 条评论
为什么被折叠?



