From 0ddc1c71a8689fa364f5838546b1b63a1d1be53e Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Fri, 8 Mar 2019 00:19:04 +0200 Subject: [PATCH] Bugfixes and hardcoded naming - Make debugmode for exosphere mandatory - Support dev RSA modulus for warmboot - Fix a critical bug where it allowed free() to be used on a non-heap address. - Better the makefile --- Makefile | 107 +++++++++++++++------------------ bootloader/hos/hos.c | 2 +- bootloader/hos/hos_config.c | 60 +++++++++--------- bootloader/hos/secmon_exo.c | 15 +++-- bootloader/hos/secmon_exo.h | 2 +- bootloader/libs/fatfs/diskio.c | 6 +- bootloader/main.c | 31 +++++----- bootloader/mem/heap.c | 2 +- bootloader/sec/se.c | 14 ++--- bootloader/soc/hw_init.c | 2 +- bootloader/soc/pmc.h | 2 + bootloader/soc/t210.h | 1 + bootloader/utils/util.c | 2 +- bootloader/utils/util.h | 4 +- 14 files changed, 127 insertions(+), 123 deletions(-) diff --git a/Makefile b/Makefile index 9692da7..95744e3 100755 --- a/Makefile +++ b/Makefile @@ -4,6 +4,8 @@ endif include $(DEVKITARM)/base_rules +################################################################################ + IPL_LOAD_ADDR := 0x40008000 IPL_MAGIC := 0x43544349 #"ICTC" BLVERSION_MAJOR := 4 @@ -12,63 +14,52 @@ BLVERSION_HOTFX := 0 BL_RESERVED := 0 +################################################################################ + TARGET := hekate -BUILD := build -OUTPUT := output +BUILDDIR := build +OUTPUTDIR := output SOURCEDIR = bootloader VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/)) -OBJS = $(addprefix $(BUILD)/$(TARGET)/, \ +# Main and graphics. +OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \ start.o \ - main.o \ - fe_emmc_tools.o \ - fe_info.o \ - fe_tools.o \ - config.o \ - btn.o \ - clock.o \ - cluster.o \ - fuse.o \ - gpio.o \ - heap.o \ - hos.o \ - hos_config.o \ - secmon_exo.o \ - sept.o \ - i2c.o \ - kfuse.o \ - bq24193.o \ - max7762x.o \ - max17050.o \ - mc.o \ - nx_emmc.o \ - sdmmc.o \ - sdmmc_driver.o \ - sdram.o \ - tui.o \ - util.o \ - di.o \ - gfx.o \ - pinmux.o \ - pkg1.o \ - pkg2.o \ - se.o \ - tsec.o \ - uart.o \ - hw_init.o \ - dirlist.o \ - ini.o \ - ianos.o \ - smmu.o \ - max77620-rtc.o \ + main.o heap.o \ + gfx.o tui.o \ + fe_emmc_tools.o fe_info.o fe_tools.o \ ) -OBJS += $(addprefix $(BUILD)/$(TARGET)/, \ +# Hardware. +OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ + clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o pinmux.o se.o smmu.o tsec.o uart.o \ + fuse.o kfuse.o \ + sdmmc.o sdmmc_driver.o \ + bq24193.o max17050.o max7762x.o max77620-rtc.o \ + hw_init.o \ +) + +# Utilities. +OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ + btn.o dirlist.o ianos.o util.o \ + config.o ini.o \ +) + +# Horizon. +OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ + nx_emmc.o \ + hos.o hos_config.o pkg1.o pkg2.o secmon_exo.o sept.o \ +) + +# Libraries. +OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \ lz.o blz.o \ diskio.o ff.o ffunicode.o ffsystem.o \ elfload.o elfreloc_arm.o \ ) +################################################################################ + CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC) CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED) CUSTOMDEFINES += -DMENU_LOGO_ENABLE @@ -84,33 +75,35 @@ LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defs MODULEDIRS := $(wildcard modules/*) +################################################################################ + .PHONY: all clean $(MODULEDIRS) all: $(TARGET).bin @echo -n "Payload size is " - @wc -c < $(OUTPUT)/$(TARGET).bin + @wc -c < $(OUTPUTDIR)/$(TARGET).bin @echo "Max size is 126296 Bytes." clean: @rm -rf $(OBJS) - @rm -rf $(BUILD) - @rm -rf $(OUTPUT) + @rm -rf $(BUILDDIR) + @rm -rf $(OUTPUTDIR) $(MODULEDIRS): $(MAKE) -C $@ $(MAKECMDGOALS) -$(TARGET).bin: $(BUILD)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) - $(OBJCOPY) -S -O binary $< $(OUTPUT)/$@ - @printf ICTC$(BLVERSION_MAJOR)$(BLVERSION_MINOR) >> $(OUTPUT)/$@ +$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) + $(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@ + @printf ICTC$(BLVERSION_MAJOR)$(BLVERSION_MINOR) >> $(OUTPUTDIR)/$@ -$(BUILD)/$(TARGET)/$(TARGET).elf: $(OBJS) +$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS) $(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@ -$(BUILD)/$(TARGET)/%.o: %.c +$(BUILDDIR)/$(TARGET)/%.o: %.c $(CC) $(CFLAGS) -c $< -o $@ -$(BUILD)/$(TARGET)/%.o: %.S - @mkdir -p "$(BUILD)" - @mkdir -p "$(BUILD)/$(TARGET)" - @mkdir -p "$(OUTPUT)" +$(BUILDDIR)/$(TARGET)/%.o: %.S + @mkdir -p "$(BUILDDIR)" + @mkdir -p "$(BUILDDIR)/$(TARGET)" + @mkdir -p "$(OUTPUTDIR)" $(CC) $(CFLAGS) -c $< -o $@ diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 24ed2c7..ea122fe 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -610,7 +610,7 @@ int hos_launch(ini_sec_t *cfg) // Config Exosphère if booting full Atmosphère. if (ctxt.atmosphere && ctxt.secmon) - config_exosphere(ctxt.pkg1_id->id, ctxt.pkg1_id->kb, (void *)ctxt.pkg1_id->warmboot_base, ctxt.pkg1, ctxt.debugmode); + config_exosphere(ctxt.pkg1_id->id, ctxt.pkg1_id->kb, (void *)ctxt.pkg1_id->warmboot_base, ctxt.pkg1); // Unmount SD card. sd_unmount(); diff --git a/bootloader/hos/hos_config.c b/bootloader/hos/hos_config.c index 4d956de..c2b6221 100644 --- a/bootloader/hos/hos_config.c +++ b/bootloader/hos/hos_config.c @@ -125,36 +125,6 @@ static int _config_kip1(launch_ctxt_t *ctxt, const char *value) return 1; } -static int _config_svcperm(launch_ctxt_t *ctxt, const char *value) -{ - if (*value == '1') - { - DPRINTF("Disabled SVC verification\n"); - ctxt->svcperm = true; - } - return 1; -} - -static int _config_debugmode(launch_ctxt_t *ctxt, const char *value) -{ - if (*value == '1') - { - DPRINTF("Enabled Debug mode\n"); - ctxt->debugmode = true; - } - return 1; -} - -static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value) -{ - if (*value == '1') - { - DPRINTF("Enabled atmosphere patching\n"); - ctxt->atmosphere = true; - } - return 1; -} - int config_kip1patch(launch_ctxt_t *ctxt, const char *value) { if (value == NULL) @@ -185,6 +155,36 @@ int config_kip1patch(launch_ctxt_t *ctxt, const char *value) return 1; } +static int _config_svcperm(launch_ctxt_t *ctxt, const char *value) +{ + if (*value == '1') + { + DPRINTF("Disabled SVC verification\n"); + ctxt->svcperm = true; + } + return 1; +} + +static int _config_debugmode(launch_ctxt_t *ctxt, const char *value) +{ + if (*value == '1') + { + DPRINTF("Enabled Debug mode\n"); + ctxt->debugmode = true; + } + return 1; +} + +static int _config_atmosphere(launch_ctxt_t *ctxt, const char *value) +{ + if (*value == '1') + { + DPRINTF("Enabled atmosphere patching\n"); + ctxt->atmosphere = true; + } + return 1; +} + typedef struct _cfg_handler_t { const char *key; diff --git a/bootloader/hos/secmon_exo.c b/bootloader/hos/secmon_exo.c index 9a5d75d..33b6450 100644 --- a/bootloader/hos/secmon_exo.c +++ b/bootloader/hos/secmon_exo.c @@ -18,6 +18,7 @@ #include "hos.h" #include "../mem/heap.h" +#include "../soc/fuse.h" #include "../storage/sdmmc.h" #include "../utils/types.h" @@ -47,7 +48,7 @@ typedef struct _atm_meta_t #define EXO_FLAG_DBG_PRIV (1 << 1) #define EXO_FLAG_DBG_USER (1 << 2) -void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool debug) +void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1) { u32 exoFwNo = 0; u32 exoFlags = 0; @@ -74,8 +75,8 @@ void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool d if (kb == KB_FIRMWARE_VERSION_620) exoFlags |= EXO_FLAG_620_KGN; - if (debug) - exoFlags |= EXO_FLAG_DBG_PRIV; + // To avoid problems, make private debug mode always on. + exoFlags |= EXO_FLAG_DBG_PRIV; // Set mailbox values. exo_cfg_depr->magic = EXO_MAGIC_VAL; @@ -87,6 +88,7 @@ void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool d exo_cfg_depr->flags = exoFlags; exo_cfg->flags = exoFlags; + // If warmboot is lp0fw, add in RSA modulus. volatile wb_cfg_t *wb_cfg = (wb_cfg_t *)(warmboot + ATM_WB_HEADER_OFF); if (wb_cfg->magic == ATM_WB_MAGIC) @@ -104,8 +106,11 @@ void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool d sdmmc_storage_read(&storage, 1, 1, rsa_mod); sdmmc_storage_end(&storage); - // Patch AutoRCM. - rsa_mod[0x10] = 0xF7; + // Patch AutoRCM out. + if ((fuse_read_odm(4) & 3) != 3) + rsa_mod[0x10] = 0xF7; + else + rsa_mod[0x10] = 0x37; memcpy(warmboot + 0x10, rsa_mod + 0x10, 0x100); } diff --git a/bootloader/hos/secmon_exo.h b/bootloader/hos/secmon_exo.h index 41db58d..1a619c2 100644 --- a/bootloader/hos/secmon_exo.h +++ b/bootloader/hos/secmon_exo.h @@ -19,6 +19,6 @@ #include "../utils/types.h" -void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1, bool debug); +void config_exosphere(const char *id, u32 kb, void *warmboot, void *pkg1); #endif diff --git a/bootloader/libs/fatfs/diskio.c b/bootloader/libs/fatfs/diskio.c index 9d7f5d8..bfc17ed 100644 --- a/bootloader/libs/fatfs/diskio.c +++ b/bootloader/libs/fatfs/diskio.c @@ -11,6 +11,8 @@ #include "diskio.h" /* FatFs lower layer API */ #include "../../storage/sdmmc.h" +#define SDMMC_UPPER_BUFFER 0xB8000000 + extern sdmmc_storage_t sd_storage; DSTATUS disk_status ( @@ -36,7 +38,7 @@ DRESULT disk_read ( { if ((u32)buff >= 0x90000000) return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR; - u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere. + u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere. if (sdmmc_storage_read(&sd_storage, sector, count, buf)) { memcpy(buff, buf, 512 * count); @@ -54,7 +56,7 @@ DRESULT disk_write ( { if ((u32)buff >= 0x90000000) return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR; - u8 *buf = (u8 *)0x98000000; //TODO: define this somewhere. + u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere. memcpy(buf, buff, 512 * count); if (sdmmc_storage_write(&sd_storage, sector, count, buf)) return RES_OK; diff --git a/bootloader/main.c b/bootloader/main.c index 5491fec..35989a4 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -116,10 +116,12 @@ void *sd_file_read(char *path) u8 *ptr = buf; while (size > 0) { - u32 rsize = MIN(size, 512 * 512); + u32 rsize = MIN(size, 512 * 8192); if (f_read(&fp, ptr, rsize, NULL) != FR_OK) { free(buf); + f_close(&fp); + return NULL; } @@ -259,7 +261,7 @@ void check_power_off_from_hos() display_backlight_brightness(10, 5000); display_backlight_brightness(100, 25000); - usleep(600000); + msleep(600); display_backlight_brightness(0, 20000); } power_off(); @@ -759,7 +761,6 @@ void auto_launch_firmware() u8 *BOOTLOGO = NULL; char *payload_path = NULL; - FIL fp; u32 btn = 0; struct _bmp_data @@ -852,7 +853,6 @@ void auto_launch_firmware() if (h_cfg.autoboot_list) { - ini_free(&ini_sections); ini_free_section(cfg_sec); boot_entry_id = 1; bootlogoCustomEntry = NULL; @@ -909,16 +909,13 @@ void auto_launch_firmware() u8 *bitmap = NULL; if (!(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH)) { - if (bootlogoCustomEntry != NULL) // Check if user set custom logo path at the boot entry. - { + if (bootlogoCustomEntry) // Check if user set custom logo path at the boot entry. bitmap = (u8 *)sd_file_read(bootlogoCustomEntry); - if (bitmap == NULL) // Custom entry bootlogo not found, trying default custom one. - bitmap = (u8 *)sd_file_read("bootloader/bootlogo.bmp"); - } - else // User has not set a custom logo path. + + if (!bitmap) // Custom entry bootlogo not found, trying default custom one. bitmap = (u8 *)sd_file_read("bootloader/bootlogo.bmp"); - if (bitmap != NULL) + if (bitmap) { // Get values manually to avoid unaligned access. bmpData.size = bitmap[2] | bitmap[3] << 8 | @@ -932,7 +929,7 @@ void auto_launch_firmware() // Sanity check. if (bitmap[0] == 'B' && bitmap[1] == 'M' && - bitmap[28] == 32 && // + bitmap[28] == 32 && // Only 32 bit BMPs allowed. bmpData.size_x <= 720 && bmpData.size_y <= 1280) { @@ -1183,6 +1180,10 @@ menu_t menu_top = { "hekate - CTCaer mod v4.8", 0, 0 }; +#define IPL_STACK_TOP 0x90010000 +#define IPL_HEAP_START 0x90020000 +#define IPL_HEAP_END 0xB8000000 + extern void pivot_stack(u32 stack_top); void ipl_main() @@ -1191,13 +1192,13 @@ void ipl_main() config_hw(); //Pivot the stack so we have enough space. - pivot_stack(0x90010000); + pivot_stack(IPL_STACK_TOP); //Tegra/Horizon configuration goes to 0x80000000+, package2 goes to 0xA9800000, we place our heap in between. - heap_init(0x90020000); + heap_init(IPL_HEAP_START); #ifdef DEBUG_UART_PORT - uart_send(DEBUG_UART_PORT, (u8 *)"Hekate: Hello!\r\n", 18); + uart_send(DEBUG_UART_PORT, (u8 *)"Hekate: Hello!\r\n", 16); uart_wait_idle(DEBUG_UART_PORT, UART_TX_IDLE); #endif diff --git a/bootloader/mem/heap.c b/bootloader/mem/heap.c index b2b03dc..e637dd2 100644 --- a/bootloader/mem/heap.c +++ b/bootloader/mem/heap.c @@ -124,6 +124,6 @@ void *calloc(u32 num, u32 size) void free(void *buf) { - if ((buf != NULL) || ((u32)buf > (_heap.start - 1))) + if ((u32)buf >= _heap.start) _heap_free(&_heap, (u32)buf); } diff --git a/bootloader/sec/se.c b/bootloader/sec/se.c index 4f01022..69b76b8 100644 --- a/bootloader/sec/se.c +++ b/bootloader/sec/se.c @@ -270,15 +270,15 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size) int res; // Setup config for SHA256, size = BITS(src_size). SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); - SE(SE_SHA_CONFIG_REG_OFFSET) = 1; + SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_ENABLE; SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3); - SE(0x208) = 0; - SE(0x20C) = 0; - SE(0x210) = 0; + SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0; + SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0; + SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 3) = 0; SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3); - SE(0x218) = 0; - SE(0x21C) = 0; - SE(0x220) = 0; + SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 1) = 0; + SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 2) = 0; + SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 3) = 0; // Trigger the operation. res = _se_execute(OP_START, NULL, 0, src, src_size); diff --git a/bootloader/soc/hw_init.c b/bootloader/soc/hw_init.c index 1992921..271140b 100644 --- a/bootloader/soc/hw_init.c +++ b/bootloader/soc/hw_init.c @@ -168,7 +168,7 @@ void _config_se_brom() // This memset needs to happen here, else TZRAM will behave weirdly later on. memset((void *)TZRAM_BASE, 0, 0x10000); - PMC(APBDEV_PMC_CRYPTO_OP) = 0; + PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_ENABLE; SE(SE_INT_STATUS_REG_OFFSET) = 0x1F; // Clear the boot reason to avoid problems later diff --git a/bootloader/soc/pmc.h b/bootloader/soc/pmc.h index 123a4c7..ec8eb99 100644 --- a/bootloader/soc/pmc.h +++ b/bootloader/soc/pmc.h @@ -32,6 +32,8 @@ #define PMC_PWR_DET_SDMMC1_IO_EN (1 << 12) #define APBDEV_PMC_DDR_PWR 0xE8 #define APBDEV_PMC_CRYPTO_OP 0xF4 +#define PMC_CRYPTO_OP_SE_ENABLE 0 +#define PMC_CRYPTO_OP_SE_DISABLE 1 #define APBDEV_PMC_SCRATCH33 0x120 #define APBDEV_PMC_SCRATCH40 0x13C #define APBDEV_PMC_OSC_EDPD_OVER 0x1A4 diff --git a/bootloader/soc/t210.h b/bootloader/soc/t210.h index 761e21e..0d0b541 100644 --- a/bootloader/soc/t210.h +++ b/bootloader/soc/t210.h @@ -181,6 +181,7 @@ /*! Special registers. */ #define EMC_SCRATCH0 0x324 +#define EMC_HEKA_UPD (1 << 30) #define EMC_SEPT_RUN (1 << 31) #endif diff --git a/bootloader/utils/util.c b/bootloader/utils/util.c index 934a5e6..ff5f59f 100644 --- a/bootloader/utils/util.c +++ b/bootloader/utils/util.c @@ -26,7 +26,7 @@ u32 get_tmr_s() u32 get_tmr_ms() { // The registers must be read with the following order: - // -> RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC) + // RTC_MILLI_SECONDS (0x10) -> RTC_SHADOW_SECONDS (0xC) return (RTC(APBDEV_RTC_MILLI_SECONDS) | (RTC(APBDEV_RTC_SHADOW_SECONDS) << 10)); } diff --git a/bootloader/utils/util.h b/bootloader/utils/util.h index 801391a..e73913a 100644 --- a/bootloader/utils/util.h +++ b/bootloader/utils/util.h @@ -20,8 +20,8 @@ #include "types.h" -#define byte_swap_32(num) ((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \ - ((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000) +#define byte_swap_32(num) (((num >> 24) & 0xff) | ((num << 8) & 0xff0000) | \ + ((num >> 8 )& 0xff00) | ((num << 24) & 0xff000000)) typedef struct _cfg_op_t {