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
This commit is contained in:
Kostas Missos 2019-03-08 00:19:04 +02:00
parent 4e7c39d6a0
commit 0ddc1c71a8
14 changed files with 127 additions and 123 deletions

107
Makefile
View file

@ -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 $@

View file

@ -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();

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -181,6 +181,7 @@
/*! Special registers. */
#define EMC_SCRATCH0 0x324
#define EMC_HEKA_UPD (1 << 30)
#define EMC_SEPT_RUN (1 << 31)
#endif

View file

@ -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));
}

View file

@ -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
{