【操作系统】进程空间管理_64位linux用户空间和内核空间

unsigned long mmap_base;	/\* base of mmap area \*/
unsigned long total_vm;		/\* total\_vm 是总共映射的页的数目 \*/
unsigned long locked_vm;	/\* Pages that have PG\_mlocked set \*/
unsigned long pinned_vm;	/\* Refcount permanently increased \*/
unsigned long data_vm;		/\* VM\_WRITE & ~VM\_SHARED & ~VM\_STACK \*/
unsigned long exec_vm;		/\* VM\_EXEC & ~VM\_WRITE & ~VM\_STACK \*/
unsigned long stack_vm;		/\* VM\_STACK \*/
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;

  • total_vm 是总共映射的页的数目,内存吃紧的时候,locked_vm 就是被锁定不能换出,pinned_vm 是不能换出,也不能移动。 换出 : 把内存写到硬盘
  • data_vm 是存放数据的页的数目,exec_vm 是存放可执行文件的页的数目,stack_vm 是栈所占的页的数目。
  • start_code 和 end_code 表示可执行代码的开始和结束位置,start_data 和 end_data 表示已初始化数据的开始位置和结束位置。
  • start_brk 是堆的起始位置,brk 是堆当前的结束位置。前面咱们讲过 malloc 申请一小块内存的话,就是通过改变 brk 位置实现的。
  • start_stack 是栈的起始位置,栈的结束位置在寄存器的栈顶指针中。
  • arg_start 和 arg_end 是参数列表的位置, env_start 和 env_end 是环境变量的位置。它们都位于栈中最高地址的地方
  • mmap_base 表示虚拟地址空间中用于内存映射的起始地址。这个空间是从高地址到低地址增长的。
    在这里插入图片描述
  • 这里用红黑树,就是为了快速查找一个内存区域,并在需要改变的时候,能够快速修改
  • anoy 就是 anonymous,匿名的意思,映射到文件就需要有 vm_file 指定被映射的文件。
  • 当 exec 运行一个二进制程序的时候,除了解析 ELF 的格式之外,另外一个重要的事情就是建立内存映射。
    在这里插入图片描述
  • 内存映射图 :
    在这里插入图片描述
  • 下面这俩种情况都会修改上面的映射关系
  • 第一种情况是函数的调用,涉及函数栈的改变,主要是改变栈顶指针。
  • 第二种情况是通过 malloc 申请一个堆内的空间,当然底层要么执行 brk,要么执行 mmap。关于内存映射的部分。
  • brk (堆) : 堆是从低地址向高地址增长的, 会有新旧的brk堆顶地址, 需要比较,如果俩者相同的话,则说明在同一页,则修改堆顶地址就行,指向新的地址, 如果新的 < 旧的 则说明不在一页,至少需要释放一页。
    • brk 判断是否需要分配新页, 并做对应操作; 需要分配新页时需要判断能否与其他 vm_area_struct 合并

内核态的布局

32 位
在这里插入图片描述
64位
在这里插入图片描述

小结

  • 内存管理信息在 task_struct 的 mm_struct 中
  • task_size 指定用户态虚拟地址大小
    • 32 位系统:3G 用户态, 1G 内核态
    • 64 位系统(只利用 48 bit 地址): 128T 用户态; 128T 内核态
  • 用户态地址空间布局和管理
    • mm_struct 中有映射页的统计信息(总页数, 锁定页数, 数据/代码/栈映射页数等)以及各区域地址
    • 有 vm_area_struct 描述各个区域(代码/数据/栈等)的属性(包含起始/终止地址, 可做的操作等), 通过链表和红黑树管理
    • 在 load_elf_bianry 时做 vm_area_struct 与各区域的映射, 并将 elf 映射到内存, 将依赖 so 添加到内存映射
    • 在函数调用时会修改栈顶指针; malloc 分配内存时会修改对应的区域信息(调用 brk 堆; 或调用 mmap 内存映射)
    • brk 判断是否需要分配新页, 并做对应操作; 需要分配新页时需要判断能否与其他 vm_area_struct 合并
  • 内核地址空间布局和管理
    • 所有进程看到的内核虚拟地址空间是同一个
    • 32 位系统, 前 896MB 为直接映射区(虚拟地址 - 3G = 物理地址)
      • 直接映射区也需要建立页表, 通过虚拟地址访问(除了内存管理模块)
      • 直接映射区组成: 1MB 启动时占用; 然后是内核代码/全局变量/BSS等,即 内核 ELF文件内容; 进程 task_struct 即内核栈也在其中
      • 896MB 也称为高端内存(指物理内存)
      • 剩余虚拟空间组成: 8MB 空余; 内核动态映射空间(动态分配内存, 映射放在内核页表中); 持久内存映射(储存物理页信息); 固定内存映射; 临时内存映射(例如为进程映射文件时使用)
    • 64 位系统: 8T 空余; 64T 直接映射区域; 32T(动态映射); 1T(物理页描述结构 struct page); 512MB(内核代码, 也采用直接映射)
      32位
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值