《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.8 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. #ifndef __KERN_MM_PMM_H__
  2. #define __KERN_MM_PMM_H__
  3. #include <defs.h>
  4. #include <mmu.h>
  5. #include <memlayout.h>
  6. #include <atomic.h>
  7. #include <assert.h>
  8. /* fork flags used in do_fork*/
  9. #define CLONE_VM 0x00000100 // set if VM shared between processes
  10. #define CLONE_THREAD 0x00000200 // thread group
  11. // pmm_manager is a physical memory management class. A special pmm manager - XXX_pmm_manager
  12. // only needs to implement the methods in pmm_manager class, then XXX_pmm_manager can be used
  13. // by ucore to manage the total physical memory space.
  14. struct pmm_manager {
  15. const char *name; // XXX_pmm_manager's name
  16. void (*init)(void); // initialize internal description&management data structure
  17. // (free block list, number of free block) of XXX_pmm_manager
  18. void (*init_memmap)(struct Page *base, size_t n); // setup description&management data structcure according to
  19. // the initial free physical memory space
  20. struct Page *(*alloc_pages)(size_t n); // allocate >=n pages, depend on the allocation algorithm
  21. void (*free_pages)(struct Page *base, size_t n); // free >=n pages with "base" addr of Page descriptor structures(memlayout.h)
  22. size_t (*nr_free_pages)(void); // return the number of free pages
  23. void (*check)(void); // check the correctness of XXX_pmm_manager
  24. };
  25. extern const struct pmm_manager *pmm_manager;
  26. extern pde_t *boot_pgdir;
  27. extern uintptr_t boot_cr3;
  28. void pmm_init(void);
  29. struct Page *alloc_pages(size_t n);
  30. void free_pages(struct Page *base, size_t n);
  31. size_t nr_free_pages(void);
  32. #define alloc_page() alloc_pages(1)
  33. #define free_page(page) free_pages(page, 1)
  34. pte_t *get_pte(pde_t *pgdir, uintptr_t la, bool create);
  35. struct Page *get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store);
  36. void page_remove(pde_t *pgdir, uintptr_t la);
  37. int page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm);
  38. void load_esp0(uintptr_t esp0);
  39. void tlb_invalidate(pde_t *pgdir, uintptr_t la);
  40. struct Page *pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm);
  41. void print_pgdir(void);
  42. /* *
  43. * PADDR - takes a kernel virtual address (an address that points above KERNBASE),
  44. * where the machine's maximum 256MB of physical memory is mapped and returns the
  45. * corresponding physical address. It panics if you pass it a non-kernel virtual address.
  46. * */
  47. #define PADDR(kva) ({ \
  48. uintptr_t __m_kva = (uintptr_t)(kva); \
  49. if (__m_kva < KERNBASE) { \
  50. panic("PADDR called with invalid kva %08lx", __m_kva); \
  51. } \
  52. __m_kva - KERNBASE; \
  53. })
  54. /* *
  55. * KADDR - takes a physical address and returns the corresponding kernel virtual
  56. * address. It panics if you pass an invalid physical address.
  57. * */
  58. #define KADDR(pa) ({ \
  59. uintptr_t __m_pa = (pa); \
  60. size_t __m_ppn = PPN(__m_pa); \
  61. if (__m_ppn >= npage) { \
  62. panic("KADDR called with invalid pa %08lx", __m_pa); \
  63. } \
  64. (void *) (__m_pa + KERNBASE); \
  65. })
  66. extern struct Page *pages;
  67. extern size_t npage;
  68. static inline ppn_t
  69. page2ppn(struct Page *page) {
  70. return page - pages;
  71. }
  72. static inline uintptr_t
  73. page2pa(struct Page *page) {
  74. return page2ppn(page) << PGSHIFT;
  75. }
  76. static inline struct Page *
  77. pa2page(uintptr_t pa) {
  78. if (PPN(pa) >= npage) {
  79. panic("pa2page called with invalid pa");
  80. }
  81. return &pages[PPN(pa)];
  82. }
  83. static inline void *
  84. page2kva(struct Page *page) {
  85. return KADDR(page2pa(page));
  86. }
  87. static inline struct Page *
  88. kva2page(void *kva) {
  89. return pa2page(PADDR(kva));
  90. }
  91. static inline struct Page *
  92. pte2page(pte_t pte) {
  93. if (!(pte & PTE_P)) {
  94. panic("pte2page called with invalid pte");
  95. }
  96. return pa2page(PTE_ADDR(pte));
  97. }
  98. static inline struct Page *
  99. pde2page(pde_t pde) {
  100. return pa2page(PDE_ADDR(pde));
  101. }
  102. static inline int
  103. page_ref(struct Page *page) {
  104. return page->ref;
  105. }
  106. static inline void
  107. set_page_ref(struct Page *page, int val) {
  108. page->ref = val;
  109. }
  110. static inline int
  111. page_ref_inc(struct Page *page) {
  112. page->ref += 1;
  113. return page->ref;
  114. }
  115. static inline int
  116. page_ref_dec(struct Page *page) {
  117. page->ref -= 1;
  118. return page->ref;
  119. }
  120. extern char bootstack[], bootstacktop[];
  121. #endif /* !__KERN_MM_PMM_H__ */