#include #include #include #include #include #include #include #include #include #include #include "i.h" typedef int64_t INTN; typedef int64_t INT64; typedef int32_t INT32; typedef uint64_t UINTN; typedef uint64_t UINT64; typedef uint32_t UINT32; typedef uint16_t UINT16; typedef uint8_t UINT8; typedef void VOID; typedef bool BOOLEAN; typedef char CHAR8; #define IN #define OUT #define STATIC static #define CONST const #define MEMORY_SIZE (1 * 1024 * 1024) STATIC VOID * MapMemory ( IN INTN Fd, IN UINT64 Length, IN INTN Prot, IN INTN Flags ) { VOID *Base = (VOID *) 0x40000000UL; Base = mmap ((void *) Base, Length, Prot, Flags, Fd, 0); return Base; } int ReadFile ( IN CHAR8 *FileName, IN VOID *Buffer ) { int Fd; VOID *Res; UINTN FileSize; Fd = open (FileName, O_RDWR); if (Fd < 0) { fprintf(stderr, "Couldn't open '%s': %s\n", FileName, strerror (errno)); return -1; } FileSize = lseek (Fd, 0, SEEK_END); if (FileSize == (UINTN) -1) { fprintf(stderr, "Couldn't size '%s': %s\n", FileName, strerror (errno)); return -1; } lseek (Fd, 0, SEEK_SET); if (read(Fd, Buffer, FileSize) != FileSize) { fprintf(stderr, "Couldn't read '%s': %s\n", FileName, strerror (errno)); return -1; } close (Fd); return 0; } int main ( IN int Argc, IN char **Argv ) { VOID *MemoryBase; char *FdName; int Status; fns f; void (*entry)(fns *fns); f.puts = puts; f.sjmp = setjmp; f.ljmp = longjmp; MemoryBase = MapMemory (0, MEMORY_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS ); if (MemoryBase == MAP_FAILED) { fprintf(stderr, "Couldn't allocate memoru\n"); return -1; } if (Argc > 1) { FdName = Argv[1]; } else { FdName = "k.bin"; } Status = ReadFile (FdName, MemoryBase); if (Status != 0) { return -1; } /* * * This is important on real E2K Linux. longjmp2 will fail if the * source and dest VM regions have non-matching attributes. * * Real system: prot must be PROT_EXEC | PROT_READ, or longjmp2 * will kill the task. * * Qemu: works fine with PROT_READ | PROT_WRITE | PROT_EXEC. */ mprotect (MemoryBase, MEMORY_SIZE, PROT_EXEC | PROT_READ); entry = MemoryBase; printf("Calling %p\n", entry); entry (&f); printf("Back from %p\n", entry); return 0; }