Linux-0.11内核源码分析系列:内存管理free_page()与free_page_tables()函数分析
2014-11-24 09:07
961 查看
/* *Author : DavidLin *Date : 2014-11-22pm *Email : linpeng1577@163.com or linpeng1577@gmail.com *world : the city of SZ, in China *Ver : 000.000.001 *history : editor time do 1)LinPeng 2014-11-22 created this file! 2) */ /* *释放addr对应的物理地址 *free_page函数被free_page_tables()函数调用 */ /* * Free a page of memory at physical address 'addr'. Used by * 'free_page_tables()' */ void free_page(unsigned long addr) { if(addr < LOW_MEM) { //如果是内核地址,直接退出 return; //LOW_MEM = 1M,0-640KB是内核驻留区域 } if(addr >= HIGH_MEMORY) { //如果是最大物理地址之外,die panic("trying to free nonexistent page"); } addr -= LOW_MEM; //获取主内存地址(以LOW_MEM处为起始0地址) addr >>= 12; //获取主内存管理数组偏移索引 //mem_map是全局数组,用于管理主内存 if(mem_map[addr]--) { //首先执行if(mem_map[addr])判断,接着mem_map[addr]-- return; //如果mem_map[addr] > 0,退出,表示物理页共享减一 } mem_map[addr] = 0; //如果mem_map[addr] = 0,die panic("trying to free free page"); } /* * 释放连续块,块必须4M对齐 * exit()函数调用,相对的函数是copy_page_tables() */ /* * This function frees a continuos block of page tables, as needed * by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks. */ int free_page_tables(unsigned long from, unsigned long size) { unsigned long *pg_table; unsigned long *dir, nr; if(from & 0x3fffff) { //4M对齐检测 panic("free_page_tables called with wrong alignment"); } if(!from) { //0地址是内核驻留地址,不允许释放 panic("Trying to free up swapper memory space"); } size = (size + 0x3fffff)>>22; //如果是4.1M,size取整为2。 dir = (unsigned long *)((from>>20) & 0xffc); /* _pg_dir = 0 */ //dir是页目录项,取线性地址高10位, //右移22位,因为每个目录项占4个字节, //所以>>22之后<<2 //等于>>20 for(; size-->0 ; dir++) { if(!(1 & *dir)) { //如果页目录项未使用,跳过 continue; } pg_table = (unsigned long *)(0xfffff000 & *dir); //取页表项 for(nr = 0; nr < 1024; nr++) { //每个页表项有1024个物理页 if(1 & *pg_table) { //位0等于1表示物理页有效 free_page(0xfffff000 & *pg_table); //释放物理页 } *pg_table = 0; //页表项内容清零 pg_table++; //指向下一个页表 } free_page(0xfffff000 & *dir); //释放页表项 *dir = 0; //页目录项内容清零 } invalidate(); //刷新高速缓存 return 0; //返回0表示操作成功 }
相关文章推荐
- Linux-0.11内核源码分析系列:内存管理free_page()与free_page_tables()函数分析
- Linux-0.11内核源码分析系列:内存管理get_free_page()函数分析
- Linux-0.11内核源码分析系列:内存管理copy_page_tables()函数分析
- Linux-0.11内核源码分析系列:内存管理copy_page_tables()函数分析
- Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析
- Linux-0.11内核源码分析系列:内存管理up_wp_page()与do_wp_page()函数分析
- Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析
- Linux-0.11内核源码分析系列:内存管理up_wp_page()与do_wp_page()函数分析
- Linux-0.11内核源码分析系列:内存管理try_to_share()与share_page()函数分析
- Linux-0.11内核源码分析系列:内存管理try_to_share()与share_page()函数分析
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
- Linux-0.11内核内存管理get_free_page()函数分析
- Linux-0.11内核源码分析系列:进程调度sleep_on()函数分析
- Linux-0.11内核源码分析系列:进程调度
- Linux-0.11内核源码分析系列:关于线性地址,逻辑地址,物理地址的关系与区别
- 《第一篇 从linux 0.11系统初始化main.c的fork()函数调用分析内核源码》
- linux0.11内核源码剖析:第一篇 内存管理、memory.c
- linux0.11内核源码剖析:第一篇 内存管理、memory.c【转】
- 2007-4-13 20:46:00 linux0.11之copy_page_tables()函数见解
- Linux内核0.11版本sys_waitpid()函数分析