diff --git a/lab2/kernel/mm/page_table.c b/lab2/kernel/mm/page_table.c
index 0109d93..bb14fd6 100644
--- a/lab2/kernel/mm/page_table.c
+++ b/lab2/kernel/mm/page_table.c
@@ -162,7 +162,24 @@ static int get_next_ptp(ptp_t * cur_ptp, u32 level, vaddr_t va,
 int query_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t * pa, pte_t ** entry)
 {
 	// <lab2>
+    ptp_t * cur_ptp = (ptp_t *) pgtbl, *next_ptp;
+    int page_type;
 
+    // 遍历 L0-L3
+    for (u32 cur_level = 0; cur_level < 4; cur_level++) {
+        page_type = get_next_ptp(cur_ptp, cur_level, va, &next_ptp, entry, false);
+        if (page_type < 0) {
+            // 无法映射
+            return page_type;
+        } else if (page_type == BLOCK_PTP) {
+            // 遇到块项直接返回
+            break;
+        } else {
+            // 遇到页表项,向下遍历
+            cur_ptp = next_ptp;
+        }
+    }
+	*pa = GET_PADDR_IN_PTE((*entry)) | (va & PAGE_MASK);
 	// </lab2>
 	return 0;
 }
@@ -186,7 +203,40 @@ int map_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t pa,
 		       size_t len, vmr_prop_t flags)
 {
 	// <lab2>
-
+    vaddr_t va_start = va, va_end = va + len, va_cur;
+    ptp_t * cur_ptp, *next_ptp;
+    int page_type;
+    u32 cur_level;
+    pte_t *entry;
+    u64 cur_pfn;
+    // 遍历所有页
+    cur_pfn = pa >> PAGE_SHIFT;
+    va_start &= ~PAGE_MASK;
+    va_end &= ~PAGE_MASK;
+    if (va_end < va + len) {
+        va_end++;  // 有不完整的一页
+    }
+    for (va_cur = va_start; va_cur < va_end; va_cur += PAGE_SIZE) {
+        // 创建一页
+        cur_ptp = (ptp_t *) pgtbl;
+        for (cur_level = 0; cur_level < 4; cur_level++) {
+            page_type = get_next_ptp(cur_ptp, cur_level, va, &next_ptp, &entry, true);
+            if (page_type < 0) {
+                // 无法映射
+                return page_type;
+            } else if (page_type == BLOCK_PTP) {
+                // 目前只支持页映射,遇到块项直接返回
+                return -ENOMAPPING;
+            } else {
+                // 遇到页表项,向下遍历
+                cur_ptp = next_ptp;
+            }
+        }
+        // 配置页
+        set_pte_flags(entry, flags, USER_PTE);
+        entry->l3_page.pfn = cur_pfn++;
+    }
+    flush_tlb();
 	// </lab2>
 	return 0;
 }
@@ -207,7 +257,40 @@ int map_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, paddr_t pa,
 int unmap_range_in_pgtbl(vaddr_t * pgtbl, vaddr_t va, size_t len)
 {
 	// <lab2>
-
+    vaddr_t va_start = va, va_end = va + len, va_cur;
+    ptp_t * cur_ptp, *next_ptp;
+    int page_type;
+    u32 cur_level;
+    pte_t *entry;
+    // 遍历所有页
+    va_start &= ~PAGE_MASK;
+    va_end &= ~PAGE_MASK;
+    if (va_end < va + len) {
+        va_end++;  // 有不完整的一页
+    }
+    for (va_cur = va_start; va_cur < va_end; va_cur += PAGE_SIZE) {
+        // 创建一页
+        cur_ptp = (ptp_t *) pgtbl;
+        for (cur_level = 0; cur_level < 4; cur_level++) {
+            page_type = get_next_ptp(cur_ptp, cur_level, va, &next_ptp, &entry, false);
+            if (page_type < 0) {
+                // 无法映射
+                break;
+            } else if (page_type == BLOCK_PTP) {
+                // 目前只支持页映射,遇到块项直接返回
+                return -ENOMAPPING;
+            } else {
+                // 遇到页表项,向下遍历
+                cur_ptp = next_ptp;
+            }
+        }
+        if (cur_level != 4) {
+            continue;
+        }
+        // 配置页
+        entry->pte = 0;
+    }
+    flush_tlb();
 	// </lab2>
 	return 0;
 }