diff --git a/arch/x86/include/asm/multiboot.h b/arch/x86/include/asm/multiboot.h index 53969da12..1745f8db5 100644 --- a/arch/x86/include/asm/multiboot.h +++ b/arch/x86/include/asm/multiboot.h @@ -144,5 +144,7 @@ typedef struct multiboot_mod_list multiboot_module_t; /// Pointer to multiboot structure /// This pointer is declared at set by entry.asm extern const multiboot_info_t* const mb_info; +extern char* cmdline; +extern size_t cmdsize; #endif diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index f3b6ce540..e68e2d481 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -70,6 +70,8 @@ align 4 global uhyve global image_size global uartport + global cmdline + global cmdsize base dq 0 limit dq 0 cpu_freq dd 0 @@ -95,6 +97,8 @@ align 4 hbmem_size dq 0 uhyve dd 0 uartport dq 0 + cmdline dq 0 + cmdsize dq 0 ; Bootstrap page tables are used during the initialization. align 4096 diff --git a/arch/x86/kernel/processor.c b/arch/x86/kernel/processor.c index d0bd0f0a8..55f6dbdc1 100644 --- a/arch/x86/kernel/processor.c +++ b/arch/x86/kernel/processor.c @@ -172,10 +172,10 @@ static void fpu_init_xsave(union fpu_state* fpu) static uint32_t get_frequency_from_mbinfo(void) { - if (mb_info && (mb_info->flags & MULTIBOOT_INFO_CMDLINE)) + if (mb_info && (mb_info->flags & MULTIBOOT_INFO_CMDLINE) && (cmdline)) { // search in the command line for cpu frequency - char* found = strstr((char*) (size_t)mb_info->cmdline, "-freq"); + char* found = strstr((char*) (size_t)cmdline, "-freq"); if (!found) return 0; diff --git a/arch/x86/kernel/tasks.c b/arch/x86/kernel/tasks.c index 41ef3cb8b..260e064ee 100644 --- a/arch/x86/kernel/tasks.c +++ b/arch/x86/kernel/tasks.c @@ -106,10 +106,10 @@ int is_proxy(void) return 0; if (!is_single_kernel()) return 1; - if (mb_info && (mb_info->flags & MULTIBOOT_INFO_CMDLINE)) + if (mb_info && (mb_info->flags & MULTIBOOT_INFO_CMDLINE) && (cmdline)) { // search in the command line for the "proxy" hint - char* found = strstr((char*) (size_t) mb_info->cmdline, "-proxy"); + char* found = strstr((char*) (size_t) cmdline, "-proxy"); if (found) return 1; } diff --git a/arch/x86/loader/main.c b/arch/x86/loader/main.c index c14aa5d06..59df480c6 100644 --- a/arch/x86/loader/main.c +++ b/arch/x86/loader/main.c @@ -44,7 +44,7 @@ extern const void bss_start; extern const void bss_end; extern size_t uartport; -static int load_code(size_t viraddr, size_t phyaddr, size_t limit, uint32_t file_size, size_t mem_size) +static int load_code(size_t viraddr, size_t phyaddr, size_t limit, uint32_t file_size, size_t mem_size, size_t cmdline, size_t cmdsize) { const size_t displacement = 0x200000ULL - (phyaddr & 0x1FFFFFULL); @@ -67,6 +67,8 @@ static int load_code(size_t viraddr, size_t phyaddr, size_t limit, uint32_t file *((uint64_t*) (viraddr + 0x38)) = mem_size; *((uint32_t*) (viraddr + 0x60)) = 1; // numa nodes *((uint64_t*) (viraddr + 0x98)) = uartport; + *((uint64_t*) (viraddr + 0xA0)) = cmdline; + *((uint64_t*) (viraddr + 0xA8)) = cmdsize; // move file to a 2 MB boundary for(size_t va = viraddr+(npages << PAGE_BITS)+displacement-sizeof(uint8_t); va >= viraddr+displacement; va-=sizeof(uint8_t)) @@ -88,6 +90,8 @@ void main(void) elf_header_t* header = NULL; uint32_t file_size = 0; size_t mem_size = 0; + size_t cmdline_size = 0; + size_t cmdline = 0; // initialize .bss section memset((void*)&bss_start, 0x00, ((size_t) &bss_end - (size_t) &bss_start)); @@ -97,6 +101,11 @@ void main(void) kprintf("Loader starts at %p and ends at %p\n", &kernel_start, &kernel_end); kprintf("Found mb_info at %p\n", mb_info); + if (mb_info && mb_info->cmdline) { + cmdline = (size_t) mb_info->cmdline; + cmdline_size = strlen(cmdline); + } + page_init(); if (mb_info) { @@ -186,7 +195,7 @@ void main(void) } } - if (BUILTIN_EXPECT(load_code(viraddr, phyaddr, limit, file_size, mem_size), 0)) + if (BUILTIN_EXPECT(load_code(viraddr, phyaddr, limit, file_size, mem_size, cmdline, cmdline_size), 0)) goto failed; kprintf("Entry point: 0x%zx\n", header->entry); diff --git a/arch/x86/mm/memory.c b/arch/x86/mm/memory.c index 8313ddb01..cda906e07 100644 --- a/arch/x86/mm/memory.c +++ b/arch/x86/mm/memory.c @@ -337,9 +337,9 @@ int memory_init(void) if (start_addr < (size_t)mb_info) start_addr = PAGE_FLOOR((size_t)mb_info); - if (mb_info->flags & MULTIBOOT_INFO_CMDLINE) { - if (start_addr < (size_t) mb_info->cmdline+2*PAGE_SIZE) - start_addr = PAGE_FLOOR((size_t) mb_info->cmdline+2*PAGE_SIZE); + if ((mb_info->flags & MULTIBOOT_INFO_CMDLINE) && cmdline) { + if (start_addr < (size_t) cmdline+cmdsize) + start_addr = PAGE_FLOOR((size_t) cmdline+cmdsize); } if (start_addr >= end_addr) diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 6b6d7ce65..a21b16045 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -325,11 +325,16 @@ int page_init(void) LOG_INFO("Detect Go runtime! Consequently, HermitCore zeroed heap.\n"); } - // reserve 2 pages for long cmdline strings - if (mb_info && (((size_t)mb_info->cmdline & PAGE_MASK) != ((size_t) mb_info & PAGE_MASK))) - page_map(((size_t) mb_info->cmdline) & PAGE_MASK, ((size_t) mb_info->cmdline) & PAGE_MASK, 1, PG_GLOBAL|PG_RW|PG_PRESENT); - if (mb_info && ((((size_t)mb_info->cmdline + PAGE_SIZE) & PAGE_MASK) != ((size_t) mb_info & PAGE_MASK))) - page_map(((size_t) mb_info->cmdline + PAGE_SIZE) & PAGE_MASK, ((size_t) mb_info->cmdline + PAGE_SIZE) & PAGE_MASK, 1, PG_GLOBAL|PG_RW|PG_PRESENT); + if (mb_info && (mb_info->flags & MULTIBOOT_INFO_CMDLINE) && (cmdline)) + { + size_t i = 0; + + while(((size_t) cmdline + i) <= ((size_t) cmdline + cmdsize)) + { + page_map(((size_t) cmdline + i) & PAGE_MASK, ((size_t) cmdline + i) & PAGE_MASK, 1, PG_GLOBAL|PG_RW|PG_PRESENT); + i += PAGE_SIZE; + } + } /* Replace default pagefault handler */ irq_uninstall_handler(14); diff --git a/arch/x86/mm/vma.c b/arch/x86/mm/vma.c index cb56aacea..3eb9d78e1 100644 --- a/arch/x86/mm/vma.c +++ b/arch/x86/mm/vma.c @@ -37,11 +37,17 @@ int vma_arch_init(void) if (BUILTIN_EXPECT(ret, 0)) goto out; - if ((mb_info->cmdline & PAGE_MASK) != ((size_t) mb_info & PAGE_MASK)) { - // reserve 2 pages for long cmdline strings - ret = vma_add((size_t)mb_info->cmdline & PAGE_MASK, ((size_t)mb_info->cmdline & PAGE_MASK) + 2*PAGE_SIZE, VMA_READ|VMA_WRITE); - if (BUILTIN_EXPECT(ret, 0)) - goto out; + if ((mb_info->flags & MULTIBOOT_INFO_CMDLINE) && cmdline) { + size_t i = 0; + while(((size_t) cmdline + i) <= ((size_t) cmdline + cmdsize)) + { + if ((((size_t)cmdline + i) & PAGE_MASK) != ((size_t) mb_info & PAGE_MASK)) { + ret = vma_add(((size_t)cmdline + i) & PAGE_MASK, (((size_t)cmdline + i) & PAGE_MASK) + PAGE_SIZE, VMA_READ|VMA_WRITE); + if (BUILTIN_EXPECT(ret, 0)) + goto out; + i += PAGE_SIZE; + } + } } }