From e1f671e8a7a2686cede3cd182703189ef4ea11d9 Mon Sep 17 00:00:00 2001 From: Braiden Vasco Date: Sat, 4 Nov 2017 11:43:55 +0000 Subject: [PATCH] Get kernel info from multiboot --- arch/multiboot.c | 100 ++++++++++++++++++++++++++++++-------- include/kernelmq/info.h | 6 +-- include/kernelmq/stdlib.h | 6 ++- libk/Makefile | 2 +- libk/memset.c | 4 +- libk/strncpy.c | 10 ++++ 6 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 libk/strncpy.c diff --git a/arch/multiboot.c b/arch/multiboot.c index b50cf28..fe5d254 100644 --- a/arch/multiboot.c +++ b/arch/multiboot.c @@ -1,5 +1,9 @@ #include "multiboot.h" +#include "kprintf.h" + +#include + #define MULTIBOOT_TAG_TYPE_END 0 #define MULTIBOOT_TAG_TYPE_CMDLINE 1 #define MULTIBOOT_TAG_TYPE_MODULE 3 @@ -61,12 +65,12 @@ struct multiboot_tag_mmap struct multiboot_mmap_entry entries[0]; }; -static void print_multiboot_tag(struct KernelMQ_Info *kinfo, const struct multiboot_tag *tag); +static unsigned char print_multiboot_tag(struct KernelMQ_Info *kinfo, const struct multiboot_tag *tag); -static void print_multiboot_tag_cmdline (struct KernelMQ_Info *kinfo, const struct multiboot_tag_string *tag); -static void print_multiboot_tag_module (struct KernelMQ_Info *kinfo, const struct multiboot_tag_module *tag); -static void print_multiboot_tag_basic_meminfo(struct KernelMQ_Info *kinfo, const struct multiboot_tag_basic_meminfo *tag); -static void print_multiboot_tag_mmap (struct KernelMQ_Info *kinfo, const struct multiboot_tag_mmap *tag); +static unsigned char print_multiboot_tag_cmdline (struct KernelMQ_Info *kinfo, const struct multiboot_tag_string *tag); +static unsigned char print_multiboot_tag_module (struct KernelMQ_Info *kinfo, const struct multiboot_tag_module *tag); +static unsigned char print_multiboot_tag_basic_meminfo(struct KernelMQ_Info *kinfo, const struct multiboot_tag_basic_meminfo *tag); +static unsigned char print_multiboot_tag_mmap (struct KernelMQ_Info *kinfo, const struct multiboot_tag_mmap *tag); unsigned char multiboot_parse(struct KernelMQ_Info *kinfo, unsigned long addr) { @@ -84,50 +88,92 @@ unsigned char multiboot_parse(struct KernelMQ_Info *kinfo, unsigned long addr) tag->type != MULTIBOOT_TAG_TYPE_END; tag = (struct multiboot_tag*)((unsigned char*)tag + ((tag->size + 7) & ~7)) ) { - print_multiboot_tag(kinfo, tag); + if (!print_multiboot_tag(kinfo, tag)) { + return 0; + } } return 1; } -void print_multiboot_tag(struct KernelMQ_Info *kinfo, const struct multiboot_tag *const tag) +unsigned char print_multiboot_tag(struct KernelMQ_Info *kinfo, const struct multiboot_tag *const tag) { switch (tag->type) { case MULTIBOOT_TAG_TYPE_CMDLINE: - print_multiboot_tag_cmdline(kinfo, (struct multiboot_tag_string*)tag); - break; + return print_multiboot_tag_cmdline(kinfo, (struct multiboot_tag_string*)tag); case MULTIBOOT_TAG_TYPE_MODULE: - print_multiboot_tag_module(kinfo, (struct multiboot_tag_module*)tag); - break; + return print_multiboot_tag_module(kinfo, (struct multiboot_tag_module*)tag); case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: - print_multiboot_tag_basic_meminfo(kinfo, (struct multiboot_tag_basic_meminfo*)tag); - break; + return print_multiboot_tag_basic_meminfo(kinfo, (struct multiboot_tag_basic_meminfo*)tag); case MULTIBOOT_TAG_TYPE_MMAP: - print_multiboot_tag_mmap(kinfo, (struct multiboot_tag_mmap*)tag); - break; + return print_multiboot_tag_mmap(kinfo, (struct multiboot_tag_mmap*)tag); } + + return 1; } -void print_multiboot_tag_cmdline(struct KernelMQ_Info *kinfo, const struct multiboot_tag_string *const tag) +unsigned char print_multiboot_tag_cmdline(struct KernelMQ_Info *kinfo, const struct multiboot_tag_string *const tag) { + unsigned int length = kstrlen(tag->string); + + if (length >= KERNELMQ_INFO_CMDLINE_SIZE_MAX) { + return 0; + } + + kstrncpy(kinfo->cmdline, tag->string, length); + kprintf("Kernel command line: %s\n", tag->string); + + return 1; } -void print_multiboot_tag_module(struct KernelMQ_Info *kinfo, const struct multiboot_tag_module *const tag) +unsigned char print_multiboot_tag_module(struct KernelMQ_Info *kinfo, const struct multiboot_tag_module *const tag) { + if (kinfo->modules_count >= KERNELMQ_INFO_MODULES_MAX) { + return 0; + } + + unsigned int cmdline_length = kstrlen(tag->cmdline); + + if (cmdline_length >= KERNELMQ_INFO_CMDLINE_SIZE_MAX) { + return 0; + } + + struct KernelMQ_Info_Module *module = &kinfo->modules[kinfo->modules_count]; + + kstrncpy(module->cmdline, tag->cmdline, cmdline_length); + + module->base = tag->mod_start; + module->limit = tag->mod_end; + module->size = module->limit - module->base + 1; + + ++kinfo->modules_count; + kprintf("Module at 0x%x-0x%x, command line: %s\n", tag->mod_start, tag->mod_end, tag->cmdline); + + return 1; } -void print_multiboot_tag_basic_meminfo(struct KernelMQ_Info *kinfo, const struct multiboot_tag_basic_meminfo *const tag) +unsigned char print_multiboot_tag_basic_meminfo(struct KernelMQ_Info *kinfo, const struct multiboot_tag_basic_meminfo *const tag) { + kinfo->mem_lower_base = KERNELMQ_INFO_MEM_LOWER_BASE; + kinfo->mem_lower_size = tag->mem_lower * 1024; + kinfo->mem_lower_limit = kinfo->mem_lower_base + kinfo->mem_lower_size - 1; + + kinfo->mem_upper_base = KERNELMQ_INFO_MEM_UPPER_BASE; + kinfo->mem_upper_size = tag->mem_upper * 1024; + kinfo->mem_upper_limit = kinfo->mem_upper_base + kinfo->mem_upper_size - 1; + kprintf("mem_lower = %uKB, mem_upper = %uKB\n", tag->mem_lower, tag->mem_upper); + + return 1; } -void print_multiboot_tag_mmap(struct KernelMQ_Info *kinfo, const struct multiboot_tag_mmap *const tag) +unsigned char print_multiboot_tag_mmap(struct KernelMQ_Info *kinfo, const struct multiboot_tag_mmap *const tag) { kprintf("Memory map:\n"); @@ -136,6 +182,20 @@ void print_multiboot_tag_mmap(struct KernelMQ_Info *kinfo, const struct multiboo (unsigned char*)mmap < (unsigned char*)tag + tag->size; mmap = (multiboot_memory_map_t*)((unsigned long) mmap + tag->entry_size) ) { + if (kinfo->areas_count >= KERNELMQ_INFO_AREAS_MAX) { + return 0; + } + + struct KernelMQ_Info_Area *area = &kinfo->areas[kinfo->areas_count]; + + area->base = mmap->addr; + area->size = mmap->len; + area->limit = area->base + area->size - 1; + + area->is_available = mmap->type == MULTIBOOT_MEMORY_AVAILABLE; + + ++kinfo->areas_count; + kprintf( " base_addr = 0x%x%x, length = 0x%x%x, type = 0x%x\n", (unsigned)(mmap->addr >> 32), @@ -145,4 +205,6 @@ void print_multiboot_tag_mmap(struct KernelMQ_Info *kinfo, const struct multiboo (unsigned)mmap->type ); } + + return 1; } diff --git a/include/kernelmq/info.h b/include/kernelmq/info.h index adebbb4..b1b97f7 100644 --- a/include/kernelmq/info.h +++ b/include/kernelmq/info.h @@ -24,9 +24,9 @@ struct KernelMQ_Info_Module { }; struct KernelMQ_Info_Area { - unsigned long base; - unsigned long size; - unsigned long limit; + unsigned long long base; + unsigned long long size; + unsigned long long limit; unsigned char is_available; }; diff --git a/include/kernelmq/stdlib.h b/include/kernelmq/stdlib.h index 818f0ca..1632d0a 100644 --- a/include/kernelmq/stdlib.h +++ b/include/kernelmq/stdlib.h @@ -5,8 +5,12 @@ extern "C" { #endif -void kmemset(void *buffer, unsigned char value, unsigned int size); +void kmemset(void *buffer, unsigned char value, unsigned long size); + unsigned int kstrlen(const char *s); + +char *kstrncpy(char *dest, const char *src, unsigned long length); + void kitoa(char *buf, int base, int d); #ifdef __cplusplus diff --git a/libk/Makefile b/libk/Makefile index 570c662..e27b89e 100644 --- a/libk/Makefile +++ b/libk/Makefile @@ -5,7 +5,7 @@ CFLAGS = -std=gnu99 -ffreestanding -nostdinc -fno-builtin -fno-stack-protector - OUTPUT = libk.a -OBJS = memset.o strlen.o itoa.o +OBJS = memset.o strlen.o itoa.o strncpy.o all: $(OUTPUT) diff --git a/libk/memset.c b/libk/memset.c index 2fc3da7..2b13215 100644 --- a/libk/memset.c +++ b/libk/memset.c @@ -1,8 +1,8 @@ -void kmemset(void *const buffer, const unsigned char value, const unsigned int size) +void kmemset(void *const buffer, const unsigned char value, const unsigned long size) { unsigned char *const s = buffer; - for (unsigned int i = 0; i < size; ++i) { + for (unsigned long i = 0; i < size; ++i) { s[i] = value; } } diff --git a/libk/strncpy.c b/libk/strncpy.c new file mode 100644 index 0000000..85dd1eb --- /dev/null +++ b/libk/strncpy.c @@ -0,0 +1,10 @@ +char *kstrncpy(char *const dest, const char *const src, const unsigned long length) +{ + for (unsigned long i = 0; i < length; ++i) { + dest[i] = src[i]; + } + + dest[length] = 0; + + return dest; +}