驱动开发之路——1.1
一、什么是模块:
模块(module)是在内核空间执行的程序,实际上是一种目标对象文件。没有链接,不能独立执行。可是能够装载到系统中作为内核的一部分执行,从而能够动态扩充内核的功能。模块最基本的用处就是用来实现设备驱动程序。
使用模块的长处:
1,将来改动内核时。不必所有又一次编译整个内核。可节省不少时间
2,系统中假设须要使用新模块,不必又一次编译内核,仅仅要插入对应的模块就可以。
静态编译。把所须要的功能都编译到linux内核。会导致生成的内核会非常大。假设我们要在现有的内核中新增或删除功能,将不得不又一次编译内核。
动态编译,linux提供这样一种机制,称为模块(Module)。
此机制的特点是,模块本身不被编译入内核映像,从而控制了内核的大小。
内核一旦被载入。它就和内核中的其它部分全然一样。
在linux中,使用lsmod命令能够获得系统中载入了的全部模块以及模块间的依赖关系。lsmod命令实际上读取并分析"/proc/modules"文件。内核中已载入模块的信息也存在于/sys/module文件夹下。
modprobe命令比insmod命令要强大。它在载入某模块时,会同一时候载入该模块所依赖的其他模块。以modprobe -r filename的方式载入将同一时候卸载其依赖的模块。
二、简单的内核实例:
实例一:
#include<linux/kernel.h>
#include <linux/init.h> #include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello,world\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye,Cruel world\n"); } module_init(hello_init); module_exit(hello_exit);
实例二:
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/kdev_t.h> #include<linux/cdev.h> #include<linux/fs.h> MODULE_LICENSE("GPL"); dev_t devno; //设备结构体 int major=1000; //主设备号 int minor=0; //此设备号 int count=1; //申请一个设备 int hello_init(void) { int ret; devno=MKDEV(major,minor); ret=register_chrdev_region(devno,count,"hello"); //静态申请设备号 if(ret) { return ret; } printk(KERN_INFO "devno register ok\n"); return 0; } void hello_exit(void) { unregister_chrdev_region(devno,count); //释放设备号 } module_init(hello_init); module_exit(hello_exit);
实例三:
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/kdev_t.h> #include<linux/cdev.h> #include<linux/fs.h> MODULE_LICENSE("GPL"); dev_t devno; int major=1000; int minor=0; int count=1; int hello_init(void) { int ret; ret=alloc_chrdev_region(&devno,0,count,"helldyn"); //动态申请设备号 if(ret) { return ret; } printk(KERN_INFO "devno register ok, major = %d ,minor = %d\n",major,minor); return 0; } void hello_exit(void) { unregister_chrdev_region(devno,count); } module_init(hello_init); module_exit(hello_exit);
实例四:
#include<linux/kernel.h> #include<linux/module.h> #include<linux/init.h> #include<linux/kdev_t.h> #include<linux/cdev.h> #include<linux/fs.h> MODULE_LICENSE("GPL"); dev_t devno; int major=1000; int minor=0; int count=1; struct cdev *hello_dev; struct file_operations hello_ops= { .owner = THIS_MODULE, }; int hello_init(void) { int ret; devno=MKDEV(major,minor); ret=register_chrdev_region(devno,count,"hello"); if(ret) { return ret; } printk(KERN_INFO "devno register ok\n"); hello_dev=cdev_alloc(); //动态获取描写叙述字符设备的结构体 if(hello_dev==NULL) return -ENODEV; cdev_init(hello_dev,&hello_ops);//初始化字符设备的结构体 hello_dev->owner=THIS_MODULE; ret=cdev_add(hello_dev,devno,count); if(ret) { unregister_chrdev_region(devno,count); } return 0; } void hello_exit(void) { cdev_del(hello_dev); unregister_chrdev_region(devno,count); } module_init(hello_init); module_exit(hello_exit);