]> Zhao Yanbai Git Server - kernel.git/commitdiff
支持bootmem的64bit区段
authoracevest <zhaoyanbai@126.com>
Fri, 26 Nov 2021 15:02:02 +0000 (23:02 +0800)
committeracevest <zhaoyanbai@126.com>
Fri, 26 Nov 2021 15:02:02 +0000 (23:02 +0800)
boot/boot.h
lib/vsprintf.c
mm/bootmem.c

index 03e3109bb52e42cafd96e6761107ad48e680c946..9d5c3b4134bbce42439840bb4f1e06b3386bb4a4 100644 (file)
@@ -14,6 +14,7 @@
 #define BOOT_INIT_PAGETBL_CNT 2  // 8MB
 
 #ifndef ASM
+#include <types.h>
 
 #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 {
index 40507716497c5fcc74c262fe3ca2d74d2bf4fb09..c7f87370af576d63c6483ca0f303c863622f5dbc 100644 (file)
@@ -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;
index 9c2d7d5e17a207568b491d8508f27f679bede2d3..92e9f7ad7a368b9f45691a0505ab50300b97c578 100644 (file)
@@ -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的时候才会用到