diff --git a/.travis.yml b/.travis.yml index 7f6157afc..9708ef723 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,8 +38,8 @@ env: - HERMIT_MEM="512M" - HERMIT_KVM="0" - HERMIT_VERBOSE="1" - - CFLAGS_FOR_TARGET="-m64 -mtls-direct-seg-refs -O2 -ftree-vectorize" - - GOFLAGS_FOR_TARGET"=-m64 -mtls-direct-seg-refs -O2 -ftree-vectorize" - - FCFLAGS_FOR_TARGET"=-m64 -mtls-direct-seg-refs -O2 -ftree-vectorize" - - FFLAGS_FOR_TARGET="-m64 -mtls-direct-seg-refs -O2 -ftree-vectorize" - - CXXFLAGS_FOR_TARGET="-m64 -mtls-direct-seg-refs -O2 -ftree-vectorize" + - CFLAGS_FOR_TARGET="-m64 -O2 -ftree-vectorize" + - GOFLAGS_FOR_TARGET"=-m64 -O2 -ftree-vectorize" + - FCFLAGS_FOR_TARGET"=-m64 -O2 -ftree-vectorize" + - FFLAGS_FOR_TARGET="-m64 -O2 -ftree-vectorize" + - CXXFLAGS_FOR_TARGET="-m64 -O2 -ftree-vectorize" diff --git a/README.md b/README.md index cd42ae4a0..42b2542d7 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ An introduction to this execution mode is provided in section [Building and test Be sure, that the option `CONFIG_HERMIT_CORE` in `Processor type and features` is enabled. 2. Install the Linux kernel and its initial ramdisk on your system (see descriptions of your Linux distribution). We recommend to disable Linux NO_HZ feature by setting the kernel parameter `nohz=off`. -3. After a reboot of the system, register the HermitCore loader at your system with following command: `echo ":hermit:M:7:\\x42::/path2proyxy/proxy:" > /proc/sys/fs/binfmt_misc/register`, in which `path2proxy` defines the path to the loader. +3. After a reboot of the system, register the HermitCore loader at your system with following command: `sudo -c sh 'echo ":hermit:M:7:\\x42::/path2proyxy/proxy:" > /proc/sys/fs/binfmt_misc/register'`, in which `path2proxy` defines the path to the loader. You find the loader `proxy` after building the HermiCore sources in the subdirectory `tools` of the directory, which contains this *README*. 4. The IP device between HermitCore and Linux currently does not support IPv6. Consequently, disable IPv6 by adding following line to `/etc/sysctl.conf`: `net.ipv6.conf.mmnif.disable_ipv6 = 1`. diff --git a/arch/x86/kernel/processor.c b/arch/x86/kernel/processor.c index ac37161fd..319192da0 100644 --- a/arch/x86/kernel/processor.c +++ b/arch/x86/kernel/processor.c @@ -416,7 +416,7 @@ int cpu_detection(void) { first_time = 1; cpuid(0, &level, &b, &c, &d); - LOG_INFO("cpuid level %d\n", level); + kprintf("cpuid level %d\n", level); a = b = c = d = 0; cpuid(1, &a, &b, &cpu_info.feature2, &cpu_info.feature1); @@ -438,7 +438,7 @@ int cpu_detection(void) { } if (first_time) { - LOG_INFO("Paging features: %s%s%s%s%s%s%s%s\n", + kprintf("Paging features: %s%s%s%s%s%s%s%s\n", (cpu_info.feature1 & CPU_FEATURE_PSE) ? "PSE (2/4Mb) " : "", (cpu_info.feature1 & CPU_FEATURE_PAE) ? "PAE " : "", (cpu_info.feature1 & CPU_FEATURE_PGE) ? "PGE " : "", @@ -448,10 +448,10 @@ int cpu_detection(void) { (cpu_info.feature3 & CPU_FEATURE_1GBHP) ? "PSE (1Gb) " : "", (cpu_info.feature3 & CPU_FEATURE_LM) ? "LM" : ""); - LOG_INFO("Physical adress-width: %u bits\n", cpu_info.addr_width & 0xff); - LOG_INFO("Linear adress-width: %u bits\n", (cpu_info.addr_width >> 8) & 0xff); - LOG_INFO("Sysenter instruction: %s\n", (cpu_info.feature1 & CPU_FEATURE_SEP) ? "available" : "unavailable"); - LOG_INFO("Syscall instruction: %s\n", (cpu_info.feature3 & CPU_FEATURE_SYSCALL) ? "available" : "unavailable"); + kprintf("Physical adress-width: %u bits\n", cpu_info.addr_width & 0xff); + kprintf("Linear adress-width: %u bits\n", (cpu_info.addr_width >> 8) & 0xff); + kprintf("Sysenter instruction: %s\n", (cpu_info.feature1 & CPU_FEATURE_SEP) ? "available" : "unavailable"); + kprintf("Syscall instruction: %s\n", (cpu_info.feature3 & CPU_FEATURE_SYSCALL) ? "available" : "unavailable"); } //TODO: add check for SMEP and SMAP @@ -509,7 +509,7 @@ int cpu_detection(void) { xcr0 |= 0xE0; xsetbv(0, xcr0); - LOG_INFO("Set XCR0 to 0x%llx\n", xgetbv(0)); + kprintf("Set XCR0 to 0x%llx\n", xgetbv(0)); } // libos => currently no support of syscalls @@ -520,7 +520,7 @@ int cpu_detection(void) { wrmsr(MSR_LSTAR, (size_t) &isrsyscall); // clear IF flag during an interrupt wrmsr(MSR_SYSCALL_MASK, EFLAGS_TF|EFLAGS_DF|EFLAGS_IF|EFLAGS_AC|EFLAGS_NT); - } else LOG_INFO("Processor doesn't support syscalls\n"); + } else kprintf("Processor doesn't support syscalls\n"); #endif if (has_nx()) diff --git a/arch/x86/loader/main.c b/arch/x86/loader/main.c index 9f783f485..97cc5e28a 100644 --- a/arch/x86/loader/main.c +++ b/arch/x86/loader/main.c @@ -43,10 +43,48 @@ extern const void kernel_end; extern const void bss_start; extern const void bss_end; +static int load_code(size_t viraddr, size_t phyaddr, size_t limit, uint32_t file_size) +{ + const size_t displacement = 0x200000ULL - (phyaddr & 0x1FFFFFULL); + + kprintf("Found program segment at 0x%zx-0x%zx (viraddr 0x%zx-0x%zx)\n", phyaddr, phyaddr+file_size-1, viraddr, viraddr+file_size-1); + + uint32_t npages = (file_size >> PAGE_BITS); + if (file_size & (PAGE_SIZE-1)) + npages++; + + 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) + return -1; + + phyaddr += displacement; + *((uint64_t*) (viraddr + 0x08)) = phyaddr; // physical start address + *((uint64_t*) (viraddr + 0x10)) = limit; // physical limit + *((uint32_t*) (viraddr + 0x24)) = 1; // number of used cpus + *((uint32_t*) (viraddr + 0x30)) = 0; // apicid + *((uint64_t*) (viraddr + 0x38)) = 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) + return -1; + + return 0; +} + void main(void) { size_t limit = 0; + size_t viraddr = 0; + size_t phyaddr = 0; elf_header_t* header = NULL; + uint32_t file_size = 0; // initialize .bss section memset((void*)&bss_start, 0x00, ((size_t) &bss_end - (size_t) &bss_start)); @@ -128,35 +166,11 @@ void main(void) switch(prog_header->type) { 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 + (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 - *((uint64_t*) (viraddr + 0x10)) = limit; // physical limit - *((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; + if (!viraddr) + viraddr = prog_header->virt_addr; + if (!phyaddr) + phyaddr = prog_header->offset + (size_t)header; + file_size = prog_header->virt_addr + PAGE_FLOOR(prog_header->file_size) - viraddr; } break; case ELF_PT_GNU_STACK: // Indicates stack executability => nothing to do @@ -168,6 +182,9 @@ void main(void) } } + if (BUILTIN_EXPECT(load_code(viraddr, phyaddr, limit, file_size), 0)) + goto failed; + kprintf("Entry point: 0x%zx\n", header->entry); // jump to the HermitCore app asm volatile ("jmp *%0" :: "r"(header->entry), "d"(mb_info) : "memory");