Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1887579
  • 博文数量: 333
  • 博客积分: 10791
  • 博客等级: 上将
  • 技术积分: 4314
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-08 07:39
文章分类

全部博文(333)

文章存档

2015年(1)

2011年(116)

2010年(187)

2009年(25)

2008年(3)

2007年(1)

分类:

2009-03-17 21:12:10

一、二级页表映射的建立
􀂉 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) |
给主人留下些什么吧!~~