|
|
|
@@ -35,9 +35,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
static void package2_decrypt(package2_header_t *package2);
|
|
|
|
static void package2_decrypt(package2_header_t *package2);
|
|
|
|
static size_t package2_get_src_section(void **section, package2_header_t *package2, unsigned int id);
|
|
|
|
static size_t package2_get_src_section(void **section, package2_header_t *package2, unsigned int id);
|
|
|
|
static size_t package2_get_thermosphere(void **thermosphere);
|
|
|
|
static size_t package2_get_thermosphere(const void **thermosphere);
|
|
|
|
static ini1_header_t *package2_rebuild_ini1(ini1_header_t *ini1, uint32_t target_firmware, void *emummc, size_t emummc_size);
|
|
|
|
static ini1_header_t *package2_rebuild_ini1(ini1_header_t *ini1, uint32_t target_firmware, void *emummc, size_t emummc_size);
|
|
|
|
static void package2_append_section(unsigned int id, package2_header_t *package2, void *data, size_t size);
|
|
|
|
static void package2_append_section(unsigned int id, package2_header_t *package2, const void *data, size_t size);
|
|
|
|
|
|
|
|
static void package2_fixup_thermosphere_and_entrypoint(package2_header_t *package2);
|
|
|
|
static void package2_fixup_header_and_section_hashes(package2_header_t *package2, size_t size);
|
|
|
|
static void package2_fixup_header_and_section_hashes(package2_header_t *package2, size_t size);
|
|
|
|
|
|
|
|
|
|
|
|
static inline size_t align_to_4(size_t s) {
|
|
|
|
static inline size_t align_to_4(size_t s) {
|
|
|
|
@@ -50,7 +51,7 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
|
|
|
|
void *kernel;
|
|
|
|
void *kernel;
|
|
|
|
size_t kernel_size;
|
|
|
|
size_t kernel_size;
|
|
|
|
bool is_sd_kernel = false;
|
|
|
|
bool is_sd_kernel = false;
|
|
|
|
void *thermosphere;
|
|
|
|
const void *thermosphere;
|
|
|
|
size_t thermosphere_size;
|
|
|
|
size_t thermosphere_size;
|
|
|
|
ini1_header_t *orig_ini1, *rebuilt_ini1;
|
|
|
|
ini1_header_t *orig_ini1, *rebuilt_ini1;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -67,6 +68,8 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
|
|
|
|
fatal_error(u8"Error: Package2 has no unused section for Thermosphère!\n");
|
|
|
|
fatal_error(u8"Error: Package2 has no unused section for Thermosphère!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package2->metadata.section_offsets[PACKAGE2_SECTION_UNUSED] = 0; /* base of DRAM */
|
|
|
|
|
|
|
|
|
|
|
|
/* Load Kernel from SD, if possible. */
|
|
|
|
/* Load Kernel from SD, if possible. */
|
|
|
|
{
|
|
|
|
{
|
|
|
|
size_t sd_kernel_size = get_file_size("atmosphere/kernel.bin");
|
|
|
|
size_t sd_kernel_size = get_file_size("atmosphere/kernel.bin");
|
|
|
|
@@ -125,6 +128,9 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm
|
|
|
|
package2_append_section(PACKAGE2_SECTION_INI1, rebuilt_package2, rebuilt_ini1, rebuilt_ini1->size);
|
|
|
|
package2_append_section(PACKAGE2_SECTION_INI1, rebuilt_package2, rebuilt_ini1, rebuilt_ini1->size);
|
|
|
|
package2_append_section(PACKAGE2_SECTION_UNUSED, rebuilt_package2, thermosphere, thermosphere_size);
|
|
|
|
package2_append_section(PACKAGE2_SECTION_UNUSED, rebuilt_package2, thermosphere, thermosphere_size);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Swap entrypoint if Thermosphère is present */
|
|
|
|
|
|
|
|
package2_fixup_thermosphere_and_entrypoint(rebuilt_package2);
|
|
|
|
|
|
|
|
|
|
|
|
/* Fix all necessary data in the header to accomodate for the new patches. */
|
|
|
|
/* Fix all necessary data in the header to accomodate for the new patches. */
|
|
|
|
package2_fixup_header_and_section_hashes(rebuilt_package2, rebuilt_package2_size);
|
|
|
|
package2_fixup_header_and_section_hashes(rebuilt_package2, rebuilt_package2_size);
|
|
|
|
|
|
|
|
|
|
|
|
@@ -309,12 +315,9 @@ static size_t package2_get_src_section(void **section, package2_header_t *packag
|
|
|
|
return package2->metadata.section_sizes[id];
|
|
|
|
return package2->metadata.section_sizes[id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t package2_get_thermosphere(void **thermosphere) {
|
|
|
|
static size_t package2_get_thermosphere(const void **thermosphere) {
|
|
|
|
/*extern const uint8_t thermosphere_bin[];
|
|
|
|
(*thermosphere) = thermosphere_bin;
|
|
|
|
extern const uint32_t thermosphere_bin_size;*/
|
|
|
|
return thermosphere_bin_size;
|
|
|
|
/* TODO: enable when tested. */
|
|
|
|
|
|
|
|
(*thermosphere) = NULL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ini1_header_t *package2_rebuild_ini1(ini1_header_t *ini1, uint32_t target_firmware, void *emummc, size_t emummc_size) {
|
|
|
|
static ini1_header_t *package2_rebuild_ini1(ini1_header_t *ini1, uint32_t target_firmware, void *emummc, size_t emummc_size) {
|
|
|
|
@@ -335,7 +338,7 @@ static ini1_header_t *package2_rebuild_ini1(ini1_header_t *ini1, uint32_t target
|
|
|
|
return merged;
|
|
|
|
return merged;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void package2_append_section(unsigned int id, package2_header_t *package2, void *data, size_t size) {
|
|
|
|
static void package2_append_section(unsigned int id, package2_header_t *package2, const void *data, size_t size) {
|
|
|
|
/* This function must be called in ascending order of id. */
|
|
|
|
/* This function must be called in ascending order of id. */
|
|
|
|
/* We assume that the loading address doesn't need to be changed. */
|
|
|
|
/* We assume that the loading address doesn't need to be changed. */
|
|
|
|
uint8_t *dst = package2->data;
|
|
|
|
uint8_t *dst = package2->data;
|
|
|
|
@@ -347,6 +350,22 @@ static void package2_append_section(unsigned int id, package2_header_t *package2
|
|
|
|
package2->metadata.section_sizes[id] = align_to_4(size);
|
|
|
|
package2->metadata.section_sizes[id] = align_to_4(size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void package2_fixup_thermosphere_and_entrypoint(package2_header_t *package2) {
|
|
|
|
|
|
|
|
/* Return if Thermosphère is not present */
|
|
|
|
|
|
|
|
if (package2->metadata.section_sizes[PACKAGE2_SECTION_UNUSED] == 0) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t *dst = package2->data;
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < PACKAGE2_SECTION_UNUSED; i++) {
|
|
|
|
|
|
|
|
dst += package2->metadata.section_sizes[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Swap kernel entrypoint with Thermosphère */
|
|
|
|
|
|
|
|
*(uint32_t *)(dst + 4) = DRAM_BASE_PHYSICAL + package2->metadata.entrypoint;
|
|
|
|
|
|
|
|
package2->metadata.entrypoint = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void package2_fixup_header_and_section_hashes(package2_header_t *package2, size_t size) {
|
|
|
|
static void package2_fixup_header_and_section_hashes(package2_header_t *package2, size_t size) {
|
|
|
|
uint8_t *data = package2->data;
|
|
|
|
uint8_t *data = package2->data;
|
|
|
|
|
|
|
|
|
|
|
|
|