《操作系统》的实验代码。
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

147 wiersze
4.9 KiB

12 lat temu
12 lat temu
12 lat temu
12 lat temu
12 lat temu
12 lat temu
12 lat temu
12 lat temu
12 lat temu
  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. // pmm_manager is a physical memory management class. A special pmm manager - XXX_pmm_manager
  9. // only needs to implement the methods in pmm_manager class, then XXX_pmm_manager can be used
  10. // by ucore to manage the total physical memory space.
  11. struct pmm_manager {
  12. const char *name; // XXX_pmm_manager's name
  13. void (*init)(void); // initialize internal description&management data structure
  14. // (free block list, number of free block) of XXX_pmm_manager
  15. void (*init_memmap)(struct Page *base, size_t n); // setup description&management data structcure according to
  16. // the initial free physical memory space
  17. struct Page *(*alloc_pages)(size_t n); // allocate >=n pages, depend on the allocation algorithm
  18. void (*free_pages)(struct Page *base, size_t n); // free >=n pages with "base" addr of Page descriptor structures(memlayout.h)
  19. size_t (*nr_free_pages)(void); // return the number of free pages
  20. void (*check)(void); // check the correctness of XXX_pmm_manager
  21. };
  22. extern const struct pmm_manager *pmm_manager;
  23. extern pde_t *boot_pgdir;
  24. extern uintptr_t boot_cr3;
  25. void pmm_init(void);
  26. struct Page *alloc_pages(size_t n);
  27. void free_pages(struct Page *base, size_t n);
  28. size_t nr_free_pages(void);
  29. #define alloc_page() alloc_pages(1)
  30. #define free_page(page) free_pages(page, 1)
  31. pte_t *get_pte(pde_t *pgdir, uintptr_t la, bool create);
  32. struct Page *get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store);
  33. void page_remove(pde_t *pgdir, uintptr_t la);
  34. int page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm);
  35. void load_esp0(uintptr_t esp0);
  36. void tlb_invalidate(pde_t *pgdir, uintptr_t la);
  37. struct Page *pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm);
  38. void unmap_range(pde_t *pgdir, uintptr_t start, uintptr_t end);
  39. void exit_range(pde_t *pgdir, uintptr_t start, uintptr_t end);
  40. int copy_range(pde_t *to, pde_t *from, uintptr_t start, uintptr_t end, bool share);
  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__ */