Skip to content
Permalink
Browse files

Almost full 8.0 support

  • Loading branch information...
EliseZeroTwo committed Apr 22, 2019
1 parent 0da52fb commit 14283ed8cdb3063052c47893b3aa15967d5a87f8
Showing with 112 additions and 102 deletions.
  1. +10 −10 src/bootloader.h
  2. +16 −54 src/firmware.c
  3. +1 −1 src/hwinit/sdmmc_driver.c
  4. +13 −0 src/hwinit/types.h
  5. +14 −0 src/kippatches/fs.inc
  6. +56 −36 src/package.c
  7. +2 −1 src/package.h
@@ -20,16 +20,16 @@

// TODO: Maybe find these with memsearch
static const pk11_offs _pk11_offs[] = {
{ KB_FIRMWARE_VERSION_100, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, 0x8000D000 }, //1.0.0
{ KB_FIRMWARE_VERSION_200, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //2.0.0 - 2.3.0
{ KB_FIRMWARE_VERSION_300, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //3.0.0
{ KB_FIRMWARE_VERSION_301, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000 }, //3.0.1 - 3.0.2
{ KB_FIRMWARE_VERSION_400, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000 }, //4.0.0 - 4.1.0
{ KB_FIRMWARE_VERSION_500, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000 }, //5.0.0 - 5.0.2
{ KB_FIRMWARE_VERSION_600, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800 }, //6.0.0
{ KB_FIRMWARE_VERSION_620, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800 }, //6.2.0
{ KB_FIRMWARE_VERSION_700, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 }, //7.0.0
{ KB_FIRMWARE_VERSION_800, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000 },
{ KB_FIRMWARE_VERSION_100, 0x1900, 0x3FE0, { 2, 1, 0 }, 0x40014020, 0x8000D000, HOS_FIRMWARE_VERSION_100 }, //1.0.0
{ KB_FIRMWARE_VERSION_200, 0x1900, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, HOS_FIRMWARE_VERSION_200 }, //2.0.0 - 2.3.0
{ KB_FIRMWARE_VERSION_300, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, HOS_FIRMWARE_VERSION_300 }, //3.0.0
{ KB_FIRMWARE_VERSION_301, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, HOS_FIRMWARE_VERSION_301 }, //3.0.1 - 3.0.2
{ KB_FIRMWARE_VERSION_400, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, HOS_FIRMWARE_VERSION_400 }, //4.0.0 - 4.1.0
{ KB_FIRMWARE_VERSION_500, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, HOS_FIRMWARE_VERSION_500 }, //5.0.0 - 5.0.2
{ KB_FIRMWARE_VERSION_600, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, HOS_FIRMWARE_VERSION_600 }, //6.0.0
{ KB_FIRMWARE_VERSION_620, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, HOS_FIRMWARE_VERSION_620 }, //6.2.0
{ KB_FIRMWARE_VERSION_700, 0x0F00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, HOS_FIRMWARE_VERSION_700 }, //7.0.0 - 7.0.1
{ KB_FIRMWARE_VERSION_800, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x40030000, 0x4003E000, HOS_FIRMWARE_VERSION_800 }, //8.0.0
{ NULL } // End.
};

@@ -132,50 +132,14 @@ u8 loadFirm() {
print("Unpacking package2...\n");

pkg2_hdr_t *dec_pkg2 = unpackFirmwarePackage(pkg2);
//If firmware is 8.0, remake package2 by moving ini1 into its section from kernel
//TODO: find better way to differentiate the firmware version that isn't TSEC firmware offset
if (pk11Offs->tsec_off == 0xE00 && pk11Offs->kb == KB_FIRMWARE_VERSION_800) {
KernelNewOffs *kOffs = (KernelNewOffs*)(dec_pkg2->data + kernelInfo[8].krnl_offs); //TODO
print("New kernel detected!\n");
print("Ini off: %X\n", kOffs->ini_off);
print("KernelLdr off: %X\n", kOffs->krnlLdr_off);

pkg2_ini1_t *old_ini1 = (pkg2_ini1_t *)(dec_pkg2->data + kOffs->ini_off);
dec_pkg2->sec_off[PKG2_SEC_INI1] = dec_pkg2->sec_off[PKG2_SEC_KERNEL] + dec_pkg2->sec_size[PKG2_SEC_KERNEL];
size_t rebuilt_package2_size = sizeof(pkg2_hdr_t) + dec_pkg2->sec_size[0] + ALIGN(old_ini1->size, 4);

pkg2_hdr_t *new_pkg2 = (pkg2_hdr_t *)malloc(rebuilt_package2_size);

memcpy(new_pkg2, dec_pkg2, sizeof(pkg2_hdr_t));
memcpy(new_pkg2->data, dec_pkg2->data, dec_pkg2->sec_size[0]);
memcpy(new_pkg2->data + dec_pkg2->sec_size[0], old_ini1, old_ini1->size);
new_pkg2->sec_size[1] = ALIGN(old_ini1->size, 4);

uint8_t *data = new_pkg2->data;

for (unsigned int section = 0; section < 3; section++) {
size_t sz = (size_t)new_pkg2->sec_size[section];
if(!sz)
continue;

se_calc_sha256(&(new_pkg2->sec_sha256[section * 0x20]), data, sz);
data += sz;
}

u32 *ctrs = (u32 *)(new_pkg2->ctr);
uint32_t package_size = ctrs[0] ^ ctrs[2] ^ ctrs[3];
ctrs[3] ^= (package_size ^ rebuilt_package2_size);
dec_pkg2 = new_pkg2;
}
print("Parsing kips\n");
LIST_INIT(kip1_info);
pkg2_parse_kips(&kip1_info, dec_pkg2);

// Patch firmware.
print("%k\nPatching HOS:\n%k", WHITE, DEFAULT_TEXT_COL);
patchWarmboot(pk11Offs->warmboot_base);
patchSecmon(pk11Offs->secmon_base, pk11Offs->kb);
patchKernel(dec_pkg2);
//patchKernel(dec_pkg2);
patchKernelExtensions(&kip1_info);

// Build Package2.
@@ -256,7 +220,6 @@ void launch() {
*BOOT_STATE_ADDR = (pk11Offs->kb < KB_FIRMWARE_VERSION_400 ? BOOT_PKG2_LOADED : BOOT_PKG2_LOADED_4X);
*SECMON_STATE_ADDR = 0;
}

// Disable display.
display_end();

@@ -286,7 +249,6 @@ void firmware() {
gfx_clear_color(&gfx_ctxt, BLACK);
gfx_con_init(&gfx_con, &gfx_ctxt);
gfx_con_setcol(&gfx_con, DEFAULT_TEXT_COL, 0, 0);
u32 currBut = btn_read();

//Mount SD
if (!sdMount()) {
@@ -299,27 +261,27 @@ void firmware() {

//Chainload ReiNX if applicable
if(PMC(APBDEV_PMC_SCRATCH49) != 69 && PMC(APBDEV_PMC_SCRATCH49) != 67 && fopen("/ReiNX.bin", "rb")) {
size_t size = fsize();
u8 *payload = malloc(size);
size_t size = fsize();
u8 *payload = malloc(size);
fread((void*)PAYLOAD_ADDR, size, 1);
fclose();
metadata_t *metadata = (metadata_t*)(payload + METADATA_OFFSET);
if(metadata->magic == metadata_section.magic) {
if(metadata->major > metadata_section.major || (metadata->major == metadata_section.major && metadata->minor > metadata_section.minor)) {
sdUnmount();
display_end();
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= 0x400; // Enable AHUB clock.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= 0x40; // Enable APE clock.
PMC(APBDEV_PMC_SCRATCH49) = 69;
((void (*)())PAYLOAD_ADDR)();
}
}
metadata_t *metadata = (metadata_t*)(payload + METADATA_OFFSET);
if(metadata->magic == metadata_section.magic) {
if(metadata->major > metadata_section.major || (metadata->major == metadata_section.major && metadata->minor > metadata_section.minor)) {
sdUnmount();
display_end();
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_V) |= 0x400; // Enable AHUB clock.
CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_Y) |= 0x40; // Enable APE clock.
PMC(APBDEV_PMC_SCRATCH49) = 69;
((void (*)())PAYLOAD_ADDR)();
}
}
}
SYSREG(AHB_AHB_SPARE_REG) &= (vu32)0xFFFFFF9F;
PMC(APBDEV_PMC_SCRATCH49) = 0;

//Chainload recovery if applicable
if((currBut & BTN_VOL_UP) && !(currBut & BTN_VOL_DOWN)){
if(btn_read() & BTN_VOL_UP){
if(fopen("/ReiNX/Recovery.bin", "rb") != 0) {
fread((void*)PAYLOAD_ADDR, fsize(), 1);
fclose();
@@ -340,7 +302,7 @@ void firmware() {
}

//Determine if booting in verbose mode
if ((currBut & BTN_VOL_DOWN) && !(currBut & BTN_VOL_UP)) {
if (btn_read() & BTN_VOL_DOWN) {
print("%kWelcome to ReiNX %d.%d!\n%k", WHITE, VERSION_MAJOR, VERSION_MINOR, DEFAULT_TEXT_COL);
} else if (drawSplash()) {
gfx_con.mute = 1;
@@ -1026,8 +1026,8 @@ void sdmmc_end(sdmmc_t *sdmmc)
if (sdmmc->id == SDMMC_1)
{
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
max77620_regulator_enable(REGULATOR_LDO2, 0);
musleep(1); // To power cycle min 1ms without power is needed.
max77620_regulator_enable(REGULATOR_LDO2, 0);
}

_sdmmc_get_clkcon(sdmmc);
@@ -60,4 +60,17 @@ enum KB_FIRMWARE_VERSION {
KB_FIRMWARE_VERSION_800 = 7,
};

enum HOS_FIRMWARE_VERSION {
HOS_FIRMWARE_VERSION_100 = 0,
HOS_FIRMWARE_VERSION_200 = 1,
HOS_FIRMWARE_VERSION_300 = 2,
HOS_FIRMWARE_VERSION_301 = 3,
HOS_FIRMWARE_VERSION_400 = 4,
HOS_FIRMWARE_VERSION_500 = 5,
HOS_FIRMWARE_VERSION_600 = 6,
HOS_FIRMWARE_VERSION_620 = 7,
HOS_FIRMWARE_VERSION_700 = 8,
HOS_FIRMWARE_VERSION_800 = 9,
};

#endif
@@ -228,6 +228,18 @@ static kipdiff_t fs_diffs_800_exfat_nosigchk[3] = {
{ 0, 0, NULL, NULL },
};

static kipdiff_t fs_diffs_800_nogc[3] = {
{ 0x136800, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0x15EB94, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};

static kipdiff_t fs_diffs_800_exfat_nogc[3] = {
{ 0x141DB0, 8, "\xF4\x4F\xBE\xA9\xFD\x7B\x01\xA9", "\xE0\x03\x1F\x2A\xC0\x03\x5F\xD6" },
{ 0x16A144, 4, "\x14\x40\x80\x52", "\x14\x80\x80\x52" },
{ 0, 0, NULL, NULL }
};

/* patches */

static kippatch_t fs_kip_patches_100[] = {
@@ -331,10 +343,12 @@ static kippatch_t fs_kip_patches_700_exfat[] = {

static kippatch_t fs_kip_patches_800[] = {
{ "nosigchk", fs_diffs_800_nosigchk },
{ "nogc", fs_diffs_800_nogc },
{ NULL, NULL }
};

static kippatch_t fs_kip_patches_800_exfat[] = {
{ "nosigchk", fs_diffs_800_exfat_nosigchk },
{ "nogc", fs_diffs_800_exfat_nogc },
{ NULL, NULL }
};
@@ -79,15 +79,18 @@ pkg2_hdr_t *unpackFirmwarePackage(u8 *data) {
error("Package2 Magic invalid!\nThere is a good chance your ReiNX build is outdated\nPlease get the newest build from our guide (reinx.guide) or our discord (discord.reiswitched.team)\nMake sure you replace the ReiNX.bin file on your SD card root too\n");
return NULL;
}
print("decrypted header\n");

//Decrypt body
data += (0x100 + sizeof(pkg2_hdr_t));

for (u32 i = 0; i < 4; i++) {
if (!hdr->sec_size[i]) continue;

se_aes_crypt_ctr(8, data, hdr->sec_size[i], data, hdr->sec_size[i], &hdr->sec_ctr[i * 0x10]);

data += hdr->sec_size[i];
}

return hdr;
}

@@ -178,9 +181,43 @@ bool hasCustomKern() {
return customKernel;
}


static u32 build_ini1(u8 *pdst, pkg2_hdr_t *hdr, link_t *kips_info, bool new_pkg2, bool cust_sec)
{
u32 ini1_size = sizeof(pkg2_ini1_t);
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
memset(ini1, 0, sizeof(pkg2_ini1_t));
ini1->magic = INI1_MAGIC;
pdst += sizeof(pkg2_ini1_t);
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
{
print("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
memcpy(pdst, ki->kip1, ki->size);
pdst += ki->size;
ini1_size += ki->size;
ini1->num_procs++;
}
ini1->size = ini1_size;
if (!new_pkg2)
{
hdr->sec_size[PKG2_SEC_INI1] = ini1_size;
hdr->sec_off[PKG2_SEC_INI1] = 0x14080000;
if (!cust_sec)
se_aes_crypt_ctr(8, ini1, ini1_size, ini1, ini1_size, &hdr->sec_ctr[PKG2_SEC_INI1 * 0x10]);
}
else
{
hdr->sec_size[PKG2_SEC_INI1] = 0;
hdr->sec_off[PKG2_SEC_INI1] = 0;
}

return ini1_size;
}

void buildFirmwarePackage(u8 *kernel, u32 kernel_size, link_t *kips_info, pk11_offs *pk11Offs) {
u8 *pdst = (u8 *)0xA9800000;
bool hasCustSecmon = hasCustomSecmon();
bool new_pkg2 = pk11Offs->hos >= HOS_FIRMWARE_VERSION_800;

// Signature.
memset(pdst, 0, 0x100);
@@ -191,38 +228,33 @@ void buildFirmwarePackage(u8 *kernel, u32 kernel_size, link_t *kips_info, pk11_o
memset(hdr, 0, sizeof(pkg2_hdr_t));
pdst += sizeof(pkg2_hdr_t);
hdr->magic = PKG2_MAGIC;
hdr->base = 0x10000000;
if (new_pkg2)
hdr->base = 0x60000;
else
hdr->base = 0x10000000;
print("kernel @ %08X (%08X)\n", (u32)kernel, kernel_size);

// Kernel.
size_t extSize = 0;
u8 *extKern = LoadExtFile("/ReiNX/kernel.bin", &extSize);
memcpy(pdst, extKern == NULL ? kernel : extKern, extKern == NULL ? kernel_size : extSize);
if (new_pkg2) {
*(u32 *)(pdst + 0x168) = kernel_size;
kernel_size += build_ini1(pdst + kernel_size, hdr, kips_info, new_pkg2, hasCustSecmon);
hdr->sec_off[PKG2_SEC_KERNEL] = 0x60000;
} else
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;

if(!hasCustSecmon)
se_aes_crypt_ctr(8, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * 0x10]);
pdst += kernel_size;

// INI1.
u32 ini1_size = sizeof(pkg2_ini1_t);
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
memset(ini1, 0, sizeof(pkg2_ini1_t));
ini1->magic = INI1_MAGIC;
pdst += sizeof(pkg2_ini1_t);
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link) {
print("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
memcpy(pdst, ki->kip1, ki->size);
pdst += ki->size;
ini1_size += ki->size;
ini1->num_procs++;
u32 ini1_size = 0;
if (!new_pkg2) {
hdr->sec_size[PKG2_SEC_INI1] = build_ini1(pdst + kernel_size, hdr, kips_info, new_pkg2, hasCustSecmon);
}
ini1->size = ini1_size;
hdr->sec_size[PKG2_SEC_INI1] = ini1_size;
hdr->sec_off[PKG2_SEC_INI1] = 0x14080000;
if (!hasCustSecmon)
se_aes_crypt_ctr(8, ini1, ini1_size, ini1, ini1_size, &hdr->sec_ctr[PKG2_SEC_INI1 * 0x10]);

// Encrypt header.
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
if (!hasCustSecmon)
@@ -239,12 +271,9 @@ size_t calcKipSize(pkg2_kip1_t *kip1) {
}

void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2) {
u8 *ptr = pkg2->data;
u8 *ptr = pkg2->data + pkg2->sec_size[PKG2_SEC_KERNEL];
if (pkg2->sec_size[PKG2_SEC_INI1] == 0)
ptr += *(u32 *)(ptr + 0x168);
else
ptr += pkg2->sec_size[PKG2_SEC_KERNEL];

ptr = pkg2->data + *(u32 *)(pkg2->data + 0x168);
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)ptr;
ptr += sizeof(pkg2_ini1_t);

@@ -253,7 +282,6 @@ void pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2) {
pkg2_kip1_info_t *ki = (pkg2_kip1_info_t *)malloc(sizeof(pkg2_kip1_info_t));
ki->kip1 = kip1;
ki->size = calcKipSize(kip1);
print("Found kip %s of size 0x%x\n", kip1->name, ki->size);
list_append(info, &ki->link);
ptr += ki->size;
}
@@ -304,8 +332,8 @@ kippatchset_t kip_patches[] = {
{ "FS", "\x33\x05\x53\xf6\xb5\xfb\x55\xc4\xc2\xd7\xb7\x36\x24\x02\x76\xb3", fs_kip_patches_600_50_exfat },
{ "FS", "\x2a\xdb\xe9\x7e\x9b\x5f\x41\x77\x9e\xc9\x5f\xfe\x26\x99\xc9\x33", fs_kip_patches_700 },
{ "FS", "\x2c\xce\x65\x9c\xec\x53\x6a\x8e\x4d\x91\xf3\xbe\x4b\x74\xbe\xd3", fs_kip_patches_700_exfat },
{ "FS", "\xdb\xd9\x41\xc0\xc5\x3c\x52\xcc\xf7\x20\x2c\x84\xd8\xe0\xf7\x80", fs_kip_patches_800 },
{ "FS", "\xb2\xf5\x17\x6b\x35\x48\x36\x4d\x07\x9a\x29\xb1\x41\xa2\x3b\x06", fs_kip_patches_800_exfat },
{ "FS", "\xb2\xf5\x17\x6b\x35\x48\x36\x4d\x07\x9a\x29\xb1\x41\xa2\x3b\x06", fs_kip_patches_800 },
{ "FS", "\xdb\xd9\x41\xc0\xc5\x3c\x52\xcc\xf7\x20\x2c\x84\xd8\xe0\xf7\x80", fs_kip_patches_800_exfat },
{ NULL, NULL, NULL },
};

@@ -359,10 +387,6 @@ u32 *getSndPayload(u32 id, size_t *size) {
*size = sizeof(PRC_ID_SND_700);
ret = PRC_ID_SND_700;
break;
case 8:
*size = sizeof(PRC_ID_SND_800);
ret = PRC_ID_SND_800;
break;
}
return ret;
}
@@ -402,10 +426,6 @@ u32 *getRcvPayload(u32 id, size_t *size) {
*size = sizeof(PRC_ID_RCV_700);
ret = PRC_ID_RCV_700;
break;
case 8:
*size = sizeof(PRC_ID_RCV_800);
ret = PRC_ID_RCV_800;
break;
}
return ret;
}
@@ -90,6 +90,7 @@ typedef struct {
u32 sec_map[3];
u32 secmon_base;
u32 warmboot_base;
u32 hos;
} pk11_offs;

typedef struct {
@@ -374,4 +375,4 @@ bool hasCustomWb();
u8 *LoadExtFile(char *path, size_t *size);
void loadKip(link_t *info, char *path);
u32 *getSndPayload(u32 id, size_t *size);
u32 *getRcvPayload(u32 id, size_t *size);
u32 *getRcvPayload(u32 id, size_t *size);

1 comment on commit 14283ed

@lavaJockey

This comment has been minimized.

Copy link

commented on 14283ed Apr 21, 2019

SO CLOSE!

Please sign in to comment.
You can’t perform that action at this time.