diff --git a/arch/x86_64/e820.c b/arch/x86_64/e820.c new file mode 100644 index 0000000..5b5b88b --- /dev/null +++ b/arch/x86_64/e820.c @@ -0,0 +1,56 @@ +#include "socks/types.h" +#include +#include +#include +#include + +void e820_scan(multiboot_memory_map_t *mmap, size_t len) +{ + size_t mem_total = 0, mem_reserved = 0; + + multiboot_memory_map_t *entry = NULL; + for (size_t i = 0; i < len; i += sizeof *entry) { + entry = (void *)((char *)mmap + i); + + int reserved = 1; + const char *type = "unknown"; + switch (entry->type) { + case MULTIBOOT_MEMORY_AVAILABLE: + type = "available"; + reserved = 0; + break; + case MULTIBOOT_MEMORY_RESERVED: + type = "reserved"; + break; + case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE: + type = "acpi"; + break; + case MULTIBOOT_MEMORY_NVS: + type = "nvs"; + break; + case MULTIBOOT_MEMORY_BADRAM: + type = "bad"; + break; + default: + break; + } + + printk("e820: [mem 0x%016llx-0x%016llx] %s", + entry->addr, entry->addr + entry->len - 1, type); + + memblock_add(entry->addr, entry->len); + + if (reserved) { + memblock_reserve(entry->addr, entry->len); + mem_reserved += entry->len; + } + + mem_total += entry->len; + } + + char str_mem_total[64], str_mem_reserved[64]; + data_size_to_string(mem_total, str_mem_total, sizeof str_mem_total); + data_size_to_string(mem_reserved, str_mem_reserved, sizeof str_mem_reserved); + + printk("e820: total memory: %s, hw reserved: %s", str_mem_total, str_mem_reserved); +} diff --git a/arch/x86_64/include/arch/e820.h b/arch/x86_64/include/arch/e820.h new file mode 100644 index 0000000..bb8a239 --- /dev/null +++ b/arch/x86_64/include/arch/e820.h @@ -0,0 +1,9 @@ +#ifndef ARCH_E820_H_ +#define ARCH_E820_H_ + +#include +#include + +extern void e820_scan(multiboot_memory_map_t *mmap, size_t len); + +#endif diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c index d828051..00ce61a 100644 --- a/arch/x86_64/init.c +++ b/arch/x86_64/init.c @@ -1,21 +1,51 @@ +#include "socks/types.h" +#include #include +#include +#include +#include #include #include +#define PTR32(x) ((void *)((uintptr_t)(x))) + static ml_cpu_block g_bootstrap_cpu = {0}; +/* start and end of kernel image (physical addresses) */ +extern char __pstart[], __pend[]; + static void bootstrap_cpu_init(void) { ml_cpu_block_init(&g_bootstrap_cpu); ml_cpu_block_use(&g_bootstrap_cpu); } +static void early_vm_init(void) +{ + uintptr_t alloc_start = VM_KERNEL_VOFFSET; + /* boot code mapped 2 GiB of memory from + VM_KERNEL_VOFFSET */ + uintptr_t alloc_end = VM_KERNEL_VOFFSET + 0x7fffffff; + + memblock_init(alloc_start, alloc_end, VM_KERNEL_VOFFSET); + printk("memblock: allocating from [0x%llx-0x%llx]", alloc_start, alloc_end); + + memblock_reserve(0x00, (uintptr_t)__pend); + printk("memblock: reserved bios+kernel at [0x%016llx-0x%016llx]", 0, (uintptr_t)__pend); +} + int ml_init(uintptr_t arg) { + multiboot_info_t *mb = (multiboot_info_t *)arg; + bootstrap_cpu_init(); vgacon_init(); print_kernel_banner(); + early_vm_init(); + + e820_scan(PTR32(mb->mmap_addr), mb->mmap_length); + return 0; } diff --git a/arch/x86_64/layout.ld b/arch/x86_64/layout.ld index 0faa7c4..e0bd1d1 100644 --- a/arch/x86_64/layout.ld +++ b/arch/x86_64/layout.ld @@ -4,19 +4,22 @@ KERNEL_LMA = 1M; KERNEL_VMA = 0xFFFFFFFF80000000; SECTIONS { - . = KERNEL_LMA; + . = KERNEL_LMA; - .boot.text ALIGN(4K) : { - *(.boot.text) - *(.boot.rodata) - } + .boot.text ALIGN(4K) : { + *(.boot.text) + *(.boot.rodata) + } - .boot.bss ALIGN(4K) : { - *(.boot.bss) - } + .boot.bss ALIGN(4K) : { + *(.boot.bss) + } . += KERNEL_VMA; + __start = .; + __pstart = . - KERNEL_VMA; + .text ALIGN(4K) : AT(ADDR(.text) - KERNEL_VMA) { *(.text) @@ -47,7 +50,8 @@ SECTIONS { *(COMMON) } - _end = .; + __end = .; + __pend = . - KERNEL_VMA; /DISCARD/ : { diff --git a/init/main.c b/init/main.c index 7c9ef31..d42c187 100644 --- a/init/main.c +++ b/init/main.c @@ -6,6 +6,8 @@ extern unsigned long get_rflags(void); +extern char __pstart[], __pend[]; + void print_kernel_banner(void) { printk("Socks kernel version " BUILD_ID); @@ -14,5 +16,6 @@ void print_kernel_banner(void) void kernel_init(uintptr_t arg) { ml_init(arg); + ml_halt_cpu(); }