关闭

xv6中的pmap.c源代码

1735人阅读 评论(0) 收藏 举报

#include"param.h"

#include"pmap.h"

#include"phymem_manager.h"

#include"spinlock.h"

#include"assert.h"

uint npages;                 //number of avaiable pages//内存以页(4k大小)的形式的数量,这里的得到的是总的页数

char *start;                  //指向kernel后的内存地址

struct e820map *e820_memmap;

const struct phymem_manager_class *pmmc;//物理内存管理策略(buddy策略,first策略等等)的指针

struct Page *pages;//

struct spinlock kalloc_lock;

void init_pages_list (paddr_t start_addr,uint len,uint flags)//初始化内存页的标志位

{

paddr_t addr;

if(start_addr>=0xfec00000)

return;

assert (PGOFF(start_addr)==0,"error in init_pages_list");

for(addr=start_addr;addr<start_addr+len;addr+=PAGE)

{

page_frame(addr)->flags=flags;

}

}

void init_phypages(void)

{

int i;

uint len;

paddr_t  base;

npages=0;

e820_memmap=(struct e820map*)(0x8000);//根据中断int 15h所提供的内存的信息(有e820__memmap->map[i]数据结构数组保存内存的信息),

for(i=0;i<e820_memmap->nr_map;i++)

{

npages+=e820_memmap->map[i].size/PAGE;//计算的内存的总页数

cprintf("total available memory pages",npages);

pages=(struct Page*)start;//设置紧跟kernel后的地址

memset(pages,0,sizeof(struct Page)*npages);//初始化pages所指的内存大小的块

start+=ROUNDUP(sizeof(struct Page)*npages,PAGE);//已PAGE向上对齐start

cprintf("start%x/n",(uint )start);

for(i=0;i<e820_memmap->nr_map;i++)//

{

base=(paddr_t)e820_memmap->map[i].addr;

base=ROUNDUP(base,PAGE);

len=(uint )e820_memmap->map[i].size;

switch(e820_memmap->map[i].type)

{

 

case E820_ARM://类型ARM

if (base+len<(uint)start)

{

init_pages_list(base,(uint)start-base,PG_reserved);//初始化页标志

cprintf("reserved for kernel %x,size%x/n",base,(uint)start-base);

else

{

 if(base<(uint )start)//当base 在start前面

{

init_pages_list(base,(uint)start-base,PG_reserved);//这段内存设置成保留区(reserved)

cprintf("reserved for kernel %x,size,%x/n",base,(uint)start-base);

init_pages_list((paddr_t)start,len+base-(uint)start,0);//这段设置成可用区

pmmc->init_memmap(page_frame((paddr_t)start),(len+base-(uint)start)/PAGE);//调用init_memmap函数把可用内存段加入buddy系统中;

cprintf("free memory%x,size%x/n",(paddr_t)start,len+base-(uint)start);

}

else

{

init_pages_list(base,len,0);

pmmc->init_memmap(page_frame(base),len/PAGE);

cprintf("free memory %x,size%x/n",base,len);

}

}

break;

case E820_ARR:

 init_pages_list(base,len,PG_reserved);

cprintf("reserved memory %x,size%x/n,base,len);

break;

default:

break;

}

}

}

 

//allocate n bytes of physical memory;

//return a kernel-segment pointer

//return 0 if the memory can not be allocated

char *kalloc(int n) //分配n个字节的物理内存

{

 int nr;

struct Page*p;

if(n<=0||n%PAGE)

panic("kalloc");

nr=n/PAGE;

if(nr>1024)

panic("kalloc:exceed maxium pages that kalloc can  handle/n");

acquire(&kalloc_lock);

p=alloc_pages(nr);//调用alloc_pages函数为请求物理内存的需求做内存分配;

release(&kalloc_lock);

if(p)

return (char*)page_addr(p);//返回物理地址

else

{

cprintf("kalloc:out of memory");

return 0;

}

}

// Free the len bytes of memory pointed at by v,
// which normally should have been returned by a
// call to kalloc(len).  (The exception is when
// initializing the allocator; see pmm_init above.)
void kfree(char *v, int len)
{
    int nr;
    if (len <= 0 || len % PAGE)
        panic("kfree");
    nr = len / PAGE;
    if (nr > 1024)
        panic("kree : exceed maximum pages that kfree can handle/n");
    acquire(&kalloc_lock);
    //cprintf("free %x/n", (uint)v);
    free_pages(page_frame(v), nr);
    release(&kalloc_lock);
}

void pmm_init(void)

{

extern int end;

start =(char*)&end;//把end指针付给start指针

start=(char*)(((uint)start+PAGE)&~(PAGE-1));//对齐

cprintf("mm_init: kernel end is at %x, new free phy mem start at %x/n", end, start);

#ifdef BUDDY
    pmmc = &pmmc_buddy;
#endif
#ifdef FIRSTFIT
    pmmc = &pmmc_firstfit;
#endif
#ifdef BESTFIT
    pmmc = &pmmc_bestfit;
#endif
#ifdef WORSTFIT
    pmmc = &pmmc_worstfit;
#endif

    init_phypages();

    pmmc->test_phymem_manager();
}

 

 

 

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21622次
    • 积分:383
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章存档