操作系统真象还原 内存管理

翻来覆去看了好多遍的内存管理 还是没有弄明白 先把想明白的记下来好了

 

首先 是开启分页管理  一共三步 1 准备好页目录表 页表 2 将页目录表的物理地址写入到cr3寄存器中 3 打开cr0的31位 即PG位

 

先说说准备页目录表和页表 页目录表被放在了低端1MB内存之内 具体位置是0x100000 占据一页大小 4K

其中包括了1024个一级页表 这1024个一级页表只有256个是被使用的 就是第0个和768-1023个 其中 最后一个页目录项指向了页目录项的起始地址

第0个和第768个指向了同一个页表项 第一个 也就是处在0x101000位置上的页表项

页目录项中有1024个pte 每个pte中有1k个页 每个页大小为4k 也就是说 每个pte指向的空间为4M 所以这一个pde 中,内核实际的大小是255个pdt × 4 也就是1GB - 4MB的内存 

 

 

从0xc009a000到0xc009e000的四个页框就是位图的位置 通过位图来对页框进行分配 

首先 内存池分为 内核内存池和用户内存池 顾名思义 内核内存池就是对内核的高1GB空间进行分配 此外 还有一个虚拟地址池 virtual_addr用于给内核分配虚拟地址

  目前使用的地址有低端1MB内存和页表项占用的内存  剩下的就是剩余内存

然后是分配页内存 主要是通过先分配一个虚拟地址 然后在物理内存池中分配一个物理内存 然后进行映射 

新建用户进程 首先为用户进程在内核内存池中申请一个页表装pcb,过程是从内核内存池中申请一页并返回地址 然后对该pcb进行初始化,过程为跳过中断栈和线程栈,并在线程栈中写入函数名,
返回值 并提前将返回值设置成kernel thread 然后给用户进程准备好页表 过程为 在内核内存池中分配好一页作为页目录表
然后将虚拟地址中的高1g的内核内存即0xc0000000开始的256个页框拷贝过去,并返回页目录表地址 再然后是准备用户线程的虚拟地址池,
位置在0x80480000(Linux的用户线程虚拟地址池入口)到0xc0000000之间,和用户线程的3级特权栈重合 并分配好页表 最后将该进程的ready tag 和all list tag加入到链表中 这是准备工作
然后是运行工作
模拟从中断退出的过程 首先是时钟中断发生,然后从就绪队列中调出下一个进程,开始是为用户进程激活页表,使接下来的工作都在用户内存池中进行
然后通过汇编的switch to将程序改成kernel thread 由此调用初始化用户进程的start process 进行一系列初始化 通过从中断退出进行用户程序的运行

 

转载于:https://www.cnblogs.com/wangjingxuan1997/p/8035254.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值