Skip to content

Instantly share code, notes, and snippets.

@creamidea
Last active December 16, 2015 06:59
Show Gist options
  • Save creamidea/5395456 to your computer and use it in GitHub Desktop.
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
#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 <creamidea@gmail.com>"
#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