虚拟地址空间

4G虚拟地址空间布局图:

由于每个进程都不能直接访问内核空间,而是通过系统调用间接进入内核,因此,所有的进程都共享内核空间。而每个进程都拥有各自的用户空间,各个进程之间不能相互访问彼此的用户空间。因此,对每一个具体的进程而言,都拥有4GB的虚拟地址空间。一个程序在经过编译、连接之后形成的地址空间是一个虚拟的地址空间,只有当程序运行的时候才会分配具体的物理空间。由此我们可以得知,程序的虚拟地址相对来时候是固定的,而物理地址则随着每一次程序的运行而有所不同。对于内核空间而有,它与物理内存之间存在一个简单的线性关系,即存在3GB的偏移量。在Linux内核中,这个偏移量叫做PAGE_OFFSET。如果内核的某个物理地址为x,那么对应的内核虚拟地址就为x+PAGE_OFFSET。对于用户空间而言,它与物理内存之间的映射远不止这么简单。与内核空间和物理空间的线性映射不同的是,分页机制将虚拟用户空间和物理地址空间分成大小相同的页,然后再通过页表将虚拟页和物理页块映射起来。

内核使用mm_struct来描述一个进程的虚拟地址空间:

struct mm_struct{
    struct vm_area_struct* mmap;  //指向虚拟区域(VMA)链表
    rb_root_t mm_rb;  //指向red_black树
    struct vm_area_struct* mmap_cache;  //指向最近找到的虚拟区间
    pgd_t* pgd;  //指向进程的页目录
    atomic_t mm_users;  //用户空间中的有多少用户
    atomic_t mm_count;  //对“struct mm_struct"有多少引用
    int map_count;  //虚拟区间的个数
    struct list_head mmlist;  //所有活动(active)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;
};

struct vm_area_struct:用来描述一个虚拟内存区域(VMA)。内核将每个内存区域作为一个单独的内存对象管理,每个内存对象管理,每个内存区域都有一致的属性,比如权限等。所以我们程序的代码段、数据段和bss段在内核里都分别有一个struct vm_area_struct结构体来描述:

struct vm_area_struct{
    struct mm_struct* vm_mm;  //虚拟内存区域所在的地址空间
    unsigned long vm_start;  //在虚拟内存中的起始地址
    unsigned long vm_end;  //在虚拟内存中的结束地址
    struct vm_area_struct* vm_next;  
    pgprot_t vm_page_prot;  //对这个虚拟内存区域的存取权限
    unsigned long vm_flags;  //虚拟内存区域的标志
    rb_node_t vm_rb;  //对这个虚拟内存区域进行操作的函数
    struct vm_operations_struct* vm_ops;
    struct file* vm_file;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值