From 70bb496388f8acde7ce517fdc1f4badddd9cd3f0 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Tue, 8 May 2018 16:51:43 +0200 Subject: [PATCH] Refactor stage1's and stage2's main.c files --- fusee/fusee-primary/src/chainloader.c | 5 +- fusee/fusee-primary/src/chainloader.h | 3 +- fusee/fusee-primary/src/main.c | 62 ++++++++----- fusee/fusee-secondary/src/chainloader.c | 5 +- fusee/fusee-secondary/src/chainloader.h | 3 +- fusee/fusee-secondary/src/main.c | 110 +++++++++++++++--------- 6 files changed, 121 insertions(+), 67 deletions(-) diff --git a/fusee/fusee-primary/src/chainloader.c b/fusee/fusee-primary/src/chainloader.c index 4caa70792..6890ff4ff 100644 --- a/fusee/fusee-primary/src/chainloader.c +++ b/fusee/fusee-primary/src/chainloader.c @@ -1,5 +1,6 @@ #include "chainloader.h" +int g_chainloader_argc = 0; char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0}; chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES] = {0}; /* keep them sorted */ size_t g_chainloader_num_entries = 0; @@ -24,11 +25,11 @@ static void *xmemmove(void *dst, const void *src, size_t len) return dst; } -void relocate_and_chainload_main(int argc) { +void relocate_and_chainload_main(void) { for(size_t i = 0; i < g_chainloader_num_entries; i++) { chainloader_entry_t *entry = &g_chainloader_entries[i]; xmemmove((void *)entry->load_address, (const void *)entry->src_address, entry->size); } - ((void (*)(int, void *))g_chainloader_entrypoint)(argc, g_chainloader_arg_data); + ((void (*)(int, void *))g_chainloader_entrypoint)(g_chainloader_argc, g_chainloader_arg_data); } diff --git a/fusee/fusee-primary/src/chainloader.h b/fusee/fusee-primary/src/chainloader.h index 9d9e44347..43fe602a2 100644 --- a/fusee/fusee-primary/src/chainloader.h +++ b/fusee/fusee-primary/src/chainloader.h @@ -14,12 +14,13 @@ typedef struct chainloader_entry_t { size_t num; } chainloader_entry_t; +extern int g_chainloader_argc; extern chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES]; /* keep them sorted */ extern size_t g_chainloader_num_entries; extern uintptr_t g_chainloader_entrypoint; extern char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE]; -void relocate_and_chainload(int argc); +void relocate_and_chainload(void); #endif diff --git a/fusee/fusee-primary/src/main.c b/fusee/fusee-primary/src/main.c index 18730024b..4234b1672 100644 --- a/fusee/fusee-primary/src/main.c +++ b/fusee/fusee-primary/src/main.c @@ -10,6 +10,9 @@ #include "lib/printk.h" #include "display/video_fb.h" +extern void (*__program_exit_callback)(int rc); + +static void *g_framebuffer; static char g_bct0_buffer[BCTO_MAX_SIZE]; #define DEFAULT_BCT0_FOR_DEBUG \ @@ -19,7 +22,7 @@ static char g_bct0_buffer[BCTO_MAX_SIZE]; "stage2_addr = 0xF0000000\n"\ "stage2_entrypoint = 0xF0000000\n" -const char *load_config(void) { +static const char *load_config(void) { if (!read_sd_file(g_bct0_buffer, BCTO_MAX_SIZE, "BCT.ini")) { printk("Failed to read BCT0 from SD!\n"); printk("[DEBUG] Using default BCT0!\n"); @@ -45,7 +48,7 @@ const char *load_config(void) { return bct0; } -void load_sbk(void) { +static void load_sbk(void) { uint32_t sbk[0x4]; /* Load the SBK into the security engine, if relevant. */ memcpy(sbk, (void *)get_fuse_chip_regs()->FUSE_PRIVATE_KEY, 0x10); @@ -57,32 +60,54 @@ void load_sbk(void) { } } -int main(void) { - const char *bct0; - void *lfb_base = (void *)0xC0000000; - const char *stage2_path; - stage2_args_t stage2_args = {0}; +static void setup_env(void) { + g_framebuffer = (void *)0xC0000000; /* Initialize DRAM. */ /* TODO: What can be stripped out to make this minimal? */ nx_hwinit(); + /* Try to load the SBK into the security engine, if possible. */ + /* TODO: Should this be done later? */ + load_sbk(); + /* Zero-fill the framebuffer and register it as printk provider. */ - video_init(lfb_base); + video_init(g_framebuffer); /* Initialize the display. */ display_init(); /* Set the framebuffer. */ - display_init_framebuffer(lfb_base); + display_init_framebuffer(g_framebuffer); /* Turn on the backlight after initializing the lfb */ /* to avoid flickering. */ display_enable_backlight(true); +} + +static void cleanup_env(void) { + f_unmount(""); + + display_enable_backlight(false); + display_end(); +} + +static void exit_callback(int rc) { + (void)rc; + relocate_and_chainload(); +} + +int main(void) { + const char *bct0; + const char *stage2_path; + stage2_args_t stage2_args = {0}; + + /* Initialize the display, console, etc. */ + setup_env(); /* Say hello. */ printk("Welcome to Atmosph\xe8re Fus\xe9" "e!\n"); - printk("Using color linear framebuffer at 0x%p!\n", lfb_base); + printk("Using color linear framebuffer at 0x%p!\n", g_framebuffer); #ifndef I_KNOW_WHAT_I_AM_DOING #error "Fusee is a work-in-progress bootloader, and is not ready for usage yet. If you want to play with it anyway, please #define I_KNOW_WHAT_I_AM_DOING -- and recognize that we will be unable to provide support until it is ready for general usage :)" @@ -92,29 +117,24 @@ int main(void) { generic_panic(); #endif - /* Try to load the SBK into the security engine, if possible. */ - /* TODO: Should this be done later? */ - load_sbk(); - /* Load the BCT0 configuration ini off of the SD. */ bct0 = load_config(); /* Load the loader payload into DRAM. */ load_stage2(bct0); - f_unmount(""); - - display_enable_backlight(false); - display_end(); - /* Setup argument data. */ stage2_path = stage2_get_program_path(); stage2_args.version = 0; strcpy(stage2_args.bct0, bct0); + g_chainloader_argc = 2; strcpy(g_chainloader_arg_data, stage2_path); memcpy(g_chainloader_arg_data + strlen(stage2_path) + 1, &stage2_args, sizeof(stage2_args_t)); - /* Jump to Stage 2. */ - relocate_and_chainload(STAGE2_ARGC); + /* Deinitialize the display, console, etc. */ + cleanup_env(); + + /* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, jump to Stage2. */ + __program_exit_callback = exit_callback; return 0; } diff --git a/fusee/fusee-secondary/src/chainloader.c b/fusee/fusee-secondary/src/chainloader.c index 4caa70792..6890ff4ff 100644 --- a/fusee/fusee-secondary/src/chainloader.c +++ b/fusee/fusee-secondary/src/chainloader.c @@ -1,5 +1,6 @@ #include "chainloader.h" +int g_chainloader_argc = 0; char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE] = {0}; chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES] = {0}; /* keep them sorted */ size_t g_chainloader_num_entries = 0; @@ -24,11 +25,11 @@ static void *xmemmove(void *dst, const void *src, size_t len) return dst; } -void relocate_and_chainload_main(int argc) { +void relocate_and_chainload_main(void) { for(size_t i = 0; i < g_chainloader_num_entries; i++) { chainloader_entry_t *entry = &g_chainloader_entries[i]; xmemmove((void *)entry->load_address, (const void *)entry->src_address, entry->size); } - ((void (*)(int, void *))g_chainloader_entrypoint)(argc, g_chainloader_arg_data); + ((void (*)(int, void *))g_chainloader_entrypoint)(g_chainloader_argc, g_chainloader_arg_data); } diff --git a/fusee/fusee-secondary/src/chainloader.h b/fusee/fusee-secondary/src/chainloader.h index 9d9e44347..43fe602a2 100644 --- a/fusee/fusee-secondary/src/chainloader.h +++ b/fusee/fusee-secondary/src/chainloader.h @@ -14,12 +14,13 @@ typedef struct chainloader_entry_t { size_t num; } chainloader_entry_t; +extern int g_chainloader_argc; extern chainloader_entry_t g_chainloader_entries[CHAINLOADER_MAX_ENTRIES]; /* keep them sorted */ extern size_t g_chainloader_num_entries; extern uintptr_t g_chainloader_entrypoint; extern char g_chainloader_arg_data[CHAINLOADER_ARG_DATA_MAX_SIZE]; -void relocate_and_chainload(int argc); +void relocate_and_chainload(void); #endif diff --git a/fusee/fusee-secondary/src/main.c b/fusee/fusee-secondary/src/main.c index b2646a59a..7e791c84e 100644 --- a/fusee/fusee-secondary/src/main.c +++ b/fusee/fusee-secondary/src/main.c @@ -13,32 +13,71 @@ #include "fs_dev.h" #include "display/video_fb.h" +extern void (*__program_exit_callback)(int rc); + static stage2_args_t *g_stage2_args; +static void *g_framebuffer; +static bool g_do_nxboot; + +static void setup_env(void) { + g_framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE); + + /* Note: the framebuffer needs to be >= 0xC0000000, this is fine because of where our heap is. */ + if (g_framebuffer == NULL) { + generic_panic(); + } + + /* Zero-fill the framebuffer and set the console up. */ + console_init(g_framebuffer); + + /* Initialize the display. */ + display_init(); + + /* Set the framebuffer. */ + display_init_framebuffer(g_framebuffer); + + /* Turn on the backlight after initializing the lfb */ + /* to avoid flickering. */ + display_enable_backlight(true); + + initialize_sd(); + if(fsdev_mount_all() == -1) { + perror("Failed to mount at least one FAT parition"); + generic_panic(); + } + fsdev_set_default_device("sdmc"); + + /* TODO: What other hardware init should we do here? */ +} + +static void cleanup_env(void) { + /* Unmount everything (this causes all open files to be flushed and closed) */ + fsdev_unmount_all(); + + /* Deinitialize the framebuffer and display */ + /*display_enable_backlight(false); + display_end(); + free(g_framebuffer); + g_framebuffer = NULL;*/ +} + +static void exit_callback(int rc) { + (void)rc; + if (g_do_nxboot) { + /* TODO: halt */ + } else { + relocate_and_chainload(); + } +} /* Allow for main(int argc, void **argv) signature. */ #pragma GCC diagnostic ignored "-Wmain" int main(int argc, void **argv) { loader_ctx_t *loader_ctx = get_loader_ctx(); - void *framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE); - /* Note: the framebuffer needs to be >= 0xC0000000, this is fine because of where our heap is. */ - if (framebuffer == NULL) { - generic_panic(); - } - - /* Zero-fill the framebuffer and set the console up. */ - console_init(framebuffer); - - /* Initialize the display. */ - display_init(); - - /* Set the framebuffer. */ - display_init_framebuffer(framebuffer); - - /* Turn on the backlight after initializing the lfb */ - /* to avoid flickering. */ - display_enable_backlight(true); + /* Initialize the display, console, FS, etc. */ + setup_env(); if (argc != STAGE2_ARGC) { printf("Error: Invalid argc (expected %d, got %d)!\n", STAGE2_ARGC, argc); @@ -47,18 +86,10 @@ int main(int argc, void **argv) { g_stage2_args = (stage2_args_t *)argv[STAGE2_ARGV_ARGUMENT_STRUCT]; if(g_stage2_args->version != 0) { - printf("Error: Incorrect Stage2 args version (expected %lu, got %lu)!\n", 0lu, g_stage2_args->version); + printf("Error: Incorrect Stage2 args version (expected %lu, got %lu)!\n", 0ul, g_stage2_args->version); generic_panic(); } - initialize_sd(); - if(fsdev_mount_all() == -1) { - perror("Failed to mount at least one FAT parition"); - } - fsdev_set_default_device("sdmc"); - - /* TODO: What other hardware init should we do here? */ - printf(u8"Welcome to Atmosphère Fusée Stage 2!\n"); printf("Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]); @@ -67,22 +98,21 @@ int main(int argc, void **argv) { printf("Loaded payloads!\n"); - /* Unmount everything (this causes all open files to be flushed and closed) */ - fsdev_unmount_all(); - - /* Deinitialize the framebuffer and display */ - /*display_enable_backlight(false); - display_end(); - free(framebuffer);*/ - - if (loader_ctx->chainload_entrypoint != 0) { + g_do_nxboot = loader_ctx->chainload_entrypoint == 0; + if (g_do_nxboot) { + nxboot_main(); + } else { /* TODO: What else do we want to do in terms of argc/argv? */ const char *path = get_loader_ctx()->file_paths[get_loader_ctx()->file_id_of_entrypoint]; + g_chainloader_argc = 1; strcpy(g_chainloader_arg_data, path); - relocate_and_chainload(1); - } else { - /* If we don't have a chainload entrypoint set, we're booting Horizon. */ - nxboot_main(); } + + /* Deinitialize the display, console, FS, etc. */ + cleanup_env(); + + /* Finally, after the cleanup routines (__libc_fini_array, etc.) are called, chainload or halt ourselves. */ + __program_exit_callback = exit_callback; + return 0; }