Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1501197
  • 博文数量: 218
  • 博客积分: 6394
  • 博客等级: 准将
  • 技术积分: 2563
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-08 15:33
个人简介

持之以恒

文章分类

全部博文(218)

文章存档

2013年(8)

2012年(2)

2011年(21)

2010年(55)

2009年(116)

2008年(16)

分类: LINUX

2009-05-13 16:16:33

Linux内核
进程管理
 进程管理负责创建和销毁进程,并处理它们与外界之间的通信
 控制进程如何共享CPU的调度器
 总之,在单个或者多个CPU上实现了多个进程的抽象
内存管理
 内核在有限的可用资源之上为每一个进程创建了独立的虚拟内存空间(MMU)
 内核的各个部分在和内存管理系统交互的时候都使用相同的一组函数调用,包括简单的malloc/free和其他一些复杂的函数
n
文件系统
 文件系统是Linux基础
 内核在没有结构的硬件系统上面构造了结构化的文件系统
 Linux支持多种文件系统类型
  YAFFS (Yet Another Flash File System)
  ROMFS
  RAMFS
  JFFS2(Journaling Flash File System)
设备控制
  几乎每一个系统操作都会映射到物理设备上
  除去CPU,内存以及其他几个很有限的对象之外,几乎所有的设备控制操作都由与被控制设备相关的代码(设备驱动程序)来完成
n
设备驱动程序的存在形式
 可卸载模块
  内核提供的特性可以在运行时进行扩展
  可在运行时添加到内核中的代码被称为“模块”
  常用模块
   设备驱动和文件系统
  灵活
 编译进内核
  与内核其他的功能模块静态编译在一起,不可卸载
用户态和核心态
  多数操作系统都把内核和应用程序分为2个层次管理
  内核态
   有较高的权限,可以控制处理器内存的映射和内存的分配方式
   访问外设空间和处理器的特殊状态寄存器,控制中断和DMA
  用户态
   权限低,优先级低
   处理器控制着对硬件的直接访问以及对内存的非授权访问
  具有不同的内存映射(指针的传递处理)get_user, put_user, copy_from_user, copy_to_user
应用程序执行系统调用或者被硬件中断的时候由用户态转换为内核态,内核代码代表应用程序执行操作,能够访问进程地址空间的所有数据
   在 Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大,但是支持函数少,只能依赖 kernel 中的函数,有些常用的操作要自己来编写,而且调试也不方便。
开发驱动程序需要对 内核有一定的了解,并不是非要精通。 
 
   这里提到的驱动程序都是针对具体设备,并通常做成模块动态加载方式工作的。
   驱动程序框架是分层的,有些驱动并不是针对具体设备的如 ext2 文件系统的驱动,tcp/ip 协议的驱动等等,这些可以称之为软驱动,工作于其他具体设备驱动程序之上。针对嵌入式开发,仅仅编写最低层的设备驱动就可以了。 
    设备驱动程序通常分为字符设备和块设备,这是泛指分类。区别就是有缓冲区的就是块设备,无缓冲区的就是字符设备。但是在 linux 源码的 drivers 目录下,不仅仅有 block 和 char 目录,还有其他的各种设备,那是因为为了方便并没有根据这种分类而是采用了更为直观的功能分类。比如 sound 目录,大家一看就知道里面存放的是各种音频驱动了。 
    既然是设备驱动,先看看设备在 linux 中如何描述。 在/dev 目录下存放有系统支持的所有设备。设备又可以成为设备节点,如果往系统中添加新设备,必须在/dev 下创建相应的节点。一个设备驱动程序往
往可以驱动若干设备,设备通过主设备号和次设备号区分同一主设备号的所有设备使用一个驱动程序次设备号为驱动程序提供了如何区分不同设备的入口
   有些情况下还可以根据次设备号的高低 4 位区分设备的工作类型。 例如,以 hda0-hda4 和hdb0-hdb4 的关系,hda 代表第一块硬盘,hdb 代表第二块硬盘,由于大家都是硬盘因此此用同一驱动程序,所以 had 和 hdb 的主设备号一致。Hda 后面的序号分别代表了该硬盘上的分区信息,为了有效的区分这些分区,次设备的设定做了分类,该字节的高四位代表不同的硬盘的,而低 4 位代表分区索引。 
 
   再考察软件的环境。开发 linux 下驱动程序与所使用的发行版本无关,不管你用 redhat 或 mandrake 等,都无所谓。真正影响你的是你当前所用的内核的版本。如果你打算在目标板上用 2.4.x 的内核,而你的主机上的 linux 用的却是2.6.x 的系统,你的开发将是件麻烦的事。建议主机和目标系统采用同样的内核。
 
   开发驱动过程中,由于采用的是内核引用,在程序编译时是不需要链接到库文件的。因此 lib 路径对我们就没什么用了。但是由于需要引用内核提供的各种数据结构和接口,必须设置好相应版本的 include 路径,通常在/usr/include。在/usr/include 下有好多头文件,真正我们需要的只有/usr/include/linux 目录和/usr/include/asm 目录。 
 
   驱动程序设计中有两个函数和三个数据结构最重要。Init_module 和cleanup_module 这两个函数。File_operations,inode,file 这三个数据结构,在linux/fs.h中定义。至于其他的象内存操作,i/o操作,定时器,中断,DMA等待都是提升部分了。
 
        一、Linux device driver 的概念 
    系统调用是操作系统内核和应用程序之间的接口, 设备驱动程序是操作系统内核和机器硬件之间的接口.设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件, 应用程序可以象操作普通文件一样对硬件设备进行操作.设备驱动程序是内核的一部分,它完成以下的功能: 
    1.对设备初始化和释放. 
    2.把数据从内核传送到硬件和从硬件读取数据. 
    3.读取应用程序传送给设备文件的数据和回送应用程序请求的数据. 
    4.检测和处理设备出现的错误. 
  在Linux 操作系统下有两类主要的设备文件类型,一种是字符设备,另一种是块设备.字符设备和块设备的主要区别是:在对字符设备发出读/写请求时, 实际的硬件 I/O 一般就紧接着发生了, 块设备则不然, 它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的 I/O 操作.块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的 CPU时间来等待. 
    已经提到,用户进程是通过设备文件来与实际的硬件打交道.每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备,另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们.设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序. 
    最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度.也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作.如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了。

阅读(1096) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~