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 },
};