Last active
December 16, 2015 06:59
-
-
Save creamidea/5395456 to your computer and use it in GitHub Desktop.
这个代码是 Character Device Drivers的一个实例代码。参考地址:http://www.tldp.org/LDP/lkmpg/2.6/html/x569.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/init.h> | |
#include <linux/kernel.h> | |
#include <linux/module.h> | |
#include <linux/moduleparam.h> /* Param header */ | |
#include <linux/fs.h> | |
/* | |
* register_chrdev_region(){} | |
* alloc_chrdev_region(){} | |
* unsregister_chrdev_region(){} | |
* */ | |
#include <linux/types.h> | |
/* | |
* dev_t | |
* MKDEV | |
* MAJOR, MINOR | |
* */ | |
#include <linux/cdev.h> | |
#include <linux/slab.h> | |
/* kfree(){} */ | |
#define DRIVER_AUTHOR "icecream <[email protected]>" | |
#define DRIVER_DESC "A sample driver" | |
#define MAJOR_NUM 200 /* 主设备号 */ | |
#define MINOR_NUM 0 /* 次设备号 */ | |
#define DEV_NAME "chardev" /* 设备名称 */ | |
typedef struct { | |
struct cdev cdev; | |
} global_dev; | |
global_dev* global_devp = NULL; /* 全局的指针 */ | |
/* 实现file_operations结构体 */ | |
static struct file_operations fops = { | |
.owner = THIS_MODULE /* 指向当前指针模块 */ | |
}; | |
static int major_num = 0; | |
/* 将设备添加到系统中去实现函数 */ | |
static void setup(global_dev* devp) | |
{ | |
/* 把当前添加到内核中正在使用的列表中 */ | |
cdev_init(&devp->cdev, &fops); | |
/* */ | |
cdev_add(&devp->cdev, MKDEV(major_num, 0), 1); | |
} | |
static int __init basic_init(void) | |
{ | |
int ret; | |
/* Makesure number of device */ | |
dev_t devno; /* 设备编号 */ | |
devno = MKDEV(MAJOR_NUM, MINOR_NUM); | |
/* register the devno to kernel */ | |
ret = register_chrdev_region(devno, 1, DEV_NAME); | |
if (ret < 0) { /* 主动注册失败 */ | |
/* 让系统帮忙注册 */ | |
alloc_chrdev_region(&devno, 0, 1, DEV_NAME); | |
} | |
major_num = MAJOR(devno); /* 提取主设备号 */ | |
printk("major_num = %d\n", major_num); | |
/* 申请内存空间 */ | |
/* GFP_KERNEL will block(sleep) */ | |
global_devp = (global_dev*)kmalloc(sizeof(global_dev), GFP_KERNEL); | |
if (global_devp == NULL) { | |
goto err; | |
} | |
/* global_devp 是全局,不传也可以 */ | |
setup(global_devp); | |
return 0; | |
err: | |
return -1; /* 告诉上层失败原因 */ | |
} | |
static void __exit basic_exit(void) | |
{ | |
/* 删除设备,空间,释放空间 */ | |
cdev_del(&global_devp->cdev); | |
kfree(global_devp); | |
/* 注销设备 */ | |
/* 利用主次编号获取设备编号 */ | |
unregister_chrdev_region(MKDEV(major_num, 0), 1); | |
printk("unregister devno finished!\n"); | |
printk("Exit the driver module!\n"); | |
} | |
module_init(basic_init); /* enter */ | |
module_exit(basic_exit); /* out */ | |
MODULE_LICENSE("Dual BSD/GPL"); | |
MODULE_AUTHOR(DRIVER_AUTHOR); | |
MODULE_DESCRIPTION(DRIVER_DESC); | |
MODULE_ALIAS("Module Exercise"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment