一、简单的驱动程序实例
驱动文件hello.c
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #define HELLO_MAJOR 231 #define DEVICE_NAME "HelloModule" static int hello_open(struct inode *inode, struct file *file){ printk(KERN_EMERG "hello open.\n"); return 0; } static int hello_write(struct file *file, const char __user * buf, size_t count, loff_t *ppos){ printk(KERN_EMERG "hello write.\n"); return 0; } static struct file_operations hello_flops = { .owner = THIS_MODULE, .open = hello_open, .write = hello_write, }; static int __init hello_init(void){ int ret; ret = register_chrdev(HELLO_MAJOR,DEVICE_NAME, &hello_flops); if (ret < 0) { printk(KERN_EMERG DEVICE_NAME " can't register major number.\n"); return ret; } printk(KERN_EMERG DEVICE_NAME " initialized.\n"); return 0; } static void __exit hello_exit(void){ unregister_chrdev(HELLO_MAJOR, DEVICE_NAME); printk(KERN_EMERG DEVICE_NAME " removed.\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL");
驱动文件主要包括函数hello_open、hello_write、hello_init、hello_exit,测试案例中并没有赋予驱动模块具有实际意义的功能,只是通过打印日志的方式告知控制台一些调试信息,这样我们就可以把握驱动程序的执行过程。
在使用printk打印的时候,在参数中加上了“KERN_EMERG”可以确保待打印信息输出到控制台上。由于printk打印分8个等级,等级高的被打印到控制台上,而等级低的却输出到日志文件中。
编译驱动所需的Makefile
ifneq ($(KERNELRELEASE),) MODULE_NAME = hellomodule $(MODULE_NAME)-objs := hello.o obj-m := $(MODULE_NAME).o else KERNEL_DIR = /lib/modules/`uname -r`/build MODULEDIR := $(shell pwd) .PHONY: modules default: modules modules: make -C $(KERNEL_DIR) M=$(MODULEDIR) modules clean distclean: rm -f *.o *.mod.c .*.*.cmd *.ko rm -rf .tmp_versio