虚存映射:Linux并不将映射装入物理内存,相反,可执行文件被链接到进程的用户空间中。随着进程的运行,被引用的程序部分会由操作系统装入到物理内存,这种将映像链接到进程用户空间的方法成为“虚存映射”
分类:
- 共享映射:有几个进程共享这一映射,即一个进程对其进行修改对于其他进程也是可见
- 私有映射:进程创建这种映射是为了读文件,因此,对于虚存区的写操作不会修改磁盘上的文件,由此可见,私有映射效率比共享映射效率高
- 匿名映射:映射与文件无关,叫做匿名映射
对于虚存映射是通过vm_area_struc t的链表或红黑树进行组织的,每一个vm_area_struct 结构代表可执行映像的一部分,可能是可执行代码、初始化的变量、未初始化的数据、也可能是港大恺的一个文件,这些映射通过mmap()系统调用对应的do_mmap 内核函数实现的 。在/proc/进程号/maps中查看虚存区。
mmap():在进程的用户空间内创建一个新的虚存区
Linux2.4内核中实现代码:
#define 0x10
#define 0x20
#define 0x0800
#define 0x1000
- asmlinkage unsigned long sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off, long arg6, long arg7, long stack)
- { struct pt_regs *regs = (struct pt_regs *) &stack;
- if ((off & ~PAGE_MASK) != 0)
- return -EINVAL; addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
- if (!IS_ERR((void *) addr))
- regs->r8 = 0; /* ensure large addresses are not mistaken as failures... */
- return addr;
- }
- static inline long do_mmap2(unsigned long addr, unsigned long len,unsigned long prot, unsigned long flags,unsigned long fd, unsigned long pgoff) {
- int error = -EBADF;
- struct file * file = NULL;
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {/*使用文件映射*/
- file = fget(fd);/*获取该文件描述符对应的struct file 的结构体,并且对文件计数加一*/
- if (!file)
- goto out;
- }
- down(¤t->mm->mmap_sem);/*P操作:减少一个信号量资源,保证当前进程的用户空间信息的统一*/
- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(¤t->mm->mmap_sem);/*V操作:增加一个信号量的资源*/
- if (file)
- fput(file);/*对于文件计数减一,如果最后为0,则将该结构体资源进行释放*/
- out:
- return error;
- }
主要实现机制在:do_mmap_pgoff(file, addr, len, prot, flags, pgoff)
根据file、len、pgoff与相应条件进行判断
|
|
判断标志位flag:SHARED 、 PRIVATE or 匿名
|
|
& ==0
|
|
= (, )
|
|
= (, );
|
|
初始化变量vma
|
|
如果在以上过程中出错或条件不满足,则进行首位处理,回收资源
阅读(1418) | 评论(0) | 转发(0) |