一、二级页表映射的建立
1、阅读mmu.h文件,熟悉一些PDX和PTX的宏的定义
// 一个线性地址有以下三块组成:
// +--------10------+-------10-------+---------12----------+
// | Page Directory | Page Table | Offset within Page |
// | Index | Index | |
// +----------------+----------------+---------------------+
// \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
// \----------- PPN(la) -----------/
2、阅读kern/pmap.h文件,了解如下函数
1)、Pa2page--得到线性地址
static inline struct Page*
pa2page(physaddr_t pa)
{
if (PPN(pa) >= npage)
panic("pa2page called with invalid pa");
return &pages[PPN(pa)];
}
2)、Page2pa--返回内存页表数
static inline physaddr_t
page2pa(struct Page *pp)
{
return page2ppn(pp) << PGSHIFT;
}
3)、Page2ppn--验证内存页的正确性.返回page所在地址
static inline ppn_t
page2ppn(struct Page *pp)
{
return pp - pages;
}
4)、PADDR—虚拟地址转换成物理地址
#define PADDR(kva) \
({ \
physaddr_t __m_kva = (physaddr_t) (kva); \
if (__m_kva < KERNBASE) \
panic("PADDR called with invalid kva %08lx", __m_kva);\
__m_kva - KERNBASE; \
})
5)、KADDR—物理地址转换成虚拟地址
#define KADDR(pa) \
({ \
physaddr_t __m_pa = (pa); \
uint32_t __m_ppn = PPN(__m_pa); \
if (__m_ppn >= npage) \
panic("KADDR called with invalid pa %08lx", __m_pa);\
(void*) (__m_pa + KERNBASE); \
})
6)、Page2kva--把物理地址转换为虚拟地址
static inline void*
page2kva(struct Page *pp)
{
return KADDR(page2pa(pp));
}
二、Struct Page数据结构
1、Page结构说明
1)、Page_LIST_entry_t pp_link——用于page链表管理
2)、uint16_t pp_ref——该物理页面被引用数(即被map到虚拟地址的数量),当引用数为0,
即可释放
三、inc/queue.h
1、LIST_ENTRY
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* ptr to ptr to this element */ \
}
定义结点的指针部分Type是链表结点的类型LIST_ENTRY(type)定义type类型包含的两个指针这两个指针把结点串接成双向链表
在Lab2中的应用:typedef LIST_ENTRY(Page) Page_LIST_entry_t; #inc/memlayout.h
2、LIST_HEAD
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
这个宏实现了类型名是name,结点类型是type的双向链表的结构体定义。
在Lab2中的应用:
LIST_HEAD(Page_list, Page); #inc/memlayout.h
static struct Page_list page_free_list; #kern/pmap.c
四、定义操作的宏
1、链表初始化
#define LIST_INIT ...
2、遍历链表中的所有结点
#define LIST_FOREACH ...
3、在链表的表头位置添加一个结点
#define LIST_INSERT_HEAD ...
4、从链表中删除一个结点
#define LIST_REMOVE ...
阅读(3355) | 评论(0) | 转发(0) |