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

    xiaoxiao2021-04-18  65

    (本章基于: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

    转载请注明原文地址: https://ju.6miu.com/read-675327.html

    最新回复(0)