精华内容
下载资源
问答
  • linux中的 主设备号与次设备号
    千次阅读
    2020-08-10 15:14:30

    linux主设备号和次设备号

    Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件, 完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3

     

          Linux为所有的设备文件都提供了统一的操作函数接口,方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针,如open()、close()、read()和write()等,但由于外设 的种类较多,操作方式各不相同。Struct file_operations结构体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。打开一个文件就是 调用这个文件file_operations中的open操作。不同类型的文l件有不同的file_operations成员函数,如普通的磁盘数据文件, 接口函数完成磁盘数据块读写操作;而对于各种设备文件,则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样,应用程序根本不必考虑操作的是设 备还是普通文件,可一律当作文件处理,具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口。

    转自:http://hi.baidu.com/wudaovip/blog/item/479b451e95c475f81ad57621.html

     设备号是在驱动module中分配并注册的,也就是说,驱动module拥有这个设备号(我的理解),而/dev目录下的设备文件是根据这个设备号创建的,因此,当访问/dev目录下的设备文件时,驱动module就知道,自己该出场服务了(当然是由内核通知)。
        在Linux内核看来,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务;而次设备号则用来标识具体且唯一的某个设备。
        在内核中,用dev_t类型(其实就是一个32位的无符号整数)的变量来保存设备的主次设备号,其中高12位表示主设备号,低20位表示次设备号。
        设备获得主次设备号有两种方式:一种是手动给定一个32位数,并将它与设备联系起来(即用某个函数注册);另一种是调用系统函数给设备动态分配一个主次设备号。

    对于手动给定一个主次设备号,使用以下函数:
    int register_chrdev_region(dev_t         first, 
                               unsigned int -count, 
                               char          *name)
        其中first是我们手动给定的设备号,count是所请求的连续设备号的个数,而name是和该设备号范围关联的设备名称,它将出现在/proc/devices和sysfs中。
        比如,若first为0x3FFFF0,count为0x5,那么该函数就会为5个设备注册设备号,分别是0x3FFFF0、 0x3FFFF1、 0x3FFFF2、 0x3FFFF3、 0x3FFFF4,其中0x3(高12位)为这5个设备所共有的主设备号(也就是说这5个设备都使用同一个驱动程序)。而0xFFFF0、 0xFFFF1、 0xFFFF2、 0xFFFF3、 0xFFFF4就分别是这5个设备的次设备号了。需要注意的是,若count的值太大了,那么所请求的设备号范围可能会和下一个主设备号重叠。比如若 first还是为0x3FFFF0,而count为0x11,那么first+count=0x400001,也就是说为最后两个设备分配的主设备号已经不是0x3,而是0x4了!用这种方法注册设备号有一个缺点,那就是若该驱动module被其他人广泛使用,那么无法保证注册的设备号是其他人的 Linux系统中未分配使用的设备号。


    对于动态分配设备号,使用以下函数:
    int alloc_chrdev_region(dev_t         *dev, 
                            unsigned int -firstminor, 
                            unsigned int -count, 
                            char          *name)
        该函数需要传递给它指定的第一个次设备号firstminor(一般为0)和要分配的设备数count,以及设备名,调用该函数后自动分配得到的设备号保存在dev中。动态分配设备号可以避免手动指定设备号时带来的缺点,但是它却也有自己的缺点,那就是无法预先在/dev下创建设备节点,因为动态分配设备号不能保证在每次加载驱动module时始终一致(其实若在两次加载同一个驱动module之间并没有加载其他的module,那么自动分配的设备号还是一致的,因为内核分配设备号并不是随机的,但是书上说某些内核开发人员预示不久的将来会用随机方式进行处理),不过,这个缺点可以避免,因为在加载驱动module后,我们可以读取/proc/devices文件以获得Linux内核分配给该设备的主设备号。

    与主次设备号相关的3个宏:
    MAJOR(dev_t dev):根据设备号dev获得主设备号;
    MINOR(dev_t dev):根据设备号dev获得次设备号;
    MKDEV(int major, int minor):根据主设备号major和次设备号minor构建设备号。

    转自:http://fanyihui1986.blog.163.com/blog/static/784485920091132043905/

     

    更多相关内容
  • Linux各种设备都以文件的形式存放在/dev目录下,称为设备文件。  应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据...对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3...

            Linux各种设备都以文件的形式存放在/dev目录下,称为设备文件。

            应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。

     

            一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各设备。例如一个嵌入式系统,有两个LED指示灯,LED灯需要独立的打开或者关闭。那么,可以写一个LED灯的字符设备驱动程序,可以将其主设备号注册成5号设备,次设备号分别为1和2。这里,次设备号就分别表示两个LED灯。

    展开全文
  • linux 内核使用的主设备号

    千次阅读 2017-08-31 14:37:26
    在include/uapi/linux/major.h中,说明了内核需要使用的一些主设备号,如果写驱动程序手工分配主设备号,避开这些即可。

    在include/uapi/linux/major.h中,说明了内核需要使用的一些主设备号,如果写驱动程序手工分配主设备号,避开这些即可。


    展开全文
  • MAJOR宏将dev_t向右移动20位,得到主设备号;MINOR宏将dev_t的高12位清零,得到次设备号。相反,可以将主设备号和次设备号转换为设备号类型(dev_t),使用宏MKDEV可以完成这个功能。 Linux内核允许多个驱动共享一...

    之前看韦东山老师视频,说到linux驱动就知道主设备号找驱动,次设备号找设备。这句到底怎么理解呢,如何在驱动中实现呢,在介绍该实现之前先看下内核中主次设备号的管理。在内核中,dev_t  类型( 在 <linux/types.h>头文件有定义 ) 用来表示设备号,包括主设备号和次设备号两部分。对于 2.6.x内核,dev_t是个32位量,其中高12位用来表示主设备号,低20位用来表示次设备号。

    (linux/kdev_t.h)
    
    #define MINORBITS   20                                 /*次设备号*/
    #define MINORMASK   ((1U << MINORBITS) - 1)            /*次设备号掩码*/
    #define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))  /*dev右移20位得到主设备号*/
    #define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))   /*与次设备掩码与,得到次设备号*/</span>


    MAJOR宏将dev_t向右移动20位,得到主设备号;MINOR宏将dev_t的高12位清零,得到次设备号。相反,可以将主设备号和次设备号转换为设备号类型(dev_t),使用宏MKDEV可以完成这个功能。

    Linux内核允许多个驱动共享一个主设备号,但更多的设备都遵循一个驱动对一个主设备号的原则。

      内核维护着一个以主设备号为key的全局哈希表,而哈希表中数据部分则为与该主设备号设备对应的驱动程序(只有一个次设备)的指针或者多个同类设备驱动程序组成的数组的指针(设备共享主设备号)。根据所编写的驱动程序,可以从内核那里得到一个直接指向设备驱动的指针,或者使用次设备号作为索引的数组来找到设备驱动程序。但无论哪种方式,内核自身几乎不知道次设备号的什么事情。如下图所示:点击打开链接

        尽管这些从设备都涉及到内存访问,但所实现功能有很大差别。然后来看下图1中主设备号为1的memory_fops中定义了哪些函数指针。代码如下:

    //driver/char/mem.c
    
    static const struct file_operations memory_fops = {
      .open = memory_open,
      .llseek = noop_llseek,
    };

    仅有一个关键的函数 memory_open ,其作用是根据次设备号找到次设备的驱动程序。

    static int memory_open(struct inode *inode, struct file *filp)
    {// select different devices through minor device number commented by guoqingbo
      int minor;
      const struct memdev *dev;
    
      minor = iminor(inode); //get the minor device number commented by guoqingbo
      if (minor >= ARRAY_SIZE(devlist))
        return -ENXIO;
    
      dev = &devlist[minor];//select the specific file_operations
      if (!dev->fops)
        return -ENXIO;
    
      filp->f_op = dev->fops;
      if (dev->dev_info)
        filp->f_mapping->backing_dev_info = dev->dev_info;
    
      /* Is /dev/mem or /dev/kmem ? */
      if (dev->dev_info == &directly_mappable_cdev_bdi)
        filp->f_mode |= FMODE_UNSIGNED_OFFSET;
    
      if (dev->fops->open)  //open the device
        return dev->fops->open(inode, filp);
    
      return 0;
    }


    该函数用到的图 中的 dvlist 数组定义如下:

    static const struct memdev {
      const char *name;
      mode_t mode;
      const struct file_operations *fops;
      struct backing_dev_info *dev_info;
    } devlist[] = {
       [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
    #ifdef CONFIG_DEVKMEM
       [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
    #endif
       [3] = { "null", 0666, &null_fops, NULL },
    #ifdef CONFIG_DEVPORT
       [4] = { "port", 0, &port_fops, NULL },
    #endif
       [5] = { "zero", 0666, &zero_fops, &zero_bdi },
       [7] = { "full", 0666, &full_fops, NULL },
       [8] = { "random", 0666, &random_fops, NULL },
       [9] = { "urandom", 0666, &urandom_fops, NULL },
      [11] = { "kmsg", 0, &kmsg_fops, NULL },
    #ifdef CONFIG_CRASH_DUMP
      [12] = { "oldmem", 0, &oldmem_fops, NULL },
    #endif
    };

        通过上面代码及图1可看出, memory_open 实际上实现了一个分配器(根据次设备号区分各个设备,并且选择适当的 file_operations ),图2说明了打开内存设备时,文件操作是如何改变的。 所涉及的函数逐渐反映了设备的具体特性。最初只知道用于打开设备的一般函数。然后由打开与内存相关设备文件的具体函数所替代。接下来根据选择的次设备号,进一步细化函数指针 ,为不同的次设备号最终选定函数指针。

     

    展开全文
  •  很久前接触linux驱动就知道主设备号找驱动,次设备号找设备。这句到底怎么理解呢,如何在驱动中实现呢,在介绍该实现之前先看下内核中主次设备号的管理:  二、Linux内核主次设备号的管理  Linux的设备...
  • Linux主设备号和次设备号

    千次阅读 2018-11-27 09:40:07
    Linux主设备号用来区分不同硬件设备类型,如串口和USB之间的区别; Linux次设备号用来区分不同硬件设备,如串口1和串口2之间的区别; 可以通过命令ls -l /dev来查看系统的设备号; 现在的 Linux 内核允许多个驱动...
  • 主设备号和次设备号

    千次阅读 2011-11-10 14:23:28
    为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。
  • Linux:主设备号和次设备号

    千次阅读 2015-06-29 17:48:20
    为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。
  • 主设备号与次设备号概念

    千次阅读 2012-07-09 11:36:08
    主设备号标志设备驱动程序,次设备号标志特定的子设备。这么想就理解了:一块有着不同分区的磁盘,那么主设备号就标志着这块磁盘,此设备号就标志着这块磁盘上的不同分区,也就是这块磁盘的各分区的主设备号是相同的...
  • linux内核的fbmem.c中注册了一个fb的字符设备,在平台代码(MTK或者高通)中会注册具体的framebuffer设备(两个设备的主设备号相同)。具体注册的设备(fb0,fb1...)的访问全部都是使用fb的file_operations接口。关于字符...
  • 使用stat (/usr/include/sys/stat.h)系统调用,接口如下: stat (__const char *__path, struct stat...要得到主设备号&此设备号,需要使用中定义的宏: MAJOR() 得到主设备号 MINOR() 得到次设备号
  • linux 查看主设备号

    万次阅读 2012-09-27 10:22:05
    1. cd /dev ls -l |grep 设备名 //显示主设备号和次设备号 2. cat /proc/devices //只显示主设备号
  • linux驱动开发 主设备号与次设备号

    万次阅读 2012-08-27 15:47:25
    一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设 备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各 设备。例如一个嵌入式系统,有两个LED指示灯,...
  • 节点有一个属性是设备号(主设备号、次设备号),其中主设备号将设备文件与驱动模块对应起来 当我们open一个设备节点时,告诉了kernel要操作的是是主设备号为XX的节点,然后kernel会通过过XX来寻找合适的内存模块...
  • linux主设备号和从设备号

    千次阅读 2014-09-19 17:54:42
    设备号是在驱动module中分配并注册的,也就是说,驱动module拥有这个设备号(我... 在Linux内核看来,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务;而次设
  • Linux的主次设备号

    千次阅读 2019-03-07 10:39:58
    主设备号与次设备号的功能 在Linux内核中,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务;而次设备号则用来标识具体且唯一的某个设备。 比如说在linux的...
  • < linux / kdev.h > 内容如下: ...#ifndef _LINUX_KDEV_T_H ...在内核中,用32位的dev_t类型来保存设备编号,高12位为主设备号,低20位为次设备...MKDEV(ma,mi) 就是先将主设备号左移20位,然后与此设备号相加得到设备号
  • 18 linux字符设备驱动之设备号

    千次阅读 2017-06-08 10:32:44
    最常用的是设备驱动里实现字符设备驱动, 实现后在”/dev”目录里提供一个设备文件, 然后用户进程就可以通过操作设备文件来调用驱动.如pc上的uart设备文件: crw-rw—- 1 root dialout 4, 64 Jun 8 09:20 /dev/...
  • 主设备号和次设备号通过访问文件系统中的名字来访问字符设备,通常这些名字被称作文件系统中的特殊的文件或这设备文件或者简单节点(simply nodes),它们位于/dev目录下。字符设备驱动的特殊文件,可以通过ls -l输出...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 367,057
精华内容 146,822
关键字:

主设备号