首页 | 邮件资讯 | 技术教程 | 解决方案 | 产品评测 | 邮件人才 | 邮件博客 | 邮件系统论坛 | 软件下载 | 邮件周刊 | 热点专题 | 工具
网络技术 | 操作系统 | 邮件系统 | 客户端 | 电子邮箱 | 反垃圾邮件 | 邮件安全 | 邮件营销 | 移动电邮 | 邮件软件下载 | 电子书下载

操作系统

Windows 9X | Linux&Uinx | Windows Server | 其它操作系统 | Vista | FreeBSD | Windows 7 |
首页 > 操作系统 > Linux&Uinx > Linux系统下设备驱动的安全端口分配 > 正文

Linux系统下设备驱动的安全端口分配

出处:5DMail.Net收集整理 作者:佚名 时间:2006-9-25 10:27:00
   摘要:

    编写设备驱动是一个具有挑战性和冒险性的工作。当设备通过init_mo dule函数登记时,设备的资源应当被分 配。一个主要的设备资源是I/O端口。作为动态连接的驱动程序,开发者应当小心将未被使用的I/O端口分配 给这些设备。 首先驱动程序应侦测这些端口是否被使用或释放。然后再为设备申请获取端口。当驱动模块被 从内核中移出时,端口应该被释放。这篇文章讨论了Linux设备驱动的安全端口分配的复杂性。

    介绍

    设备驱动开发者一个主要关心的问题是设备的资源分配。这些资源包括I/O端口,内存和中断。这篇文章试图解释I/O子系统的基本原理和资源分配的重要性,主要是I/O端口的资源处理。同时还将阐明如何侦测,申请和释放设备的端口地址。

    基本的硬件元素,如端口,总线和设备控制器,构成了大量的不同的I/O设备。设备驱动向I/O子系统提供了 一个通用的设备存取界面,这非常类似于系统调用(systmem call)在应用程序和操作系统之间提供的标准界 面。现在有很多种类型的设备附属在电脑上,举例说来有: 存储设备,如磁盘,磁带,光驱和软驱; 人机交 互设备,如键盘,鼠标和屏幕; 传输设备,如网卡和调制解调器。不论这些不同设备的数目巨大,我们只需要理解一些基本的概念,即设备如何加载以及软件如何控制硬件。

    基本概念

    设备由两部分组成,一个是被称设备为控制器的电器部分,另一个是机械部分。控制器通过系统总线加载到 电脑上。典型的方式是,一组互不冲突的寄存器组被赋予到各个控制器。I/O端口包含4组寄存器,即状态寄 存器,控制寄存器,数据输入寄存器,数据输出寄存器。状态寄存器拥有可以被主机读取的(状态)位,用来 指示当前命令是否执行完毕,或者字节是否可以被读出或写入,以及任何错误提示。控制寄存器则被主机写操作以启动一条命令或者改变设备的(工作)模式。数据输入寄存器用于获取输入而数据输出寄存器则向主机发送结果。

    所以,处理器和设备之间的基本界面是控制和状态寄存器。当处理器执行程序并且遇到与设备相关的指令 时,它通过向相应的设备发送一条命令来执行该指令。控制器执行所要求的动作并设置状态寄存器的特定位,然后进入等待。处理器有责任检查设备的状态直到发现操作完成。例如并口驱动程序(打印机使用的)一般会 轮询打印机以知道打印机是否准备好。如果打印机没有准备好,驱动程序会睡眠一段时间(处理器此时会做其他有用的工作),该过程将重复直到打印机准备好。这种轮询的机制能够改进系统的性能。另外一种方式则是 系统进行不必要的"死等"(unnecessarily waiting)而不做任何有用的工作。

    寄存器拥有在I/O空间明确定义的地址范围。通常这些地址在启动时被分配,使用一组在配置文件中定义的参数。各个设备的地址范围可能被预分配,如果设备是静态加载的。这意味内核包含了已存在设备的驱动 程序,以分配的I/O端口能被存放在Proc目录下。你可以在系统使用这些设备时,通过运行“cat /proc/ioports” 命令同步的检查其所使用的地址范围。第一列输出显示了端口的范围而第二列则是拥用这些端口的设备。一 些操作系统具备在运行时动态加载设备驱动模块的特性。所以任何新的设备都能通过动态加载模块在系统运行时加载到系统中,并且能够被控制和访问。

    设备驱动的概念是非常抽象的并且处于一台计算上所运行软件的最低层。由于直接到设备的硬件特性的限 制。每个设备驱动都只管理一种单一类型的设备。这些类型可能是字符型,快设备型或网络型。如果一个应用程序向设备提出(操作)要求。内核会联系到对应的设备驱动,设备驱动接着向特定的设备发出命令。设备驱 动是一个函数集合:包含了许多调用入口,类似于open,close,read,write,ioctl,llseek 等。当你插入你的模块时,init_module ( ) 函数会被调用,而模块被移出时,cleanup_module ( ) 函数会被调用。设备是在 设备驱动的init_module ( ) 例程中被登记的。

    当设备在 init_module ( ) 中登记时,设备的资源如I/O端口,内存和中断号也在这个函数被分配,这也 是驱动程序能够正确操作设备的需要。如果你分配了任何错误的内存地址,系统会显示错误信息segmentation fault. 而对于I/O端口,系统不会给出任何类似wrong I/O port的信息,但是指派任何现有设备已使用的端 口将会造成系统崩溃。当你移出模块时,设备应当被注销,更确切的说,主(设备)号和资源将在cleanup_module ( ) 函 数中被释放。

    设备驱动最频繁的工作时读写IO端口。所以你的驱动应当是确信完美的,被设备使用的端口地址是独占的。任何其他设备都不会使用这段地址范围。为了确认这点,首先驱动应当查明这段地址是否在使用,当驱动发现 这段地址未被使用时,可以申请内核为设备分配这段地址。

