01: 一个简单的示例

总线是处理器与外设之间通信的通道。在当前版本的Linux设备模型(Linux Device Model, LDM)中,所有的设备都是通过总线相连的,甚至是通过虚拟的”platform”总线。总线之间可以互相插入,比如一个SCSI控制器(适配器)一般是一个PCI-E设备,而一个USB控制器一般是一个PCI设备。

相关阅读:Linux总线驱动-02: struct bus_type 结构体

在设备模型中,每类总线都有一个设备链表和驱动链表。每当有新的设备插入(必定会插入到某总线),驱动核心遍历新设备所在总线的驱动链表,给设备匹配驱动;每当有新的驱动插入(也必定插入到某总线),驱动核心遍历驱动所在总线的设备链表,对于没有关联上驱动的设备,会尝试匹配。驱动移除时,驱动核心通知相关驱动,驱动移除时,驱动核心通知所有该驱动关联的设备。这就是驱动核心实现的热插拔机制。LDD3的第十四章Linux设备模型对此有详细描述。

在新的驱动核心支持下,实现一个什么都不做的总线驱动是很简单的。如下,拷贝代码并保存为ycbus.c:

/*    * ycbus: a software bus driver (virtual bus driver)    *    * a trivial ycbus driver    */   #include <linux/device.h>    #include <linux/module.h>    struct bus_type ycbus_type = {      .name      = "ycbus",    };    static int __init ycbus_driver_init(void)    {      printk(KERN_DEBUG "ycbus_driver_init\n");      return bus_register(&ycbus_type);    }    static void __exit ycbus_driver_exit(void)    {      printk(KERN_DEBUG "ycbus_driver_exit\n");      bus_unregister(&ycbus_type);    }    module_init(ycbus_driver_init);    module_exit(ycbus_driver_exit);    MODULE_AUTHOR("yc <cppgp@qq.com>");    MODULE_DESCRIPTION("yc pseudo-bus driver");    MODULE_LICENSE("GPL");  

提供一个简单的Makefile文件完成编译。如下,拷贝内容并保存为Makefile,和ycbus.c置于同一目录):

# A trivial bus driver Makefile. Saved as “Makefile” exactly    ifneq ($(KERNELRELEASE),)      obj-m := ycbus.o    else     KERNDIR ?= /lib/modules/$(shell uname -r)/build      PWD := $(shell pwd)      default:        $(MAKE) -C ${KERNDIR} M=${PWD} modules    endif    clean:        rm -rf modules.order Module.symvers .tmp_versions ycbus.ko .ycbus.ko.cmd ycbus.mod.c ycbus.mod.o .ycbus.mod.o.cmd ycbus.o .ycbus.o.cmd  

注意,$(MAKE)和rm两行前面是TAB而不是空格。键入空格Makefile是不会工作的。

执行编译/加载命令:

$ make    $ sudo insmod ycbus.ko  

在/sys/bus/ycbus下查看ycbus的信息:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxdjz.html