您的位置:首页 > 运维架构 > Linux

Linux Kernel 学习笔记3:设备编号

2017-04-14 15:55 381 查看
(本章基于:linux-4.4.0-37)

Linux中设备编号分为主、次两种。主设备编号表示设备相连的驱动。次设备号决定引用哪个设备,这个由驱动自行定义。

在内核中,设备编号类型为dev_t,本质就是一个32位无符号整型的量,在linux/types.h中定义。其中主编号占12位,次编号占20位。通过下面的宏可以获取主次编号:

MAJOR(dev_t dev);

MINOR(dev_t dev);

相反,通过主次编号获取设备编号使用:

MKDEV(int major, int minor);

以上宏在linux/kdev_t.h中定义

静态注册设备编号:

int register_chrdev_region(dev_t, unsigned, const char *);

1)需要注册的设备编号

2)连续编号个数

3)设备名,会出现在/proc/devices中

注册成功返回0,失败返回一个错误码

静态注册需要实现准备好一个设备号,但必须去其他的驱动模块区分开来,不能重复,因此静态注册并不常用,更通用的方法是让内核动态为你分配一个设备编号。

动态注册设备编号:

int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);

1)设备编号

2)第一个次设备号,常用0

3)连续编号个数

4)设备名

成功注册返回0,失败返回一个错误码

无论用哪种方式注册设备编号,当不再使用的时候需要注销此设备号,以防止不必要的资源占用。

注销设备编号:

void unregister_chrdev_region(dev_t, unsigned);

1)待注销的设备号

2)连续的设备号个数

以上函数均在linux/fs.h中定义

例:

hello.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>

dev_t devId;

static __init int hello_init(void)
{
int result;
#if 0
//静态
if(( result = register_chrdev_region(MKDEV(888, 0), 10, "stone-dev") ) != 0) {
printk(KERN_WARNING "register dev id error:%d\n", result);
} else {
printk(KERN_WARNING "register dev id success!\n");
}
#else
//动态
if(( result = alloc_chrdev_region(&devId, 0, 1, "stone-alloc-dev") ) != 0) {
printk(KERN_WARNING "register dev id error:%d\n", result);
} else {
printk(KERN_WARNING "register dev id success!\n");
}
#endif
printk(KERN_ALERT "hello init success!\n");
return 0;
}

static __exit void hello_exit(void)
{
//unregister_chrdev_region(MKDEV(888, 0), 10);
unregister_chrdev_region(devId, 1);
printk(KERN_WARNING "helloworld exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);

成功加载模块后可在/proc/devices中查看

# cat /proc/devices | grep stone
247 stone-alloc-dev
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息