diff --git a/src/kernel/entry.c b/src/kernel/entry.c index 97dff272..4f440723 100644 --- a/src/kernel/entry.c +++ b/src/kernel/entry.c @@ -245,6 +245,7 @@ __attribute__((noinline)) void pongo_entry_cached() { default: // >4 case BOOT_FLAG_RAW: // 4 + case BOOT_FLAG_M1N1: // 3 break; case BOOT_FLAG_HOOK: // 2 @@ -291,7 +292,7 @@ __attribute__((noinline)) void pongo_entry_cached() */ extern void set_exception_stack_core0(); extern void lowlevel_set_identity(void); -extern _Noreturn void jump_to_image_extended(uint64_t image, uint64_t args, uint64_t tramp, uint64_t original_image); +extern _Noreturn void jump_to_image_extended(void *image, void *args, void *tramp, void *original_image); extern uint64_t gPongoSlide; _Noreturn void pongo_entry(uint64_t *kernel_args, void *entryp, void (*exit_to_el1_image)(void *boot_args, void *boot_entry_point, void *trampoline)) @@ -308,23 +309,32 @@ _Noreturn void pongo_entry(uint64_t *kernel_args, void *entryp, void (*exit_to_e set_exception_stack_core0(); gFramebuffer = (uint32_t*)gBootArgs->Video.v_baseAddr; lowlevel_cleanup(); - if(gBootFlag == BOOT_FLAG_RAW) + + // Unused space above kernel static area + void *boot_tramp = (void*)((gTopOfKernelData + 0x3fffULL) & ~0x3fffULL); + if(gBootFlag == BOOT_FLAG_RAW || gBootFlag == BOOT_FLAG_M1N1) { // We're in EL1 here, but we might need to go back to EL3 - uint64_t pfr0; - __asm__ volatile("mrs %0, id_aa64pfr0_el1" : "=r"(pfr0)); - if((pfr0 & 0xf000) != 0) + if((__builtin_arm_rsr64("id_aa64pfr0_el1") & 0xf000) != 0) { __asm__ volatile("smc 0"); // elevate to EL3 } + uint64_t entryOff = 0x800; + if(gBootFlag == BOOT_FLAG_RAW) + { + boot_tramp = NULL; + entryOff = 0; + } // XXX: We should really replace loader_xfer_recv_data with something dedicated here. - jump_to_image_extended(((uint64_t)loader_xfer_recv_data) - kCacheableView + 0x800000000, (uint64_t)gBootArgs, 0, (uint64_t)gEntryPoint); + void *image = (void*)((uint64_t)loader_xfer_recv_data - kCacheableView + 0x800000000 + entryOff); + jump_to_image_extended(image, gBootArgs, boot_tramp, gEntryPoint); } else { xnu_boot(); - exit_to_el1_image(gBootArgs, gEntryPoint, (void*)((gTopOfKernelData + 0x3fffULL) & ~0x3fffULL)); + exit_to_el1_image(gBootArgs, gEntryPoint, boot_tramp); } + screen_puts("didn't boot?!"); while(1) {} diff --git a/src/kernel/main_task.c b/src/kernel/main_task.c index 4787ae12..1c438449 100644 --- a/src/kernel/main_task.c +++ b/src/kernel/main_task.c @@ -38,6 +38,7 @@ void shell_main(); */ uint64_t gBootTimeTicks; +char gFWVersion[256]; void pongo_main_task() { gBootTimeTicks = get_ticks(); @@ -87,6 +88,7 @@ void pongo_main_task() { char *fwversion = dt_get_prop("/chosen", "firmware-version", NULL); iprintf("Booted by: %s\n", fwversion); + strlcpy(gFWVersion, fwversion, 256); strcpy(fwversion, "pongoOS-" PONGO_VERSION); #ifdef __clang__ iprintf("Built with: Clang %s\n", __clang_version__); diff --git a/src/kernel/pongo.h b/src/kernel/pongo.h index 2089377e..d0d61508 100644 --- a/src/kernel/pongo.h +++ b/src/kernel/pongo.h @@ -110,7 +110,7 @@ extern volatile char gBootFlag; #define BOOT_FLAG_DEFAULT 0 #define BOOT_FLAG_HARD 1 #define BOOT_FLAG_HOOK 2 -// 3: Reserved +#define BOOT_FLAG_M1N1 3 #define BOOT_FLAG_RAW 4 typedef uint64_t lock; diff --git a/src/shell/main.c b/src/shell/main.c index 7c897a16..5bea0409 100644 --- a/src/shell/main.c +++ b/src/shell/main.c @@ -46,6 +46,21 @@ void pongo_boot_raw() { task_yield(); } +extern char gFWVersion[256]; +void pongo_boot_m1n1() { + if (!loader_xfer_recv_count) { + iprintf("please upload a raw m1n1.bin before issuing this command\n"); + return; + } + + loader_xfer_recv_count = 0; + char *fwversion = dt_get_prop("/chosen", "firmware-version", NULL); + strlcpy(fwversion, gFWVersion, 256); + + gBootFlag = BOOT_FLAG_M1N1; + task_yield(); +} + void* ramdisk_buf; uint32_t ramdisk_size; @@ -251,6 +266,7 @@ void shell_main() { command_register("ps", "lists current tasks and irq handlers", task_list); command_register("ramdisk", "loads a ramdisk for xnu", ramdisk_cmd); command_register("bootr", "boot raw image", pongo_boot_raw); + command_register("bootm", "boots m1n1", pongo_boot_m1n1); command_register("spin", "spins 1 second", pongo_spin); command_register("md8", "memory dump", md8_cmd); command_register("peek", "32bit mem read", peek_cmd);