进程结构
linux内核中使用 **task_struct** 结构体表示一个进程,其中包含了 kernel 所需要的关于进程的所有信息,如 进程pid、父进程、进程优先级控制参数 以及 进程地址空间:mm_struct 等。
mm_struct
用以描述进程的地址空间信息,在实际的 mm_struct 结构体中,并没有直接划定区域,而是使用不同的字段进行界定
虚拟地址
直接使用物理地址的问题
- 问题1:进程地址空间不隔离,有安全性问题
- 问题2:内存使用效率低,会产生很多碎片化的内存
- 问题3:程序运行地址不确定,影响程序运行效率
因此有了使用虚拟地址的设计方法,对于每一个进程而言都是“独占”整个内存,
分段式的虚拟地址
分段式的虚拟地址思想是:
- 在虚拟地址空间和物理地址空间做等值的映射
比如虚拟空间中一个大小为 20M 的段,就映射到物理地址空间上的某个 20M 大小的空间。
这种方式解决了问题1和问题3的问题,但是由于每次换入的内存大小为整个程序,因此会造成大量的磁盘访问操作,导致效率低下。
分页式的虚拟地址
分页式的虚拟地址思想是:
- 把物理地址空间划分为许多页,每个页的大小由CPU决定,一般大小是4KB,当程序运行需要某个页时,如果对应页未载入,则触发缺页中断,进而从内存中加载对应页
这种方式使换入换出的内存空间固定,因此能够同时解决问题1,2,3。
程序访问虚拟地址的过程
当加载可执行文件之后,系统会为其创建进程(task_struct),进程会为每一条指令和数据都分配一个虚拟地址。
当程序开始执行时,虚拟地址对应的物理页不在内存中,虚拟页表项(PTE)也不在 TLB 中,因此会执行一个 缺页中断 之后的加载流程
具体流程如下图:
![Image [9].png](/uploads/projects/u26617090@bgnz9l/851eb1c13039d519f69333f6cb1d54c2.png)
