=============================
NO-MMU MEMORY MAPPING SUPPORT
=============================
在没有MMU的情况下Linux内核并不支持内存映射,如uCLinux环境。从用户空间来看,
内存映射是通过像map(),shmat(),或execve()这样的系统调用来实现的。而从内核的
角度来看,execve()其实是通过binfmt驱动来实现的,最后通过调用map()来实现。
内存映射的行为会影响到fork(),vfork(),clone()和ptrace()的工作方式。而在
uCLinux环境下的fork(),clone()函数并不需要传递CLONE_VM的标志,因为它们没有虚
拟内存机制。
在有MMU支持与没有MMU支持的情况下,内核的行为基本相同,但不完全相同。如下几
种情况:
1,匿名映射,MAP_PRIVATE
MMU:虚拟块可以是任意的(连续/不连续)的物理块组成,在fork时进行写时复制
NO-MMU:虚拟块只能是连续的物理块组成
2,匿名映射,MAP_SHARED
MMU:MAP_PRIVATE情况相似,只不过在fork(),clone()的时候不传CLONE_VM标志。
NO-MMU:由于没有MMU支持所以与MAP_PRIVATE行为相同
3,文件映射,MAP_PRIVATE, PROT_READ / PROT_EXEC, !PROT_WRITE
MMU:文件的内存以虚拟块的形式读入,对文件的修改将会实时反应到内存映射中,同
时在fork的时候需要复制。
NO-MMU:VM regions backed by arbitrary contiguous runs of
pages into which the appropriate bit of the file is read; ???
内存映射多余的部分都是空;可以共享;对文件的修改并不会反映到映射中来;对内
存 映射的修改也不会反映到文件中;不过对内存映射的修改对于其他进程也是可见
的,最后 不要让这种情况发生。
4,文件, MAP_PRIVATE, PROT_READ / PROT_EXEC, PROT_WRITE
MMU:这种情况在读取的情况下与non-PROT_WRITE的情况是相同的,不过在写操作之前
需要对写页进行复制。不过之后对这个页的修改将无法反应到原始那个页面了。
NO-MMU:以上一种情况完全相似
5,(一般文件、块设备), MAP_SHARED, PROT_READ / PROT_EXEC / PROT_WRITE
MMU:以页的形式映射文件中的内容,对页的修改将反应到文件中,对文件的修改将反
应到原始页中。可通过fork进行共享。
NO-MMU:不支持???
6,(一般内存文件)Memory backed regular file, MAP_SHARED, PROT_READ /
PROT_EXEC / PROT_WRITE
MMU:与一般文件一样
NO-MMU:像一些内存文件系统支持open(),truncat(),mmap()来分配一些连续的页块。
像在这种情况下是允许映射可共享的内存块。它的工作方式与MMU一样。不过如过文件
系统不做支持,映射的请求将被拒绝。
7,(字符设备内存文件)Memory backed chardev, MAP_SHARED, PROT_READ /
PROT_EXEC / PROT_WRITE
MMU:与一般文件相同
NO-MMU:如果块设备有一定的可供程序直接读取的内存,也许支持通过mmap()来对其
内存进行映射。如frame buffer和flash device.如果设备没有这种性能,映射失败。
============================
FURTHER NOTES ON NO-MMU MMAP
============================
(*)当申请私有(MAP_PRIVATE)内存映射时的大小小于一个页时,返回的内存块可能不
是页对齐的。因为内核是通过调用kmalloc()去分配内存的,而不是get_free_page().
(*)在NO-MMU的模式下,可以通过/proc/maps看到所有系统中的内存映射
(*)MAP_FIXED的申请或申请某一地址的映射将失败
MAP_FIXED:将文件或设备映射到用户指定的地址
(*)私有文件映射时设备或文件系统必须提供可读权限,以便可以把数据从设备或文件
中读入到映射好的内存中。否则的话将失败。特别在映射字符设备文件,管道,fifo
和socket文件的时候容易碰到这种情况。
============================================
PROVIDING SHAREABLE CHARACTER DEVICE SUPPORT
============================================
为了支持共享的字符设备,这个设备的驱动必须提供file->f_op->get_unmapped_area()
函数。mmap()将会调用这个函数从合适的地址开始映射内存。如果请求映射的内存空间
过大,或者一些组合的标示将可能使得映射失败。
当设备移除的时候必须调用vm_ops->close()这个函数。已经映射的内存可能会被共享,
或私有,但这些动作可以不通知驱动。
file->f_op->get_unmapped_area()可能会返回-ENOSYS。碰到这种情况说明虽然收到
请求,但是它并不想去处理它。如有些时候去直接去调用原来没有实现的驱动。比如
framedriver就会去调用设备的驱动,而此时设备的驱动可能没有实现。
==============================================
PROVIDING SHAREABLE MEMORY-BACKED FILE SUPPORT
==============================================
文件的内存映射与字符设备的内存映射基本相似,主要的区别在于当文件映射时将分
配一些连续的内存页,而映射将基于这些分配好的连续内存页。
如果将一个映射的文件清空,或则文件本身的大小就是空,当增大这个文件的时候,
必须要准备更多的内存空间来实现映射。POSIX的映射接口对这一功能有所要求。
内存映射的设备可以通过backing_dev_info的memory_backed标志予以确定。
阅读(1864) | 评论(0) | 转发(0) |