diff --git a/nyx/BOOTLOADER_SYS_ORIGINS.md b/nyx/BOOTLOADER_SYS_ORIGINS.md new file mode 100644 index 00000000..de6ebb39 --- /dev/null +++ b/nyx/BOOTLOADER_SYS_ORIGINS.md @@ -0,0 +1,63 @@ +# bootloader/sys/ – Missing files and where they come from + +The repo only builds and packages **nyx.bin**, **libsys_lp0.bso**, and **libsys_minerva.bso**. The rest of `bootloader/sys/` is not built here. Below is where each missing piece comes from. + +--- + +## res.pak + +- **What:** Nyx GUI resource pack (fonts, glyphs, assets). Loaded at `NYX_RES_ADDR`; without it Nyx will show “res.pak not found or corrupted”. +- **Where:** Built with **nyx-res-tool** (extract/build res.pak from a directory of resources). + - **Repo:** https://github.com/friedkeenan/nyx-res-tool + - **Usage:** `extract.py` to unpack an existing res.pak; `build.py` to pack a directory into res.pak. +- **Alternative:** Use a res.pak from an official hekate release (e.g. CTCaer) and place it in `bootloader/sys/`. + +--- + +## thk.bin + +- **What:** Atmosphère **Tsec Hovi Keygen** firmware. Used for TSEC/crypto when booting HOS (e.g. package1 decryption). If missing, boot can fail with TSEC/keygen errors. +- **Where:** From **Atmosphère** (Atmosphere-NX/Atmosphere). It is built as part of their sept/tsec keygen and shipped in their release package; the binary that hekate expects as `bootloader/sys/thk.bin` is that keygen blob. + - **Repo:** https://github.com/Atmosphere-NX/Atmosphere + - **In practice:** Copy `thk.bin` from an official Atmosphère release (e.g. `atmosphere/` or their “hekate” bundle) into `bootloader/sys/`. + +--- + +## emummc.kipm + +- **What:** emuMMC **KIP1 module** (patch data). Injected into the **FS** KIP1 at boot when emuMMC is used (`_kipm_inject("bootloader/sys/emummc.kipm", "FS", ki)` in `pkg2.c`). Contains caps + .text that get merged into the FS kip. +- **Where:** Built from the **m4xw/emuMMC** project (not this repo). + - **Repo:** https://github.com/m4xw/emuMMC + - **Build (hekate):** Run `./build.sh` in the emuMMC repo; it produces a `.kipm` file. Copy that file to `bootloader/sys/` as `emummc.kipm`. + - **Requirements:** devkitARM / devkitA64 and the toolchain expected by the emuMMC Makefile (see their README). + - **Alternative:** Copy **emummc.kipm** from an official hekate release (e.g. CTCaer/hekate) into `bootloader/sys/`. Use a kipm that matches your hekate/HOS version. + +--- + +## bootloader/sys/l4t/ + +- **What:** Firmware blobs for **L4T** (Linux/Android on Switch): BL31, BL33, SC7 entry/exit, BPMP, etc. Used when booting L4T or when warmboot needs `sc7exit_b01.bin`. +- **Files expected (from `l4t.c` and `pkg1.c`):** + - `bl31.bin` + - `bl33.bin` + - `sc7entry.bin` + - `sc7exit.bin` + - `bpmpfw.bin` + - `bpmpfw_b01.bin` + - `mtc_tbl_b01.bin` + - `sc7exit_b01.bin` (referenced in `pkg1.c` for warmboot) +- **Where:** From **L4T / Switchroot** (or similar) L4T/SD release packages that provide “bootloader/sys/l4t/” (or equivalent) with these binaries. Not built in hekate-pro. + - **In practice:** Copy the **l4t/** folder (with the files above) from an official hekate L4T-capable release or from a Switchroot/L4T image that matches the expected layout. + +--- + +## Summary + +| File or folder | Origin | +|----------------------|--------| +| **res.pak** | Build with [nyx-res-tool](https://github.com/friedkeenan/nyx-res-tool), or copy from official hekate release. | +| **thk.bin** | Atmosphère (sept/tsec keygen); copy from official Atmosphère release. | +| **emummc.kipm** | Build from [m4xw/emuMMC](https://github.com/m4xw/emuMMC) (`./build.sh`), or copy from official hekate release. | +| **bootloader/sys/l4t/** | L4T/Switchroot firmware; copy from hekate L4T bundle or L4T image. | + +After copying these into `bootloader/sys/` (and `bootloader/sys/l4t/`), your SD layout matches what the reference `hekate_pro_6.5.1_Nyx_1.9.1`-style folder expects. diff --git a/nyx/nyx_gui/frontend/gui_emummc_tools.c b/nyx/nyx_gui/frontend/gui_emummc_tools.c index b8061227..85fcc595 100644 --- a/nyx/nyx_gui/frontend/gui_emummc_tools.c +++ b/nyx/nyx_gui/frontend/gui_emummc_tools.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -2120,6 +2121,13 @@ lv_res_t create_tab_emummc_tools(lv_obj_t *parent) lv_obj_align(h1, parent, LV_ALIGN_IN_TOP_LEFT, 0, 0); lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI * 17 / 29, 0); + /* Re-apply container position after reload so it does not jump when returning from sub-windows */ + lv_obj_t *win = lv_obj_get_parent(parent); + if (win) { + lv_obj_t *content = lv_win_get_content(win); + if (content) + lv_obj_align(parent, content, LV_ALIGN_IN_TOP_MID, -20, 50); + } return LV_RES_OK; } diff --git a/sd_out.py b/sd_out.py new file mode 100644 index 00000000..abdf0303 --- /dev/null +++ b/sd_out.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +""" +Pack hekate build output into a ZIP with SD card layout: + ZIP + ├── payload.bin (hekate payload for injection / root of SD) + └── bootloader/ + ├── update.bin (hekate payload; for modchips / auto-update) + ├── ini/ (empty; for More configs) + ├── res/ (empty; for user icons/background) + ├── payloads/ (empty; for Payloads menu) + └── sys/ + ├── nyx.bin + ├── libsys_lp0.bso + └── libsys_minerva.bso + +Run from repo root after `make`. No hekate_ipl.ini or patches.ini. +Optional: res.pak, thk.bin, emummc.kipm must be added separately. +""" + +import os +import re +import sys +import zipfile +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parent +OUTPUT = REPO_ROOT / "output" + + +def parse_versions(): + """Read Versions.inc and return (bl_ver, nyx_ver) e.g. ('6.5.1', '1.9.1').""" + inc = REPO_ROOT / "Versions.inc" + if not inc.exists(): + return ("0.0.0", "0.0.0") + vals = {} + for line in inc.read_text().splitlines(): + m = re.match(r"(\w+)\s*:?=\s*(\d+)", line.strip()) + if m: + vals[m.group(1)] = m.group(2) + bl_ver = f"{vals.get('BLVERSION_MAJOR', 0)}.{vals.get('BLVERSION_MINOR', 0)}.{vals.get('BLVERSION_HOTFX', 0)}" + nyx_ver = f"{vals.get('NYXVERSION_MAJOR', 0)}.{vals.get('NYXVERSION_MINOR', 0)}.{vals.get('NYXVERSION_HOTFX', 0)}" + return (bl_ver, nyx_ver) + + +def main(): + bl_ver, nyx_ver = parse_versions() + zip_name = f"hekate_{bl_ver}_Nyx_{nyx_ver}.zip" + zip_path = OUTPUT / zip_name + + # Required build artifacts + payload_src = OUTPUT / "hekate.bin" + sys_files = [ + ("bootloader/sys/nyx.bin", OUTPUT / "nyx.bin"), + ("bootloader/sys/libsys_lp0.bso", OUTPUT / "libsys_lp0.bso"), + ("bootloader/sys/libsys_minerva.bso", OUTPUT / "libsys_minerva.bso"), + ] + + missing = [] + if not payload_src.exists(): + missing.append(str(payload_src)) + for _, src in sys_files: + if not src.exists(): + missing.append(str(src)) + if missing: + print("Missing build outputs (run 'make' first):", file=sys.stderr) + for m in missing: + print(" ", m, file=sys.stderr) + sys.exit(1) + + zip_path.parent.mkdir(parents=True, exist_ok=True) + with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf: + # Payload at root (for injection / some setups) + zf.write(payload_src, "payload.bin") + # bootloader/update.bin (same payload; for modchips / auto-update) + zf.write(payload_src, "bootloader/update.bin") + + # bootloader/sys/* + for arc, src in sys_files: + zf.write(src, arc) + + # Empty dirs (ZIP has no true directories; .keep so extractors create them) + for d in ("bootloader/ini/", "bootloader/res/", "bootloader/payloads/", "bootloader/screenshots/"): + zf.writestr(d + ".keep", "") + + print(f"Wrote {zip_path}") + print("Note: res.pak, thk.bin, emummc.kipm are not in this repo; add to bootloader/sys/ if needed.") + + +if __name__ == "__main__": + main()