[hos] Support new mailbox and refactor a little bit

This commit is contained in:
Kostas Missos 2019-02-24 02:54:32 +02:00
parent 2fb37db707
commit 7d908c9ac5
4 changed files with 126 additions and 106 deletions

View file

@ -50,6 +50,19 @@ extern void sd_unmount();
//#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__) //#define DPRINTF(...) gfx_printf(&gfx_con, __VA_ARGS__)
#define DPRINTF(...) #define DPRINTF(...)
#define SECMON_MB_ADDR 0x40002EF8
#define SECMON7_MB_ADDR 0x400000F8
// Secmon mailbox.
typedef struct _secmon_mailbox_t
{
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
// >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
u32 in;
// Non-zero: Secmon ready.
u32 out;
} secmon_mailbox_t;
static const u8 keyblob_keyseeds[][0x10] = { static const u8 keyblob_keyseeds[][0x10] = {
{ 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0 { 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, //1.0.0
{ 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0 { 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, //3.0.0
@ -68,7 +81,7 @@ static const u8 master_keyseed_retail[0x10] =
static const u8 console_keyseed[0x10] = static const u8 console_keyseed[0x10] =
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 }; { 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
static const u8 key8_keyseed[] = static const u8 package2_keyseed[] =
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 }; { 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
static const u8 master_keyseed_4xx_5xx_610[0x10] = static const u8 master_keyseed_4xx_5xx_610[0x10] =
@ -129,9 +142,7 @@ void _pmc_scratch_lock(u32 kb)
PMC(APBDEV_PMC_SEC_DISABLE7) = 0xFFFFFFFF; PMC(APBDEV_PMC_SEC_DISABLE7) = 0xFFFFFFFF;
PMC(APBDEV_PMC_SEC_DISABLE8) = 0xFFAAFFFF; PMC(APBDEV_PMC_SEC_DISABLE8) = 0xFFAAFFFF;
break; break;
case KB_FIRMWARE_VERSION_400: default:
case KB_FIRMWARE_VERSION_500:
case KB_FIRMWARE_VERSION_600:
PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF; PMC(APBDEV_PMC_SEC_DISABLE2) |= 0x3FCFFFF;
PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF; PMC(APBDEV_PMC_SEC_DISABLE4) |= 0x3F3FFFFF;
PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF; PMC(APBDEV_PMC_SEC_DISABLE5) = 0xFFFFFFFF;
@ -165,20 +176,27 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
u8 tmp[0x20]; u8 tmp[0x20];
u32 retries = 0; u32 retries = 0;
tsec_ctxt->size = 0xF00;
if (kb > KB_FIRMWARE_VERSION_MAX) if (kb > KB_FIRMWARE_VERSION_MAX)
return 0; return 0;
// Get TSEC key. if (kb <= KB_FIRMWARE_VERSION_600)
if (kb >= KB_FIRMWARE_VERSION_620) tsec_ctxt->size = 0xF00;
{ else if (kb == KB_FIRMWARE_VERSION_620)
tsec_ctxt->size = 0x2900; tsec_ctxt->size = 0x2900;
else
tsec_ctxt->size = 0x3000;
// Prepare smmu tsec page for 6.2.0.
if (kb == KB_FIRMWARE_VERSION_620)
{
u8 *tsec_paged = (u8 *)page_alloc(3); u8 *tsec_paged = (u8 *)page_alloc(3);
memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size); memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size);
tsec_ctxt->fw = tsec_paged; tsec_ctxt->fw = tsec_paged;
} }
// Get TSEC key.
if (kb <= KB_FIRMWARE_VERSION_620)
{
while (tsec_query(tmp, kb, tsec_ctxt) < 0) while (tsec_query(tmp, kb, tsec_ctxt) < 0)
{ {
memset(tmp, 0x00, 0x20); memset(tmp, 0x00, 0x20);
@ -191,8 +209,9 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
return 0; return 0;
} }
} }
}
if (kb >= KB_FIRMWARE_VERSION_620) if (kb == KB_FIRMWARE_VERSION_620)
{ {
// Set TSEC key. // Set TSEC key.
se_aes_key_set(12, tmp, 0x10); se_aes_key_set(12, tmp, 0x10);
@ -203,7 +222,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
se_aes_key_set(8, tmp + 0x10, 0x10); se_aes_key_set(8, tmp + 0x10, 0x10);
se_aes_unwrap_key(8, 8, master_keyseed_620); se_aes_unwrap_key(8, 8, master_keyseed_620);
se_aes_unwrap_key(8, 8, master_keyseed_retail); se_aes_unwrap_key(8, 8, master_keyseed_retail);
se_aes_unwrap_key(8, 8, key8_keyseed); se_aes_unwrap_key(8, 8, package2_keyseed);
} }
else else
{ {
@ -264,7 +283,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt)
// Package2 key. // Package2 key.
se_key_acc_ctrl(8, 0x15); se_key_acc_ctrl(8, 0x15);
se_aes_unwrap_key(8, 12, key8_keyseed); se_aes_unwrap_key(8, 12, package2_keyseed);
} }
return 1; return 1;
@ -285,10 +304,10 @@ static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1); ctxt->pkg1_id = pkg1_identify(ctxt->pkg1);
if (!ctxt->pkg1_id) if (!ctxt->pkg1_id)
{ {
gfx_printf(&gfx_con, "%kUnknown pkg1,\nVersion (= '%s').%k\n", 0xFFFF0000, (char *)ctxt->pkg1 + 0x10, 0xFFCCCCCC); gfx_printf(&gfx_con, "%kUnknown pkg1 version.%k\n", 0xFFFF0000, 0xFFCCCCCC);
goto out; goto out;
} }
gfx_printf(&gfx_con, "Identified pkg1 ('%s'),\nKeyblob version %d\n\n", (char *)(ctxt->pkg1 + 0x10), ctxt->pkg1_id->kb); gfx_printf(&gfx_con, "Identified pkg1 and Keyblob %d\n\n", ctxt->pkg1_id->kb);
// Read the correct keyblob. // Read the correct keyblob.
ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1); ctxt->keyblob = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
@ -371,7 +390,7 @@ int hos_launch(ini_sec_t *cfg)
gfx_con_setpos(&gfx_con, 0, 0); gfx_con_setpos(&gfx_con, 0, 0);
// Try to parse config if present. // Try to parse config if present.
if (cfg && !_parse_boot_config(&ctxt, cfg)) if (cfg && !parse_boot_config(&ctxt, cfg))
return 0; return 0;
gfx_printf(&gfx_con, "Initializing...\n\n"); gfx_printf(&gfx_con, "Initializing...\n\n");
@ -384,10 +403,10 @@ int hos_launch(ini_sec_t *cfg)
if (h_cfg.autonogc && !(fuse_read_odm(7) & ~0xF) && ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_400) if (h_cfg.autonogc && !(fuse_read_odm(7) & ~0xF) && ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_400)
config_kip1patch(&ctxt, "nogc"); config_kip1patch(&ctxt, "nogc");
gfx_printf(&gfx_con, "Loaded pkg1 and keyblob\n"); gfx_printf(&gfx_con, "Loaded pkg1 & keyblob\n");
// Generate keys. // Generate keys.
if (!h_cfg.se_keygen_done || ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_620) if (!h_cfg.se_keygen_done || ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_620)
{ {
tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off; tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
tsec_ctxt.pkg1 = ctxt.pkg1; tsec_ctxt.pkg1 = ctxt.pkg1;
@ -407,9 +426,13 @@ int hos_launch(ini_sec_t *cfg)
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600) if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_600)
pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1); pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1);
if (ctxt.pkg1_id->kb <= KB_FIRMWARE_VERSION_620)
{
pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1); pkg1_unpack((void *)ctxt.pkg1_id->warmboot_base, (void *)ctxt.pkg1_id->secmon_base, NULL, ctxt.pkg1_id, ctxt.pkg1);
gfx_printf(&gfx_con, "Decrypted & unpacked pkg1\n");
gfx_printf(&gfx_con, "Decrypted and unpacked pkg1\n"); }
else
return 0;
} }
// Replace 'warmboot.bin' if requested. // Replace 'warmboot.bin' if requested.
@ -439,7 +462,7 @@ int hos_launch(ini_sec_t *cfg)
*(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val; *(vu32 *)(ctxt.pkg1_id->secmon_base + secmon_patchset[i].off) = secmon_patchset[i].val;
} }
gfx_printf(&gfx_con, "Loaded warmboot.bin and secmon\n"); gfx_printf(&gfx_con, "Loaded warmboot and secmon\n");
// Read package2. // Read package2.
u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt); u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt);
@ -498,7 +521,7 @@ int hos_launch(ini_sec_t *cfg)
} }
// Merge extra KIP1s into loaded ones. // Merge extra KIP1s into loaded ones.
gfx_printf(&gfx_con, "%kPatching kernel initial processes%k\n", 0xFFFFBA00, 0xFFCCCCCC); gfx_printf(&gfx_con, "%kPatching kips%k\n", 0xFFFFBA00, 0xFFCCCCCC);
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link) LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1); pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
@ -506,7 +529,7 @@ int hos_launch(ini_sec_t *cfg)
const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches); const char* unappliedPatch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
if (unappliedPatch != NULL) if (unappliedPatch != NULL)
{ {
gfx_printf(&gfx_con, "%kFailed to apply patch '%s'!%k\n", 0xFFFF0000, unappliedPatch, 0xFFCCCCCC); gfx_printf(&gfx_con, "%kFailed to apply '%s'!%k\n", 0xFFFF0000, unappliedPatch, 0xFFCCCCCC);
sd_unmount(); // Just exiting is not enough until pkg2_patch_kips stops modifying the string passed into it. sd_unmount(); // Just exiting is not enough until pkg2_patch_kips stops modifying the string passed into it.
_free_launch_components(&ctxt); _free_launch_components(&ctxt);
@ -516,7 +539,7 @@ int hos_launch(ini_sec_t *cfg)
// Rebuild and encrypt package2. // Rebuild and encrypt package2.
pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info); pkg2_build_encrypt((void *)0xA9800000, ctxt.kernel, ctxt.kernel_size, &kip1_info);
gfx_printf(&gfx_con, "Rebuilt and loaded pkg2\n"); gfx_printf(&gfx_con, "Rebuilt & loaded pkg2\n");
gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC); gfx_printf(&gfx_con, "\n%kBooting...%k\n", 0xFF96FF00, 0xFFCCCCCC);
@ -547,7 +570,7 @@ int hos_launch(ini_sec_t *cfg)
case KB_FIRMWARE_VERSION_600: case KB_FIRMWARE_VERSION_600:
se_key_acc_ctrl(12, 0xFF); se_key_acc_ctrl(12, 0xFF);
se_key_acc_ctrl(15, 0xFF); se_key_acc_ctrl(15, 0xFF);
case KB_FIRMWARE_VERSION_620: default:
bootStateDramPkg2 = 2; bootStateDramPkg2 = 2;
bootStatePkg2Continue = 4; bootStatePkg2Continue = 4;
break; break;
@ -586,22 +609,22 @@ int hos_launch(ini_sec_t *cfg)
if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_620) if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_620)
_sysctr0_reset(); _sysctr0_reset();
// Free allocated memory.
ini_free_section(cfg);
_free_launch_components(&ctxt);
// < 4.0.0 pkg1.1 locks PMC scratches. // < 4.0.0 pkg1.1 locks PMC scratches.
//_pmc_scratch_lock(ctxt.pkg1_id->kb); //_pmc_scratch_lock(ctxt.pkg1_id->kb);
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot. // Set secmon mailbox address.
// >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot. if (ctxt.pkg1_id->kb >= KB_FIRMWARE_VERSION_700)
vu32 *mb_in = (vu32 *)0x40002EF8; secmon_mb = (secmon_mailbox_t *)SECMON7_MB_ADDR;
// Non-zero: Secmon ready. else
vu32 *mb_out = (vu32 *)0x40002EFC; secmon_mb = (secmon_mailbox_t *)SECMON_MB_ADDR;
// Start from DRAM ready signal. // Start from DRAM ready signal and reset outgoing value.
*mb_in = bootStateDramPkg2; secmon_mb->in = bootStateDramPkg2;
*mb_out = 0; secmon_mb->out = 0;
// Free allocated memory.
ini_free_section(cfg);
_free_launch_components(&ctxt);
// Disable display. This must be executed before secmon to provide support for all fw versions. // Disable display. This must be executed before secmon to provide support for all fw versions.
display_end(); display_end();
@ -611,14 +634,14 @@ int hos_launch(ini_sec_t *cfg)
smmu_exit(); smmu_exit();
else else
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base); cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
while (!*mb_out) while (!secmon_mb->out)
usleep(1); // This only works when in IRAM or with a trained DRAM. usleep(1); // This only works when in IRAM or with a trained DRAM.
// Signal pkg2 ready and continue boot. // Signal pkg2 ready and continue boot.
*mb_in = bootStatePkg2Continue; secmon_mb->in = bootStatePkg2Continue;
// Halt ourselves in waitevent state and resume if there's JTAG activity. // Halt ourselves in waitevent state and resume if there's JTAG activity.
while (1) while (true)
FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = 0x50000000; FLOW_CTLR(FLOW_CTLR_HALT_COP_EVENTS) = 0x50000000;
return 0; return 0;

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018 naehrwert * Copyright (c) 2018 naehrwert
* Copyright (c) 2018 st4rk * Copyright (c) 2018 st4rk
* Copyright (c) 2018 CTCaer * Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018 balika011 * Copyright (c) 2018 balika011
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -20,8 +20,11 @@
#include <string.h> #include <string.h>
#include "pkg1.h" #include "pkg1.h"
#include "../utils/aarch64_util.h" #include "../gfx/gfx.h"
#include "../sec/se.h" #include "../sec/se.h"
#include "../utils/aarch64_util.h"
extern gfx_con_t gfx_con;
#define _NOPv7() 0xE320F000 #define _NOPv7() 0xE320F000
@ -116,20 +119,6 @@ PATCHSET_DEF(_warmboot_4_patchset,
{ 0x558, _NOPv7() } // Segment id check. { 0x558, _NOPv7() } // Segment id check.
); );
PATCHSET_DEF(_warmboot_5_patchset,
{ 0x544, _NOPv7() }, // Fuse check.
{ 0x558, _NOPv7() } // Segment id check.
);
PATCHSET_DEF(_warmboot_6_patchset,
{ 0x544, _NOPv7() }, // Fuse check.
{ 0x558, _NOPv7() } // Segment id check.
);
PATCHSET_DEF(_warmboot_620_patchset,
{ 0x544, _NOPv7() }, // Fuse check.
{ 0x558, _NOPv7() } // Segment id check.
);
/* /*
* package1.1 header: <wb, ldr, sm> * package1.1 header: <wb, ldr, sm>
@ -150,15 +139,19 @@ static const pkg1_id_t _pkg1_ids[] = {
{ "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0 { "20170519101410", 1, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.0
{ "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2 { "20170710161758", 2, 0x1A00, 0x3FE0, { 0, 1, 2 }, 0x4002D000, 0x8000D000, true, _secmon_3_patchset, _warmboot_3_patchset }, //3.0.1 - 3.0.2
{ "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0 { "20170921172629", 3, 0x1800, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_4_patchset, _warmboot_4_patchset }, //4.0.0 - 4.1.0
{ "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_5_patchset }, //5.0.0 - 5.1.0 { "20180220163747", 4, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003B000, false, _secmon_5_patchset, _warmboot_4_patchset }, //5.0.0 - 5.1.0
{ "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_6_patchset }, //6.0.0 - 6.1.0 { "20180802162753", 5, 0x1900, 0x3FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_6_patchset, _warmboot_4_patchset }, //6.0.0 - 6.1.0
{ "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_620_patchset }, //6.2.0 { "20181107105733", 6, 0x0E00, 0x6FE0, { 1, 2, 0 }, 0x4002B000, 0x4003D800, false, _secmon_620_patchset, _warmboot_4_patchset }, //6.2.0
{ NULL } //End. { NULL } //End.
}; };
const pkg1_id_t *pkg1_identify(u8 *pkg1) const pkg1_id_t *pkg1_identify(u8 *pkg1)
{ {
char build_date[15];
memcpy(build_date, (char *)(pkg1 + 0x10), 14);
build_date[14] = 0;
gfx_printf(&gfx_con, "Found pkg1 ('%s').\n\n", build_date);
for (u32 i = 0; _pkg1_ids[i].id; i++) for (u32 i = 0; _pkg1_ids[i].id; i++)
if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12)) if (!memcmp(pkg1 + 0x10, _pkg1_ids[i].id, 12))
return &_pkg1_ids[i]; return &_pkg1_ids[i];

View file

@ -26,6 +26,9 @@
#include "../gfx/gfx.h" #include "../gfx/gfx.h"
#pragma GCC push_options
#pragma GCC optimize ("Os")
extern gfx_con_t gfx_con; extern gfx_con_t gfx_con;
/*#include "util.h" /*#include "util.h"
@ -902,3 +905,4 @@ DPRINTF("INI1 encrypted\n");
*(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size; *(u32 *)hdr->ctr = 0x100 + sizeof(pkg2_hdr_t) + kernel_size + ini1_size;
} }
#pragma GCC pop_options

View file

@ -117,16 +117,16 @@ typedef struct _pkg2_kernel_id_t
typedef struct _kip1_patch_t typedef struct _kip1_patch_t
{ {
u32 offset; //section+offset of patch to apply u32 offset; // section+offset of patch to apply.
u32 length; //in bytes, 0 means last patch u32 length; // In bytes, 0 means last patch.
const char* srcData; //that must match const char* srcData; // That must match.
const char* dstData; //that it gets replaced by const char* dstData; // That it gets replaced by.
} kip1_patch_t; } kip1_patch_t;
typedef struct _kip1_patchset_t typedef struct _kip1_patchset_t
{ {
const char* name; //NULL means end const char* name; // NULL means end.
kip1_patch_t* patches; //NULL means not necessary kip1_patch_t* patches; // NULL means not necessary.
} kip1_patchset_t; } kip1_patchset_t;
typedef struct _kip1_id_t typedef struct _kip1_id_t