0、建立文件夹busdevdrv 1、总线 在文件夹内建立总线文件bus.c,代码如下。 #include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> MODULE_AUTHOR("sjwangjinbao"); MODULE_LICENSE("Dual BSD/GPL"); static char *Version = "$Revision: 1.0 $"; static int my_match(struct device *dev, struct device_driver *driver) { return !strncmp(dev_name(dev), driver->name, strlen(driver->name) ); } static void my_bus_release(struct device *dev) { printk("my bus release/n"); } struct device my_bus = { .release = my_bus_release }; struct bus_type my_bus_type = { .name = "my_bus", .match = my_match, }; EXPORT_SYMBOL(my_bus); EXPORT_SYMBOL(my_bus_type); /* * Export a simple attribute. */ static ssize_t show_bus_version(struct bus_type *bus, char *buf) { return snprintf(buf, PAGE_SIZE, "%s/n", Version); } static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL); static int __init my_bus_init(void) { int ret; /*注册总线*/ ret = bus_register(&my_bus_type); if (ret) { return ret; } /*创建属性文件*/ if (bus_create_file(&my_bus_type, &bus_attr_version)) { printk("Fail to create version attribute!/n"); } /*初始化总线设备*/ dev_set_name(&my_bus, "my_bus0"); /*注册总线设备*/ ret = device_register(&my_bus); if (ret) { printk("Fail to register device:my_bus!/n"); } return ret; } static void my_bus_exit(void) { device_unregister(&my_bus); bus_unregister(&my_bus_type); } module_init(my_bus_init); module_exit(my_bus_exit); 2、设备 在文件夹下建立设备文件dev.c,代码如下。 #include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> MODULE_AUTHOR("sjwangjinbao"); MODULE_LICENSE("Dual BSD/GPL"); extern struct device my_bus; extern struct bus_type my_bus_type; static void my_dev_release(struct device *dev) { } struct device my_dev = { .bus = &my_bus_type, .parent = &my_bus, .release = my_dev_release, }; /* * Export a simple attribute. */ static ssize_t mydev_show(struct device *dev,struct device_attribute *attr, char *buf) { return sprintf(buf, "%s/n", "This is sjwangjinbao device!"); } static DEVICE_ATTR(dev, S_IRUGO, mydev_show, NULL); static int __init my_device_init(void) { int ret = 0; /*初始化设备*/ dev_set_name(&my_dev, "my_dev"); /*注册设备*/ device_register(&my_dev); /*创建属性文件*/ device_create_file(&my_dev, &dev_attr_dev); return ret; } static void my_device_exit(void) { device_unregister(&my_dev); } module_init(my_device_init); module_exit(my_device_exit); 3、驱动 在文件夹下建立驱动文件drv.c,代码如下。 #include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> MODULE_AUTHOR("sjwangjinbao"); MODULE_LICENSE("Dual BSD/GPL"); extern struct bus_type my_bus_type; static int my_probe(struct device *dev) { printk("Driver found device which my driver can handle!/n"); return 0; } static int my_remove(struct device *dev) { printk("Driver found device unpluged!/n"); return 0; } struct device_driver my_driver = { .name = "my_dev", .probe = my_probe, }; /* * Export a simple attribute. */ static ssize_t mydriver_show(struct device_driver *driver, char *buf) { return sprintf(buf, "%s/n", "This is sjwangjinbao driver!"); } static DRIVER_ATTR(drv, S_IRUGO, mydriver_show, NULL); static int __init my_driver_init(void) { int ret = 0; /*注册驱动*/ driver_register(&my_driver); /*创建属性文件*/ driver_create_file(&my_driver, &driver_attr_drv); return ret; } static void my_driver_exit(void) { driver_unregister(&my_driver); } module_init(my_driver_init); module_exit(my_driver_exit); 4、Makefile 在文件夹下建立Makefile,如下。 ifneq ($(KERNELRELEASE),) obj-m := bus.o dev.o drv.o else KDIR := /usr/src/linux-2.6.33.2 all: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers endif 5、make 在文件夹下执行make命令,将得到bus.ko, dev.ko, drv.ko三个文件。 6、添加模块 使用root用户依次调用如下命令添加3个模块: insmod bus.ko insmod dev.ko insmod.drv.ko 这时候,会在/sys/bus下面发现my_bus已经存在了。到/sys/bus/my_bus/devices/看看,发现我们的my_dev设备已经存在了;到/sys/bus/my_bus/drivers/看看,发现我们的my_dev驱动也存在了。在到/sys/bus/my_bus/devices/my_dev/driver去瞧瞧,发现my_dev驱动已经存在了,这说明我们的 my_dev设备和my_dev驱动已经联系在一起了。同样,在/sys/bus/my_bus/drivers/my_dev下也会发现有个my_dev的设备,这也说明我们的 my_dev设备和my_dev驱动已经联系在一起了。 另外,我们也可以查看他们的属性。 1) 在/sys/bus/my_bus下,我们发现有个version文件,用cat查看它,得到输出为: $Revision: 1.9 $ 这正是我们在程序中指定的。 2) 在/sys/bus/my_bus/devices/my_dev下,我们会发现有个 dev文件,用cat查看它,结果为: This is my device! 这也正是我们程序中指定的。 3) 在/sys/bus/my_bus/drivers/my_dev下,我们也会发现drv文件,用cat查看结果为: This is my driver! 当然,这也是我们在程序中指定的。
浙公网安备 33010602011771号