Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

linux内核--进程空间(二)

$
0
0

    内核处理管理本身的内存外,还必须管理用户空间进程的内存。我们称这个内存为进程地址空间,也就是系统中每个用户空间进程所看到的内存。linux操作系统采用虚拟内存技术,因此,系统中的所有进程之间虚拟方式共享内存。对一个进程而言,它好像都可以访问整个系统的所有物理内存。即使单独一个进程,它拥有的地址空间也可以远远大于系统物理内存。

一、地址空间

    每个进程都有一个32位或64位的平坦地址空间,空间的具体大小取决于体系结构。术语“平坦”指的是地址空间范围是一个独立的连续区间(比如,地址从0扩展到4294967295的32位地址空间)。一些操作系统提供了段地址空间,这种地址空间并非是一个独立的线性区域,而是被分段的,但现代采用虚拟内存的操作系统通常都是使用平坦地址空间而不是分段式的内存模式。一个进程的地址空间与另一个进程的地址空间即使有相同的内存地址,实际上也彼此互不相干。

    进程只能访问有效内存区域内的内存地址。内存区域可以包含各种内存对象:代码段、数据段、bss段、栈、堆。

二、内存描述符

    内核使用内存描述符结构体表示进程的地址空间,该结构包含了和进程地址空间有关的全部信息。内存描述符由mm_struct结构体表示,定义在文件<linux/shed.h>。在上一篇文章中介绍了这个结构体。

  1)分配内存描述符

    在进程的进程描述符(task_struct结构体就表示进程描述符)中,mm域存放着该进程使用的内存描述符,所以current->mm便指向当前进程的内存描述符。fork()函数利用copy_mm()函数复制父进程的内存描述符,也就是current->mm域给其子进程,而子进程中的mm_struct结构体实际是通过文件kernel/fork.c中的allocate_mm()宏从mm_cachep_slab缓存中分配得到的。通常,每个进程都有唯一的mm_struct结构体,既唯一的进程地址空间。

  2)撤销内存描述符

    当进程退出时,内核会调用定义在kernel/exit.c中的exit_mm()函数,该函数执行一些常规的撤销工作,同时更新一些统计量。其中,该函数会调用mmput()函数减少内存描述符中的mm_users用户计数,如果用户计数为0,调用mmdrop()函数,减少mm_count使用计数。如果使用计数也等于0,说明该内存描述符不再有任何使用者了,那么调用free_mm()宏通过kmem_cache_free()函数将mm_struct结构体归还给mm_cachep_slab缓存中。

  3)mm_struct与内核线程

    内核线程没有进程地址空间,也没有相关的内存描述符。所以内核线程对应的进程描述符中mm域为空。因为内核线程并不需要访问任何用户空间的内存而且因为内核线程在用户空间中没有任何页,所以实际上它们并不需要有自己的内存描述符和页表。尽管如此,即使访问内核内存,内核线程也还是需要使用一些数据的,比如页表。

    当一个进程被调度时,该进程的mm域指向的地址空间被装载到内存,进程描述符中的active_mm域会被更新,指向新的地址空间。内核线程没有地址空间,所以mm域为NULL。当一个内核线程被调度时,内核发现它的mm域为NULL,就会保留前一个进程的地址空间,随后内核更新内核线程对应的进程描述符中的active_mm域,时期指向前一个进程的内存描述符。   

三、虚拟内存区域


四、操作内存区域

五、mmap()和do_mmap():创建地址区间

六、mummap()和do_mummap():删除地址区间

七、页表

作者:yusiguyuan 发表于2013-9-26 19:11:43 原文链接
阅读:45 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles