📄 memory.c.txt
字号:
any question,send email to netxiong@263.net
这个文件定义了页式管理的几乎全部数据和处理函数,包括3级页表结构的一些列处理函数,
和缺页处理等函数,以及页错误等。
******************************基本数据结构*****************************************
unsigned long max_mapnr;
unsigned long num_physpages;
void * high_memory;
struct page *highmem_start_page;
mem_map_t * mem_map //物理页表的数组
***********************************************************************************
*******************************影射函数********************************************
(1)int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
//这个函数将一段虚拟地址映射为一段实际的物理地址
struct mm_struct *mm = current->mm; //得到当前进程的内存结构指针
dir = pgd_offset(mm, from);
do {
pmd_t *pmd = pmd_alloc(mm, dir, from); //分配一个中间页目录
error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
//进行中间页目录的映射
dir++; //如果不够的话,增加一个页目录
} while (from && (from < end)); //直到所有的地址都映射完毕
flush_tlb_range(mm, beg, end); //刷新tlb缓存
(2)static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
unsigned long phys_addr, pgprot_t prot)
//分配一个中间页目录,但由于i386体系的原因,这个结构是空的
do {
pte_t * pte = pte_alloc(mm, pmd, address); //分配一个页表
remap_pte_range(pte, address, end - address, address + phys_add , prot);
//对页表进行地址映射
address = (address + PMD_SIZE) & PMD_MASK;
pmd++; //如果不够的话,在增加一个页表
} while (address && (address < end)); //直到地址用玩
(3)static inline void remap_pte_range(pte_t * pte, unsigned long address, unsignedlong size,
unsigned long phys_addr, pgprot_t prot)
//对分配的这个页表项进行设置
do {
struct page *page;
page = virt_to_page(__va(phys_addr));
if ((!VALID_PAGE(page)) || PageReserved(page))
set_pte(pte, mk_pte_phys(phys_addr, prot));
pte++;
} while (address && (address < end));
经过以上三个步骤的映射,系统就可以将一段虚拟内存映射到物理内存上,
也就是在改进程的页目录上建立起了一系列的表项,
从而对这段虚拟内存建立的到实际的物理内存页的映射。
***********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -