Linux-0.11内核源码分析系列:内存管理free_page()与free_page_tables()函数分析
2014-12-28 12:10
971 查看
/* *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表示操作成功 }
本文出自 “山下问童子” 博客,请务必保留此出处http://linpeng.blog.51cto.com/9779987/1596832
相关文章推荐
- Linux-0.11内核源码分析系列:内存管理free_page()与free_page_tables()函数分析
- Linux-0.11内核源码分析系列:内存管理copy_page_tables()函数分析
- Linux-0.11内核源码分析系列:内存管理get_free_page()函数分析
- Linux-0.11内核源码分析系列:内存管理copy_page_tables()函数分析
- Linux-0.11内核源码分析系列:内存管理up_wp_page()与do_wp_page()函数分析
- Linux-0.11内核源码分析系列:内存管理try_to_share()与share_page()函数分析
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
- Linux-0.11内核源码分析系列:内存管理up_wp_page()与do_wp_page()函数分析
- Linux-0.11内核源码分析系列:内存管理try_to_share()与share_page()函数分析
- Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析
- Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析
- Linux-0.11内核内存管理get_free_page()函数分析
- Linux-0.11内核源码分析系列:进程调度sleep_on()函数分析
- Linux-0.11内核源码分析系列:关于线性地址,逻辑地址,物理地址的关系与区别
- Linux-0.11内核源码分析系列:进程调度
- 《第一篇 从linux 0.11系统初始化main.c的fork()函数调用分析内核源码》
- Linux+page+cache+里的几个函数的源码分析
- Linux0.11 kernel/exit.c中的free_page_tables()
- linux0.11内核源码剖析:第一篇 内存管理、memory.c
- Linux 0.11的get_free_page分析