From c52d9f4960b58889247314a62caee84c37e7944e Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 19 Feb 2024 01:03:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E9=A1=B5=E8=AE=A1=E6=95=B0=E7=A7=BB?= =?UTF-8?q?=E5=85=A5=E6=9E=B6=E6=9E=84=E6=94=AF=E6=8C=81=E4=B8=AD=EF=BC=88?= =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E4=B8=8D=E5=90=8C=E7=9A=84=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=9C=BA=E5=88=B6=E4=B8=8D=E5=90=8C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/memm.h | 79 +++++++++++++++++----------- include/kernel/memm.h | 6 +-- src/kernel/arch/x86_64/memm_x86_64.c | 6 +-- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index 2702399..dc2ba65 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -7,9 +7,9 @@ /** * @name MEMM_PAGE_SIZE * @addindex 平台定制宏 - * + * * 最小的页大小。 - * + * * @if arch == x86_64 then * 4096 * @endif @@ -28,7 +28,7 @@ extern u64 PML4[512]; /** * @name MEMM_PAGE_TABLE_FLAGS_MASK * @addindex 平台依赖宏 x86_64 - * + * * 页表项中属性标志位使用的最低12位的掩码`0xfff`。 */ #define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff) @@ -36,7 +36,7 @@ extern u64 PML4[512]; /** * @name MEMM_xx_ALIGN_MASK * @addindex 平台依赖宏 x86_64 - * + * * 页对齐掩码。 * `xx`为`x86_64`架构的页的三种大小,分别为`4K`、`2M`和`1G`。这些页一定是以它们自己的大小对齐,因此会出现低n位总为0的情况。 * `4K`对应`0xfff`;`2M`对应`0x1fffff`;`1G`对应`0x3fffffff`。 @@ -48,9 +48,9 @@ extern u64 PML4[512]; /** * @name MEMM_ENTRY_FLAG_xx * @addindex 平台依赖宏 x86_64 - * + * * 页表项属性标志位。定义如下: - * + * * ```c * #define MEMM_ENTRY_FLAG_PRESENT ((u64)1) * #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1) @@ -65,7 +65,7 @@ extern u64 PML4[512]; * #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7) * #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63) * ``` - * + * * 其中`MEMM_PTE_ENTRY_FLAG_PAT`的`pte`表示此属性标志位只存在与`pte`页表项中。 */ #define MEMM_ENTRY_FLAG_PRESENT ((u64)1) @@ -84,9 +84,9 @@ extern u64 PML4[512]; /** * @name memm_entry_flag_get(entry, flag) * @addindex 平台依赖宏 x86_64 - * + * * 获取页表项中某个属性标志位,得到布尔值。 - * + * * 其中`flag`是`MEMM_ENTRY_FLAG_xx`。 */ #define memm_entry_flag_get(entry, flag) \ @@ -95,13 +95,13 @@ extern u64 PML4[512]; /** * @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK * @addindex 平台依赖宏 x86_64 - * + * * 页表项地址域掩码。将页表项与掩码作与运算可得到页表项指向的**下一级页表的起始地址**或**页框的起始地址**。 - * + * * 含`BP`的为大型页页表项的地址域掩码。 - * + * * 定义如下: - * + * * ```c * #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000) * #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000) @@ -113,7 +113,7 @@ extern u64 PML4[512]; /** * @name memm_entry_get_address(entry) * @addindex 平台依赖宏 x86_64 - * + * * 获取页表项指向的地址。 */ #define memm_entry_get_address(entry) \ @@ -138,7 +138,7 @@ extern u64 PML4[512]; /** * @name MEMM_LA_xxxxI * @addindex 平台依赖宏 x86_64 - * + * * 在4级分页中,线性地址的四个页表项索引宏。其中`xxxx`分别为`PML4E`、`PDPTE`、`PDE`和`PE`。 */ #define MEMM_LA_PML4EI @@ -149,9 +149,9 @@ extern u64 PML4[512]; /** * @name memm_la_get_entry_index(addr, entry) * @addindex 平台依赖宏 x86_64 - * + * * 获取线性地址`addr`中的`entry`页表项索引。 - * + * * 其中`entry`应为宏`MEMM_LA_xxxxI`。 */ #define memm_la_get_entry_index(addr, entry) \ @@ -160,7 +160,7 @@ extern u64 PML4[512]; /** * @name MEMM_LA_xxx_PAGE_OFFSET * @addindex 平台依赖宏 x86_64 - * + * * 线性地址的页内偏移宏。其中`xxx`为三种页容量`4KB`、`2MB`、`1GB`。 */ #define MEMM_LA_1GB_PAGE_OFFSET @@ -170,9 +170,9 @@ extern u64 PML4[512]; /** * @name memm_la_get_offset(addr, page_type) * @addindex 平台依赖宏 x86_64 - * + * * 获取线性地址的页内偏移部分。 - * + * * 其中`page_type`应为宏`MEMM_LA_xxx_PAGE_OFFSET`。 */ #define memm_la_get_offset(addr, page_type) \ @@ -180,20 +180,20 @@ extern u64 PML4[512]; /** * @name memm_map_pageframes_to - * + * * ```c * bool memm_map_pageframes_to( * u64 target, u64 physical, * usize size, * bool user, bool write); * ``` - * + * * 仅支持**canonical**型地址 - * + * * `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。 - * + * * 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false - * + * * 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页; * 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页; * 否则映射4KB页。 @@ -206,7 +206,7 @@ bool memm_map_pageframes_to( /** * @name reload_pml4 * @addindex 平台依赖宏 x86_64 - * + * * ```c * void reload_pml4(); * ``` @@ -216,9 +216,9 @@ extern void reload_pml4(); /** * @name is_user_address(addr) * @addindex 平台定制宏 - * + * * 判断`addr`是否是一个用户空间地址,得到一个布尔值。 - * + * * @if arch == x86_64 * `canonical`型地址的高地址为用户空间,低地址为内核空间。 * @endif @@ -229,7 +229,7 @@ extern void reload_pml4(); /** * @name is_cannonical(addr) * @addindex 平台依赖宏 x86_64 - * + * * 判断`addr`是否是一个cannonical型地址。 */ #define is_cannonical(addr) \ @@ -238,9 +238,9 @@ extern void reload_pml4(); /** * @name memm_get_page_align(addr) * @addindex 平台依赖宏 x86_64 - * + * * 获取地址`addr`的页对齐大小,得到一个`memm_page_size`类型值。 - * + * * 当地址`addr`是*4KB对齐*或*没有4KB对齐时*,都得到`MEMM_PAGE_SIZE_4K`。 */ #define memm_get_page_align(addr) \ @@ -250,4 +250,21 @@ extern void reload_pml4(); ? MEMM_PAGE_SIZE_2M \ : MEMM_PAGE_SIZE_4K)) +/** + * @name memm_page_counter + * @addindex 平台定制结构 + * + * 页计数器 + * + * @if arch == x86_64 + * 使用三个成员分别记录`4KB`、`2MB`、`1GB`页的大小。 + * @endif + */ +typedef struct __memm_page_counter +{ + usize mapped_4k_page; + usize mapped_2m_page; + usize mapped_1g_page; +} memm_page_counter; + #endif diff --git a/include/kernel/memm.h b/include/kernel/memm.h index 0074ca8..f522507 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -186,11 +186,7 @@ typedef struct __mem_manager_t // 已经映射的页数量。若不是最小的页会被视作多个最小页计数。 usize mapped_page_amount; -#ifdef __x86_64__ - usize mapped_4k_page; - usize mapped_2m_page; - usize mapped_1g_page; -#endif + memm_page_counter platformed_page_counter; // 页地图。每个bit都表示这个页是否被映射。 u8 *page_map; diff --git a/src/kernel/arch/x86_64/memm_x86_64.c b/src/kernel/arch/x86_64/memm_x86_64.c index 080de11..e924ab6 100644 --- a/src/kernel/arch/x86_64/memm_x86_64.c +++ b/src/kernel/arch/x86_64/memm_x86_64.c @@ -126,11 +126,11 @@ bool memm_map_pageframes_to( switch (align) { case MEMM_PAGE_SIZE_4K: - mm->mapped_4k_page++; + mm->platformed_page_counter.mapped_4k_page++; case MEMM_PAGE_SIZE_2M: - mm->mapped_2m_page++; + mm->platformed_page_counter.mapped_2m_page++; case MEMM_PAGE_SIZE_1G: - mm->mapped_1g_page++; + mm->platformed_page_counter.mapped_1g_page++; } for (usize i = physical / MEMM_PAGE_SIZE; i < physical / MEMM_PAGE_SIZE + align; i++) {