安全端口分配

现在我们来看看如何通过系统函数来完成资源分配和资源释放。下面的实例 是在linux 2。4内核上进行实验的,以下的所有实现仅适用于Linux操作系统和某些扩展的Unix变种。

首先侦测可用的端口(地址)范围,通过下面的函数:

int check_region (unsigned long start, unsigned long len);

函数返回0表示端口地址可用,返回小于零或负的错误编码( -EBUSY or -EINVAL) 表示已在使用中。函数接受2个参数: start 是 连续区域(或I/O端口范围)的起始值,而len是区域内的端口数目。

当端口可用时,应该将它分配给设备,通过request_region 函数。

struct resource *request_region (unsigned long start, unsigned long len, char *name);

头两个参数和我们前面看到的一样,字符指针变量name是要分配端口地址的设备名称。函数返回指向resource结构的指针。Resource结构用来描述资源的范围,定义于。结构的格式定义如下:

struct resource {
        const char *name;
        unsigned long start, end;
        unsigned long flags;
        struct resource *parent, *sibiling, *child;
      };

当模块从内核移出时,端口应当被释放以便为其它设备使用,为此我们在 cleanup_module ( )中 使用release_region ( ) 函数。 函数的语法如下:

void release_region ( unsigned long start, unsigned long len);

两个参数的解释和前面一致。 以上的3个函数实际上是宏定义,定义于

设备端口分配的驱动代码例子

下面的程序说明了动态加载设备的端口分配与回收:

#include <linux/fs。h。>
#include <linux/ioport。h。>
struct file_operations fops;
unsigned long start, len;
int init_module (void)
{
 int status;
 start = 0xff90;
 len   = 0x90;
 register_chrdev(254,"your_device",&fops);
 status = check_region (start, len);
 if (status == 0) {
     printk ("The ports are available in that range。\n");
     request_region(start,len,"your_device");
 } else {
     printk ("The ports are already in use。 Try other range。\n");
     return (status);
 }
 return 0;
}
void cleanup_module (void)
{
 release_region(start, len);
 printk (" ports are freed successfully\n");
 unregister_chrdev(254,"your_device");}
 printk (" your device is unregistered\n");
      }

为了避免混淆,例子代码中去掉了错误检查和和主(设备)号的动态分配。 当端口分配成功时,我们可以在proc目录中检查:

$cat /proc/ioports

驱动程序的内核I/O端口函数选择

Linux支持不同位宽的端口函数,用于I/O端口的读写。端口可以是8位,16位或32位。Linux的内 核头文件定义了访问I/O端口的内联(inline)函数,用于读取(inx)或写入(outx) 8位,16位以及32位端口。这些函数是:

__u8 inb (unsigned int port);
void outb (__u8 data, unsigned int port);
__u16 inw (unsigned int port);
void outw(__u16 data, unsigned int port);
__u32 inl (unsigned int prot);
      void outl (__u32 data, unsigned int port);

这些函数的串版本(string versions)能让你在单位时间内更有效的传输一个以上的数据,通过以下函数:

void insb(unsigned int port, void *addr, unsigned long count);
      void outsb(unsigned int port, void *addr, unsigned long count);

addr 是被传入或传出的内存单元地址,count是被传输单元的数量。 Data 则是被读取或 写入到"port"端口的数据:

void insw(unsigned int port, void *addr, unsigned long count);
      void outsw(unsigned int port, void *addr, unsigned long count);

向16位端口读写16位数据:

void insl(unsigned int port, void *addr, unsigned long count);
      void outsl(unsigned int port, void *addr, unsigned long count);

向32位端口读写32位数据。

