Linux的内存管理

Linux采用请求分页存储管理方法。

系统为每个进程提供4GB的虚拟内存空间。各虚拟内存空间各自独立。

Linux的内存管理

 一 硬件基础

还是逻辑地址,线性地址,物理地址,分段机制和分页机制依次转换。

其中涉及到GDT,LDT,段寄存器,段描述符,

逻辑地址到线性地址的转换

Linux的内存管理

 linux的分段模型

Linux使用如下段描述符

内核代码段,内核数据段,用户代码段,用户数据段,TSS段,默认LDT段

段基地址为0,段界限4GB,偏移量=线性地址

Linux必须分别为内核和用户程序创建代码段和数据段

虚拟地址等同于线性地址

分页机制

Linux的内存管理

二 虚拟内存的管理

linux中,每个用户都可以访问4GB的线性虚拟地址空间。

分为用户空间和内核空间。

用户空间:0到3GB-1,可以直接访问

内核空间:3GB到4GB-1,存放供操作系统和内核访问的代码和数据,用户进程不能访问

注意!!!!!

所有的进程的3GB到4GB-1的虚拟空间都是一样的,

linux以此方式让内核态进程共享代码段和数据段。

注意!!!!!

一个进程通过系统调用之后,就进入内核态了。,,一开始还想task_struct中有没有什么标志位神马的。

附上神图

Linux的内存管理

 好图+1

Linux的内存管理

 mm_struct详解

前面也已经提到过了这个,task_struct的mm项指向这个,描述进程的虚拟空间。

现在给出具体代码

struct mm_struct 
{  struct vm_area_struct * mmap;    
                                          /*指向VMA链表表头的指针*/ 
    rb_root_t mm_rb;             /*指向进程红黑树的根*/ 
    struct vm_area_struct * mmap_cache; 
                                              /*指向最后使用的VMA*/ 
    pgd_t * pgd;             /*指向进程页目录表的指针*/
    atomic_t mm_users;                 /*用户空间数*/
    atomic_t mm_count;
                                    /* 访问mm_struct结构的计数*/
    int map_count;                           /* VMA的数量 */ 
    struct rw_semaphore mmap_sem;   /*读写信号量*/ 
    spinlock_t page_table_lock;  
                                          /*保护任务页表和mm->rss*/
    struct list_head mmlist;       /*所有活动mm的列表*/    
    unsigned long start_code, end_code, start_data, end_data; 
                 /*分别为代码段、数据段的 首地址和终止地址*/
     unsigned long start_brk, brk, start_stack;
                                                       /*堆位置及栈顶地址*/ 
    unsigned long arg_start, arg_end, env_start, env_end;
          /*分别为参数区、环境变量区的首地址和终止地址*/
    unsigned long rss, total_vm, locked_vm; 
        /*驻留内存页框总数,VMA总数及被锁 VMA总数*/
    unsigned long def_flags;          
    unsigned long cpu_vm_mask;  
    unsigned long swap_address;
    unsigned dumpable:1;
    mm_context_t context; 
                            /*和具体硬件结构有关的MM上下文*/
};

vm_area_struct详解

虚拟内存区域名为vma,是进程一段连续的区域

用vm_area_struct描述

进程的mm_struct的mmap指向这个链表的首地址

Linux的内存管理

 注意vma和其代表vm_area_struct按地址排序

Linux的内存管理

vma数量大的时候启用AVL树排序

代码

struct vm_area_struct
{ struct mm_struct * vm_mm;
                                             /*指向进程的mm_struct结构体*/
   unsigned long vm_start;      /*虚拟区域的开始地址*/
   unsigned long vm_end;       /*虚拟区域的终止地址*/ 
                       /*每个进程的虚存区域链表,按地址排序*/
   struct vm_area_struct vm_next;  
     /*指向下一个vm_area_struct结构体,链表的首地址由*/ /*mm_struct中成员项mmap指出*/
   pgprot_t  vm_page_prot;      /*该VMA的访问权限*/
   unsigned short vm_flags;  /*指出虚存区域的操作特性*/ 
   struct rb_node vm_rb;       /*红黑树*/
   struct list_head shared;
struct vm_operations_struct * vm_ops; 
            /*该结构体中包含着指向各种操作的函数的指针*/

    /* 后援存储器的信息*/
   unsigned long vm_pgoff;  /*PAGE_SIZE单元中的偏移量*/   
   unsigned long vm_offset; /*该区域的内容相对于文件起始位置的偏移量,或相对于共享内存首址的偏移量*/
   
   struct file * vm_file;/* 若虚存区域映射的是磁盘文件或设备文件的内容,则vm_file指向这个文件,否则为NULL*/
   void * vm_private_data; /*共享内存页表vm_pte */ 
};

内核态地址空间

Linux的内存管理

 高位128MB内存建立临时映射,重复使用

可实现所有物理内存访问。

用户态地址空间

有代码段,数据段,BSS段,堆,栈

相关推荐