虚拟内存
http://www.cnblogs.com/feng9exe/p/6379686.html
来理解一下虚拟地址映射的过程:拿到一个虚拟地址,根据已有的vm_area_struct看这个虚拟地址是否属于某个vm_area_struct
- 如果没有匹配到,就报段错误,访问了一个没有分配的虚拟地址。
- 如果匹配到了vm_area_struct,根据虚拟地址和页表的映射关系,找到对应的页表项PTE,如果PTE没有分配,就报一个缺页异常,去加载相应的文件数据到物理内存,如果PTE分配,就去相应的物理页的偏移位置读取数据
所以虚拟页的三种状态的实际含义如下:
- 未分配虚拟页,指的是没有使用mmap建立vm_area_struct,所以也就没有对应到具体的页表项
- 已分配虚拟页,未映射到物理页,指的是已经使用了mmap建立的vm_area_struct,可以映射到对应的页表项,但是页表项没有指向具体的物理页
- 已分配虚拟页,已映射到物理页,指的是已经使用了mmap建立的vm_area_struct,可以映射到对应的页表项,并且页表项指向具体的物理页
mmap要么映射到一个后备文件,要么映射到一个匿名文件。操作系统分配物理内存时实际用到了匿名文件的mmap。
2. vm_page_prot 表示这个区域的页的访问权限
http://blog.csdn.net/xu3737284/article/details/12710217
linux操作系统是通过sys_exec对可执行文件进行映射以及读取的,有如下几步:
1.创建一组vm_area_struct
2.圈定一个虚拟用户空间,将其起始结束地址(elf段中已设置好)保存到vm_start和vm_end中。
3.将磁盘file句柄保存在vm_file中
4.将对应段在磁盘file中的偏移值(elf段中已设置好)保存在vm_pgoff中;
5.将操作该磁盘file的磁盘操作函数保存在vm_ops中
http://blog.csdn.net/al_xin/article/details/38590931
一个具体区域结构包含下面的字段:
- vm_start:指向这个区域的起始处。
- vm_end:指向这个区域的结束处。
- vm_prot:描述这个区域的内包含的所有页的读写许可权限。
- vm_flags:描述这个区域内页面是与其他进程共享的,还是这个进程私有的(还描述了其他一些信息)。
- vm_next:指向链表中下一个区域结构。
http://blog.csdn.net/chen98765432101/article/details/54881652
缩写解释:
VA:虚拟地址
VPN:虚拟页号
PTE:页表项
PTEA:页表项地址
PA:物理地址
DATA:数据
MMU:内存管理单元
TLB:地址翻译缓冲器
设置存储器层次结构主要是为了缓存低速的存储器。主存是对磁盘等设备的缓存,cache是对主存的缓存,tlb是对主存页表的缓存。
http://www.cnblogs.com/feng9exe/p/6379650.html
struct mm_struct
{
struct vm_area_struct *mmap; /* list of VMAs */
struct rb_root mm_rb;
struct vm_area_struct *mmap_cache; /* last find_vma result */
...
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
...
};
struct vm_area_struct
{
struct mm_struct *vm_mm; /* The address space we belong to. */
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
within vm_mm. */
....
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next;
....
/* describe the permissable operation */
unsigned long vm_flags;
/* operations on this area */
struct vm_operations_struct * vm_ops;
struct file * vm_file; /* File we map to (can be NULL). */
} ;