Linux内核与用户空间通信机制研究

时间:2022-10-29 01:08:10

Linux内核与用户空间通信机制研究

摘要:Linux内核采用单内核架构,具有简单、高效、安全的优点。Linux各子系统包含在内核中,而系统配置及管理工具运行于用户空间。开发人员需要采用一种合适的在内核与用户空间之间通信的方法。该文总结了几种常用的通信方法:设备节点适合于驱动程序开发,但创建过程比较复杂;/proc文件易于创建,但是不支持大量数据的传输;netlink具有高可扩展性,越来越多的系统工具采用这种方式,而其传输速度较慢;内存映射是传输速度最快的方式,使用不当时会对系统造成破坏。

关键词:Linux;驱动程序;proc文件;netlink;内存映射

中图分类号:TP316.8文献标识码:A文章编号:1009-3044(2012)16-3816-02

The Research of Communication Mechanism between Linux Kernel and User-space

LIU Bin, ZHU Cheng-rong

(Computer Science and Technology Department of Tongji University, Shanghai 201804, China)

Abstract: The architecture of Linux is designed as monolithic kernel, this makes Linux simple, efficient, secure. Since all Linux subsystems are contained in its kernel, while most system configuration and management tools are running in user-space, developers have to find a proper way to communicate between kernel and user-space. The author introduces several usual mechanisms: device node is used for driv er development, to create a device driver interface is complicated than other methods; /proc file is easy to create and use, but it can not transfer large message; netlink sockets is a highly extensible message mechanism, more and more system tools use this mechanism, even though its transfer speed is low; memory-mapped I/O is fastest, but its misuse will cause system failure.

Key words: Linux; device driver; proc file; netlink; memory-mapped I/O

Linux是一个开源操作系统,具有良好的平台间可移植性,在嵌入式及服务器操作系统领域所占的份额越来越大。Linux内核,跟许多其他类Unix系统一样,采用单内核架构,即内核运行在一个独立的地址空间中[1]。单内核架构有以下优点:

1)简单。单内核使得内核设计较为简单,内核映像文件更容易存储。

2)高效。所有内核服务运行于同一个内核空间,其间的通信不需涉及状态转换过程,使内核保持较高的工作效率。

3)安全。运行于内核空间的指令具有特权,内核空间独立于用户空间,这使得用户不能随意占用系统资源、对系统修改甚至危害系统的安全,这样内核就具有较高的安全性。

Linux内核子系统运行于内核空间,而对其的配置管理却是通过用户空间的管理工具来完成的。Linux内核需要提供一定的接口,允许用户空间进程获取内核的资源、信息和服务,甚至配置、监控内核的运行。为了完成与用户空间的交互,需要内核提供一组接口。

系统调用是Linux中除异常和陷入外,用户空间访问内核的唯一合法入口。添加新的系统调用的过程比较简单,但是涉及申请系统调用号和重新编译内核等问题,直接在程序中使用新系统调用会对程序的可移植性造成很大的影响。替代方法包括使用设备节点、使用/proc文件系统等方式。这些方式都是通过系统已有的系统调用实现的。

该文介绍了几种用户空间与内核通信机制的使用方法,并对其性能及安全性进行比较。

1设备驱动接口

设备节点位于/dev目录下。字符设备驱动和块设备驱动接口允许用户从特定的设备节点中读取以及向其中写入数据。这些接口允许在内核与用户空间之间传递数据,就像访问文件一样,并且具有较好的可扩展性。但是此类接口通常为内核设备驱动程序保留[2]。因此,Linux内核开发者认为新的内核子系统使用设备节点并不是好的选择。设备节点的复用也是经常遇到的问题。该文以字符设备驱动为例说明数据传递过程。

字符设备驱动函数地址保存在file_operations结构体中。该结构体包含众多成员,此处重点关注字符设备读写处理函数。读处理函数使用copy_from_user从用户空间复制数据,写处理函数使用copy_to_user向用户空间写入数据。在模块初始化过程中,首先生成设备号,将设备号注册到系统中;初始化字符设备,将驱动程序函数与字符设备关联;在/dev目录下建立设备节点。在模块退出函数中,首先删除/dev目录下的设备节点,然后删除字符设备,从系统中注销其设备号。

内核函数copy_from_uer用于从用户空间向内核空间复制数据,执行成功返回0,失败时返回未被复制的字节数。该函数可能睡眠,无法使用在中断上下文中。在开始复制数据前,该函数验证用户空间地址的有效性,检查所复制的内存区域是否超出了用户空间进程大小。通过验证之后才进行数据复制。如果复制过程中遇到非法指针,系统调用页异常处理程序进行后续处理。内核函数copy_to_user用于内核空间向用户空间复制数据,其实现过程与copy_from_user相似,不再复述。

上一篇:妇产科护患纠纷原因分析及预防对策 下一篇:基于WebSocket的实时Web应用解决方案