mmap映射的mmap内存映射 dev mem空间是内核态还是用户态

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
Linux下用户态和内核态内存共享的实现.pdf 3页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:100 &&
Linux下用户态和内核态内存共享的实现
你可能关注的文档:
··········
··········
SOFTWARE DEVELOPMENT AND DESIGN
软件开发与设软件开发与设计软件开发与设计软件开发与设计计
Linux 下用户态和内核态内存共享的实现
(江苏食品职业技术学院计算机应用技术系,淮安223003)
摘 要: 共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同
malloc( ) 函数向不同进程返回了指向同一个物理内存区域的指针。因为所有进程共享同一块内存,共享内存在各种
进程间通信方式中具有最高的效率。主要介绍Linux 下基于Netlink 机制的用户态和内核态内存共享的实现。
关键词: 内核态; 用户态 ; netlink
; 共享内存
User Mode and Kernel Mode Shared Memory under Linux
(Department of Computer Applied Technology , Jiangsu Food Science College , Huai'an 223003)
Abstract :Shared
communication.
visit the same piece of memory. as like as function malloc(),It towards to the different process return a pointer of point to the
area.Because
memory,shared
efficiency
Communication.This
principally
introduction
implementation
and kernel mode shared memory under Linux.
Key words : Shared memory
系统调用和中断两种情况下发生,一般程序一开始都是运行
Linux 是一类Unix 计算机操作系统的统称。Linux 操作系
于用户态,当程序需要使用系统资源时,就必须通过调用软
统的内核的名字也是 “Linux”。Linux 操作系统也是自由软件
中断进入内核态。
和开放源代码发展中最著名的例子。Linux 是一套免费使用和
Linux 的用户态和内核态
自由传播的类Unix 操作系统。无论是普通用户还是企业用户
Linux 使用了Ring3 级别运行用户态,Ring0 作为内核态。
都可以编写自己的内核代码,再加上对标准内核的裁剪从而
Ring3 状态不能访问 Ring0
的地址空间,包括代码和数据。
制作出适合自己的操作系统。
Linux 进程的4GB 地址空间,3GB-4GB 部分是共享的,是内
一个或多个内核模块的实现并不能满足一般Linux 系统软
核态的地址空间,这里存放着整个内核的代码和所有的内核
件的需要,因为内核的局限性太大,如不能在终端上打印,
模块,以及内核所维护的数据。
正在加载中,请稍后...温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(105)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'[转贴]init进程如何从内核态切换到用户态',
blogAbstract:'[转贴]init进程如何从内核态切换到用户态原文出自:http://www.linuxforum.net 作者: chstar==============================================大家都知道如何产生一个新的进程。通过sys_fork,之后再调用sys_execve系统初启后(核心态)的第一个用户态进程是init。这要涉及到内层(特权级高)向外层(特权级低)转移的问题。通常情况下,内核是不会调用用户层的代码,要想实现这逆向的转移,一般做法是在用户进程的核心栈(tss-&;esp0)压入用户态的,ESP,EFLAGS,CS,EIP,伪装成用户进程是通过陷阱门进入核心态,之后通过iret返回用户态。那么linux 2.2.14中的用户态进程init是如何实现的?',
blogTag:'如何,用户',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:4,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}理解mmap_Android开发_动态网站制作指南
来源:人气:325
在接入日志xlog的工作中,对mmap内存映射加深了了解,分享一下学习心得。
1.一个进程的虚拟内存
如图展示了一个Linux进程的虚拟内存。
虚拟的意思是进程以为自己有这么一大块内存,实际上物理内存可能还没有分配给它,等到缺页异常是系统才会分配,通过这种以时间换空间的方式提高了内存利用效率。从虚拟内存到物理内存的映射过程需要一个专门的硬件单元MMU来完成。
系统调用的代码和数据就在内核虚拟内存中,
因为在保护模式下,用户态进程无法访问到这里,必须要通过系统调用的方式陷入到内核态才行。
2.Linux是如何组织虚拟内存的
内核为系统中的每个进程维护一个单独的任务结构task_struct,其中元素包含了内核运行该进程所需要的所有信息(PID、指向用户栈的指针、可执行目标文件的名字、虚拟内存状态、pc指针等)
task_struct中的mm_struct描述了虚拟内存的当前状态,其中mmap字段指向一个vm_area_struct(区域结构)的链表。顺序搜索区域结构的链表花销会很大,实际上Linux在链表中构建了一个树,并在这棵树中进行查找。
进程对某一虚拟内存区域的任何操作需要用要的信息,都可以从vm_area_struct中获得。mmap函数就是要创建一个新的vm_area_struct结构,并将其与文件的物理磁盘地址相连。
3.缺页处理
当MMU在试图某个虚拟地址A时,触发了一个缺页。缺页异常处理程序会做如下检查:
- 1)虚拟地址A是否合法?即是否在链表mm_struct所描述的区域内。
- 2)试图进行的内存访问是否合法?即检查指令的权限是否与vm_ot字段所描述的页读写许可权限相匹配。
- 3)正常缺页。系统会负责把该虚拟内存区域对应的文件加载到内存中。
4.内存映射
Linux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射。
Linux进程可以使用mmap函数来创建新的虚拟内存区域,并将对象映射到这些区域中。
mmap函数定义在libc中:
#include &sys/mman.h&
mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
具体内容可以通过命令man 2 mmap查看。
mmap参数的可视化解释:
在调用mmap实现这样的映射关系后,它只是在进程的虚拟空间中分配了一段空间,真实的物理地址还不会分配的,当进程第一次访问这段空间(当作内存一样),CPU陷入OS内核执行异常处理,然后异常处理会在这个时间分配物理内存,并用文件的内容填充这片内存,然后才返回进程的上下文,这时进程才会感知到这片内存里有数据。
之后进程即可对这片主存进行读或者写的操作,如果写操作改变了其内容,一定时间后系统会自动回写脏页面到对应磁盘地址,也即完成了写入到文件的过程。
mmap 的回写时机:
* 内存不足
* 进程退出
* 调用 msync 或者 munmap
* 不设置 MAP_NOSYNC 情况下 30s-60s(仅限FreeBSD)
程序的加载
Linux执行一个ELF格式的程序,这个程序在磁盘上,为了执行这个程序,需要把程序加载到内存中,这时采用的就是mmap,mmap让虚拟空间和文件的内容组成的空间(文件空间)对应。因为ELF格式是区分代码、数据段的,这里的就不是简单的整个文件的映射了,需要将文件的分段区域映射到内存的不同位置。OS加载ELF文件的过程非常复杂这里就不展开了,具体内容可以看《程序员的自我修养》。
当CPU真的在这个地址上发起读写执行等操作时,因为文件的内容在磁盘上是不能被CPU访问的,所以OS会进入异常,系统的缺页处理程序会调用文件系统把一页或者多页的文件内容加载到物理内存中。
可以通过 cat /proc/&pid&/maps看到某个进程的mmap状态,其实就是通过遍历vm_area_struct链表得到的,有关maps的解释可以看这里。
下面是使用xlog的Android程序进程的内存状态(截取一小部分):
shell@shamu:# cat /proc/9032/maps
perms offset
6e000 rwxp :00 0
b7e800 rwxp b7e 0
fe:00 791721
/data/dalvik-cache/arm/data@app@com.x-1@base.apk@classes.dex
x-x r-xp 00a6f000 fe:00 791721
/data/dalvik-cache/arm/data@app@com.x-1@base.apk@classes.dex
fe:00 791721
/data/dalvik-cache/arm/data@app@com.x-1@base.apk@classes.dex
x-x r--p :09 630
/system/fonts/CarroisGothicSC-Regular.ttf
b35b0 rw-s :14 3082
/storage/emulated/0/log.mmap2
b6fb00 r-xp :09 206
/system/bin/linker
b6fc00 r-xp :00 0
b6fc00 r--p :09 206
/system/bin/linker
b6fc00 rw-p :09 206
/system/bin/linker
b6fc00 rw-p :00 0
b6fc7000-b6fca000 r-xp :09 136
/system/bin/app_process32
b6fca000-b6fcb000 r--p :09 136
/system/bin/app_process32
be246000-bea45000 rw-p :00 0
ffff0000-ffff1000 r-xp :00 0
这些分段空间后面的那些,就是每个虚拟空间分段对应的文件。这些文件,称为这片虚拟空间的backlog文件,它的作用是当这些内存需要被使用的时候,从磁盘中把对应的文件内容加载到物理内存中。
这里同一个文件/system/bin/linker在虚拟内存中有不同的内存映射区域,就是因为其文件中有不同的分段,从offset可以看出来。
/storage/emulated/0/log.mmap2就是xlog用作mmap的backlog文件了,它被映射到b35b0这段内存区域。
5.为什么mmap()可以节约IO读写时间
常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制,这是由OS控制的。这样造成读文件时需要先将文件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对应的用户空间中。这样,通过了两次数据拷贝过程,才能完成进程对文件内容的获取任务。写操作也是一样,待写入的buffer在内核空间不能直接访问,必须要先拷贝至内核空间对应的主存,再写回磁盘中(延迟写回),也是需要两次数据拷贝。
而使用mmap操作文件中,由于不需要经过内核空间的数据缓存,只使用一次数据拷贝,就从磁盘中将数据传入内存的用户空间中,供进程使用。
mmap的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同数据不通的繁琐过程。因此mmap效率更高。
xlog对mmap的效率做了验证
为了验证 mmap 是否真的有直接写内存的效率,通过一个简单的测试用例进行验证:把512 Byte的数据分别写入150 kb大小的内存和 mmap,以及磁盘文件100w次并统计耗时
从上图看出mmap几乎和直接写内存一样的性能,而且 mmap 既不会丢日志,回写时机又基本可控。
《深入理解计算机》
《程序员的自我修养》
认真分析mmap:是什么 为什么 怎么用
微信mars 的高性能日志模块 xlog
Linux 中 mmap() 函数的内存映射问题理解
proc(5) - Linux man page
How to interpret /proc/pid/maps
优质网站模板&&&&&&DOC文档下载
游客快捷下载
会员登录下载
下载资源需要5元
邮箱/手机号:
您支付成功后,系统会自动为您创建此邮箱/手机号的账号,密码跟您输入的邮箱/手机号一致,以方便您下次登录下载和查看订单。
支付方式:
已注册用户请登录:
当日自动登录&&
合作网站一键登录:
2:本站资源不支持迅雷下载,请使用浏览器直接下载(不支持QQ浏览器)
3:本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰&&&
linux内核空间和用户空间通信
linux 内核空间和用户空间通信作者:harvey wang 邮箱:harvey.新浪博客地址:.cn/harveyperfect ,有关于减肥和学习英语相关的博文,欢迎交流因网上已有很多介绍各种通信方式的示例代码,所以在本文中只是给出各种内核空间和用户空间通信方式的介绍说明。希望给像我一样的初学者提供一定的指导。因水平有限,欢迎各位批评指点。1 概述Linux 内核将这 4G 字节的空间分为两部分。将最高的 1G 字节(从虚拟地址0xC0000000 到 0xFFFFFFFF) ,供内核使用,称为“ 内核空间 ”。而将较低的 3G 字节(从虚拟地址 0x 到 0xBFFFFFFF) ,供各个进程使用,称为 “用户空间“) 。除了进程之间的通信外,在嵌入式设计中还经常需要进行内核空间和用户空间的信息交互。本文主要讨论内核空间和用户空间信息交互的方法。1.1 处理器状态处理器总处于以下状态中的一种:A、内核态,运行于进程上下文,内核代表进程运行于内核空间;B、内核态,运行于中断上下文,包括硬中断和软中断;C、用户态,运行于用户空间。1.2 不同状态的限制根据上面的状态分类,内核空间和用户空间之间的信息交互就分为两类,即中断上下文内核态空间与进程空间信息交互;进程上下文内核态空间和进程空间信息交互。内核态环境 进入内核态的方式 局限性 说明进程上下文 在进程中通过系统调用进入内核态,内核态代码与该进程相关。内核空间和进程空间的虚拟地址不同,不能直接传递信息。该进程的页表基地址依然在页表基地址寄存器(如 X86 中的CR3)中,内核空间中可以使用__user 强制使用用户空间的地址,从而进行数据交互。中断上下文 硬件触发中断,或内核中挂接软中断。不与特定的进程相关。内核空间和进程空间的虚拟地址不同,不能直接传递信息。中断中不能睡眠,不能运行引起阻塞的函数。由于中断触发的随机性,中断上下文内核态不与特定的进程相关。2 各种通信方式本节说明各种通信方式是否适合内核空间和用户空间信息交互,以及如何使用。2.1 信号在进程中使用函数 signal()或 sigaction()安装信号时指定了关联的函数。在内核空间相进程发送信号,从内核空间返回进程空间时检查并执行相应的关联函数。在进程中可以
本文(linux内核空间和用户空间通信)为本站会员(豆浆)主动上传,金锄头文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
若此文所含内容侵犯了您的版权或隐私,请立即阅读金锄头文库的“”【网址:】,按提示上传提交保证函及证明材料,经审查核实后我们立即给予删除!
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。
分享当前资源【linux内核空间和用户空间通信】到朋友圈,您即可以免费下载此资源!
微信扫一扫分享到朋友圈
操作提示:任选上面一个二维码,打开微信,点击“发现”使用“扫一扫”,即可将选择的网页分享到朋友圈
您可能感兴趣的------------------------------------------------------------------------------------------------------
元price_share
&|&川公网安备 12号&|&经营许可证(蜀ICP备号-1)(C) by Sichuan Goldhoe Inc. All Rights Reserved.内核态空间地址直接映射到用户态空间访问 - CSDN博客
内核态空间地址直接映射到用户态空间访问
【摘要】Linux中的内核空间到用户空间的地址映射让用户层应用可以直接访问内核地址,这就是mmap方法。应用程序通过内存映射可以直接访问设备的I/O存储区或DMA缓冲。内存映射使用户空间的一段地址关联到设备内存上,程序在映射的地址范围内进行读取或者写入,实际上就是对设备的访问。
struct file_operations simple_fops = {
THIS_MODULE,
simple_open,
simple_mmap,// mmap接口
.release =
simple_release,
在初始化的时候分配内存:
buffer = kmalloc(4096,GFP_KERNEL);
printk(" mmap buffer = %p\n",buffer);
buffer_area=(int *)(((unsigned long)buffer + PAGE_SIZE -1) & PAGE_MASK);
for (virt_addr=(unsigned long)buffer_ virt_addr&(unsigned long)buffer_area+4096;
virt_addr+=PAGE_SIZE)
SetPageReserved(virt_to_page(virt_addr));
memset(buffer,'C',100);
simple_mmap函数实现mmap文件接口:
static int simple_mmap(struct file *filp, struct vm_area_struct *vma)
ret = remap_pfn_range(vma,
vma-&vm_start,
virt_to_phys((void*)((unsigned long)kmalloc_area)) && PAGE_SHIFT,
vma-&vm_end-vma-&vm_start,
PAGE_SHARED);
if(ret != 0) {
return -EAGAIN;
测试程序参考代码如下:
int main(void)
char *addr=NULL;
fd = open("/dev/mmap",O_RDWR);
if(fd & 0) {
perror("open");
addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED,
if(addr == MAP_FAILED) {
perror("mmap");
printf("%s\n", addr);
memset(addr,'f',100);
addr[0]='p';
printf("%s\n", addr);
munmap(addr,4096);
addr=NULL;
close(fd);
fd = open("/dev/mmap",O_RDWR);//重新打开进行验证
if(fd & 0) {
perror("open");
addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED,
if(addr == MAP_FAILED) {
perror("mmap");
printf("%s\n", addr);
munmap(addr,4096);
close(fd);
return(0);
运行结果如下:
[root@/home]
mmap buffer = c3c82000
[root@/home]
[root@/home]
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
pfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
pfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
本文已收录于以下专栏:
相关文章推荐
当内核空间和用户空间存在大量数据交互时, 共享内存映射就成了这种情况下的不二选择; 它能够最大限度的降低内核空间和用户空间之间的数据拷贝, 从而大大提高系统的性能.
以下是创建从内核空间到用户...
/************************************************************/
/* file name : memmap.c
【摘要】Linux中的内核空间到用户空间的地址映射让用户层应用可以直接访问内核地址,这就是mmap方法。应用程序通过内存映射可以直接访问设备的I/O存储区或DMA缓冲。内存映射使用户空间的一段地址关联...
前段时间一个学习Linux的朋友问我:“可不可以在调试设备驱动的时候,利用一个小工具来查看CPU中寄存器的值?”我当时对他说:“一般都是Printk打印出来的。”后来这个朋友自己去找了资料告诉我:好像...
转载http://blog.csdn.net/xy/article/details/
【摘要】 在Linux开发中着实用到的调试工具并不是很多。devm...
【摘要】这个工具的原理也比较简单,就是应用程序通过mmap函数实现对/dev/mem驱动中mmap方法的使用,映射了设备的内存到用户空间,实现对这些物理地址的读写操作。
本知识点来自网易云课堂的上课笔记,linux内核分析----中国科学技术大学软件学院:孟宁
 一般现代CPU都有几种不同的指令执行级别。
在高执行级别下,代码可以执行特权指令,访问任意的物理地址,...
转载于:http://blog.chinaunix.net/uid--id-3001090.html**一、devmem2**
前段时间一个学习Linux的朋友问我:“可不可以在调试...
查看dtb头四个字节数据
dtb 地址 uboot
#define AMBOOT_TAG_OFFSET  (0x)
#define AMBOOT_DTB_ADDR(k) (((...
all:commtest
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE=-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Ari...
他的最新文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 mmap内存映射 dev mem 的文章

 

随机推荐