forked from CTCaer/hekate
[Versioning] Better and smarter for update and sept
- Still compatible with old hekate. - Allows for hotfix control - Sept is now copied from actual running payload, negating the need to check update.bin - If a foreign payload is found in sept then it is renamed and hekate copies itself. After sept run, it renames it back and continues with boot.
This commit is contained in:
parent
ca68818efe
commit
2e9a89aa20
11
Makefile
11
Makefile
@ -5,8 +5,12 @@ endif
|
||||
include $(DEVKITARM)/base_rules
|
||||
|
||||
IPL_LOAD_ADDR := 0x40008000
|
||||
IPL_MAGIC := 0x43544349 #"ICTC"
|
||||
BLVERSION_MAJOR := 4
|
||||
BLVERSION_MINOR := 8
|
||||
BLVERSION_HOTFX := 0
|
||||
|
||||
BL_RESERVED := 0
|
||||
|
||||
TARGET := hekate
|
||||
BUILD := build
|
||||
@ -65,12 +69,15 @@ OBJS += $(addprefix $(BUILD)/$(TARGET)/, \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
|
||||
CUSTOMDEFINES := -DBLVERSIONMJ=$(BLVERSION_MAJOR) -DBLVERSIONMN=$(BLVERSION_MINOR) -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
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
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=0
|
||||
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
@ -35,6 +35,7 @@ extern gfx_con_t gfx_con;
|
||||
#define EPRINTF(text) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, 0xFFCCCCCC)
|
||||
#define EPRINTFARGS(text, args...) gfx_printf(&gfx_con, "%k"text"%k\n", 0xFFFF0000, args, 0xFFCCCCCC)
|
||||
|
||||
#define RELOC_META_OFF 0x7C
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
|
||||
#define WB_RST_ADDR 0x40010ED0
|
||||
@ -55,7 +56,6 @@ u8 warmboot_reboot[] = {
|
||||
#define SEPT_PRI_ADDR 0x4003F000
|
||||
|
||||
#define SEPT_PK1T_ADDR 0xC0400000
|
||||
#define SEPT_PK1T_STACK 0x40008000
|
||||
#define SEPT_TCSZ_ADDR (SEPT_PK1T_ADDR - 0x4)
|
||||
#define SEPT_STG1_ADDR (SEPT_PK1T_ADDR + 0x2E100)
|
||||
#define SEPT_STG2_ADDR (SEPT_PK1T_ADDR + 0x60E0)
|
||||
@ -63,13 +63,24 @@ u8 warmboot_reboot[] = {
|
||||
|
||||
extern boot_cfg_t b_cfg;
|
||||
extern hekate_config h_cfg;
|
||||
extern const volatile ipl_ver_meta_t ipl_ver;
|
||||
|
||||
extern void *sd_file_read(char *path);
|
||||
extern void sd_mount();
|
||||
extern void sd_unmount();
|
||||
extern bool is_ipl_updated(void *buf);
|
||||
extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size);
|
||||
|
||||
void check_sept()
|
||||
{
|
||||
// Check if non-hekate payload is used for sept and restore it.
|
||||
if (h_cfg.sept_run && !f_stat("sept/payload.bak", NULL))
|
||||
{
|
||||
f_unlink("sept/payload.bin");
|
||||
f_rename("sept/payload.bak", "sept/payload.bin");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *pkg1 = (u8 *)calloc(1, 0x40000);
|
||||
|
||||
sdmmc_storage_t storage;
|
||||
@ -133,25 +144,41 @@ int reboot_to_sept(const u8 *tsec_fw)
|
||||
}
|
||||
f_close(&fp);
|
||||
|
||||
// Save auto boot config to payload, if any.
|
||||
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
|
||||
b_cfg.boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
|
||||
|
||||
tmp_cfg->boot_cfg |= (BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_SEPT_RUN);
|
||||
|
||||
if (f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
|
||||
goto error;
|
||||
|
||||
u32 magic;
|
||||
f_lseek(&fp, f_size(&fp) - 6);
|
||||
f_read(&fp, &magic, 4, NULL);
|
||||
if (magic == 0x43544349)
|
||||
bool update_sept_payload = true;
|
||||
if (!f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
|
||||
{
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||
ipl_ver_meta_t tmp_ver;
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||
f_read(&fp, &tmp_ver, sizeof(ipl_ver_meta_t), NULL);
|
||||
|
||||
if (tmp_ver.magic == ipl_ver.magic)
|
||||
{
|
||||
if (tmp_ver.version == ipl_ver.version)
|
||||
{
|
||||
// Save auto boot config to sept payload, if any.
|
||||
boot_cfg_t *tmp_cfg = malloc(sizeof(boot_cfg_t));
|
||||
memcpy(tmp_cfg, &b_cfg, sizeof(boot_cfg_t));
|
||||
f_lseek(&fp, PATCHED_RELOC_SZ);
|
||||
f_write(&fp, tmp_cfg, sizeof(boot_cfg_t), NULL);
|
||||
f_close(&fp);
|
||||
update_sept_payload = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
f_rename("sept/payload.bin", "sept/payload.bak"); // Backup foreign payload.
|
||||
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
if (update_sept_payload)
|
||||
{
|
||||
volatile reloc_meta_t *reloc = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
|
||||
f_open(&fp, "sept/payload.bin", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_write(&fp, (u8 *)reloc->start, reloc->end - reloc->start, NULL);
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
sd_unmount();
|
||||
|
||||
@ -172,8 +199,6 @@ int reboot_to_sept(const u8 *tsec_fw)
|
||||
|
||||
(*sept)();
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
EPRINTF("Failed to run sept\n");
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
|
@ -6,6 +6,7 @@ SECTIONS {
|
||||
.text : {
|
||||
*(.text._start);
|
||||
*(._boot_cfg);
|
||||
*(._ipl_version);
|
||||
*(.text*);
|
||||
}
|
||||
.data : {
|
||||
|
@ -279,6 +279,7 @@ void check_power_off_from_hos()
|
||||
// This is a safe and unused DRAM region for our payloads.
|
||||
// IPL_LOAD_ADDR is defined in makefile.
|
||||
#define EXT_PAYLOAD_ADDR 0xC03C0000
|
||||
#define RELOC_META_OFF 0x7C
|
||||
#define PATCHED_RELOC_SZ 0x94
|
||||
#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10))
|
||||
#define PAYLOAD_ENTRY 0x40010000
|
||||
@ -312,9 +313,25 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size)
|
||||
#define BOOTLOADER_UPDATED_MAGIC 0x424F4F54 // "BOOT".
|
||||
#define BOOTLOADER_UPDATED_MAGIC_ADDR 0x4003E000
|
||||
|
||||
bool is_ipl_updated(void *buf)
|
||||
{
|
||||
ipl_ver_meta_t *update_ft = (ipl_ver_meta_t *)(buf + PATCHED_RELOC_SZ + sizeof(boot_cfg_t));
|
||||
|
||||
if (update_ft->magic == ipl_ver.magic)
|
||||
{
|
||||
if (byte_swap_32(update_ft->version) <= byte_swap_32(ipl_ver.version))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
int launch_payload(char *path, bool update)
|
||||
{
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
if (!update)
|
||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||
gfx_con_setpos(&gfx_con, 0, 0);
|
||||
if (!path)
|
||||
return 1;
|
||||
@ -350,66 +367,17 @@ int launch_payload(char *path, bool update)
|
||||
f_close(&fp);
|
||||
free(path);
|
||||
|
||||
// Check for updated version.
|
||||
if (update)
|
||||
{
|
||||
u8 *update_ft = calloc(1, 6);
|
||||
if (update && is_ipl_updated(buf))
|
||||
return 1;
|
||||
|
||||
bool update_sept = true;
|
||||
if (!f_open(&fp, "sept/payload.bin", FA_READ | FA_WRITE))
|
||||
{
|
||||
memset(update_ft, 0, 6);
|
||||
f_lseek(&fp, f_size(&fp) - 6);
|
||||
f_read(&fp, update_ft, 6, NULL);
|
||||
f_close(&fp);
|
||||
update_ft[4] -= '0';
|
||||
update_ft[5] -= '0';
|
||||
if (*(u32 *)update_ft == 0x43544349)
|
||||
{
|
||||
if (update_ft[4] == BLVERSIONMJ && update_ft[5] == BLVERSIONMN)
|
||||
update_sept = false;
|
||||
}
|
||||
else
|
||||
update_sept = false;
|
||||
}
|
||||
|
||||
if (update_sept)
|
||||
{
|
||||
if (!f_open(&fp, "sept/payload.bin", FA_CREATE_ALWAYS | FA_WRITE))
|
||||
{
|
||||
f_write(&fp, buf, size, NULL);
|
||||
f_close(&fp);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(update_ft, buf + size - 6, 6);
|
||||
update_ft[4] -= '0';
|
||||
update_ft[5] -= '0';
|
||||
if (*(u32 *)update_ft == 0x43544349)
|
||||
{
|
||||
if (update_ft[4] < BLVERSIONMJ || (update_ft[4] == BLVERSIONMJ && update_ft[5] <= BLVERSIONMN))
|
||||
{
|
||||
free(update_ft);
|
||||
return 1;
|
||||
}
|
||||
*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR = BOOTLOADER_UPDATED_MAGIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(update_ft);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(update_ft);
|
||||
}
|
||||
sd_unmount();
|
||||
|
||||
if (size < 0x30000)
|
||||
{
|
||||
if (!update)
|
||||
reloc_patcher(PAYLOAD_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
if (update)
|
||||
memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t)); // Transfer boot cfg.
|
||||
else
|
||||
memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), (u8 *)(IPL_LOAD_ADDR + PATCHED_RELOC_SZ), sizeof(boot_cfg_t));
|
||||
reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10));
|
||||
|
||||
reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32))));
|
||||
}
|
||||
@ -433,23 +401,12 @@ int launch_payload(char *path, bool update)
|
||||
|
||||
void auto_launch_update()
|
||||
{
|
||||
FIL fp;
|
||||
|
||||
if (*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR == BOOTLOADER_UPDATED_MAGIC)
|
||||
*(vu32 *)BOOTLOADER_UPDATED_MAGIC_ADDR = 0;
|
||||
else
|
||||
if (EMC(EMC_SCRATCH0) & EMC_HEKA_UPD)
|
||||
EMC(EMC_SCRATCH0) &= ~EMC_HEKA_UPD;
|
||||
else if (sd_mount())
|
||||
{
|
||||
if (sd_mount())
|
||||
{
|
||||
if (f_open(&fp, "bootloader/update.bin", FA_READ))
|
||||
return;
|
||||
else
|
||||
{
|
||||
f_close(&fp);
|
||||
launch_payload("bootloader/update.bin", true);
|
||||
}
|
||||
|
||||
}
|
||||
if (!f_stat("bootloader/update.bin", NULL))
|
||||
launch_payload("bootloader/update.bin", true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -825,7 +782,7 @@ out:
|
||||
|
||||
void auto_launch_firmware()
|
||||
{
|
||||
if (!(b_cfg->boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
if (!(b_cfg.boot_cfg & BOOT_CFG_FROM_LAUNCH))
|
||||
{
|
||||
auto_launch_update();
|
||||
gfx_con.mute = true;
|
||||
@ -856,10 +813,8 @@ void auto_launch_firmware()
|
||||
|
||||
if (sd_mount())
|
||||
{
|
||||
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_READ))
|
||||
if (f_stat("bootloader/hekate_ipl.ini", NULL))
|
||||
create_config_entry();
|
||||
else
|
||||
f_close(&fp);
|
||||
|
||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||
{
|
||||
|
@ -76,4 +76,12 @@ typedef struct __attribute__((__packed__)) _ipl_ver_meta_t
|
||||
u16 rsvd1;
|
||||
} ipl_ver_meta_t;
|
||||
|
||||
typedef struct __attribute__((__packed__)) _reloc_meta_t
|
||||
{
|
||||
u32 start;
|
||||
u32 stack;
|
||||
u32 end;
|
||||
u32 ep;
|
||||
} reloc_meta_t;
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user