Linux 系统内核空间与用户空间通信的实现与分析

2 Linux 内核模块的运行环境与传统进程间通信

在一台运行 Linux 的计算机中,CPU 在任何时候只会有如下四种状态:

【1】 在处理一个硬中断。

【2】 在处理一个软中断,如 softirq、tasklet 和 bh。

【3】 运行于内核态,但有进程上下文,即与一个进程相关。

【4】 运行一个用户态进程。

其中,【1】、【2】和【3】是运行于内核空间的,而【4】是在用户空间。其中除了【4】,其他状态只可以被在其之上的状态抢占。比如,软中断只可以被硬中断抢占。

Linux 内核模块是一段可以动态在内核装载和卸载的代码,装载进内核的代码便立即在内核中工作起来。Linux 内核代码的运行环境有三种:用户上下文环境、硬中断环境和软中断环境。但三种环境的局限性分两种,因为软中断环境只是硬中断环境的延续。比较如表【1】。

表【1】
内核态环境介绍局限性
用户上下文内核态代码的运行与一用户空间进程相关,如系统调用中代码的运行环境。不可直接将本地变量传递给用户态的内存区,因为内核态和用户态的内存映射机制不同。
硬中断和软中断环境硬中断或软中断过程中代码的运行环境,如 IP 数据报的接收代码的运行环境,网络设备的驱动程序等。不可直接向用户态内存区传递数据;
代码在运行过程中不可阻塞。

Linux 传统的进程间通信有很多,如各类管道、消息队列、内存共享、信号量等等。但它们都无法介于内核态与用户态使用,原因如表【2】。

表【2】

通信方法无法介于内核态与用户态的原因
管道(不包括命名管道)局限于父子进程间的通信。
消息队列在硬、软中断中无法无阻塞地接收数据。
信号量无法介于内核态和用户态使用。
内存共享需要信号量辅助,而信号量又无法使用。
套接字在硬、软中断中无法无阻塞地接收数据。

3 Linux内核态与用户态进程通信方法的提出与实现

3.1 用户上下文环境

运行在用户上下文环境中的代码是可以阻塞的,这样,便可以使用消息队列和 UNIX 域套接字来实现内核态与用户态的通信。但这些方法的数据传输效率较低,Linux 内核提供 copy_from_user()/copy_to_user() 函数来实现内核态与用户态数据的拷贝,但这两个函数会引发阻塞,所以不能用在硬、软中断中。一般将这两个特殊拷贝函数用在类似于系统调用一类的函数中,此类函数在使用中往往"穿梭"于内核态与用户态。此类方法的工作原理路如图【1】。


图【1】














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值