diff --git a/hermit/arch/x86/loader/entry.asm b/hermit/arch/x86/loader/entry.asm index 3babb7afd..2d99a6f36 100644 --- a/hermit/arch/x86/loader/entry.asm +++ b/hermit/arch/x86/loader/entry.asm @@ -42,6 +42,7 @@ extern kernel_end SECTION .mboot global start start: + cli ; avoid any interrupt jmp stublet ; This part MUST be 4 byte aligned, so we solve that issue using 'ALIGN 4'. @@ -74,7 +75,7 @@ GDT64: ; Global Descriptor Table (64-bit). dw 0 ; Limit (low). dw 0 ; Base (low). db 0 ; Base (middle) - db 10011000b ; Access. + db 10011010b ; Access. db 00100000b ; Granularity. db 0 ; Base (high). .Data: equ $ - GDT64 ; The data descriptor. diff --git a/hermit/arch/x86/loader/main.c b/hermit/arch/x86/loader/main.c index 8a9dc799b..fa0dc278e 100644 --- a/hermit/arch/x86/loader/main.c +++ b/hermit/arch/x86/loader/main.c @@ -32,6 +32,8 @@ #include #include +#define HALT asm volatile ("hlt") + /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. @@ -123,22 +125,32 @@ void main(void) case ELF_PT_LOAD: { // load program segment size_t viraddr = prog_header->virt_addr; size_t phyaddr = prog_header->offset + (size_t)header; + const size_t displacement = 0x200000ULL - (phyaddr & 0x1FFFFFULL); uint32_t npages = (prog_header->file_size >> PAGE_BITS); if (prog_header->file_size & (PAGE_SIZE-1)) npages++; - kprintf("Map %u pages from physical start address 0x%zx linear to 0x%zx\n", npages, phyaddr, viraddr); - int ret = page_map(viraddr, phyaddr, npages, PG_GLOBAL|PG_RW); + kprintf("Map %u pages from physical start address 0x%zx linear to 0x%zx\n", npages + (displacement >> PAGE_BITS), phyaddr, viraddr); + int ret = page_map(viraddr, phyaddr, npages + (displacement >> PAGE_BITS), PG_GLOBAL|PG_RW); if (ret) goto failed; + phyaddr += displacement; *((uint64_t*) (viraddr + 0x08)) = phyaddr; // physical start address - *((uint32_t*) (viraddr + 0x1C)) = 0; // apicid; *((uint32_t*) (viraddr + 0x24)) = 1; // number of used cpus *((uint32_t*) (viraddr + 0x30)) = 0; // apicid *((uint64_t*) (viraddr + 0x38)) = prog_header->file_size; *((uint32_t*) (viraddr + 0x60)) = 1; // numa nodes + + // 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)) + *((uint8_t*) va) = *((uint8_t*) (va-displacement)); + + kprintf("Remap %u pages from physical start address 0x%zx linear to 0x%zx\n", npages, phyaddr, viraddr); + ret = page_map(viraddr, phyaddr, npages, PG_GLOBAL|PG_RW); + if (ret) + goto failed; } break; case ELF_PT_GNU_STACK: // Indicates stack executability => nothing todo @@ -153,11 +165,11 @@ void main(void) asm volatile ("jmp *%0" :: "r"(header->entry) : "memory"); // we should never reach this point - while(1); + while(1) { HALT; } failed: kputs("Upps, kernel panic!\n"); - while(1); + while(1) { HALT; } invalid: kprintf("Invalid executable!\n"); @@ -167,5 +179,5 @@ invalid: kprintf("elf ident class 0x%x\n", (uint32_t) header->ident._class); kprintf("elf identdata 0x%x\n", header->ident.data); kprintf("program entry point 0x%lx\n", (size_t) header->entry); - while(1); + while(1) { HALT; } } diff --git a/hermit/arch/x86/loader/page.c b/hermit/arch/x86/loader/page.c index 39eb54265..e316aae08 100644 --- a/hermit/arch/x86/loader/page.c +++ b/hermit/arch/x86/loader/page.c @@ -209,13 +209,16 @@ int page_init(void) // we need only the program header of the ELF file for(int i=0; imods_count; i++) { addr = mmodule[i].mod_start; - //npages = PAGE_FLOOR(mmodule[i].mod_end - mmodule[i].mod_start) >> PAGE_BITS; + npages = PAGE_FLOOR(mmodule[i].mod_end - mmodule[i].mod_start) >> PAGE_BITS; ret = page_map(addr, addr, 1 /*npages*/, PG_GLOBAL); kprintf("Map first page of module %d at 0x%lx (ret %d)\n", i, addr, ret); + kprintf("Module %d consists %zd\n", i, npages); } } } + // add space for the migration of the elf file + first_page += 0x200000; kprintf("Page pool starts at 0x%zx\n", first_page); return 0;