From b0a16a5902c29cc1f4bc8e7b35badfd1fa9f393c Mon Sep 17 00:00:00 2001 From: acevest Date: Fri, 26 Nov 2021 23:02:02 +0800 Subject: [PATCH] =?utf8?q?=E6=94=AF=E6=8C=81bootmem=E7=9A=8464bit=E5=8C=BA?= =?utf8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- boot/boot.h | 7 ++++--- lib/vsprintf.c | 44 ++++++++++++++++++++++++++++++++++++++++---- mm/bootmem.c | 32 +++++++++++++------------------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/boot/boot.h b/boot/boot.h index 03e3109..9d5c3b4 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -14,6 +14,7 @@ #define BOOT_INIT_PAGETBL_CNT 2 // 8MB #ifndef ASM +#include #define E820_RAM 1 #define E820_RESERVED 2 @@ -24,9 +25,9 @@ #define E820_MAP_CNT 128 struct e820_entry { - unsigned long addr; - unsigned long size; - unsigned long type; + uint64_t addr; + uint64_t size; + uint32_t type; }; struct e820map { diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4050771..c7f8737 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -10,8 +10,9 @@ char *itoa(char *s, int n); char *itou(char *s, unsigned int n); -char *itox(char *s, unsigned int n); +char *itox(char *s, unsigned int n, int upper); char *i64tou(char *s, int64_t n); +char *i64tox(char *s, uint64_t n, int upper); enum { ALIGN_RIGHT, ALIGN_LEFT }; @@ -86,6 +87,11 @@ int vsprintf(char *buf, const char *fmt, char *args) { i64tou(tmp, *((int64_t *)args)); p += write_buf(p, tmp, char_fill, char_cnt, align); args += 4; + } else if (*fmt == 'x' || *fmt == 'X') { + // i64tox(tmp, *((uint64_t *)args), *fmt == 'X' ? 1 : 0); + i64tox(tmp, *((uint64_t *)args), 1); // x X都强制为大写 + p += write_buf(p, tmp, char_fill, char_cnt, align); + args += 4; } break; case 's': @@ -96,7 +102,9 @@ int vsprintf(char *buf, const char *fmt, char *args) { p += write_buf(p, tmp, char_fill, char_cnt, align); break; case 'x': - itox(tmp, *((unsigned int *)args)); + case 'X': + // itox(tmp, *((unsigned int *)args), *fmt == 'X' ? 1 : 0); + itox(tmp, *((unsigned int *)args), 1); // x X都强制为大写 p += write_buf(p, tmp, char_fill, char_cnt, align); break; default: @@ -169,7 +177,7 @@ char *itou(char *s, unsigned int n) { } } -char *itox(char *s, unsigned int n) { +char *itox(char *s, unsigned int n, int upper) { char *p = s; char ch; int i; @@ -182,7 +190,35 @@ char *itox(char *s, unsigned int n) { ch += '0'; } else { ch -= 10; - ch += 'A'; + ch += upper == 1 ? 'A' : 'a'; + } + + if (ch != '0') flag = true; + + if (flag || ch != '0') *p++ = ch; + } + + if (s == p) *p++ = '0'; + + *p = 0; + + return s; +} + +char *i64tox(char *s, uint64_t n, int upper) { + char *p = s; + char ch; + int i; + bool flag = false; + + for (i = 60; i >= 0; i -= 4) { + ch = (n >> i) & 0x0F; + + if (ch >= 0 && ch <= 9) { + ch += '0'; + } else { + ch -= 10; + ch += upper == 1 ? 'A' : 'a'; } if (ch != '0') flag = true; diff --git a/mm/bootmem.c b/mm/bootmem.c index 9c2d7d5..92e9f7a 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -67,8 +67,8 @@ void e820_print_map() { for (i = 0; i < boot_params.e820map.map_cnt; ++i) { struct e820_entry *p = boot_params.e820map.map + i; - printk(" [%02d] 0x%08x - 0x%08x size %- 10d %8dKB %5dMB ", i, p->addr, p->addr + p->size - 1, p->size, - p->size >> 10, p->size >> 20); + printk(" [%02d] 0x%010lX - 0x%010lX size %- 10u %8dKB %5dMB ", i, p->addr, (p->addr + p->size - 1), + (uint32_t)p->size, (uint32_t)(p->size >> 10), (uint32_t)(p->size >> 20)); e820_print_type(p->type); @@ -96,16 +96,16 @@ void e820_init_bootmem_data() { continue; } - unsigned long bgn_pfn = PFN_UP(p->addr); - unsigned long end_pfn = PFN_DW(p->addr + p->size); - - // 在x86_64的机器上低32bit可能出现回绕的情况 - // 就算物理内存小于4G也可能出现 - // 这种情况直接忽略 - if (bgn_pfn < bootmem_data.max_pfn) { + if (p->addr > 0xFFFFFFFF) { break; } + if (p->addr + p->size > 0xFFFFFFFF) { + p->size = 0xFFFFFFFF + 1 - p->addr; + } + + unsigned long bgn_pfn = PFN_UP(p->addr); + unsigned long end_pfn = PFN_DW(p->addr + p->size); if (bootmem_data.min_pfn > bgn_pfn) { bootmem_data.min_pfn = bgn_pfn; @@ -130,7 +130,6 @@ void e820_init_bootmem_data() { } void register_bootmem_pages() { - unsigned long max_pfn = 0; for (unsigned int i = 0; i < boot_params.e820map.map_cnt; ++i) { struct e820_entry *p = boot_params.e820map.map + i; @@ -138,18 +137,12 @@ void register_bootmem_pages() { continue; } - unsigned long bgn_pfn = PFN_UP(p->addr); - unsigned long end_pfn = PFN_DW(p->addr + p->size); - - // 在x86_64的机器上低32bit可能出现回绕的情况 - // 就算物理内存小于4G也可能出现 - // 这种情况直接忽略 - if (bgn_pfn < max_pfn) { + if (p->addr > 0xFFFFFFFF) { break; } - max_pfn = end_pfn; - + unsigned long bgn_pfn = PFN_UP(p->addr); + unsigned long end_pfn = PFN_DW(p->addr + p->size); #if 1 // 用一个相对快的方式 @@ -210,6 +203,7 @@ void init_bootmem() { e820_print_map(); e820_init_bootmem_data(); init_bootmem_allocator(); + // asm("cli;hlt;"); } // 由于只有在构建buddy system的时候才会用到 -- 2.44.0