嘉鱼网站建设多少钱,网络营销案例具体分析,美食健康网站的建设,北京电脑培训班零基础目录
补充点1#xff1a;进程地址空间堆区管理
补充点2#xff1a;Linux内核进程上下文切换
补充点3#xff1a;页表映射
补充点4#xff1a;两级页表 补充点1#xff1a;进程地址空间堆区管理 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程#…
目录
补充点1进程地址空间堆区管理
补充点2Linux内核进程上下文切换
补充点3页表映射
补充点4两级页表 补充点1进程地址空间堆区管理 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程这个结构体包含了一个进程所需的所有信息。该结构体存放在叫做任务列表的双向循环列表中 所学习过的包含 进程标识符 - 进程优先级 - 进程状态 - 进程地址空间 - 文件描述符表 - 进程信号位图 - CPU寄存器的上下文数据 - 进程相关页表内核级页表、用户级页表 在进程地址空间中栈区代码区等一部分区域是被整体所使用的而堆区具有更细粒度的划分包括使用者等参考文章Glibc——堆利用机制[拓展]_IfYouHave的博客-CSDN博客因此堆是使用一个vm_area_struct小的结构体进行区分使用双链表的形式进行管理 参考文章linux内核学习笔记-struct vm_area_struct_struct vm_area_struct source code_带着耳机去梦游的博客-CSDN博客 在进行堆区申请空间上层调用malloc函数 - 底层调用brk系统调用就会申请一个vm_area_struct内有start表针虚拟地址起始end表示虚拟地址结束经过页表映射至内存。 堆区典型特征申请的空间连续 OS是可以做到让进程进行资源细粒度划分的 补充点2Linux内核进程上下文切换 进程上下文是进程执行活动全过程的静态描述。我们把已执行过的进程指令和数据在相关寄存器与堆栈中的内容称为进程上文把正在执行的指令和数据在寄存器与堆栈中的内容称为进程正文把待执行的指令和数据在寄存器与堆栈中的内容称为进程下文。 实际上linux内核中进程上下文包括进程的虚拟地址空间和硬件上下文。 进程硬件上下文包含了当前cpu的一组寄存器的集合arm64中使用task_struct结构的thread成员的cpu_context成员来描述包括x19-x28,sp, pc等。 进程上下文切换主要涉及到两部分主要过程进程地址空间切换和处理器状态切换。地址空间切换主要是针对用户进程而言而处理器状态切换对应于所有的调度单位。 进程地址空间切换 进程地址空间内有进程运行的指令和数据因此到调度器从其他进程重新切换到我的时候为了保证当前进程访问的虚拟地址是自己的必须切换地址空间。 进程pcb内mm_struct结构体将各个vma组织起来进行管理其中有一个成员pgd至关重要地址空间切换中最重要的是pgd的设置。pgd中保存的是进程的页全局目录的虚拟地址那么pgd的值是何时被设置的呢 答案是fork的时候如果是创建进程需要分配设置mm_struct其中会分配进程页全局目录所在的页然后将首地址赋值给pgd完成了这一步也就完成了进程的地址空间切换确切的说是进程的虚拟地址空间切换。 处理器状态硬件上下文切换 处理器状态切换就是将前一个进程的sp,pc等寄存器的值保存到一块内存上然后将即将执行的进程的sp,pc等寄存器的值从另一块内存中恢复到相应寄存器中恢复sp完成了进程内核栈的切换恢复pc完成了指令执行流的切换。 其中保存/恢复所用到的那块内存需要被进程所标识这块内存这就是cpu_contex这个结构的位置进程切换都是在内核空间完成。 线程部分会学习 内核线程不需要切换地址空间只进行硬件上下文切换 所有的进程线程之间进行切换都需要切换处理器状态。 对于普通的用户进程之间进行切换需要切换地址空间 同一个线程组中的线程之间切换不需要切换地址空间因为他们共享相同的地址空间。 内核线程在上下文切换的时候不需要切换地址空间仅仅是借用上一个进程mm_struct结构。参考文章深入理解Linux内核进程上下文的切换 - 知乎 (zhihu.com) 补充点3页表映射 MMU(Memory Management Unit)即内存管理单元是一个硬件是现代CPU架构中不可或缺的一部分MMU主要包含以下几个功能 虚实地址翻译 在用户访问内存时将用户访问的虚拟地址翻译为实际的物理地址以便CPU对实际的物理地址进行访问。 访问权限控制 可以对一些虚拟地址进行访问权限控制以便于对用户程序的访问权限和范围进行管理如代码段一般设置为只读如果有用户程序对代码段进行写操作系统会触发异常。 引申的物理内存管理 对系统的物理内存资源进行管理为用户程序提供物理内存的申请、释放等操作接口。 使用MMU带来的好处或者优势 提升物理内存的利用率 物理内存按需申请如代码段的内存在执行时进行映射和转换进程fork后t通过写时复制(Copy-On-Write)进行真正的物理内存分配。解决内存管理碎片化的问题即在系统运行一段时间后频繁的内存申请和释放会导致内存碎片化无法申请到一块足够大的地址连续的内存。 对内存地址的访问进行控制 如上述代码段只读权限控制多线程的栈内存之间的空洞页隔离可以防止栈溢出后改写其他线程的栈内存不同进程之间的地址隔离等等。 将进程的地址空间隔离 不同进程之间可以使用相同的虚拟内存地址空间而进程间的物理内存又可以做到隔离这保证了进程的独立性同时又简化了地址的访问方式如在早期32位CPU上为了支持4G以上的物理内存一般物理地址有36-bit(如PowerPC-604系列)但是用户的虚地址仍然使用32-bit做法就是将用户的不同进程的32-bit虚地址在MMU转换时转换为36-bit的物理地址这样每个进程仍然能访问0-3G虚地址范围将多个进程的3G空间映射到36-bit的物理内存空间中去。 上述参考文档MMU原理 - page 如何从虚拟地址映射到物理内存 .exe就是一个文件我们的可执行程序本来就是按照地址空间方式进行编译的编译形成二进制文件的格式 - ELF格式可执行程序其实按照区域也已经以4KB为单位进行了划分物理内存也早就按照4KB为单位划分成一个个page操作系统进行IO的基本单位就是4KB因为被划分操作系统就需要管理划分后每一块物理内存的属性等先描述在组织page。因此4G的物理内存便会形成100w个块假设一个结构体为20字节100w个page会使用20MB的内存空间 磁盘内文件以4KB为单位划分的块成为页帧物理内存划分块称为页框 IO基本单位是4KB就是将页帧内容 - 页框 补充点4两级页表 页表在进行映射时会通过虚拟地址访问物理内存页表中含有其他字段表征磁盘数据是否被加载到内存没有变会进行申请内存page通过文件系统加载内存最后填充在页表右侧这种行为为缺页中断用户零感知 4.1 单级页表存在的问题 若计算机系统按字节寻址支持32位逻辑地址采用分页存储管理页面大小为4KB页表项长度为4B。4KB 2^12B因此页内地址要用12位表示剩余20位表示页号。 物理内存 4GB 2^20 * 2^12 B 因此该系统中用户进程最多有2^20页。相应的一个进程的页表中最多会有2^20个页表项所以一个页表最大需要2^20 * 4B 2^22B。一个页框内存大小为4KB所以需要2^22/2^12 2^10个页框存储该页表。 而页表的存储是需要连续存储的因为根据页号查询页表的方法 K号页对应的页表项的位置 页表起始地址 K * 4B页表项长度所以这就要求页表的存储必须是连续的。 回想一下当初为什么使用页表就是要将进程划分为一个个页面可以不用连续的存放在内存中但是此时页表就需要1024个连续的页框似乎和当时的目标有点背道而驰了.... 此外根据局部性原理可知很多时候进程在一段时间内只需要访问某几个页面就可以正常运行了。因此也没有必要让整个页面都常驻内存。 所以单级页表存在以上两个问题。 (参考文章两级页表 - 简书 (jianshu.com)) 4.2 两级页表 如何解决页表过大需要连续存储的问题呢这个问题可以参考进程太大需要连续存储的答案。因为页表必须连续存放所以可以将页表再分页。 解决方案可以将长长的页表进行分组使每个页面中刚好可以放下一个分组如上面的例子中页面的大小4KB每个页表项4B所以每个页面中可以存放1K个1024个页表项因此每1K个连续的页表项为一组每组刚好占一个页面再讲各组离散的放在各个内存块中。这样就需要为离散的页表再建立一张页表称为页目录表或外层页表或顶层页表。 32位的逻辑地址空间页表项大小为4B页面大小4KB则页内地址占12位 将页表分为分为1024个表每个表中包含1024个页表项形成二级页表。二级页表结构的逻辑地址结构如下图 两级页表如何实现地址转换 (1) 按照地址结构将逻辑地址拆成三个部分。 (2) 从PCB中读取页目录起始地址再根据一级页号查页目录表找到下一级页表在内存中存放位置。 (3) 根据二级页号查表找到最终想要访问的内存块号。 (4) 结合页内偏移量得到物理地址 下面以一个逻辑地址为例。将逻辑地址0000000000,0000000001,11111111111转换为物理地址的过程。