- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
基于NETLINK的内核与用户空间共享内存的实现
原文链接:
前言
前些日子,开发中用到了netlink来实现内核与用户空间共享内存,写点笔记与大家分享。因为我对这块也不了解,写出来的东西一定存在很多错误,请大家批评指正。
内核与用户空间共享内存的关键是,用户空间必须得知共享内存的起始地址,这就要求内核空间应该有一种通信机制来通知用户空间。已经有Godbach版主等人用proc文件系统实现了(可以google?共享内存?内核?用户空间),很显然任何内核空间与用户空间的通信方法都可资利用。本文主要讲基于NETLINK机制的实现。
NETLINK简介
NETLINK在linux的内核与用户空间通信中用得很多(但具体例子我举不出,因为我不清楚~~请google之),其最大优势是接口与网络编程中的socket相似,且内核要主动发信息给用户空间很方便。但通过实践,我发现netlink通信机制的最大弊病在于其在各内核版本中接口变化太大,让人难以适从(可从后文列出的源码中的kernel_receive的声明窥一斑)。
既然涉及到内核与用户空间两个空间,就应该在两个空间各有一套接口。用户空间的接口很简单,与一般的socket接口相似,内核空间则稍先复杂,但简单的应用只需简单地了解即可:首先也是建立描述符,建立描述符时会注册一个回调函数(源码中的kernel_receive即是),然后当用户空间有消息发过来时,我们的函数将被调用,显然在这个函数里我们可做相应的处理;当内核要主动发消息给用户进程时,直接调用一个类send函数即可(netlink_unicast系列函数)。当然这个过程中,有很多结构体变量需要填充。具体用法请google,我差不多忘光了~。
基于netlink的共享内存
这里的共享内存是指内核与用户空间,而不是通常的用户进程间的。大概流程如下:
内核:__get_free__pages分配连续的物理内存页(貌似返回的其实是虚拟地址)。
SetPageReserved每一页(每一页都需这个操作,参见源码)。
如果用户空间通过netlink要求获取共享内存的起始物理地址,将__get_free__pages返回的地址__pa下发给用户空间。
用户空间:open?/dev/shm(一个读写物理内存的设备,具体请googlelinux读写物理内存)发netlink消息给内核,得到共享内存的起始物理地址。
mmap上步得到的物理地址。
源码说明
正如二中提到的,netlink接口在各版本中接口变化很大,本人懒惰及时间紧,只实验了比较新的内核2.6.25,源码如需移植到老版本上,需要一些改动,敬请原谅。
另外,由于本源码是从一个比较大的程序里抠出来的,所以命名什么的可能有点怪异。
源码包括shm_k.c(内核模块)和用户空间程序(shm_u.c)两部分。shm_k.c模块的工作是:分配8KB内存供共享,并把前几十个字节置为“hello,?use?share?memory?with netlink字样。shm_u.c工作是:读取共享内存的前几十个字节,将内容输出在stdout上。
该程序只适用于2.6.25左右的新版本!用__get_free_pages分配连续内存时,宜先用get_order获取页数,然后需将各页都SetPageReserved下,同样地,释放内存时,需要对每一页调用ClearPageReserved。
我成功用该程序分配了4MB共享内存,运行还比较稳定。因为linux内核的默认设置,一般情况下用get_free_pages只能分配到4MB内存左右,如需增大,可能需改相应的参数并重新编译内核。
运行结果
我是在mpc8377上运行的,全过程如下(有少许编辑,如dmesg信息只列出新增的)。
-sh-2.05b#?insmod?shm_k.ko?-sh-2.05b#?dmesg?SHM_TEST:?linux?versionSHM_TEST:?init_netlink?ok.?SHM_TEST:?size?page_cnt=2?SHM_TEST:?__get_free_pages?ok.?SHM_TEST:?init_mem_pool?ok.?
-sh-2.05b#?./shm_u?SHM_TEST:?24,?errno=0.Success,?0defe000,the?first?30?bytes?of?shm?are:?hello,?use?share?memory?with?netlink?-sh-2.05b#?dmesg?SHM_TEST:?begin?kernel_receive?SHM_TEST:?receiv?TA_GET_SHM_I
文档评论(0)