边学边干Linux内核指导(6)——虚拟存储

时间:2021-02-28 15:48:58

虚拟地址由操作系统维护,由MMU可以进行转换。扩大了内存空间
分页管理,把内存分为页和页桢,大小一样,一个在磁盘,一个在内存。页表就像一个函数,输入是页号,输出是页桢号。
页表可以是多级页表,可以用TLB(Translation Lookaside Buffer)缓存。速度和成本介于内存和寄存器

页表项:禁止缓存,访问位,保护位,修改位,存在位----页桢号

页面置换:最优算法,先进先出和最近最少使用 (Leaset Recently Used)

Linux 虚拟内存的管理
1.缺省页面大小8K,每一个进程维护自己的一张页表。所以,不同进程的虚拟地址可能一样
2.虚拟地址:0x2194 ---> 因为页面大小0x2000,所以此地址在页面1处。页内偏移地址是0x194
如果页1映射为页桢4,那么它的物理地址是0x8000+0x194=0x8194
3.换页,paging ondemand
4.交换 thrashing LRU

5.Linux 总假定处理器支持三级页表结构,PGD, PMD, PTE
在Intel X86的微机上,linux表结构只有两级 PGD, PTE (PMD 只有一个表项)
6.每当启动一个新线程,linux都会为它分配一个task_struct结构体,内含ldt(local descriptor table),tss(task state segment),mm等内存管理信息。其中,mm_struct结构体,包含了用户进程中的存储相关的信息
7.vma
程序执行时,并将执行映像调入进程虚拟地址空间中,共享库也是。但是,实际上没有进入到物理内存中。
在mm_struct,包含一些指向vm_area_struct数据结构描述了虚拟内存的起始与结束位置,进程对此内存区域的权限以及一组内存操作。所以,操作系统对虚拟内存的管理,就是对这个数据结构的管理。而且,vma不是一个是一组,所以需要通过红黑树算法来进行管理,分配和取消

8.页面分配,用Buddy算法来进行,内存分配代码在free_area数组维护的链表中寻找一个满足要求,同时又尽可能小的空闲块
分割的同时,剩余的进行再分配

9.asmlinkage do_page_fault(struct pt_regs *regs, unsigned long error_code);
编译器不要使用寄存器,而是使用堆栈来传递参数
当MMS发现错误了,就调用这个函数。当缺页时,CPU将会发生缺页异常的地址拷贝到cr2控制寄存器中,然后进入缺页异常的处理过程。
如果发生异常时的系统状态EFLAGS的中断位置位,那么在保存了cr2之后便可以允许终端发生,底层过程调用sti指令开中断。
handle_fault_mm()->handle_pte_fault()->do_no_page()->do_swap_page()