Nyx: emuMMC Manage window, Tools UI, and misc updates
- Add gui_emu_tools: emuMMC Manage window with correct positioning (LV_PROTECT_PARENT + re-parent to win) - Tools: single SD button (tap = SD partition manager, 3s hold = eMMC) - Remove emuSD from Nyx UI (tabs, UMS, partition manager); keep bootloader emusd - Shorten Create emuMMC description text by one character - Storage/build/config and dependency updates Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 st4rk
|
||||
* Copyright (c) 2018 Ced2911
|
||||
* Copyright (c) 2018-2026 CTCaer
|
||||
* Copyright (c) 2018-2025 CTCaer
|
||||
* Copyright (c) 2018 balika011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "../frontend/fe_tools.h"
|
||||
#include "../config.h"
|
||||
#include "../storage/emummc.h"
|
||||
#include "../storage/emusd.h"
|
||||
#include <storage/boot_storage.h>
|
||||
|
||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
#define DPRINTF(...)
|
||||
@@ -166,7 +168,7 @@ static void _hos_eks_get()
|
||||
|
||||
// Decrypt EKS blob.
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x80);
|
||||
se_aes_crypt_ecb(14, DECRYPT, eks, eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, DECRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Check if valid and for this unit.
|
||||
if (eks->magic == HOS_EKS_MAGIC && eks->lot0 == FUSE(FUSE_OPT_LOT_CODE_0))
|
||||
@@ -212,7 +214,7 @@ static void _hos_eks_save()
|
||||
|
||||
// Get keys.
|
||||
u8 *keys = (u8 *)zalloc(SZ_8K);
|
||||
se_aes_ctx_get_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
|
||||
se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
|
||||
|
||||
// Set magic and personalized info.
|
||||
h_cfg.eks->magic = HOS_EKS_MAGIC;
|
||||
@@ -227,7 +229,7 @@ static void _hos_eks_save()
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = malloc(sizeof(hos_eks_mbr_t));
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
@@ -262,7 +264,7 @@ static void _hos_eks_clear(u32 mkey)
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = malloc(sizeof(hos_eks_mbr_t));
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
@@ -350,7 +352,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s
|
||||
*/
|
||||
|
||||
// Use custom TSEC Hovi Keygen firmware.
|
||||
tsec_ctxt->fw = sd_file_read("bootloader/sys/thk.bin", NULL);
|
||||
tsec_ctxt->fw = boot_storage_file_read("bootloader/sys/thk.bin", NULL);
|
||||
if (!tsec_ctxt->fw)
|
||||
{
|
||||
_hos_crit_error("Failed to load thk.bin");
|
||||
@@ -406,7 +408,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s
|
||||
else
|
||||
{
|
||||
// Decrypt eks and set keyslots.
|
||||
se_aes_crypt_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0]);
|
||||
se_aes_unwrap_key(15, 14, tsec_keys.tmp);
|
||||
|
||||
// Derive device keys.
|
||||
@@ -442,7 +444,7 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s
|
||||
else
|
||||
{
|
||||
// Decrypt eks and set keyslots for Exosphere 2.
|
||||
se_aes_crypt_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0]);
|
||||
se_aes_unwrap_key(15, 14, tsec_keys.tmp);
|
||||
|
||||
// Derive device keys.
|
||||
@@ -469,9 +471,9 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s
|
||||
se_aes_key_set(13, tsec_keys.tsec, SE_KEY_128_SIZE);
|
||||
|
||||
// Derive eks keys from TSEC+SBK.
|
||||
se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[0]);
|
||||
se_aes_unwrap_key(15, 14, tsec_keys.tsec);
|
||||
se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[mkey], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[mkey]);
|
||||
se_aes_unwrap_key(13, 14, tsec_keys.tsec);
|
||||
|
||||
// Clear SBK.
|
||||
@@ -481,21 +483,21 @@ static int _hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt, bool s
|
||||
// Verify eks CMAC.
|
||||
u8 cmac[SE_KEY_128_SIZE];
|
||||
se_aes_unwrap_key(11, 13, cmac_keyseed);
|
||||
se_aes_hash_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)eks->ctr, sizeof(eks->ctr) + sizeof(eks->keys));
|
||||
se_aes_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)eks->ctr, sizeof(eks->ctr) + sizeof(eks->keys));
|
||||
if (!memcmp(eks->cmac, cmac, SE_KEY_128_SIZE))
|
||||
return 0;
|
||||
*/
|
||||
|
||||
se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed);
|
||||
se_aes_unwrap_key(11, 13, cmac_keyseed);
|
||||
|
||||
// Decrypt eks and set keyslots.
|
||||
se_aes_crypt_ctr(13, &eks->keys, &eks->keys, sizeof(eks_keys_t), eks->ctr);
|
||||
se_aes_crypt_ctr(13, &eks->keys, sizeof(eks_keys_t), &eks->keys, sizeof(eks_keys_t), eks->ctr);
|
||||
se_aes_key_set(11, eks->keys.package1_key, SE_KEY_128_SIZE);
|
||||
se_aes_key_set(12, eks->keys.master_kekseed, SE_KEY_128_SIZE);
|
||||
se_aes_key_set(13, eks->keys.master_kekseed, SE_KEY_128_SIZE);
|
||||
|
||||
se_aes_crypt_ecb(12, DECRYPT, tsec_keys.tsec, master_keyseed_retail, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tsec, master_keyseed_retail);
|
||||
|
||||
if (!is_exo)
|
||||
{
|
||||
@@ -666,7 +668,7 @@ static bool _get_fs_exfat_compatible(link_t *info, u32 *hos_revision)
|
||||
if (strcmp((char *)ki->kip1->name, "FS"))
|
||||
continue;
|
||||
|
||||
if (!se_sha_hash_256_oneshot(sha_buf, ki->kip1, ki->size))
|
||||
if (!se_calc_sha256_oneshot(sha_buf, ki->kip1, ki->size))
|
||||
break;
|
||||
|
||||
pkg2_get_ids(&kip_ids, &fs_ids_cnt);
|
||||
@@ -726,8 +728,14 @@ void hos_launch(ini_sec_t *cfg)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (emusd_storage_init_mmc() || !emusd_mount()) {
|
||||
_hos_crit_error("error: Failed to init emuSD.");
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Check if SD Card is GPT.
|
||||
if (sd_is_gpt())
|
||||
if (emusd_is_gpt())
|
||||
{
|
||||
_hos_crit_error("SD has GPT only! Run Fix Hybrid MBR!");
|
||||
goto error;
|
||||
@@ -746,6 +754,8 @@ void hos_launch(ini_sec_t *cfg)
|
||||
// Check if stock is enabled and device can boot in OFW.
|
||||
if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled()))
|
||||
{
|
||||
emusd_storage_end();
|
||||
emummc_storage_end();
|
||||
emmc_end();
|
||||
|
||||
WPRINTF("\nRebooting to OFW in 5s...");
|
||||
@@ -758,7 +768,8 @@ void hos_launch(ini_sec_t *cfg)
|
||||
|
||||
mkey = ctxt.pkg1_id->mkey;
|
||||
|
||||
bool emummc_enabled = emu_cfg.enabled && !h_cfg.emummc_force_disable;
|
||||
// TODO: separate force_disable for emuSD?
|
||||
bool emummc_enabled = (emu_cfg.enabled || emu_sd_cfg.enabled) && !h_cfg.emummc_force_disable;
|
||||
|
||||
// Enable emummc patching.
|
||||
if (emummc_enabled)
|
||||
@@ -839,7 +850,7 @@ void hos_launch(ini_sec_t *cfg)
|
||||
if (h_cfg.t210b01)
|
||||
{
|
||||
u32 bek_vector[4] = {0};
|
||||
se_aes_crypt_ecb(13, ENCRYPT, bek_vector, bek_vector, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(13, ENCRYPT, bek_vector, SE_KEY_128_SIZE, bek_vector, SE_KEY_128_SIZE);
|
||||
if (bek_vector[0] == 0x59C14895) // Encrypted zeroes first 32bits.
|
||||
EPRINTF("Pkg1 corrupt?");
|
||||
else
|
||||
@@ -947,9 +958,9 @@ void hos_launch(ini_sec_t *cfg)
|
||||
// Hash only Kernel when it embeds INI1.
|
||||
u8 kernel_hash[0x20];
|
||||
if (!ctxt.new_pkg2)
|
||||
se_sha_hash_256_oneshot(kernel_hash, ctxt.kernel, ctxt.kernel_size);
|
||||
se_calc_sha256_oneshot(kernel_hash, ctxt.kernel, ctxt.kernel_size);
|
||||
else
|
||||
se_sha_hash_256_oneshot(kernel_hash, ctxt.kernel + PKG2_NEWKERN_START,
|
||||
se_calc_sha256_oneshot(kernel_hash, ctxt.kernel + PKG2_NEWKERN_START,
|
||||
pkg2_newkern_ini1_start - PKG2_NEWKERN_START);
|
||||
|
||||
ctxt.pkg2_kernel_id = pkg2_identify(kernel_hash);
|
||||
@@ -989,12 +1000,12 @@ void hos_launch(ini_sec_t *cfg)
|
||||
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
|
||||
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
|
||||
|
||||
// Check if FS is compatible with exFAT and if 5.1.0 or 10.2.0.
|
||||
// Check if FS is compatible with exFAT and if 5.1.0.
|
||||
if (!ctxt.stock && (sd_fs.fs_type == FS_EXFAT || mkey == HOS_MKEY_VER_500 || ctxt.pkg1_id->fuses == 13))
|
||||
{
|
||||
bool exfat_compat = _get_fs_exfat_compatible(&kip1_info, &ctxt.exo_ctx.hos_revision);
|
||||
|
||||
if (sd_fs.fs_type == FS_EXFAT && !exfat_compat)
|
||||
if (emusd_get_fs_type() == FS_EXFAT && !exfat_compat)
|
||||
{
|
||||
_hos_crit_error("SD Card is exFAT but installed HOS driver\nonly supports FAT32!");
|
||||
|
||||
@@ -1008,14 +1019,14 @@ void hos_launch(ini_sec_t *cfg)
|
||||
{
|
||||
EHPRINTFARGS("Failed to apply '%s'!", failed_patch);
|
||||
|
||||
bool emu_patch_failed = !strcmp(failed_patch, "emummc");
|
||||
if (!emu_patch_failed)
|
||||
bool emmc_patch_failed = !strcmp(failed_patch, "emummc");
|
||||
if (!emmc_patch_failed)
|
||||
{
|
||||
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
|
||||
display_backlight_brightness(h_cfg.backlight, 1000);
|
||||
}
|
||||
|
||||
if (emu_patch_failed || !(btn_wait() & BTN_POWER))
|
||||
if (emmc_patch_failed || !(btn_wait() & BTN_POWER))
|
||||
goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
|
||||
}
|
||||
|
||||
@@ -1027,6 +1038,9 @@ void hos_launch(ini_sec_t *cfg)
|
||||
config_exosphere(&ctxt, warmboot_base);
|
||||
|
||||
// Unmount SD card and eMMC.
|
||||
emummc_storage_end();
|
||||
emusd_storage_end();
|
||||
boot_storage_end();
|
||||
sd_end();
|
||||
emmc_end();
|
||||
|
||||
@@ -1127,6 +1141,8 @@ void hos_launch(ini_sec_t *cfg)
|
||||
|
||||
error:
|
||||
_free_launch_components(&ctxt);
|
||||
emummc_storage_end();
|
||||
emusd_storage_end();
|
||||
emmc_end();
|
||||
|
||||
EPRINTF("\nFailed to launch HOS!");
|
||||
|
||||
Reference in New Issue
Block a user