把 page 資訊存在 kernel 的資料結構中
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];
|
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();
...
|
在對 pages 的資料結構進行索引時,會需要每個 Page 的數字,這個資訊可以直接從 physical address 拿到
Kernel virtual address : 0xffff000012345678
Physical address : 0x0000000012345678
|___________|
PFN
PFN : 0x0000000000012345
page descriptor : struct page[0x12345]
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;
}
|