驱动加载的两种模式:
1.静态编译进内核:
静态编译进内核的驱动程序会随着内核的启动而开始执行,并且一直存在于内核的镜像文件中,这种静态编译进内核的方式适用于那些需要一直随着内核启动而执行的驱动程序。
2.作为模块化动态加载进内核:
作为模块化动态加载进内核的方式在编译内核的时候,不会编译这些被选为模块化的驱动程序,这些模块化的驱动程序是通过make modules的方式生成 .ko文件,然后挂载到根文件系统下,在需要这些驱动模块的时候,才会执行这些驱动模块,将这些驱动模块加载进内核中的模块驱动区域。
加载模块化驱动程序进内核的指令为:insmod xxx.ko
查看模块化驱动程序的指令为:lsmod;
卸载模块化驱动程序的指令为:rmmod xxx(没有.ko后缀)
注意:如果是模块化动态加载驱动程序需要在程序最后加上 MODULE_LICENSE("GPL")。这条指令的作用是告诉内核该驱动程序是符合GPL协议的。
它的作用是在第一次动态加载的时候,不会提示 脏内核。如果不加这个指令,在第一次加载的时候会提示 脏内核,但是卸载之后再加载也不会再出现提示。
两种驱动程序的编写模板:
1.标准字符设备驱动:
标准字符设备驱动程序的编写一般分为:
1.设备的各种操作:open;read;write;close;
2.设备的cdev:也就是设备的编号(这是对于设备底层的标识,设备的各种操作(即1中的各种操作),链表。
3.初始化程序:dev_t设备号;cdev_add()设备节点添加;cdev_init()设备信息初始化;register_chrdev_region()设备号与设备名称的映射关系注册。
4.卸载程序:cdev_del()删除设备节点;unregister_chrdev_region()删除映射表中的信息
5.module_init();module_exit()
2.杂项设备驱动:
杂项设备驱动程序的编写一般分为:
1.设备的各种操作:
2.miscdevice misc:杂项设备结构体。杂项设备结构体中:minor:次设备号;设备名称;设备操作。(杂项设备的主设备号为确定值10,所以只需要确定次设备号)
3.初始化程序:misc_register()
4.卸载程序:misc_deregister();
5.module_init();module_exit();MODULE_LECENSE("GPL");
内核空间与用户空间的数据拷贝:
copy_from_user():将用户空间的数据拷贝到内核空间。
copy_to_user():将内核空间的数据拷贝到用户空间。
设备节点的创建:
手动创建设备节点:mknod /dev/led c 主设备号 次设备号
自动创建设备节点:class = class_create(THIS_MODULE,设备类的名称);device = device_create(class,NULL,devt,NULL,设备节点名称)。
inline内联函数:内联函数的作用是:程序中调用内联函数并不会执行程序的跳转,而是在编译的阶段将函数在调用处展开,从而减少函数的调用和返回,提高执行效率。