Linux下用户态和内核态内存共享的实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一个或多个内核模块的实现并不能满足一般 Linux 系统软 件的需要,因为内核的局限性太大,如不能在终端上打印, 不能做大延时的处理等等。当需要做这些的时候,就需要将 在内核态采集到的数据传送到用户态的一个或多个进程中进 行处理。这样,内核态与用户空间进程通信的方法就显得尤 为重要。将列举 Linux 下基于 Netlink 机制的内核态与用户态 进程通信的方法以及如何实现用户态和内核态的内存共享。
中断过程发送数据
图 1 Netlink 通过软中断调用用户进程
当 Netlink 套接字用于内核空间与用户空间的通信时,在 用户空间的创建方法和一般套接字使用类似,但内核空间的 创建方法则不同,图 2 是 Netlink 套接字实现此类通信时创建 的过程。
内核态
使用 netlink_kernel_create() 创建套接字,并指明接收函数
接收函数收到用户空间 进程 ID
用户态
用户空间进程创建套接 字,并将进程 ID 发送至内 核空间
用户空间与内核空间可以通信
图 2 用 Netlink 套接字实现内核态与用户态的通信
5 基于 Netlink 的共享内存
5.1 工作流程 内 核 部 分 首 先 用 get_order 获 取 页 数 , 接 着 调 用
Abstract:Shared memory is the most simple of the Process communication. Shared memory allowed two or more process visit the same piece of memory. as like as function malloc(),It towards to the different process return a pointer of point to the same physics memory area.Because all of the process shared the same memory,shared memory is the top efficiency of all kind of process Communication.This paper principally introduction implementation base on Netlink mechanism user mode and kernel mode shared memory under Linux. Key words:kernel mode ; user mode ; netlink ; Shared memory
6 结语
介绍基于 Netlink 的用户空间与内核空间的数据交换方式, 并通过实际例子程序向读者讲解了如何在内核开发中使用这 些技术。Netlink 是一种双向的数据交换方式,它使用起来非
4 实现内核态与用户态的通信
内核与用户空间共享内存的关键是,用户空间必须知道 共享内存的起始地址,这就要求内核空间应该有一种通信机 制来通知用户空间。理论上任何内核空间与用户空间的通信 方法都可以利用。接下来主要介绍基于 Netlink 机制的实现。
Netlink 在 linux 的内核与用户空间通信中用得很多,其最 大优势是接口与网络编程中的 socket 相似,且内核要主动发 信息给用户空间很方便。既然涉及到内核与用户空间两个空 间,就应该在两个空间各有一套接口。用户空间的接口与一
1 引言
Linux 是一类 Unix 计算机操作系统的统称。Linux 操作系 统的内核的名字也是“Linux”。Linux 操作系统也是自由软件 和开放源代码发展中最著名的例子。Linux 是一套免费使用和 自由传播的类 Unix 操作系统。无论是普通用户还是企业用户 都可以编写自己的内核代码,再加上对标准内核的裁剪从而 制作出适合自己的操作系统。
26 2011. 04
_get_free_page 分配连续的物理内存页,这时返回的是虚拟地 址,然后调用 SetPageReserved,相当于告诉系统,这个页面 已经占了。对于每一个申请到的页面,应该都要这样做,同 样地,释放内存时,需要对每一页调用 ClearPageReserved。如 果用户空间通过 Netlink 要求获取共享内存的起始物理地址, 将 _get_free_pages 返回的地址 _pa 下发给用户空间。
系统调用和中断两种情况下发生,一般程序一开始都是运行 于用户态,当程序需要使用系统资源时,就必须通过调用软 中断进入内核态。
3 Linux 的用户态和内核态
Linux 使用了 Ring3 级别运行用户态,Ring0 作为内核态。 Ring3 状态不能访问 Ring0 的地址空间,包括代码和数据 。 Linux 进程的 4GB 地址空间,3GB-4GB 部分是共享的,是内 核态的地址空间,这里存放着整个内核的代码和所有的内核 模块,以及内核所维护的数据。
Netlink 套接字的最大特点是对中断过程的支持,它在内 核空间接收用户空间数据时不再需要用户自行启动一个内核 程,而是通过另一个软中断调用用户事先指定的接收函数。
如图 1 所示,这里使用了软中断而不是内核线程来接收 数据,这样就可以保证数据接收的实时性。
用户态进程
源自文库
软中断
中断过程
进程发送数据
临界区 (使用自 旋锁来 使内核 线程与 中断过 程同步)
SOFTWARE DEVELOPMENT AND DESIGN
软件开发与设计
Linux 下用户态和内核态内存共享的实现
陈浩
(江苏食品职业技术学院计算机应用技术系,淮安 223003)
摘 要: 共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc ( )函数向不同进程返回了指向同一个物理内存区域的指针。因为所有进程共享同一块内存,共享内存在各种 进程间通信方式中具有最高的效率。主要介绍 Linux 下基于 Netlink 机制的用户态和内核态内存共享的实现。 关键词: 内核态; 用户态; netlink; 共享内存
用户空间调用 open /dev/shm 进行物理内存设备的读写, 发送 Netlink 消息给内核,得到共享内存的起始物理地址,最 后调用 mmap 上步得到的物理地址。用户空间的进程得到这个 地址后根据这个地址去读取其中的内容。 5.2 设计实现
为了创建一个 Netlink socket,用户需要使用如下参数调 用 socket ():
socket (AF_NETLINK, SOCK_RAW, netlink_type) socket 函数返回的套接字可以交给 bing 等函数调用: static int skfd; skfd = socket (PF_NETLINK, SOCK_RAW, NL_IMP2) ; if (skfd < 0) { printf (" can not create a netlink socket\n") ; exit (0) ; } 用 户 空 间 可 以 调 用 send 函 数 簇 向 内 核 发 送 消 息 , 如 sendto、sendmsg 等。也可以使用 struct sockaddr_nl 来描述一 个对端地址,以待 send 函数来调用,与本地地址稍不同的是, 因为对端为内核,所以 nl_pid 成员需要设置为 0: struct sockaddr_nl kpeer; memset (&kpeer, 0, sizeof (kpeer)) ; kpeer.nl_family = AF_NETLINK; kpeer.nl_pid = 0; kpeer.nl_groups = 0; 当发送完请求后,就可以调用 recv 函数簇从内核接收数 据了,接收到的数据包含了 Netlink 消息首部和要传输的数据, 然后调用 close 函数关闭 Netlink 套接字,退出程序。 5.3 内核空间的设计与实现 与应用程序内核一样,内核空间也主要完成 3 件工作: 创建 Netlink 套接字、接收处理用户空间发送的数据、发送数 据至用户空间。API 函数 netlink_kernel_create 用于创建一个 Netlink socket,同时,注册一个回调函数,用于接收处理用户 空间的消息: struct sock * netlink_kernel_create (int unit, void (*input) (struct sock *sk, int len)) ; 用户空间向内核发送了自定义消息,分别是请求和关闭。 kernel_receive 函数分别处理这两种消息。因为内核模块可能 同时被多个进程同时调用,所以函数中使用了信号量和锁来 进行互斥。 函数初始化 Netlink 消息首部,填充数据区,然后设置控 制字段,最后调用 netlink_unicast 函数把数据发送出去。在内 核中使用函数 sock_release 来释放函数 netlink_kernel_create ()
User Mode and Kernel Mode Shared Memory under Linux
CHEN Hao
(Department of Computer Applied Technology , Jiangsu Food Science College , Huai'an 223003)
2 用户态和内核态
用户态与内核态是操作系统的两种运行级别,Intel CPU 提 供 Ring0 -Ring33 种 级 别 的 运 行 模 式 。 Ring0 级 别 最 高 , Ring3 最低。
用户态:当进程在执行用户自己的代码时,则称其处于 用户运行态即用户态。此时处理器在特权级最低的 (3 级) 用 户代码中运行。
内核态:当一个任务 (进程) 执行系统调用而陷入内核 代码中执行时,就称进程处于内核运行态或简称为内核态。 此时处理器处于特权级最高的 0 级内核代码中执行。当进程 处于内核态时,执行的内核代码会使用当前进程的内核栈。
在内核态下 CPU 可执行任何指令,在用户态下 CPU 只能 执行非特权指令。当 CPU 处于内核态,可以随意进入用户态; 而当 CPU 处于用户态时,用户从用户态切换到内核态只有在
用户运行一个程序,该程序所创建的进程开始是运行在 用户态的,如果要执行文件操作,网络数据发送等操作,必 须通过 write,send 等系统调用,这些系统调用会利用内核中 的 代 码 来 完 成 操 作 , 这 时 , 必 须 切 换 到 Ring0, 然 后 进 入 3GB-4GB 中的内核地址空间去执行这些代码,完成操作,完 成后,切换回 Ring3,回到用户态。这样,用户态的程序就不 能随意操作内核地址空间,具有一定的安全保护作用。
SOFTWARE DEVELOPMENT AND DESIGN
软件开发与设计
创建的 Netlink socket: void sock_release (struct socket * sock) ;
程序在退出模块中释放 Netlink sockets 和 netfilter hook: static void __exit fini (void) { ?if (nlfd) { sock_release (nlfd->socket) ; } nf_unregister_hook (&imp2_ops) ; }
作者简介:陈浩,男,研究方向:计算机应用。 收稿日期:2010-12-18
201019. 04 25
电脑编程技巧与维护
般的 socket 接口相似,标准的 socket API 的函数,socket () , bind () , sendmsg () , recvmsg () 和 close () 很 容 易 地 应 用 netlink socket;内核空间则稍为复杂:首先也是建立描述符, 建立描述符时会注册一个回调函数,然后当用户空间有消息 发过来时,函数将被调用;当内核要主动发消息给用户进程 时,直接调用一个类 send 函数即可。
相关文档
最新文档