diff --git a/.gitignore b/.gitignore index 768c7ab..273ba03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .vs .vscode -build_ipl/* +build/*.o +build/*.elf +build/bin/ipl diff --git a/Makefile b/Makefile index ede5553..d6f6381 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,12 @@ LD = $(DEVKITARM)/bin/arm-none-eabi-ld OBJCOPY = $(DEVKITARM)/bin/arm-none-eabi-objcopy TARGET := ipl -BUILD := ipl +BUILD := build +BUILD_BINARY := build/bin SOURCEDIR := ipl OBJS = $(addprefix $(BUILD)/, \ start.o \ main.o \ - btn.o \ clock.o \ cluster.o \ fuse.o \ @@ -20,7 +20,6 @@ OBJS = $(addprefix $(BUILD)/, \ heap.o \ hos.o \ i2c.o \ - kfuse.o \ lz.o \ max7762x.o \ mc.o \ @@ -29,7 +28,6 @@ OBJS = $(addprefix $(BUILD)/, \ sdmmc_driver.o \ sdram.o \ sdram_lp0.o \ - tui.o \ util.o \ di.o \ gfx.o \ @@ -39,7 +37,6 @@ OBJS = $(addprefix $(BUILD)/, \ se.o \ tsec.o \ uart.o \ - ini.o \ ) OBJS += $(addprefix $(BUILD)/, diskio.o ff.o ffunicode.o) @@ -49,14 +46,14 @@ LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections .PHONY: all clean -all: $(BUILD)/$(TARGET) +all: $(BUILD_BINARY)/$(TARGET) clean: @rm -rf $(OBJS) @rm -rf $(BUILD)/$(TARGET).elf - @rm -rf $(BUILD)/$(TARGET) + @rm -rf $(BUILD_BINARY)/$(TARGET) -$(BUILD)/$(TARGET): $(BUILD)/$(TARGET).elf +$(BUILD_BINARY)/$(TARGET): $(BUILD)/$(TARGET).elf $(OBJCOPY) -S -O binary $< $@ $(BUILD)/$(TARGET).elf: $(OBJS) diff --git a/README.md b/README.md index b4aca67..b3b68dc 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,9 @@ -# hekate for 5.0.x +# hekate for 4.x / 5.0.x -DO NOT UPDATE TO 5.0.2 FOR THIS +DO NOT UPDATE FOR THIS Original by @nwert ![Image of Hekate](https://upload.wikimedia.org/wikipedia/commons/f/fc/H%C3%A9cate_-_Mallarm%C3%A9.png) Nintendo Switch bootloader, firmware patcher, and more. - -## ipl config - -The ipl can be configured via 'hekate_ipl.ini' (if it is present on the SD card). Each ini section represents a boot entry, except for the special section 'config' that controls the global configuration. - -Possible key/value combinations: - - - warmboot={SD path} - - secmon={SD path} - - kernel={SD path} - - kip1={SD path} diff --git a/build/bin/DELETE_ME b/build/bin/DELETE_ME new file mode 100644 index 0000000..e69de29 diff --git a/ipl/btn.c b/ipl/btn.c deleted file mode 100644 index c346fce..0000000 --- a/ipl/btn.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 "btn.h" -#include "i2c.h" -#include "gpio.h" -#include "t210.h" - -u32 btn_read() -{ - u32 res = 0; - if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7)) - res |= BTN_VOL_DOWN; - if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6)) - res |= BTN_VOL_UP; - if (i2c_recv_byte(4, 0x3C, 0x15) & 0x4) - res |= BTN_POWER; - return res; -} - -u32 btn_wait() -{ - u32 res = 0, btn = btn_read(); - do - { - res = btn_read(); - } while (btn == res); - return res; -} diff --git a/ipl/btn.h b/ipl/btn.h deleted file mode 100644 index 8c5a8c5..0000000 --- a/ipl/btn.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 _BTN_H_ -#define _BTN_H_ - -#include "types.h" - -#define BTN_POWER 0x1 -#define BTN_VOL_DOWN 0x2 -#define BTN_VOL_UP 0x4 - -u32 btn_read(); -u32 btn_wait(); - -#endif diff --git a/ipl/btn.o b/ipl/btn.o deleted file mode 100644 index cbdac1a..0000000 Binary files a/ipl/btn.o and /dev/null differ diff --git a/ipl/clock.o b/ipl/clock.o deleted file mode 100644 index 4a6c71d..0000000 Binary files a/ipl/clock.o and /dev/null differ diff --git a/ipl/cluster.o b/ipl/cluster.o deleted file mode 100644 index b882f88..0000000 Binary files a/ipl/cluster.o and /dev/null differ diff --git a/ipl/di.o b/ipl/di.o deleted file mode 100644 index ee8712b..0000000 Binary files a/ipl/di.o and /dev/null differ diff --git a/ipl/diskio.o b/ipl/diskio.o deleted file mode 100644 index 7626cab..0000000 Binary files a/ipl/diskio.o and /dev/null differ diff --git a/ipl/ff.o b/ipl/ff.o deleted file mode 100644 index 6e19735..0000000 Binary files a/ipl/ff.o and /dev/null differ diff --git a/ipl/ffunicode.o b/ipl/ffunicode.o deleted file mode 100644 index cb2d2fb..0000000 Binary files a/ipl/ffunicode.o and /dev/null differ diff --git a/ipl/fuse.o b/ipl/fuse.o deleted file mode 100644 index 4ddb779..0000000 Binary files a/ipl/fuse.o and /dev/null differ diff --git a/ipl/gfx.o b/ipl/gfx.o deleted file mode 100644 index 68564da..0000000 Binary files a/ipl/gfx.o and /dev/null differ diff --git a/ipl/gpio.o b/ipl/gpio.o deleted file mode 100644 index 712ee3c..0000000 Binary files a/ipl/gpio.o and /dev/null differ diff --git a/ipl/heap.o b/ipl/heap.o deleted file mode 100644 index c7de54b..0000000 Binary files a/ipl/heap.o and /dev/null differ diff --git a/ipl/hos.c b/ipl/hos.c index 5c6454d..9a33805 100644 --- a/ipl/hos.c +++ b/ipl/hos.c @@ -265,42 +265,6 @@ out:; return res; } -static int _config_warmboot(launch_ctxt_t *ctxt, const char *value) -{ - FIL fp; - if (f_open(&fp, value, FA_READ) != FR_OK) - return 0; - ctxt->warmboot_size = f_size(&fp); - ctxt->warmboot = malloc(ctxt->warmboot_size); - f_read(&fp, ctxt->warmboot, ctxt->warmboot_size, NULL); - f_close(&fp); - return 1; -} - -static int _config_secmon(launch_ctxt_t *ctxt, const char *value) -{ - FIL fp; - if (f_open(&fp, value, FA_READ) != FR_OK) - return 0; - ctxt->secmon_size = f_size(&fp); - ctxt->secmon = malloc(ctxt->secmon_size); - f_read(&fp, ctxt->secmon, ctxt->secmon_size, NULL); - f_close(&fp); - return 1; -} - -static int _config_kernel(launch_ctxt_t *ctxt, const char *value) -{ - FIL fp; - if (f_open(&fp, value, FA_READ) != FR_OK) - return 0; - ctxt->kernel_size = f_size(&fp); - ctxt->kernel = malloc(ctxt->kernel_size); - f_read(&fp, ctxt->kernel, ctxt->kernel_size, NULL); - f_close(&fp); - return 1; -} - static int _config_kip1(launch_ctxt_t *ctxt, const char *value) { FIL fp; @@ -315,30 +279,6 @@ DPRINTF("loaded kip from SD (size %08X)\n", f_size(&fp)); return 1; } -typedef struct _cfg_handler_t -{ - const char *key; - int (*handler)(launch_ctxt_t *ctxt, const char *value); -} cfg_handler_t; - -static const cfg_handler_t _config_handlers[] = { - { "warmboot", _config_warmboot }, - { "secmon", _config_secmon }, - { "kernel", _config_kernel }, - { "kip1", _config_kip1 }, - { NULL, NULL }, -}; - -static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg) -{ - LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link) - for(u32 i = 0; _config_handlers[i].key; i++) - if (!strcmp(_config_handlers[i].key, kv->key) && - !_config_handlers[i].handler(ctxt, kv->val)) - return 0; - return 1; -} - int hos_launch() { launch_ctxt_t ctxt; diff --git a/ipl/hos.h b/ipl/hos.h index 699bf03..4920796 100644 --- a/ipl/hos.h +++ b/ipl/hos.h @@ -18,7 +18,6 @@ #define _HOS_H_ #include "types.h" -#include "ini.h" int hos_launch(); diff --git a/ipl/hos.o b/ipl/hos.o deleted file mode 100644 index 0a3bb9a..0000000 Binary files a/ipl/hos.o and /dev/null differ diff --git a/ipl/i2c.o b/ipl/i2c.o deleted file mode 100644 index a78b851..0000000 Binary files a/ipl/i2c.o and /dev/null differ diff --git a/ipl/ini.c b/ipl/ini.c deleted file mode 100644 index 8551203..0000000 --- a/ipl/ini.c +++ /dev/null @@ -1,93 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 "ini.h" -#include "ff.h" -#include "heap.h" - - -static char *_strdup(char *str) -{ - char *res = malloc(strlen(str) + 1); - strcpy(res, str); - return res; -} - -int ini_parse(link_t *dst, char *ini_path) -{ - u32 lblen; - char lbuf[512]; - FIL fp; - ini_sec_t *csec = NULL; - - if (f_open(&fp, ini_path, FA_READ) != FR_OK) - return 0; - - do - { - //Fetch one line. - lbuf[0] = 0; - f_gets(lbuf, 512, &fp); - lblen = strlen(lbuf); - - //Skip empty lines and comments. - if (lblen <= 1 || lbuf[0] == '#') - continue; - - //Remove trailing newline. - if (lbuf[lblen - 1] == '\n') - lbuf[lblen - 1] = 0; - - if (lblen > 2 && lbuf[0] == '[') //Create new section. - { - if (csec) - { - list_append(dst, &csec->link); - csec = NULL; - } - - u32 i; - for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != ']'; i++) - ; - lbuf[i] = 0; - - csec = (ini_sec_t *)malloc(sizeof(ini_sec_t)); - csec->name = _strdup(&lbuf[1]); - list_init(&csec->kvs); - } - else if (csec) //Extract key/value. - { - u32 i; - for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '='; i++) - ; - lbuf[i] = 0; - - ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t)); - kv->key = _strdup(&lbuf[0]); - kv->val = _strdup(&lbuf[i + 1]); - list_append(&csec->kvs, &kv->link); - } - } while (!f_eof(&fp)); - - f_close(&fp); - - if (csec) - list_append(dst, &csec->link); - - return 1; -} diff --git a/ipl/ini.h b/ipl/ini.h deleted file mode 100644 index 091009e..0000000 --- a/ipl/ini.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 _INI_H_ -#define _INI_H_ - -#include "types.h" -#include "list.h" - -typedef struct _ini_kv_t -{ - char *key; - char *val; - link_t link; -} ini_kv_t; - -typedef struct _ini_sec_t -{ - char *name; - link_t kvs; - link_t link; -} ini_sec_t; - -int ini_parse(link_t *dst, char *ini_path); - -#endif diff --git a/ipl/ini.o b/ipl/ini.o deleted file mode 100644 index 6482eac..0000000 Binary files a/ipl/ini.o and /dev/null differ diff --git a/ipl/ipl.elf b/ipl/ipl.elf deleted file mode 100644 index bbf450d..0000000 Binary files a/ipl/ipl.elf and /dev/null differ diff --git a/ipl/kfuse.c b/ipl/kfuse.c deleted file mode 100644 index 03d95bb..0000000 --- a/ipl/kfuse.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 "kfuse.h" -#include "clock.h" -#include "t210.h" - -int kfuse_read(u32 *buf) -{ - int res = 0; - - clock_enable_kfuse(); - - while (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_DONE)) - ; - - if (!(KFUSE(KFUSE_STATE) & KFUSE_STATE_CRCPASS)) - goto out; - - KFUSE(KFUSE_KEYADDR) = KFUSE_KEYADDR_AUTOINC; - for (int i = 0; i < KFUSE_NUM_WORDS; i++) - buf[i] = KFUSE(KFUSE_KEYS); - - res = 1; - -out:; - clock_disable_kfuse(); - return res; -} diff --git a/ipl/kfuse.h b/ipl/kfuse.h deleted file mode 100644 index 4aa1b09..0000000 --- a/ipl/kfuse.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 _KFUSE_H_ -#define _KFUSE_H_ - -#include "types.h" - -#define KFUSE_STATE_SOFTRESET (1<<31) -#define KFUSE_STATE_STOP (1<<25) -#define KFUSE_STATE_RESTART (1<<24) -#define KFUSE_STATE_CRCPASS (1<<17) -#define KFUSE_STATE_DONE (1<<16) -#define KFUSE_STATE_ERRBLOCK_MASK 0x3F00 -#define KFUSE_STATE_ERRBLOCK_SHIFT 8 -#define KFUSE_STATE_CURBLOCK_MASK 0x3F - -#define KFUSE_KEYADDR_AUTOINC (1<<16) - -#define KFUSE_STATE 0x80 -#define KFUSE_KEYADDR 0x88 -#define KFUSE_KEYS 0x8C - -#define KFUSE_NUM_WORDS 144 - -int kfuse_read(u32 *buf); - -#endif diff --git a/ipl/kfuse.o b/ipl/kfuse.o deleted file mode 100644 index af2ca54..0000000 Binary files a/ipl/kfuse.o and /dev/null differ diff --git a/ipl/lz.o b/ipl/lz.o deleted file mode 100644 index 0bb9018..0000000 Binary files a/ipl/lz.o and /dev/null differ diff --git a/ipl/main.c b/ipl/main.c index 047d8af..62947cf 100644 --- a/ipl/main.c +++ b/ipl/main.c @@ -30,35 +30,14 @@ #include "fuse.h" #include "util.h" #include "gfx.h" -#include "btn.h" -#include "tsec.h" -#include "kfuse.h" #include "max77620.h" -#include "max7762x.h" #include "gpio.h" #include "sdmmc.h" #include "ff.h" -#include "tui.h" #include "heap.h" -#include "list.h" -#include "nx_emmc.h" #include "se.h" #include "se_t210.h" #include "hos.h" -#include "pkg1.h" - -void panic(u32 val) -{ - //Set panic code. - PMC(APBDEV_PMC_SCRATCH200) = val; - //PMC(APBDEV_PMC_CRYPTO_OP) = 1; //Disable SE. - TMR(0x18C) = 0xC45A; - TMR(0x80) = 0xC0000000; - TMR(0x180) = 0x8019; - TMR(0x188) = 1; - while (1) - ; -} void config_oscillators() { @@ -239,99 +218,6 @@ void config_hw() //TODO: ugly. gfx_ctxt_t gfx_ctxt; gfx_con_t gfx_con; - -void print_fuseinfo() -{ - gfx_clear(&gfx_ctxt, 0xFF000000); - gfx_con_setpos(&gfx_con, 0, 0); - - gfx_printf(&gfx_con, "%k(Unlocked) fuse cache:\n\n%k", 0xFFFF9955, 0xFFFFFFFF); - gfx_hexdump(&gfx_con, 0x7000F900, (u8 *)0x7000F900, 0x2FC); - - sleep(100000); - btn_wait(); -} - -void print_kfuseinfo() -{ - gfx_clear(&gfx_ctxt, 0xFF000000); - gfx_con_setpos(&gfx_con, 0, 0); - - gfx_printf(&gfx_con, "%kKFuse contents:\n\n%k", 0xFFFF9955, 0xFFFFFFFF); - u32 buf[KFUSE_NUM_WORDS]; - if (!kfuse_read(buf)) - gfx_printf(&gfx_con, "%kCRC fail.\n", 0xFF0000FF); - else - gfx_hexdump(&gfx_con, 0, (u8 *)buf, KFUSE_NUM_WORDS * 4); - - sleep(100000); - btn_wait(); -} - -void print_tsec_key() -{ - gfx_clear(&gfx_ctxt, 0xFF000000); - gfx_con_setpos(&gfx_con, 0, 0); - - sdmmc_storage_t storage; - sdmmc_t sdmmc; - - sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4); - - //Read package1. - u8 *pkg1 = (u8 *)malloc(0x40000); - sdmmc_storage_set_mmc_partition(&storage, 1); - sdmmc_storage_read(&storage, 0x100000 / NX_EMMC_BLOCKSIZE, 0x40000 / NX_EMMC_BLOCKSIZE, pkg1); - const pkg1_id_t *pkg1_id = pkg1_identify(pkg1); - if (!pkg1_id) - { - gfx_printf(&gfx_con, "%kCould not identify package 1 version to read TSEC firmware (= '%s').%k\n", 0xFF0000FF, (char *)pkg1 + 0x10, 0xFFFFFFFF); - goto out; - } - - for(u32 i = 1; i <= 3; i++) - { - u8 key[0x10]; - int res = tsec_query(key, i, pkg1 + pkg1_id->tsec_off); - - gfx_printf(&gfx_con, "%kTSEC key %d: %k", 0xFFFF9955, i, 0xFFFFFFFF); - if (res >= 0) - { - for (u32 i = 0; i < 0x10; i++) - gfx_printf(&gfx_con, "%02X", key[i]); - } - else - gfx_printf(&gfx_con, "%kERROR %X", 0xFF0000FF, res); - gfx_putc(&gfx_con, '\n'); - } - -out:; - free(pkg1); - sdmmc_storage_end(&storage); - sleep(100000); - btn_wait(); -} - -void reboot_normal() -{ - panic(0x21); //Bypass fuse programming in package1. -} - -void reboot_rcm() -{ - PMC(APBDEV_PMC_SCRATCH0) = 2; //Reboot into rcm. - PMC(0) |= 0x10; - while (1) - sleep(1); -} - -void power_off() -{ - //TODO: we should probably make sure all regulators are powered off properly. - i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); -} - -//TODO: ugly. sdmmc_t sd_sdmmc; sdmmc_storage_t sd_storage; FATFS sd_fs; @@ -352,261 +238,30 @@ int sd_mount() return 0; } -void *sd_file_read(char *path) -{ - FIL fp; - if (f_open(&fp, path, FA_READ) != FR_OK) - return NULL; - - u32 size = f_size(&fp); - void *buf = malloc(size); - - u8 *ptr = buf; - while (size > 0) - { - u32 rsize = MIN(size, 512); - if (f_read(&fp, ptr, rsize, NULL) != FR_OK) - { - free(buf); - return NULL; - } - - ptr += rsize; - size -= rsize; - } - - f_close(&fp); - - return buf; -} - -int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) -{ - static const u32 FAT32_FILESIZE_LIMIT = 0xFFFFFFFF; - static const u32 MULTIPART_SPLIT_SIZE = (1u << 31); - - u32 totalSectors = part->lba_end - part->lba_start + 1; - char* outFilename = sd_path; - u32 sdPathLen = strlen(sd_path); - u32 numSplitParts = 0; - if ((sd_fs.fs_type != FS_EXFAT) && totalSectors > (FAT32_FILESIZE_LIMIT/NX_EMMC_BLOCKSIZE)) - { - static const u32 MULTIPART_SPLIT_SECTORS = MULTIPART_SPLIT_SIZE/NX_EMMC_BLOCKSIZE; - numSplitParts = (totalSectors+MULTIPART_SPLIT_SECTORS-1)/MULTIPART_SPLIT_SECTORS; - - outFilename = alloca(sdPathLen+4); - memcpy(outFilename, sd_path, sdPathLen); - outFilename[sdPathLen++] = '.'; - - outFilename[sdPathLen] = '0'; - if (numSplitParts >= 10) - { - outFilename[sdPathLen+1] = '0'; - outFilename[sdPathLen+2] = 0; - } - else - outFilename[sdPathLen+1] = 0; - } - - FIL fp; - if (f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) - return 0; - - static const u32 NUM_SECTORS_PER_ITER = 512; - u8 *buf = (u8 *)malloc(NX_EMMC_BLOCKSIZE * NUM_SECTORS_PER_ITER); - - u32 lba_curr = part->lba_start; - u32 bytesWritten = 0; - u32 currPartIdx = 0; - u32 prevPct=200; - while(totalSectors > 0) - { - if (numSplitParts != 0 && bytesWritten >= MULTIPART_SPLIT_SIZE) - { - f_close(&fp); - memset(&fp, 0, sizeof(fp)); - currPartIdx++; - - if (numSplitParts >= 10 && currPartIdx < 10) - { - outFilename[sdPathLen] = '0'; - itoa(currPartIdx, &outFilename[sdPathLen+1], 10); - } - else - itoa(currPartIdx, &outFilename[sdPathLen], 10); - - if (f_open(&fp, outFilename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) - { - free(buf); - return 0; - } - bytesWritten = 0; - } - - int retryCount=0; - u32 num = MIN(totalSectors, NUM_SECTORS_PER_ITER); - while(!sdmmc_storage_read(storage, lba_curr, num, buf)) - { - gfx_printf(&gfx_con, "%kError reading %d blocks @ LBA %08X (try %d) %k\n", - 0xFF0000FF, num, lba_curr, ++retryCount, 0xFFFFFFFF); - - sleep(500000); - if (retryCount >= 3) - goto out; - } - f_write(&fp, buf, NX_EMMC_BLOCKSIZE * num, NULL); - u32 pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start); - if (pct != prevPct) - { - tui_pbar(&gfx_con, 0, gfx_con.y, pct); - prevPct = pct; - } - - lba_curr += num; - totalSectors -= num; - bytesWritten += num * NX_EMMC_BLOCKSIZE; - - //force a flush after a lot of data if not splitting - if (numSplitParts == 0 && bytesWritten >= MULTIPART_SPLIT_SIZE) - { - f_sync(&fp); - bytesWritten = 0; - } - } - tui_pbar(&gfx_con, 0, gfx_con.y, 100); - -out:; - free(buf); - f_close(&fp); - return 1; -} - -typedef enum -{ - DUMP_BOOT = 1, - DUMP_SYSTEM = 2, - DUMP_USER = 4, - DUMP_RAW = 8 -} dumpType_t; +void print_header() { + static const char switchblade[] = + " _____ _ __ __ ____ __ __ \n\n" + " / ___/ __(_) /______/ /_ / __ )/ /___ _____/ /__ \n\n" + " \\__ \\ | /| / / / __/ ___/ __ \\/ __ / / __ `/ __ / _ \'\n\n" + " ___/ / |/ |/ / / /_/ /__/ / / / /_/ / / /_/ / /_/ / __/\n\n" + "/____/|__/|__/_/\\__/\\___/_/ /_/_____/_/\\__,_/\\__,_/\\___/ \n\n" + " - v1.0 Wicked Fast Hekate Booter Payload (@StevenMattera & @shmadul)\n" + "Based on the awesome work of naehrwert, st4rk\n" + "Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8\n" + "Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute\n" + "Open source and free packages used:\n" + " - FatFs R0.13a (Copyright (C) 2017, ChaN)\n" + " - bcl-1.2.0 (Copyright (c) 2003-2006 Marcus Geelnard)\n\n"; -static void dump_emmc_selected(dumpType_t dumpType) -{ gfx_clear(&gfx_ctxt, 0xFF000000); gfx_con_setpos(&gfx_con, 0, 0); - if (!sd_mount()) - { - gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF); - goto out; - } - - sdmmc_storage_t storage; - sdmmc_t sdmmc; - if(!sdmmc_storage_init_mmc(&storage, &sdmmc, SDMMC_4, SDMMC_BUS_WIDTH_8, 4)) - { - gfx_printf(&gfx_con, "%kFailed to init eMMC.%k\n", 0xFF0000FF, 0xFFFFFFFF); - goto out; - } - - int i = 0; - if (dumpType & DUMP_BOOT) - { - static const u32 BOOT_PART_SIZE = 0x400000; - - emmc_part_t bootPart; - memset(&bootPart, 0, sizeof(bootPart)); - bootPart.lba_start = 0; - bootPart.lba_end = (BOOT_PART_SIZE/NX_EMMC_BLOCKSIZE)-1; - for (i=0; i<2; i++) - { - memcpy(bootPart.name, "BOOT", 4); - bootPart.name[4] = (u8)('0' + i); - bootPart.name[5] = 0; - - gfx_printf(&gfx_con, "%02d: %s (%08X-%08X)\n", i, - bootPart.name, bootPart.lba_start, bootPart.lba_end); - - sdmmc_storage_set_mmc_partition(&storage, i+1); - dump_emmc_part(bootPart.name, &storage, &bootPart); - gfx_putc(&gfx_con, '\n'); - } - } - - if ((dumpType & DUMP_SYSTEM) || (dumpType & DUMP_USER) || (dumpType & DUMP_RAW)) - { - sdmmc_storage_set_mmc_partition(&storage, 0); - - if ((dumpType & DUMP_SYSTEM) || (dumpType & DUMP_USER)) - { - LIST_INIT(gpt); - nx_emmc_gpt_parse(&gpt, &storage); - LIST_FOREACH_ENTRY(emmc_part_t, part, &gpt, link) - { - if ((dumpType & DUMP_USER) == 0 && !strcmp(part->name, "USER")) - continue; - if ((dumpType & DUMP_SYSTEM) == 0 && strcmp(part->name, "USER")) - continue; - - gfx_printf(&gfx_con, "%02d: %s (%08X-%08X)\n", i++, - part->name, part->lba_start, part->lba_end); - - dump_emmc_part(part->name, &storage, part); - gfx_putc(&gfx_con, '\n'); - } - } - - if (dumpType & DUMP_RAW) - { - static const u32 RAW_AREA_NUM_SECTORS = 0x3A3E000; - - emmc_part_t rawPart; - memset(&rawPart, 0, sizeof(rawPart)); - rawPart.lba_start = 0; - rawPart.lba_end = RAW_AREA_NUM_SECTORS-1; - strcpy(rawPart.name, "RawNand.bin"); - { - gfx_printf(&gfx_con, "%02d: %s (%08X-%08X)\n", i++, - rawPart.name, rawPart.lba_start, rawPart.lba_end); - - dump_emmc_part(rawPart.name, &storage, &rawPart); - gfx_putc(&gfx_con, '\n'); - } - } - } - - sdmmc_storage_end(&storage); - gfx_puts(&gfx_con, "Done.\n"); - -out:; - sleep(100000); - btn_wait(); + gfx_printf(&gfx_con, switchblade, 0xFFFFCC00, 0xFFFFFFFF, + 0xFFFFCC00, 0xFFCCFF00, 0xFFFFCC00, 0xFFFFFFFF); } -void dump_emmc_system() { dump_emmc_selected(DUMP_SYSTEM); } -void dump_emmc_user() { dump_emmc_selected(DUMP_USER); } -void dump_emmc_boot() { dump_emmc_selected(DUMP_BOOT); } -void dump_emmc_rawnand() { dump_emmc_selected(DUMP_RAW); } - void launch_firmware() { - ini_sec_t *cfg_sec = NULL; - LIST_INIT(ini_sections); - -static const char switchblade[] = - " _____ _ __ __ ____ __ __ \n\n" - " / ___/ __(_) /______/ /_ / __ )/ /___ _____/ /__ \n\n" - " \\__ \\ | /| / / / __/ ___/ __ \\/ __ / / __ `/ __ / _ \'\n\n" - " ___/ / |/ |/ / / /_/ /__/ / / / /_/ / / /_/ / /_/ / __/\n\n" - "/____/|__/|__/_/\\__/\\___/_/ /_/_____/_/\\__,_/\\__,_/\\___/ \n\n" - " - v1.0 Wicked Fast Hekate Booter Payload (@StevenMattera & @shmadul)\n\n"; - - gfx_clear(&gfx_ctxt, 0xFF000000); - gfx_con_setpos(&gfx_con, 0, 0); - - gfx_printf(&gfx_con, switchblade, 0xFFFFCC00, 0xFFFFFFFF, - 0xFFFFCC00, 0xFFCCFF00, 0xFFFFCC00, 0xFFFFFFFF); - sleep(1.25); - if (sd_mount()) { if (!hos_launch()) @@ -614,93 +269,8 @@ static const char switchblade[] = } else gfx_printf(&gfx_con, "%kFailed to mount SD card (make sure that it is inserted).%k\n", 0xFF0000FF, 0xFFFFFFFF); - - if (!cfg_sec) - gfx_printf(&gfx_con, "Using default launch configuration.\n"); - -out:; - sleep(200000); - btn_wait(); -} - -void about() -{ - static const char octopus[] = - "hekate (c) 2018 naehrwert, st4rk\n\n" - "Thanks to: %kderrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8%k\n\n" - "Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute\n\n" - "Open source and free packages used:\n" - " - FatFs R0.13a (Copyright (C) 2017, ChaN)\n" - " - bcl-1.2.0 (Copyright (c) 2003-2006 Marcus Geelnard)\n\n" - " %k___\n" - " .-' `'.\n" - " / \\\n" - " | ;\n" - " | | ___.--,\n" - " _.._ |0) = (0) | _.---'`__.-( (_.\n" - " __.--'`_.. '.__.\\ '--. \\_.-' ,.--'` `\"\"`\n" - " ( ,.--'` ',__ /./; ;, '.__.'` __\n" - " _`) ) .---.__.' / | |\\ \\__..--\"\" \"\"\"--.,_\n" - " `---' .'.''-._.-'`_./ /\\ '. \\ _.--''````'''--._`-.__.'\n" - " | | .' _.-' | | \\ \\ '. `----`\n" - " \\ \\/ .' \\ \\ '. '-._)\n" - " \\/ / \\ \\ `=.__`'-.\n" - " / /\\ `) ) / / `\"\".`\\\n" - " , _.-'.'\\ \\ / / ( ( / /\n" - " `--'` ) ) .-'.' '.'. | (\n" - " (/` ( (` ) ) '-; %k[switchbrew]%k\n" - " ` '-; (-'%k"; - - gfx_clear(&gfx_ctxt, 0xFF000000); - gfx_con_setpos(&gfx_con, 0, 0); - - gfx_printf(&gfx_con, octopus, 0xFFFFCC00, 0xFFFFFFFF, - 0xFFFFCC00, 0xFFCCFF00, 0xFFFFCC00, 0xFFFFFFFF); - - sleep(1000000); - btn_wait(); } -ment_t ment_cinfo[] = { - MDEF_BACK(), - MDEF_HANDLER("Print fuse info", print_fuseinfo), - MDEF_HANDLER("Print kfuse info", print_kfuseinfo), - MDEF_HANDLER("Print TSEC keys", print_tsec_key), - MDEF_END() -}; -menu_t menu_cinfo = { - ment_cinfo, - "Console info", 0, 0 -}; - -ment_t ment_tools[] = { - MDEF_BACK(), - MDEF_HANDLER("Dump eMMC RawNand", dump_emmc_rawnand), - MDEF_HANDLER("Dump eMMC SYS", dump_emmc_system), - MDEF_HANDLER("Dump eMMC USER", dump_emmc_user), - MDEF_HANDLER("Dump eMMC BOOT", dump_emmc_boot), - MDEF_END() -}; -menu_t menu_tools = { - ment_tools, - "Tools", 0, 0 -}; - -ment_t ment_top[] = { - MDEF_HANDLER("Launch firmware", launch_firmware), - MDEF_MENU("Tools", &menu_tools), - MDEF_MENU("Console info", &menu_cinfo), - MDEF_HANDLER("Reboot (normal)", reboot_normal), - MDEF_HANDLER("Reboot (rcm)", reboot_rcm), - MDEF_HANDLER("Power off", power_off), - MDEF_HANDLER("About", about), - MDEF_END() -}; -menu_t menu_top = { - ment_top, - "hekate - ipl", 0, 0 -}; - extern void pivot_stack(u32 stack_top); void ipl_main() @@ -723,9 +293,6 @@ void ipl_main() gfx_clear(&gfx_ctxt, 0xFF000000); gfx_con_init(&gfx_con, &gfx_ctxt); - while (1) - launch_firmware(); - - while (1) - ; + print_header(); + launch_firmware(); } diff --git a/ipl/main.o b/ipl/main.o deleted file mode 100644 index b70ae21..0000000 Binary files a/ipl/main.o and /dev/null differ diff --git a/ipl/max7762x.o b/ipl/max7762x.o deleted file mode 100644 index feb71ed..0000000 Binary files a/ipl/max7762x.o and /dev/null differ diff --git a/ipl/mc.o b/ipl/mc.o deleted file mode 100644 index cc4c65c..0000000 Binary files a/ipl/mc.o and /dev/null differ diff --git a/ipl/nx_emmc.o b/ipl/nx_emmc.o deleted file mode 100644 index 4cd93f2..0000000 Binary files a/ipl/nx_emmc.o and /dev/null differ diff --git a/ipl/pinmux.o b/ipl/pinmux.o deleted file mode 100644 index 12c0e2e..0000000 Binary files a/ipl/pinmux.o and /dev/null differ diff --git a/ipl/pkg1.c b/ipl/pkg1.c index b2b60cb..be00348 100644 --- a/ipl/pkg1.c +++ b/ipl/pkg1.c @@ -39,12 +39,22 @@ PATCHSET_DEF(_secmon_2_patchset, { 0xAC8 + 0xB3C, _NOP() }, //Version. { 0xAC8 + 0xB58, _NOP() } //Sections SHA2. ); + +PATCHSET_DEF(_secmon_5_patchset, + //Patch package2 decryption and signature/hash checks. + { 0x1218 + 0x6E68, _NOP() }, //Header signature. + { 0x1218 + 0x6E74, _NOP() }, //Version. + { 0x1218 + 0x6FE4, _NOP() }, //Sections SHA2. + { 0x1218 + 0x2DC, _NOP() } //Unknown. +); + PATCHSET_DEF(_secmon_6_patchset, - { 0x12b0 + 0x4d0, _NOP() }, - { 0x12b0 + 0x4dc, _NOP() }, - { 0x12b0 + 0x794, _NOP() }, - { 0x12b0 + 0xb30, _NOP() }//, - //{ 0x12b0 + 0xa18 , _NOP() } // BootConfig Retail Check + //Patch package2 decryption and signature/hash checks. + { 0x12B0 + 0x4D0, _NOP() }, //Header signature. + { 0x12B0 + 0x4DC, _NOP() }, //Version. + { 0x12B0 + 0x794, _NOP() }, //Sections SHA2. + { 0x12B0 + 0xB30, _NOP() } /*,*/ //Unknown. + //{ 0x12B0 + 0xA18 , _NOP() } // BootConfig Retail Check ); /* @@ -63,7 +73,7 @@ static const pkg1_id_t _pkg1_ids[] = { { "20170210155124", 0, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, _secmon_2_patchset }, //2.0.0 { "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.0 { "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, NULL }, //3.0.1 - { "20170921172629", 3, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, NULL }, //4.0.0 + { "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_5_patchset }, //4.0.0 { "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, _secmon_6_patchset }, //5.0.0 { NULL, 0, 0, 0, 0 } //End. }; diff --git a/ipl/pkg1.o b/ipl/pkg1.o deleted file mode 100644 index ba3a1de..0000000 Binary files a/ipl/pkg1.o and /dev/null differ diff --git a/ipl/pkg2.o b/ipl/pkg2.o deleted file mode 100644 index 8c583ef..0000000 Binary files a/ipl/pkg2.o and /dev/null differ diff --git a/ipl/sdmmc.o b/ipl/sdmmc.o deleted file mode 100644 index c1fb19d..0000000 Binary files a/ipl/sdmmc.o and /dev/null differ diff --git a/ipl/sdmmc_driver.o b/ipl/sdmmc_driver.o deleted file mode 100644 index b97ef28..0000000 Binary files a/ipl/sdmmc_driver.o and /dev/null differ diff --git a/ipl/sdram.o b/ipl/sdram.o deleted file mode 100644 index 86da92f..0000000 Binary files a/ipl/sdram.o and /dev/null differ diff --git a/ipl/sdram_lp0.o b/ipl/sdram_lp0.o deleted file mode 100644 index 181b6b1..0000000 Binary files a/ipl/sdram_lp0.o and /dev/null differ diff --git a/ipl/tui.c b/ipl/tui.c deleted file mode 100644 index ef3aff1..0000000 --- a/ipl/tui.c +++ /dev/null @@ -1,98 +0,0 @@ -/*{ -* Copyright (c) 2018 naehrwert -* -* 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 "tui.h" -#include "btn.h" - -void tui_pbar(gfx_con_t *con, int x, int y, u32 val) -{ - u32 cx, cy; - - gfx_con_getpos(con, &cx, &cy); - - gfx_con_setpos(con, x, y); - - gfx_printf(con, "[%3d%%]", val); - - x += 7 * 8; - - for (int i = 0; i < 6; i++) - { - gfx_line(con->gfx_ctxt, x, y + i + 1, x + 3 * val, y + i + 1, 0xFFFFFFFF); - gfx_line(con->gfx_ctxt, x + 3 * val, y + i + 1, x + 3 * 100, y + i + 1, 0xFF888888); - } - - gfx_con_setpos(con, cx, cy); -} - -void *tui_do_menu(gfx_con_t *con, menu_t *menu) -{ - int idx = 0, cnt; - - gfx_clear(con->gfx_ctxt, 0xFF000000); - - while (1) - { - gfx_con_setcol(con, 0xFFFFFFFF, 1, 0xFF000000); - gfx_con_setpos(con, menu->x, menu->y); - gfx_printf(con, "[%s]\n\n", menu->caption); - - for (cnt = 0; menu->ents[cnt].type != MENT_END; cnt++) - { - if (cnt == idx) - gfx_con_setcol(con, 0xFF000000, 1, 0xFFCCCCCC); - else - gfx_con_setcol(con, 0xFFFFFFFF, 1, 0xFF000000); - con->x += 8; - gfx_printf(con, "%s", menu->ents[cnt].caption); - if(menu->ents[cnt].type == MENT_MENU) - gfx_printf(con, "%k...", 0xFFEE9900); - gfx_putc(con, '\n'); - } - - gfx_con_setcol(con, 0xFFFFFFFF, 1, 0xFF000000); - gfx_putc(con, '\n'); - - u32 btn = btn_wait(); - - if (btn & BTN_VOL_DOWN && idx < cnt - 1) - idx++; - if (btn & BTN_VOL_UP && idx > 0) - idx--; - if (btn & BTN_POWER) - { - ment_t *ent = &menu->ents[idx]; - switch (ent->type) - { - case MENT_HANDLER: - ent->handler(ent->data); - break; - case MENT_MENU: - return tui_do_menu(con, ent->menu); - break; - case MENT_CHOICE: - return ent->data; - break; - case MENT_BACK: - return NULL; - break; - } - gfx_clear(con->gfx_ctxt, 0xFF000000); - } - } - - return NULL; -} diff --git a/ipl/tui.h b/ipl/tui.h deleted file mode 100644 index 6b1f2df..0000000 --- a/ipl/tui.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* Copyright (c) 2018 naehrwert -* -* 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 _TUI_H_ -#define _TUI_H_ - -#include "types.h" -#include "gfx.h" - -#define MENT_END 0 -#define MENT_HANDLER 1 -#define MENT_MENU 2 -#define MENT_CHOICE 3 -#define MENT_BACK 4 - -typedef struct _ment_t -{ - u32 type; - const char *caption; - void *data; - union - { - void(*handler)(void *); - struct _menu_t *menu; - }; -} ment_t; - -typedef struct _menu_t -{ - ment_t *ents; - const char *caption; - u32 x; - u32 y; -} menu_t; - -#define MDEF_END() {MENT_END} -#define MDEF_HANDLER(caption, _handler) { MENT_HANDLER, caption, NULL, { .handler = _handler } } -#define MDEF_HANDLER_EX(caption, data, _handler) { MENT_HANDLER, caption, data, { .handler = _handler } } -#define MDEF_MENU(caption, _menu) { MENT_MENU, caption, NULL, { .menu = _menu } } -#define MDEF_BACK() { MENT_BACK, "Back" } - -void tui_pbar(gfx_con_t *con, int x, int y, u32 val); -void *tui_do_menu(gfx_con_t *con, menu_t *menu); - -#endif