注册完设备和驱动之后,就需要注册设备节点
Linux杂项设备出现的意义在于:有很多简单的外围字符设备,它们功能相对简单,一个设备占用一个主设备号对于内核资源来说太浪费。所以对于这些简单的字符设备它们共用一个主设备号,不同的设备使用不同的次设备号。
MISC_DYNAMIC_MINOR 表示由系统分配子设备号
生成helloword.ko文件后,执行 insmod helloworld,就可以在 dev/ 文件夹下看到 hello_device_node 文件,表明成功生成设备节点,执行 rmmod helloword,则节点消失。
helloworld.c
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/miscdevice.h> #include <linux/fs.h> #define DRIVER_NAME "hello" #define NODE_NAME "hello_device_node" MODULE_LICENSE("Dual BSD/GPL"); // required MODULE_AUTHOR("liuShuiDeng"); static long hello_fs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { printk("cmd is %d, arg is %ld\n", cmd, arg); return 0; } static int hello_fs_release(struct inode *inode, struct file *file) { printk(KERN_EMERG "hello_fs_release"); return 0; } static int hello_fs_open(struct inode *inode, struct file *file) { printk(KERN_EMERG "hello_fs_open"); return 0; } static struct file_operations hello_fops = { .owner = THIS_MODULE, .open = hello_fs_open, .release = hello_fs_release, .unlocked_ioctl = hello_fs_ioctl, }; static struct miscdevice hello_miscdevice = { .minor = MISC_DYNAMIC_MINOR, .name = NODE_NAME, .fops = &hello_fops, }; static int hello_probe(struct platform_device *p) { printk(KERN_EMERG "\nhello_probe\n"); misc_register(&hello_miscdevice); return 0; } static int hello_remove(struct platform_device *p) { printk(KERN_EMERG "\nhello_remove\n"); misc_deregister(&hello_miscdevice); return 0; } static void hello_shutdown(struct platform_device *p) { printk(KERN_EMERG "\nhello_shutdown\n"); } static int hello_suspend(struct platform_device *p, pm_message_t state) { printk(KERN_EMERG "\nhello_suspend\n"); return 0; } static int hello_resume(struct platform_device *p) { printk(KERN_EMERG "\nhello_resume\n"); return 0; } static struct platform_driver hello_driver={ .probe = hello_probe, .remove = hello_remove, .shutdown = hello_shutdown, .suspend = hello_suspend, .resume = hello_resume, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, }; static int hello_init(void) //insmod xxx.ko, execute it { printk(KERN_EMERG "\nhello world enter~\n\n"); platform_driver_register(&hello_driver); return 0; } static void hello_exit(void) //rmmod xxx( note: not xxx.ko ), execute it { printk(KERN_EMERG "\nhello world exit~\n\n"); platform_driver_unregister(&hello_driver); } module_init(hello_init); module_exit(hello_exit);
Makefile
obj-m += helloworld.o # source file is helloworld.c #kernel root directory KDIR := /home/god/Desktop/logicalVolume/iTop4412_Kernel_3.0 # directory of source file and Makefile PWD ?= $(shell pwd) all: $(MAKE) -C $(KDIR) M=$(PWD) modules rm -rf *.o rm -rf Module.* rm -rf modules.order rm -rf *.mod.* rm -rf .*.cmd rm -rf .*versions clean: make -C $(KDIR) M=$(PWD) clean