开始从头学起linux 设备驱动,当然是先从字符驱动看起。相关阅读:Linux 设备驱动 ====> 并发控制 --- 原子操作 http://www.linuxidc.com/Linux/2012-03/57580.htm下面仿照着书上的例子,写了一个misc 字符驱动。
- root@www.linuxidc.com:/home/jay/globalmem# tree globalmem/
- globalmem/
- ├── globalmem.c
- └── Makefile
首先咱来看下Makefile, 其实这东西都一个模子,
- KVERS = $(shell uname -r)
-
- obj-m += globalmem.o
-
- build: kernel_modules
-
- kernel_modules:
- make -C /lib/modules/$(KVERS)/build/ M=$(CURDIR) modules
-
- clean:
- make -C /lib/modules/$(KVERS)/build/ M=$(CURDIR) clean
然后是我们的驱动文件globalmem.c,我们从init函数看起
- int globalmem_init(void)
- {
- int result;
- globalmem_devp = kmalloc(sizeof(struct globalmem_dev) ,GFP_KERNEL);
- if(!globalmem_devp) {
- result = -ENOMEM;
- goto fail_malloc;
- }
- memset(globalmem_devp, 0, sizeof(struct globalmem_dev));
-
- globalmem_devp->mdev = mdev_struct;
-
- result = misc_register(&(globalmem_devp->mdev));
- if(result<0)
- return result;
- else
- return 0;
-
- fail_malloc:
- return result;
- }
首先是给我们的全局指针变量分配内存
- globalmem_devp = kmalloc(sizeof(struct globalmem_dev) ,GFP_KERNEL);
- if(!globalmem_devp) {
- result = -ENOMEM;
- goto fail_malloc;
- }
- memset(globalmem_devp, 0, sizeof(struct globalmem_dev));
看下这个指针的定义
- struct globalmem_dev {
- struct miscdevice mdev;
- unsigned char mem[GLOBALMEM_SIZE];
- };
-
- struct globalmem_dev *globalmem_devp;
globalmem_dev结构体中内嵌了一个miscdevice结构体,这个结构体就是描述我们的misc字符驱动的结构体,若想注册一个misc 字符设备就必须包含有这样一个结构体,
- struct miscdevice {
- int minor;
- const char *name;
- const struct file_operations *fops;
- struct list_head list;
- struct device *parent;
- struct device *this_device;
- };
这个结构体描述了这个驱动的信息,包含次设备号, 文件操作结构体,驱动名称等。 内存分配结束之后是调用misc_register来注册我们的misc驱动,使用misc字符驱动相对于标准的字符驱动写起来简单。然后是exit函数,跟init相反:
- void globalmem_exit(void)
- {
- misc_deregister(&(globalmem_devp->mdev));
- if(globalmem_devp)
- kfree(globalmem_devp);
- }
-
- module_init(globalmem_init);
- module_exit(globalmem_exit);
千万别忘了最后要释放我们分配的内存。 然后使我们的miscdevice和fops结构体
- static const struct file_operations globalmem_fops = {
- .owner = THIS_MODULE,
- .open = globalmem_open,
- .release = globalmem_release,
- .unlocked_ioctl = globalmem_ioctl,
- .read = globalmem_read,
- .write = globalmem_write,
- };
-
- static struct miscdevice mdev_struct = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "globalmem",
- .fops = &globalmem_fops,
- };
这里主要是这个file_operations接头体的定义,这里主要是把这个结构体中我们想要实现的读,写等方法与对应的回调函数挂钩起来。