Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56851
  • 博文数量: 12
  • 博客积分: 1480
  • 博客等级: 上尉
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-20 10:01
文章分类
文章存档

2010年(1)

2008年(11)

我的朋友
最近访客

分类:

2008-10-21 18:42:00

从文件kern/kernel.ld的内容可知,内核将被加载到地址0xF0100000处。

函数i386_init()中调用i386_detect_memory(), 得到内存的大小。

函数i386_vm_init()中,通过函数boot_alloc()分配页目录pgdir. 可知内核中分配的内存地址将在KERNBASE(0xf0000000)以上。从boot_alloc的实现中有这样一句:boot_freemem = end; 而end定义于ern/kernel.ld中也可知道这一点。
类似的,数组pages的地址也在KERNBASE以上。数组pages的成员为所有的物理内存页面,其索引为0~npage。而page_free_list则是该数组中所有pp_ref值为0的元素的链表。而KERNBASE以上可用的内存只能通过pages使用,大小为i386_detect_memory()中获得的值,最多不超过256M。

页目录和页表其自身地址均在KADDR内,但二者中各项内容所含的地址值则都位于0~256M的物理地址空间内。

而pages数组各元素只定义了一个成员pp_ref, 那么,这些元素是怎么和物理内存一一对应的呢?这是通过pages的索引和物理内存从0M开始的关系来联系起来的。pages[X]对应物理内存X*4K~(X+1)*4K. 具体实现是通过kern/pmap.h中的四个函数实现的:
static inline ppn_t
page2ppn(struct Page *pp)
{
        return pp - pages;
}

static inline physaddr_t
page2pa(struct Page *pp)
{
        return page2ppn(pp) << PGSHIFT;
}

static inline struct Page*
pa2page(physaddr_t pa)
{
        if (PPN(pa) >= npage)
                panic("pa2page called with invalid pa");
        return &pages[PPN(pa)];
}

static inline void*
page2kva(struct Page *pp)
{
        return KADDR(page2pa(pp));
}

阅读(1094) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-10-30 17:05:33

请问Lab3你做完了么?