Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1184759
  • 博文数量: 232
  • 博客积分: 7563
  • 博客等级: 少将
  • 技术积分: 1930
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-21 11:17
文章分类

全部博文(232)

文章存档

2011年(17)

2010年(90)

2009年(66)

2008年(59)

分类: LINUX

2008-07-14 22:16:31

在文件include/linux/major.h中提供了所使用的linux发行版中主设备号的完整列表。
fs/open.c:  本文件实现了许多与文件操作相关的系统调用。主要有文件的创建、打开和关闭,文件宿主和属性的修改、文件访问权限的修改、文件操作时间的修改和系统文件系统 root 的变动等。

  1. 设备驱动程序如何组织??
  2. 每个设备驱动程序都可以使用轮询或者中断的策略
  3. 在传统的UNIX中,块设备和字符设备的接口完全不同,但是在linux中二者之间的区别没有那么明显。设备的接口被设计为看起来和文件系统的接口相同。(每个文件系统都定义了一组固定的操作函数集合,这些函数可以适用于任何文件和目录)。设备驱动程序只需要定义对他有意义的函数操作。设计人员决定这个设备需要那些操作,然后实现这些所需要的函数,最后使用所定义的特定的入口点建立一个struct file_operations结构的实例。
    在UNIX中,设备驱动是在系统启动时进行定义的,此时,设备驱动程序在内核中注册自己特有的设备接口的实现;而在linux中,设备驱动接口实现既可以在系统启动时注册,也可以以模块的方式注册。
  4. 设备驱动程序是一些函数和数据结构的集合,为管理设备实现一个简单的接口。内核通过这个接口来请求驱动程序对设备进行I/O操作。内核通过一个主设备号和从设备号对设备驱动程序进行引用。linux已经为广泛支持的设备类别规定了一些标准的主设备号。如软盘:2;IDE硬盘:3;并口:6。
    这些在include/linux/major.h中有介绍。
    由于许多主设备号已经静态的分配给了公用设备,linux提供了动态分配机制以获取空闲的主设备号。

    从设备号是一个从0开始的一个8位数字。

  5. 内核怎么知道设备的存在?
    在启动时,内核为系统中的每个设备建立一个特殊文件:/dev目录下的设备文件,用来为该设备指定设备驱动程序。???
  6. 1)初始化代码:定义初始化函数**_init
    可装载模块不需要使用init函数,但init_module()函数可用于初始化代码。例如串口的初始化代码为tty_init()。
    **_init()在装载驱动程序时允许设备驱动程序设置必需的数据结构。另外,初始化代码应该使用register_chrdev()函数或者register_blkdev()函数在内核中注册字符设备和块设备的驱动程序接口。
    2)接下来必须修改内核初始化代码,使得内核可以调用新的**_init()函数.
    字符设备:修改drives/char/merr.c中的chr_dev_init()函数;
    块设备: 修改drives/block/ll_rw_bl.c中的blk_dev_init()函数。
    SCSI设备和网络设备的驱动程序有自己的初始化程序。
    3)设备完成初始化工作后,内核就可以在驱动程序的**_open()函数中使用这样的系统调用:
     open(/dev/**, O_RDONLY);
    用户空间程序调用内核中的open()系统调用时就调用了**_open(),因为**_open()在内核中注册为设备文件/dev/**的open函数。
  7. 可装载内核模块驱动程序:
    init_module()代码中的初始化代码与上述传统方法中的init代码的功能是一样的,唯一不同的是这段代码是由/sbin/insmod调用的,而不是由内核初始化代码调用的。





参考内容:
Linux驱动程序:
  1. 用户态和内核态:
    多数的操作系统都把内核和运行在其上的应用程序分为2个层次管理,这就是用户态和内核态。

    内核态:
    有较高的权限,可以控制处理器内存的映射和分配方式,访问外设空间和处理器的特殊状态寄存器,控制中断和DMA等。
    用户态:
    只能运行系统上的应用程序。

       在有MMU的处理器上,Linux系统把内核重新映射在3GB(即0XC0000000)以上的虚拟地址空间(3GB~4GB)-内核空间;每一个应用程序或者进程都通过MMU建立独立寻址空间-用户空间(0~3GB)。不能直接通过指针,把用户空间的数据地址传递给内核(因为MMU映射的地址根本不一样)。要想在应用程序和驱动程序之间传递数据,需要通过转换,把用户态“看到”的空间地址转换成内核态可访问的地址(get_user()、put_user()、copy_from_user()、copy_to_user()等) ,他们自己负责访问权限的检查,使用时不用考虑。
       从用户态到内核态的切换通常通过软件中断实现。
  2. 驱动程序:
    驱动程序作为系统内核的一部分,他工作在内核态。
    • 类型:字符设备
           块设备
           网络设备
  3. 设备文件和设备文件系统:
    Linux设备文件简介
         http://lamp.linux.gov.cn/Linux/device_files.html

    设备文件
       在linux中,字符设备和块设备是通过文件节点访问的(open()、read()、write()等)。在linux的文件系统中,可以找到(或者使用mknod创建)设备对应的文件名--设备文件。对于设备文件的输入/输出操作,系统会调用对应的设备驱动程序。
       惯上,这些设备文件存放在系统的/dev目录下面。但是,系统并不是靠路径去关联设备文件和对应的驱动程序的,因此你可以通过mknod命令将设备文件创建在任意的其他位置。不过一般不这样做。  

      既然系统不是靠路径去关联设备文件和对应的驱动程序的,那么它是靠什么来对应的呢?
      Linux系统是靠主次设备号来联系驱动程序和设备文件节点的,而不是设备文件的路径。
      主设备号:系统依靠主设备号识别不同的驱动程序,每一个驱动程序都对应了一个主设备号。因此,在同一个系统中,一类设备的(当前)主设备号是唯一的。
      次设备号:同一个驱动程序可以管理多个设备,他们依靠次设备号来区分。次设备号只在驱动程序的内部使用,系统内核直接把次设备号传递给驱动程序,由驱动程序去管理。(参看内核源码)

    附:
    1)cat /proc/devices 可以列出系统内核支持的设备驱动程序和对应的主设备号;
    2)内核源码中,Documentation/devices.txt文件定义了常用的linux驱动程序的主设备号。

    设备文件系统

    1)主设备号的获取:

       主设备号的范围是1~255,因此为每一个设备驱动程序分配唯一的主设备号是不现实的。因此Linux内核允许使用动态分配主设备号的方式,即在创建设备时,由系统自动分配一个未使用的设备号给驱动程序。事实上,在Linux2.4和2.6内核中的大多数驱动程序都采用这种动态分配方式。

       但是,动态设备号又带来了新的问题:如何去对应设备文件和驱动程序之间的关系?
       动态分配设备号的缺点::由于分配的主设备号不能保证总是一样的,无法事先创建设备节点。
    但是这并不是什么问题,因为一旦分配了设备号,我们就可以从/proc/devices 读到。 
    最初的解决方法:使用脚本语言来处理。利用脚本读取/proc/devices,得到注册在系统中的各种驱动程序及其对应的主设备号,根据/proc/devices中的对应关系,动态的创建(或者删除)设备文件。这种方法是很麻烦的。
      其实后来,内核完全可以自己管理设备文件,只不过是通过设备文件系统来实现的。

    2)设备文件系统:
       通常,系统启动时会把设备文件系统挂载在/dev目录下面。有了设备文件系统以后,Linux设备文件的创建、删除和目录层次等都由各设备驱动程序管理,再也不用手工创建设备文件节点了,再也不需要mknod时查找对应的主设备号了,也不用依靠复杂的脚本来管理设备文件了。新添加(或者删除)一个设备,如插入一个U盘,系统就会自动的在/dev目录中创建(或删除)对应的设备文件节点。
     
       设备文件路径的改变:
      在没有使用设备文件系统之前,比如桢缓冲设备是/dev/fb0,使用了设备文件系统以后,他的路径对应变为/dev/fb/0.


    3)使用设备文件系统的条件:
       *使用设备文件系统需要驱动程序的支持。事实上,在Linux2.4和2.6内核中,几乎所有的驱动程序都支持设备文件系统。如果一个驱动程序的代码没有对设备文件系统的支持,则宁愿修改这个驱动程序代码(事实上,这种修改是很简单的),而不会去掉内核对设备文件系统的支持。

       *在配置内核时,要选中对设备文件系统的支持(/dev file system support)。这样,系统驱动程序通过CONFIG_DEVFS_FS宏定义判断系统是否对
    备文件系统提供支持。
     
  4. 版本变迁:
    设备文件系统(devfs)在Linux2.6早期内核(Linux2.6.15以前的版本)中被标记为舍弃的特性,在Linux2.6.15及以后的版本则取消了对他的支持。linux2.6内核引入了系统文件系统(sysfs)为每个系统的硬件树进行分级管理,他提供了设备的基本信息。同时,使用udev脚本,这是一种linux2.6内核采用的/dev目录管理系统。他在用户态动态地维护/dev目录下的设备文件。

      
      
  参考文章:
   http://blog.chinaunix.net/u2/70445/showart_720105.html























































阅读(1442) | 评论(0) | 转发(0) |
0

上一篇:等待队列

下一篇:充电电池在国内的发展

给主人留下些什么吧!~~