Hello World
| |
| |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| #include <linux/fs.h> |
| #include <linux/device.h> |
| #include <linux/version.h> |
| |
| #define CLASS_NAME "char_cdev_class" |
| #define DEVICE_NAME "char_cdev" |
| |
| static int major = 232; |
| static int minor = 0; |
| static dev_t devno; |
| static struct class *char_cdev_class; |
| module_param(major, int, S_IRUGO); |
| module_param(minor, int, S_IRUGO); |
| |
| |
| 398 static int char_cdev_open(struct inode *inode, struct file *filp) |
| { |
| |
| try_module_get(THIS_MODULE); |
| printk(KERN_INFO DEVICE_NAME " opened!\n"); |
| return 0; |
| } |
| |
| static int char_cdev_release(struct inode *inode, struct file *filp) |
| { |
| |
| printk(KERN_INFO DEVICE_NAME " closed!\n"); |
| module_put(THIS_MODULE); |
| return 0; |
| } |
| |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) |
| static long char_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
| { |
| |
| printk(KERN_INFO DEVICE_NAME " ioctl method!\n"); |
| return 0; |
| } |
| #else |
| static int char_cdev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) |
| { |
| |
| printk(KERN_INFO DEVICE_NAME " ioctl method!\n"); |
| return 0; |
| } |
| #endif |
| |
| static ssize_t char_cdev_read(struct file *filp, char *buffer, size_t count, loff_t *ppos) |
| { |
| |
| printk(KERN_INFO DEVICE_NAME " read method!\n"); |
| return count; |
| } |
| |
| static ssize_t char_cdev_write(struct file *filp, const char *buffer, size_t count, loff_t *ppos) |
| { |
| |
| printk(KERN_INFO DEVICE_NAME " write method!\n"); |
| 399 return count; |
| } |
| |
| |
| static struct file_operations char_cdev_fops = { |
| .owner = THIS_MODULE, |
| .open = char_cdev_open, |
| .release = char_cdev_release, |
| .read = char_cdev_read, |
| .write = char_cdev_write, |
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) |
| .unlocked_ioctl = char_cdev_ioctl, |
| #else |
| .ioctl = char_cdev_ioctl, |
| #endif |
| }; |
| |
| |
| static int char_cdev_init(void) |
| { |
| int ret; |
| |
| ret = register_chrdev(major, DEVICE_NAME, &char_cdev_fops); |
| if (major > 0) |
| { |
| if (ret < 0) |
| { |
| printk(KERN_INFO " Can't get major number!\n"); |
| return ret; |
| } |
| } |
| else |
| { |
| printk(KERN_INFO " ret is %d\n", ret); |
| major = ret; |
| } |
| devno = MKDEV(major, minor); |
| |
| char_cdev_class = class_create(THIS_MODULE, CLASS_NAME); |
| if (IS_ERR(char_cdev_class)) |
| { |
| printk(KERN_INFO "create class error!\n"); |
| return -1; |
| } |
| 400 |
| |
| device_create(char_cdev_class, NULL, devno, NULL, DEVICE_NAME); |
| printk(KERN_INFO "%s ok!\n", __func__); |
| return ret; |
| } |
| |
| |
| static void char_cdev_exit(void) |
| { |
| |
| device_destroy(char_cdev_class, devno); |
| class_destroy(char_cdev_class); |
| unregister_chrdev(major, DEVICE_NAME); |
| printk(KERN_INFO "%s\n", __func__); |
| } |
| module_init(char_cdev_init); |
| module_exit(char_cdev_exit); |
| |
| MODULE_LICENSE("GPL"); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!