瀏覽代碼

feat: read mem_map from bios

greatbridf 3 年之前
父節點
當前提交
e0bd7ce1a4
共有 3 個文件被更改,包括 104 次插入1 次删除
  1. 18 0
      include/asm/boot.h
  2. 60 1
      src/boot.s
  3. 26 0
      src/kernel_main.c

+ 18 - 0
include/asm/boot.h

@@ -10,3 +10,21 @@ struct gdt_descriptor {
 extern struct gdt_descriptor asm_gdt_descriptor;
 
 extern uint32_t check_a20_on(void);
+
+struct e820_mem_map_entry_20 {
+    uint64_t base;
+    uint64_t len;
+    uint32_t type;
+};
+
+struct e820_mem_map_entry_24 {
+    struct e820_mem_map_entry_20 in;
+    uint32_t acpi_extension_attr;
+};
+
+extern uint8_t asm_e820_mem_map[1024];
+extern uint32_t asm_e820_mem_map_count;
+extern uint32_t asm_e820_mem_map_entry_size;
+
+#define e820_mem_map_20 ((struct e820_mem_map_entry_20*)asm_e820_mem_map)
+#define e820_mem_map_24 ((struct e820_mem_map_entry_24*)asm_e820_mem_map)

+ 60 - 1
src/boot.s

@@ -85,12 +85,55 @@ _get_memory_size_use_ax:
     movw %ax, (%edx)
     addw $2, %dx
     movw %bx, (%edx)
-    jmp _load_gdt
+    jmp _e820_mem_map_load
 
 _get_memory_size_error:
     xchgw %bx, %bx
     jmp loader_halt
 
+_e820_mem_map_load:
+    addl $4, %esp
+    movl $0, (%esp)
+
+    # save the destination address to es:di
+    movw %cs, %ax
+    movw %ax, %es
+
+    movl $(asm_e820_mem_map-loader_start), %edi
+
+    # clear ebx
+    xorl %ebx, %ebx
+
+    # set the magic number to edx
+    movl $0x534D4150, %edx
+
+_e820_mem_map_load_loop:
+    # set function number to eax
+    movl $0xe820, %eax
+
+    # set default entry size
+    movl $24, %ecx
+
+    int $0x15
+
+    incl (%esp)
+    addl %ecx, %edi
+
+    jc _e820_mem_map_load_fin
+    cmpl $0, %ebx
+    jz _e820_mem_map_load_fin
+    jmp _e820_mem_map_load_loop
+
+_e820_mem_map_load_fin:
+    movl (%esp), %eax
+    movl $(asm_e820_mem_map_count-loader_start), %edi
+    movl %eax, (%edi)
+
+    movl $(asm_e820_mem_map_entry_size-loader_start), %edi
+    movl %ecx, (%edi)
+
+    jmp _load_gdt
+
 _load_gdt:
     cli
     lgdt (asm_gdt_descriptor-loader_start)
@@ -159,3 +202,19 @@ asm_mem_size_info:
 .globl asm_mem_size_info
 .type  asm_mem_size_info @object
 .size  asm_mem_size_info, (.-asm_mem_size_info)
+
+asm_e820_mem_map:
+    .space 1024
+.globl asm_e820_mem_map
+.type  asm_e820_mem_map @object
+.size  asm_e820_mem_map, (.-asm_e820_mem_map)
+
+asm_e820_mem_map_count:
+    .long 0
+.globl asm_e820_mem_map_count
+.type  asm_e820_mem_map_count @object
+
+asm_e820_mem_map_entry_size:
+    .long 0
+.globl asm_e820_mem_map_entry_size
+.type  asm_e820_mem_map_entry_size @object

+ 26 - 0
src/kernel_main.c

@@ -51,6 +51,32 @@ void kernel_main(void)
         (int32_t)asm_mem_size_info.n_1k_blks,
         (int32_t)asm_mem_size_info.n_64k_blks);
 
+    printkf(
+        "mem_map_entry_count: %d , mem_map_entry_size: %d \n",
+        asm_e820_mem_map_count,
+        asm_e820_mem_map_entry_size);
+
+    if (asm_e820_mem_map_entry_size == 20) {
+        for (uint32_t i = 0; i < asm_e820_mem_map_count; ++i) {
+            printkf(
+                "[mem] entry %d: %lld ~ %lld, type: %d\n",
+                i,
+                e820_mem_map_20[i].base,
+                e820_mem_map_20[i].base + e820_mem_map_20[i].len,
+                e820_mem_map_20[i].type);
+        }
+    } else {
+        for (uint32_t i = 0; i < asm_e820_mem_map_count; ++i) {
+            printkf(
+                "[mem] entry %d: %lld ~ %lld, type: %d, acpi_attr: %d\n",
+                i,
+                e820_mem_map_24[i].in.base,
+                e820_mem_map_24[i].in.base + e820_mem_map_24[i].in.len,
+                e820_mem_map_24[i].in.type,
+                e820_mem_map_24[i].acpi_extension_attr);
+        }
+    }
+
     printkf("Initializing interrupt descriptor table...\n");
 
     init_idt();