mirror of
https://github.com/CTCaer/hekate.git
synced 2024-11-22 18:06:40 +00:00
hos: allow reusage of embedded INI1 region
This commit is contained in:
parent
533fb08a1c
commit
03f11370c7
1 changed files with 25 additions and 14 deletions
|
@ -702,30 +702,39 @@ DPRINTF("sec %d has size %08X\n", i, hdr->sec_size[i]);
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 _pkg2_ini1_build(u8 *pdst, pkg2_hdr_t *hdr, link_t *kips_info, bool new_pkg2)
|
static u32 _pkg2_ini1_build(u8 *pdst, u8 *psec, pkg2_hdr_t *hdr, link_t *kips_info, bool new_pkg2)
|
||||||
{
|
{
|
||||||
|
// Calculate INI1 size.
|
||||||
u32 ini1_size = sizeof(pkg2_ini1_t);
|
u32 ini1_size = sizeof(pkg2_ini1_t);
|
||||||
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
|
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
|
||||||
|
{
|
||||||
|
ini1_size += ki->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align size and set it.
|
||||||
|
ini1_size = ALIGN(ini1_size, 4);
|
||||||
|
|
||||||
|
// For new kernel if INI1 fits in the old one, use it.
|
||||||
|
bool use_old_ini_region = psec && ini1_size <= (pkg2_newkern_ini1_end - pkg2_newkern_ini1_start);
|
||||||
|
if (use_old_ini_region)
|
||||||
|
pdst = psec + pkg2_newkern_ini1_start;
|
||||||
|
|
||||||
// Set initial header and magic.
|
// Set initial header and magic.
|
||||||
|
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)pdst;
|
||||||
memset(ini1, 0, sizeof(pkg2_ini1_t));
|
memset(ini1, 0, sizeof(pkg2_ini1_t));
|
||||||
ini1->magic = INI1_MAGIC;
|
ini1->magic = INI1_MAGIC;
|
||||||
|
ini1->size = ini1_size;
|
||||||
pdst += sizeof(pkg2_ini1_t);
|
pdst += sizeof(pkg2_ini1_t);
|
||||||
|
|
||||||
// Merge kips into INI1.
|
// Merge KIPs into INI1.
|
||||||
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
|
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, kips_info, link)
|
||||||
{
|
{
|
||||||
DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
|
DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->size);
|
||||||
memcpy(pdst, ki->kip1, ki->size);
|
memcpy(pdst, ki->kip1, ki->size);
|
||||||
pdst += ki->size;
|
pdst += ki->size;
|
||||||
ini1_size += ki->size;
|
|
||||||
ini1->num_procs++;
|
ini1->num_procs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Align size and set it.
|
|
||||||
ini1_size = ALIGN(ini1_size, 4);
|
|
||||||
ini1->size = ini1_size;
|
|
||||||
|
|
||||||
// Encrypt INI1 in its own section if old pkg2. Otherwise it gets embedded into Kernel.
|
// Encrypt INI1 in its own section if old pkg2. Otherwise it gets embedded into Kernel.
|
||||||
if (!new_pkg2)
|
if (!new_pkg2)
|
||||||
{
|
{
|
||||||
|
@ -739,16 +748,16 @@ DPRINTF("adding kip1 '%s' @ %08X (%08X)\n", ki->kip1->name, (u32)ki->kip1, ki->s
|
||||||
hdr->sec_off[PKG2_SEC_INI1] = 0;
|
hdr->sec_off[PKG2_SEC_INI1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ini1_size;
|
return !use_old_ini_region ? ini1_size : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info, bool is_exo)
|
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info, bool is_exo)
|
||||||
{
|
{
|
||||||
u8 *pdst = (u8 *)dst;
|
|
||||||
launch_ctxt_t * ctxt = (launch_ctxt_t *)hos_ctxt;
|
launch_ctxt_t * ctxt = (launch_ctxt_t *)hos_ctxt;
|
||||||
u32 kernel_size = ctxt->kernel_size;
|
u32 kernel_size = ctxt->kernel_size;
|
||||||
bool is_meso = *(u32 *)(ctxt->kernel + 4) == ATM_MESOSPHERE;
|
bool is_meso = *(u32 *)(ctxt->kernel + 4) == ATM_MESOSPHERE;
|
||||||
u8 kb = ctxt->pkg1_id->kb;
|
u8 kb = ctxt->pkg1_id->kb;
|
||||||
|
u8 *pdst = (u8 *)dst;
|
||||||
|
|
||||||
// Force new Package2 if Mesosphere.
|
// Force new Package2 if Mesosphere.
|
||||||
if (is_meso)
|
if (is_meso)
|
||||||
|
@ -789,12 +798,14 @@ DPRINTF("%s @ %08X (%08X)\n", is_meso ? "Mesosphere": "kernel",(u32)ctxt->kernel
|
||||||
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
|
hdr->sec_off[PKG2_SEC_KERNEL] = 0x10000000;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Build INI1 for new Package2.
|
||||||
|
u32 ini1_size = _pkg2_ini1_build(pdst + kernel_size, is_meso ? NULL : pdst, hdr, kips_info, true);
|
||||||
|
hdr->sec_off[PKG2_SEC_KERNEL] = 0x60000;
|
||||||
|
|
||||||
// Set new INI1 offset to kernel.
|
// Set new INI1 offset to kernel.
|
||||||
*(u32 *)(pdst + (is_meso ? 8 : pkg2_newkern_ini1_info)) = kernel_size;
|
*(u32 *)(pdst + (is_meso ? 8 : pkg2_newkern_ini1_info)) = kernel_size;
|
||||||
|
|
||||||
// Build INI1 for new Package2.
|
kernel_size += ini1_size;
|
||||||
kernel_size += _pkg2_ini1_build(pdst + kernel_size, hdr, kips_info, ctxt->new_pkg2);
|
|
||||||
hdr->sec_off[PKG2_SEC_KERNEL] = 0x60000;
|
|
||||||
}
|
}
|
||||||
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
|
hdr->sec_size[PKG2_SEC_KERNEL] = kernel_size;
|
||||||
se_aes_crypt_ctr(pkg2_keyslot, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * SE_AES_IV_SIZE]);
|
se_aes_crypt_ctr(pkg2_keyslot, pdst, kernel_size, pdst, kernel_size, &hdr->sec_ctr[PKG2_SEC_KERNEL * SE_AES_IV_SIZE]);
|
||||||
|
@ -804,7 +815,7 @@ DPRINTF("kernel encrypted\n");
|
||||||
// Build INI1 for old Package2.
|
// Build INI1 for old Package2.
|
||||||
u32 ini1_size = 0;
|
u32 ini1_size = 0;
|
||||||
if (!ctxt->new_pkg2)
|
if (!ctxt->new_pkg2)
|
||||||
ini1_size = _pkg2_ini1_build(pdst, hdr, kips_info, false);
|
ini1_size = _pkg2_ini1_build(pdst, NULL, hdr, kips_info, false);
|
||||||
DPRINTF("INI1 encrypted\n");
|
DPRINTF("INI1 encrypted\n");
|
||||||
|
|
||||||
if (!is_exo) // Not needed on Exosphere 1.0.0 and up.
|
if (!is_exo) // Not needed on Exosphere 1.0.0 and up.
|
||||||
|
|
Loading…
Reference in a new issue