字符设备号本质就是一个32位的无符号整型值。高12位为主设备号;低20位为次设备号。
- 查看设备号
cat /proc/devices
4.1、构造设备号
源码路径: include/linux/kdev_t.h
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
4.2、注册/注销设备号
/**
* register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name)
/**
* unregister_chrdev_region() - return a range of device numbers
* @from: the first in the range of numbers to unregister
* @count: the number of device numbers to unregister
*
* This function will unregister a range of @count device numbers,
* starting with @from. The caller should normally be the one who
* allocated those numbers in the first place...
*/
void unregister_chrdev_region(dev_t from, unsigned count)
4.3、示例代码
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kdev_t.h>
#include<linux/fs.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NEONAN");
static int major = 230;
static int minor = 0;
static dev_t devno;
static int hello_init(void)
{
int result;
printk("hello_init\n");
devno = MKDEV(major, minor);
result = register_chrdev_region(devno, 1, "dev_test");
if(result < 0){
printk("register_chrdev_region fauil\n");
return result;
}
return 0;
}
static void hello_exit(void)
{
printk("hello_exit\n");
unregister_chrdev_region(devno,1);
return;
}
module_init(hello_init);
module_exit(hello_exit);
编译后,注册该驱动
root@work:/home/work/dirve/dev_t# insmod dev_t.ko
root@work:/home/work/dirve/dev_t# cat /proc/devices
Character devices:
...
230 dev_test