相关文章 热门文章
  • 如何在Android系统中使用QQ邮箱Exchange移动终端同步服务?
  • 如何在塞班S60系统中使用QQ邮箱Exchange移动终端同步服务?
  • IMF系统遭黑客攻击 部分电子邮件和文档丢失
  • Powercfg 从命令行控制系统的电源管理
  • 实现微软AD与Domino OA系统的互连互用
  • 邮件系统双雄PK: TurboMail vs Exchange
  • 利用Transporter Suite实现从第3方邮件系统迁移到Exchange 2007
  • 使用远程桌面连接的10大技巧 从Windows XP客户端连接和管理远程系统
  • 监视Windows 7中的系统启动性能
  • TurboMail邮件系统双机热备方案
  • TurboMail免费打造企业级别邮件系统
  • 现代通信系统的革命:Email死了?
  • linux的基本操作(上)
  • Linux系统下应用知识大荟萃
  • GNU GRUB启动管理器
  • 制作基于软盘的Linux系统
  • 网络配置文件快速解读
  • linux的基本操作(下)
  • 剖析Linux系统启动过程
  • DameWare让局域网管理不再繁琐
  • 在Redhat 9下实现双机热备和集群功能
  • LINUX守护进程介绍
  • Redhat advance server 2.1集群的安装与管理
  • Linux必须学会的60个命令-文件处理
  • 自由广告区
     
    最新软件下载
  • SharePoint Server 2010 部署文档
  • Exchange 2010 RTM升级至SP1 教程
  • Exchange 2010 OWA下RBAC实现的组功能...
  • Lync Server 2010 Standard Edition 标..
  • Lync Server 2010 Enterprise Edition...
  • Forefront Endpoint Protection 2010 ...
  • Lync Server 2010 Edge 服务器部署文档
  • 《Exchange 2003专家指南》
  • Mastering Hyper-V Deployment
  • Windows Server 2008 R2 Hyper-V
  • Microsoft Lync Server 2010 Unleashed
  • Windows Server 2008 R2 Unleashed
  • 今日邮件技术文章
  • 腾讯,在创新中演绎互联网“进化论”
  • 华科人 张小龙 (中国第二代程序员 QQ...
  • 微软推出新功能 提高Hotmail密码安全性
  • 快压技巧分享:秒传邮件超大附件
  • 不容忽视的邮件营销数据分析过程中的算..
  • 国内手机邮箱的现状与未来发展——访尚..
  • 易观数据:2011Q2中国手机邮箱市场收入..
  • 穿越时空的爱恋 QQ邮箱音视频及贺卡邮件
  • Hotmail新功能:“我的朋友可能被黑了”
  • 入侵邻居网络发骚扰邮件 美国男子被重..
  • 网易邮箱莫子睿:《非你莫属》招聘多过..
  • 中国电信推广189邮箱绿色账单
  • 最新专题
  • 鸟哥的Linux私房菜之Mail服务器
  • Exchange Server 2010技术专题
  • Windows 7 技术专题
  • Sendmail 邮件系统配置
  • 组建Exchange 2003邮件系统
  • Windows Server 2008 专题
  • ORF 反垃圾邮件系统
  • Exchange Server 2007 专题
  • ISA Server 2006 教程专题
  • Windows Vista 技术专题
  • “黑莓”(BlackBerry)专题
  • Apache James 专题
  • 分类导航
    邮件新闻资讯:
    IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮
    电子邮箱 | 反垃圾邮件|邮件客户端|网络安全
    行业数据 | 邮件人物 | 网站公告 | 行业法规
    网络技术:
    邮件原理 | 网络协议 | 网络管理 | 传输介质
    线路接入 | 路由接口 | 邮件存储 | 华为3Com
    CISCO技术 | 网络与服务器硬件
    操作系统:
    Windows 9X | Linux&Uinx | Windows NT
    Windows Vista | FreeBSD | 其它操作系统
    邮件服务器:
    程序与开发 | Exchange | Qmail | Postfix
    Sendmail | MDaemon | Domino | Foxmail
    KerioMail | JavaMail | Winwebmail |James
    Merak&VisNetic | CMailServer | WinMail
    金笛邮件系统 | 其它 |
    反垃圾邮件:
    综述| 客户端反垃圾邮件|服务器端反垃圾邮件
    邮件客户端软件:
    Outlook | Foxmail | DreamMail| KooMail
    The bat | 雷鸟 | Eudora |Becky! |Pegasus
    IncrediMail |其它
    电子邮箱: 个人邮箱 | 企业邮箱 |Gmail
    移动电子邮件:服务器 | 客户端 | 技术前沿
    邮件网络安全:
    软件漏洞 | 安全知识 | 病毒公告 |防火墙
    攻防技术 | 病毒查杀| ISA | 数字签名
    邮件营销:
    Email营销 | 网络营销 | 营销技巧 |营销案例
    邮件人才:招聘 | 职场 | 培训 | 指南 | 职场
    解决方案:
    邮件系统|反垃圾邮件 |安全 |移动电邮 |招标
    产品评测:
    邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端
    广告联系 | 合作联系 | 关于我们 | 联系我们 | 繁體中文
    版权所有:邮件技术资讯网©2003-2010 www.5dmail.net, All Rights Reserved
    www.5Dmail.net Web Team   粤ICP备05009143号