Skip to content

Commit

Permalink
Add m1n1 boot support
Browse files Browse the repository at this point in the history
Entry ABI:

x0 = Kernel Boot args
CurrentEL = Highest EL
Entry point is 0x800 into the image.

Link: https://github.com/asdfugil/m1n1-idevice
  • Loading branch information
asdfugil authored and Siguza committed Nov 10, 2024
1 parent 455eabb commit e1313a7
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 8 deletions.
24 changes: 17 additions & 7 deletions src/kernel/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand All @@ -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)
{}
Expand Down
2 changes: 2 additions & 0 deletions src/kernel/main_task.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void shell_main();
*/

uint64_t gBootTimeTicks;
char gFWVersion[256];
void pongo_main_task() {
gBootTimeTicks = get_ticks();

Expand Down Expand Up @@ -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__);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/pongo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
16 changes: 16 additions & 0 deletions src/shell/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit e1313a7

Please sign in to comment.