分类: LINUX
2009-03-18 00:36:12
存储管理容易把人高糊涂
pgdir_walk
对一个线性地址,查找其在页表内的页表项的指针地址(这个指针是虚拟地址)
查找两级页目录/表,需要注意虚拟地址/线性地址和物理地址。如果使用指针访问,要使用虚拟地址,如果不是,可以使用KADDR()或者page2kva()等进行转换;如果是在页目录/表里的某一项,它是物理地址,可以使用PTE_ADDR()取出地址。
在当页表不存在时,需要创建页表的时候,注意使用memset进行初始化(使用虚拟地址),否则有可能通不过assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
page_insert
将物理地址映射到线性地址,如果该线性地址已经被映射过,则删除先前的映射
使用pgdir_walk查找线性地址的页表项指针,然后进行映射操作。这里需要注意的是应该首先把物理页的pp_ref加1,然后再进行删除先前的映射,删除时使用page_decref(),它对pp_ref进行减1操作,如果pp_ref减到0则释放页(加入空闲列表);如果先减后加,是会出问题的,assert(page_alloc(&pp)==-E_NO_MEM)通不过,考虑:当对同一个物理页面映射到同一个线性地址两次,先减(释放),可能物理页加到空闲列表,然后再加就会有问题,因为空闲列表是一个全局变量,如果在这个过程中有别人申请空间,那么使用到本不该被使用的页。
page_remove
页计数减1,减到0就把页添加到空闲列表。