diff --git a/lab2/boot/mmu.c b/lab2/boot/mmu.c index d29be16..00eac43 100644 --- a/lab2/boot/mmu.c +++ b/lab2/boot/mmu.c @@ -48,7 +48,7 @@ void init_boot_pt(void) boot_ttbr0_l0[0] = ((u64) boot_ttbr0_l1) | IS_TABLE | IS_VALID; boot_ttbr0_l1[0] = ((u64) boot_ttbr0_l2) | IS_TABLE | IS_VALID; - /* Usuable memory: PHYSMEM_START ~ PERIPHERAL_BASE */ + /* Usable memory: PHYSMEM_START ~ PERIPHERAL_BASE */ start_entry_idx = PHYSMEM_START / SIZE_2M; end_entry_idx = PERIPHERAL_BASE / SIZE_2M; diff --git a/lab2/kernel/mm/mm.c b/lab2/kernel/mm/mm.c index f137cb7..95c99d5 100644 --- a/lab2/kernel/mm/mm.c +++ b/lab2/kernel/mm/mm.c @@ -16,6 +16,7 @@ #include "buddy.h" #include "slab.h" +#include "page_table.h" extern unsigned long *img_end; @@ -51,6 +52,35 @@ unsigned long get_ttbr1(void) void map_kernel_space(vaddr_t va, paddr_t pa, size_t len) { // +#define IS_VALID (1UL << 0) +#define UXN (0x1UL << 54) +#define ACCESSED (0x1UL << 10) +#define INNER_SHARABLE (0x3UL << 8) + +#define SIZE_2M (2UL*1024*1024) +#define PAGE_SHIFT (12) +#define GET_PADDR_IN_PTE(entry) \ + (((u64)entry.table.next_table_addr) << PAGE_SHIFT) + + paddr_t addr_l0, addr_l1, addr_l2; + pte_t pte_l0, pte_l1; + u64 *table_l2; + + // 获得页表地址 + // 不妨假设 len 小于 1G 且属于同一块 + addr_l0 = get_ttbr1(); + pte_l0.pte = *((u64 *) phys_to_virt(addr_l0) + GET_L0_INDEX(va)); + addr_l1 = GET_PADDR_IN_PTE(pte_l0); + pte_l1.pte = *((u64 *) phys_to_virt(addr_l1) + GET_L1_INDEX(va)); + addr_l2 = GET_PADDR_IN_PTE(pte_l1); + table_l2 = (u64 *) phys_to_virt(addr_l2); + + // 设置页表 + u32 start_entry_idx = GET_L2_INDEX(va); + u32 end_entry_idx = GET_L2_INDEX((va + len)); + for (u32 idx = start_entry_idx; idx < end_entry_idx; ++idx) { + table_l2[idx] = (pa + idx * SIZE_2M) | UXN | ACCESSED | INNER_SHARABLE | NORMAL_MEMORY | IS_VALID; + } // } diff --git a/note.org b/note.org index b0c6817..355e9b7 100644 --- a/note.org +++ b/note.org @@ -107,3 +107,17 @@ LR *** 练习1 基本思路就是回收的时候一路尝试向上合并,分配的时候找一个更大的块然后一路向下分裂。 + +*** 练习2 + +没啥特别的。不过目前只实现了用户空间的 2k 页分配。 + +*** 练习3 + +boot/mmu.c:L80-106 映射了 KBASE~KBASE+256M + +boot/mmu.c:L109-110 映射了 KBASE+512M~KBASE+4G + +因此只需要类似操作,补全中间的 256M 即可。 + +注意的是,寄存器保存的地址是 paddr_t