日期:2014-05-16 浏览次数:20986 次
#define PAGE_SIZE 4096
/* these are not to be changed without changing head.s etc */
#define LOW_MEM 0x100000
extern unsigned long HIGH_MEMORY;
#define PAGING_MEMORY (15*1024*1024)
#define PAGING_PAGES (PAGING_MEMORY>>12)
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)
#define USED 100
extern unsigned char mem_map [ PAGING_PAGES ];
#define PAGE_DIRTY 0x40
#define PAGE_ACCESSED 0x20
#define PAGE_USER 0x04
#define PAGE_RW 0x02
#define PAGE_PRESENT 0x01
截取了一部分mm.h 的内容相当重要的说。。。。
PAGE_SIZE 定义了1页内存字节书。特别注意,高速缓冲块长度是1024 byte
LOW_MEM 机器物理内存1M
PAGING_MEMORY 15M 主内存区最多15M。。。其实这里如果内存大的话就应该会相应的变(个人推论,如有错误,欢迎指正!)
PAGING_PAGE 分页后的物理内存页面数,>>12 就是除以4M,每个页面的大小是4M,于是可以算得所有的页面数
MAP_NR(addr)得到指定内存地址映射页面号
USED 页面被占用号
mem_map 数组记录的值是每一个位,对应的页被引用的次数。 这里linux 0.12 采用了bits-map的策略
mem_map 数组记录的值是每一个位,对应的页被引用的次数。 这里linux 0.12 采用了bits-map的策略
关于bitmaps可以看 MOS的第三章的 Memory Management with Bitmaps (在检索目录里面有)
http://blog.csdn.net/cinmyheart/article/details/24888847#t8
void free_page(unsigned long addr)
{
if(addr <LOW_MEM) return; //如果addr是1M的内核模块映射页,那么是不能free掉的,free无效,主动return挂掉free_page
if(addr>= HIGH_MEMORY)//我刚开始一直很纠结,不是很明白为什么HIGH_MEMORY会被定义成0这里》=0是干嘛。。。
panic("tryingto free nonexistent page");
addr-=LOW_MEM;
addr>>=12;//右移12位,那么得到addr的页面数
if(mem_map[addr]--)return;
/*我只能说这个后—太技巧了。如果当前mem_map[addr]== 0 那么这个页是个free page,if判断为假于是执行下面的语句,这时候实质上是试图free一个free page是错误的。如果mem_map[addr] >0 说明有进程占用这个page,那么返回,并-1 */
mem_map[addr]=0;
panic("tryingtofree free page");
}
void mem_init(long start_mem, long end_mem)
{
int i;
HIGH_MEMORY = end_mem;
for (i=0 ; i<PAGING_PAGES ; i++)
mem_map[i] = USED;//把所有15M主内存区的mem_map 置为USED
i = MAP_NR(start_mem);
end_mem -= start_mem;
end_mem >>= 12;//除以4M得到页数
while (end_mem-->0)
mem_map[i++]=0;//把扩展内存区的mem_map 置0,设置为空闲
}