在/dev下自动创建设备节点
2015-07-02 15:12
811 查看
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
static int major = 0;
dev_t dev;
struct cdev scull_cdev;
struct file_operations scull_fops = {
.owner = THIS_MODULE,
// .ioctl = scull_ioctl,
// .open = scull_open,
// .release = scull_close,
};
static struct class * scull_class;
// 驱动加载函数
static int hello_init(void)
{
int result = 0;
int err = 0;
printk(KERN_ALERT "Hello, world\n");
if(major){// 静态分配设备编号范围
dev = MKDEV(major, 0);
result = register_chrdev_region(dev, 1, "scull0");
}else{
// 动态分配设备编号范围
result = alloc_chrdev_region(&dev, 0, 1, "scull0");
major = MAJOR(dev);
}
if(result < 0){
printk(KERN_WARNING "scull: can't get major %d\n", major);
return result;
}
printk("get major is %d\n", major);
// 分配初始化struct cdev和struct file_operations
cdev_init(&scull_cdev, &scull_fops);
scull_cdev.owner = THIS_MODULE;
scull_cdev.ops = &scull_fops;
// 将设备添加到系统中
err = cdev_add(&scull_cdev, dev, 1);
if(err){
printk(KERN_NOTICE "Error %d adding scull0", err);
return -1;
}
// 为设备创建一个类
scull_class = class_create(THIS_MODULE, "scull0");
if(IS_ERR(scull_class)){
printk(KERN_NOTICE "Error faild in creating class.\n");
return -1;
}
// 创建对应设备节点
device_create(scull_class, NULL, dev, NULL, "scull0");
printk("scull0 install ok.\n");
return 0;
}
static void hello_exit(void)
{
// 从系统中移除这个字符设备
cdev_del(&scull_cdev);
// 删除设备节点
device_destroy(scull_class, dev);
// 释放设备节点类
class_destroy(scull_class);
// 释放设备编号
unregister_chrdev_region(dev, 1);
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
注意:必须启动mdev。
下面做详细介绍。
udev 和mdev 是两个使用uevent 机制处理热插拔问题的用户空间程序,两者的实现机理不同。udev 是基于netlink 机制的,它在系统启动时运行了一个deamon 程序udevd,通过监听内核发送的uevent 来执行相应的热拔插动作,包括创建/删除设备节点,加载/卸载驱动模块等等。mdev 是基于uevent_helper 机制的,它在系统启动时修改了内核中的uevnet_helper 变量(通过写/proc/sys/kernel/hotplug),值为“/sbin/mdev”。这样内核产生uevent
时会调用uevent_helper 所指的用户级程序,也就是mdev,来执行相应的热拔插动作。udev 使用的netlink 机制在有大量uevent 的场合效率高,适合用在PC 机上;而mdev 使用的uevent_helper 机制实现简单,适合用在嵌入式系统中。
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
static int major = 0;
dev_t dev;
struct cdev scull_cdev;
struct file_operations scull_fops = {
.owner = THIS_MODULE,
// .ioctl = scull_ioctl,
// .open = scull_open,
// .release = scull_close,
};
static struct class * scull_class;
// 驱动加载函数
static int hello_init(void)
{
int result = 0;
int err = 0;
printk(KERN_ALERT "Hello, world\n");
if(major){// 静态分配设备编号范围
dev = MKDEV(major, 0);
result = register_chrdev_region(dev, 1, "scull0");
}else{
// 动态分配设备编号范围
result = alloc_chrdev_region(&dev, 0, 1, "scull0");
major = MAJOR(dev);
}
if(result < 0){
printk(KERN_WARNING "scull: can't get major %d\n", major);
return result;
}
printk("get major is %d\n", major);
// 分配初始化struct cdev和struct file_operations
cdev_init(&scull_cdev, &scull_fops);
scull_cdev.owner = THIS_MODULE;
scull_cdev.ops = &scull_fops;
// 将设备添加到系统中
err = cdev_add(&scull_cdev, dev, 1);
if(err){
printk(KERN_NOTICE "Error %d adding scull0", err);
return -1;
}
// 为设备创建一个类
scull_class = class_create(THIS_MODULE, "scull0");
if(IS_ERR(scull_class)){
printk(KERN_NOTICE "Error faild in creating class.\n");
return -1;
}
// 创建对应设备节点
device_create(scull_class, NULL, dev, NULL, "scull0");
printk("scull0 install ok.\n");
return 0;
}
static void hello_exit(void)
{
// 从系统中移除这个字符设备
cdev_del(&scull_cdev);
// 删除设备节点
device_destroy(scull_class, dev);
// 释放设备节点类
class_destroy(scull_class);
// 释放设备编号
unregister_chrdev_region(dev, 1);
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
注意:必须启动mdev。
下面做详细介绍。
udev 和mdev 是两个使用uevent 机制处理热插拔问题的用户空间程序,两者的实现机理不同。udev 是基于netlink 机制的,它在系统启动时运行了一个deamon 程序udevd,通过监听内核发送的uevent 来执行相应的热拔插动作,包括创建/删除设备节点,加载/卸载驱动模块等等。mdev 是基于uevent_helper 机制的,它在系统启动时修改了内核中的uevnet_helper 变量(通过写/proc/sys/kernel/hotplug),值为“/sbin/mdev”。这样内核产生uevent
时会调用uevent_helper 所指的用户级程序,也就是mdev,来执行相应的热拔插动作。udev 使用的netlink 机制在有大量uevent 的场合效率高,适合用在PC 机上;而mdev 使用的uevent_helper 机制实现简单,适合用在嵌入式系统中。
相关文章推荐
- Linux socket 初步
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝
- vivi下重新调整分区
- Linux VS Unix:Linux欲一统天下 Unix不死
- linux下设定环境变量
- Linux下修改MySQL编码的方法