From f139f9c56f2e01dccc0e119eebc5f0cf3e8a729a Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Fri, 8 Mar 2019 01:14:43 +0200 Subject: [PATCH] [FSS0] Add Fusee secondary storage parser Using "fss0={sd path}" allows you to parse kips, exosphere and warmboot from a fusee secondary binary. Exosphere and warmboot are overridable if these entries are defined after that. Additionally any extra kip can be loaded as before via kip1={sd path}/* for many or kip1={sd path} for a sigle one Warning: Don't double load core kips like loader, pm, sm and ams_mitm. The result will be a hang. --- Makefile | 2 +- bootloader/hos/fss.c | 127 ++++++++++++++++++++++++++++++++++++ bootloader/hos/fss.h | 24 +++++++ bootloader/hos/hos_config.c | 7 ++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 bootloader/hos/fss.c create mode 100644 bootloader/hos/fss.h diff --git a/Makefile b/Makefile index 95744e3..899a0d8 100755 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ # Horizon. OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ nx_emmc.o \ - hos.o hos_config.o pkg1.o pkg2.o secmon_exo.o sept.o \ + hos.o hos_config.o pkg1.o pkg2.o fss.o secmon_exo.o sept.o \ ) # Libraries. diff --git a/bootloader/hos/fss.c b/bootloader/hos/fss.c new file mode 100644 index 0000000..149e90b --- /dev/null +++ b/bootloader/hos/fss.c @@ -0,0 +1,127 @@ +/* + * Atmosphère Fusée Secondary Storage parser. + * + * Copyright (c) 2019 CTCaer + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "fss.h" +#include "hos.h" +#include "../libs/fatfs/ff.h" +#include "../mem/heap.h" + +#include "../gfx/gfx.h" +#define DPRINTF(...) + +#define FSS0_MAGIC 0x30535346 +#define CNT_TYPE_FSP 0 +#define CNT_TYPE_EXO 1 +#define CNT_TYPE_WBT 2 +#define CNT_TYPE_RBT 3 +#define CNT_TYPE_SP1 4 +#define CNT_TYPE_SP2 5 +#define CNT_TYPE_KIP 6 +#define CNT_TYPE_BMP 7 + +typedef struct _fss_t +{ + u32 magic; + u32 size; + u32 crt0_off; + u32 cnt_off; + u32 cnt_count; + u32 hos_ver; + u32 version; + u32 git_rev; +} fss_t; + +typedef struct _fss_content_t +{ + u32 offset; + u32 size; + u32 type; + u32 rsvd1; + char name[0x10]; +} fss_content_t; + +int parse_fss(launch_ctxt_t *ctxt, const char *value) +{ + FIL fp; + if (f_open(&fp, value, FA_READ) != FR_OK) + return 0; + + void *fss = malloc(f_size(&fp)); + // Read header. + f_read(&fp, fss, 0x400, NULL); + + u32 fss_entry = *(u32 *)(fss + 4); + fss_t *fss_meta = (fss_t *)(fss + fss_entry); + + if (fss_meta->magic == FSS0_MAGIC) + { + gfx_printf(&gfx_con, "Found FSS0, Atmosphere %d.%d.%d-%08x\n" + "Max HOS supported: %d.%d.%d\n" + "Unpacking and loading components.. ", + fss_meta->version >> 24, (fss_meta->version >> 16) & 0xFF, (fss_meta->version >> 8) & 0xFF, fss_meta->git_rev, + fss_meta->hos_ver >> 24, (fss_meta->hos_ver >> 16) & 0xFF, (fss_meta->hos_ver >> 8) & 0xFF); + + fss_content_t *curr_fss_cnt = (fss_content_t *)(fss + fss_meta->cnt_off); + void *content; + for (int i = 0; i < fss_meta->cnt_count; i++) + { + content = (void *)(fss + curr_fss_cnt[i].offset); + if ((curr_fss_cnt[i].offset + curr_fss_cnt[i].size) > fss_meta->size) + continue; + + // Load content to launch context. + switch (curr_fss_cnt[i].type) + { + case CNT_TYPE_KIP:; + merge_kip_t *mkip1 = (merge_kip_t *)malloc(sizeof(merge_kip_t)); + mkip1->kip1 = content; + list_append(&ctxt->kip1_list, &mkip1->link); + DPRINTF("Loaded %s.kip1 from FSS0 (size %08X)\n", curr_fss_cnt[i].name, curr_fss_cnt[i].size); + break; + case CNT_TYPE_EXO: + ctxt->secmon_size = curr_fss_cnt[i].size; + ctxt->secmon = content; + break; + case CNT_TYPE_WBT: + ctxt->warmboot_size = curr_fss_cnt[i].size; + ctxt->warmboot = content; + break; + default: + continue; + // TODO: add more types? + // case CNT_TYPE_SP1: + // case CNT_TYPE_SP2: + } + + f_lseek(&fp, curr_fss_cnt[i].offset); + f_read(&fp, content, curr_fss_cnt[i].size, NULL); + } + + gfx_printf(&gfx_con, "Done!\n"); + f_close(&fp); + + return 1; + } + + f_close(&fp); + free(fss); + + return 0; +} \ No newline at end of file diff --git a/bootloader/hos/fss.h b/bootloader/hos/fss.h new file mode 100644 index 0000000..f3669df --- /dev/null +++ b/bootloader/hos/fss.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019 CTCaer + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _FSS_H_ +#define _FSS_H_ + +#include "hos.h" + +int parse_fss(launch_ctxt_t *ctxt, const char *value); + +#endif diff --git a/bootloader/hos/hos_config.c b/bootloader/hos/hos_config.c index c2b6221..5099577 100644 --- a/bootloader/hos/hos_config.c +++ b/bootloader/hos/hos_config.c @@ -19,6 +19,7 @@ #include "hos.h" #include "hos_config.h" +#include "fss.h" #include "../libs/fatfs/ff.h" #include "../mem/heap.h" #include "../utils/dirlist.h" @@ -185,6 +186,11 @@ static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value) return 1; } +static int _config_fss(launch_ctxt_t *ctxt, const char *value) +{ + return parse_fss(ctxt, value); +} + typedef struct _cfg_handler_t { const char *key; @@ -200,6 +206,7 @@ static const cfg_handler_t _config_handlers[] = { { "fullsvcperm", _config_svcperm }, { "debugmode", _config_debugmode }, { "atmosphere", _config_atmosphere }, + { "fss0", _config_fss }, { NULL, NULL }, };