Page Bookkeeping

Page Bookkeeping

把 page 資訊存在 kernel 的資料結構中

src/mm.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#define PAGE_FRAMES_NUM         (0x40000000 / PAGE_SIZE)

enum page_status {
    AVAL,
    USED,
};

struct page_t {
    enum page_status used;
};

/* Variables init in mm.c */
extern struct page_t page[PAGE_FRAMES_NUM];

src/mm.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
struct page_t page[PAGE_FRAMES_NUM];
int first_aval_page, last_aval_page;
uint64_t remain_page = 0;

void mm_init() {
    extern uint8_t __kernel_end;  // defined in linker
    uint8_t* kernel_end = &__kernel_end;
    int kernel_end_page = (uint64_t)kernel_end / PAGE_SIZE;
    int mmio_base_page = MMIO_PHYSICAL / PAGE_SIZE;

    int i = 0;
    for (; i < kernel_end_page; i++) {
        page[i].used = USED;
    }
    for (; i < mmio_base_page; i++) {
        remain_page++;
        page[i].used = AVAL;
    }
    for (; i < PAGE_FRAMES_NUM; i++) {
        page[i].used = USED;
    }

    first_aval_page = kernel_end_page + 1;
    last_aval_page = mmio_base_page - 1;
}

src/main.c

1
2
3
void boot_init() {
    mm_init();
    ...

Page Frame Number (PFN)

在對 pages 的資料結構進行索引時,會需要每個 Page 的數字,這個資訊可以直接從 physical address 拿到

Kernel virtual address : 0xffff000012345678
Physical address       : 0x0000000012345678
                           |___________|
                                PFN
PFN                    : 0x0000000000012345
page descriptor        : struct page[0x12345]

src/mm.c

1
2
3
4
5
6
7
uint64_t virtual_to_physical(uint64_t virt_addr) {
    return (virt_addr << 16) >> 16;
}

uint64_t phy_to_pfn(uint64_t phy_addr) {
    return phy_addr >> 12;
}
comments powered by Disqus