Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

big ol' bag of stuff #50

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open

big ol' bag of stuff #50

wants to merge 22 commits into from

Conversation

yo1dog
Copy link
Contributor

@yo1dog yo1dog commented Oct 25, 2024

A number of changes that I had made a year or two ago. Rebased onto latest. I also reordered the commits to be easier to cherry-pick. Commits have descriptions as well.

Happy to walk through these one at a time and cherry-pick/rebase as we go.

I can also split these up into individual PRs if that is better.

Code reorganization/preparation

First 11 or so commits do not change any functionality. They clean up the code base in preparation for upcoming changes.

  • Code that is or will be called from multiple locations has been abstracted into functions.
  • Some code is organized into separate files as main.c was growing quite large.
  • Global state was removed (and function interfaces updated accordingly).
  • Some complex function interfaces were simplified using structs.
  • De-linted to conform with established coding style.

CLI path and parsing improvements

  • Improves the algo used to parse CLI option strings. Now ignores insignificant white space.
  • Improves logic for generating CLI filepath. Now checks if DOL filepath ends with .dol before replacing last 3 characters with cli.

Rather than simply looking for EOL characters, this algo tracks the position of the first and last non-whitespace character seen. Once an EOL or NULL character is found, we use the first and last non-whitespace characters to define the argument. Then state is reset.

Debug mode

Debug mode replaces the "hold D-Down to delay exit" functionality. Instead, holding D-Down or the reset button on boot will enable debug mode. Debug mode increases verbosity and will always prompt the user before exiting and at various other points to facilitate reading the logs.

Config files

As gekkoboot searches each device it will first look for a gekkoboot.ini configuration file at root. If it does not exist, the old behavior of looking for hardcoded shortcut files is used. If that file is also not found, it moves on to the next device.

I also updated the logic such that once shortcut information is found on a device (either config file or selected hardcoded shortcut file), if the shortcut then fails for any reason, it stops rather than continuing to the next device.

If a shortcut is found, the device populates a BOOT_PAYLOAD containing the BOOT_TYPE gekkoboot should preform along with the loaded DOL and argv (if applicable).

The configuration file is read and parsed using ini.h and mapped to the CONFIG struct. A configuration contains a BOOT_ACTION for each shortcut (including the default). All shortcuts default to BOOT_TYPE_NONE which is ignored in favor of the the default shortcut. The default shortcut defaults to BOOT_TYPE_DOL and a path of ipl.dol which matches the previous behavior.

The user can also specify ONBOARD and USBGECKO as the shortcut action to explicitly boot into the onboard IPL or USB gecko devices. Debug mode can also be enabled via config file.

Examples here: https://github.com/yo1dog/gekkoboot/?tab=readme-ov-file#configuration

Emulator build

Added ability to build a DOL that can run in the Dolphin emulator (and on Wii, presumably). This allows testing using Dolphin and its Wii virtual SD card feature on PC. Super fast iteration this way (much faster than swapping SD cards for those of us without proper dev hardware).

To create an emulator build you must setup mosen like so:

meson setup . build --cross-file=devkitPPC.ini --cross-file=devkitPPCEmu.ini -D emu_build=true

I use it like this under WSL2 for instant testing:

meson compile -C build && Dolphin.exe -b -e ./build/gekkoboot_emu.dol

When in "emu mode" it overloads the filesystem functions to use libfat which works on Wii. There are few other differences in "emu mode": It will also only attempt to read from the Wii SD device. It will wait for input on boot since it is not possible to have a button held when the emulator window opens. Debug mode is enabled automatically. The stub is not loaded.

Misc

  • Improved logging.
  • Added argv support.

@9ary
Copy link
Member

9ary commented Oct 26, 2024

Thanks for updating this! Haven't looked at the code yet, but breaking it down and merging things one step at a time would be ideal.
Let's keep this open as a meta thing, and open a new PR for the cleanups, we'll get those sorted then move on to the next step.

Some thoughts:

  • De-linted to conform with established coding style.

There isn't really one, gekkoboot grew from a patchwork of code copied from other projects and there is no consistent style within it. I have a clang-format configuration I kinda like, and we'll be able to solve the conflicts reformatting would create with some git magic, so no worries there.

Linting would be extremely helpful and I think we should aim to implement it.

CLI path and parsing improvements

This must stay in sync with Swiss for compatibility reasons, so ideally all improvements should be done there, then synced back here.

Debug mode

For what it's worth, I want the current behavior to remain the default. A huge motivator for the change was that autoskipping to stock mode was making picoboot installs very hard to troubleshoot, between flaky SD card adapters, incorrect SD card setups and actual wiring issues. I have been bitten by this myself many times by forgetting to reinsert my SD card after putting new files on it, and wondering what was wrong.
You can't even assume the user has a working controller, especially with blueretro and wavebirds.

I also think removing the SD card to boot into stock mode is a pretty mediocre way to do things, it just started out that way before gekkoboot ever attempted to read controller input, since that was the easiest way to do it implementation-wise.

The last thing is that I don't like the idea of consoles changing owners without the knowledge that a modchip is installed. Halting lets the user know that the system is modified, and I intend to add some help text, most likely a link to some documentation for them to get started with homebrew.

At this point, I believe the default should always be to halt if something went wrong, unless explicitly configured otherwise by the user (essentially, this is what the stealth mode should be).

If it does not exist, the old behavior of looking for hardcoded shortcut files is used.

I'd like to deprecate the hardcoded paths entirely, in large part because I want to discourage renaming files going forward, since that makes it a lot harder to tell what's what.
The default configuration should set the default path to /swiss_r*.dol, and have a shortcut set up to boot into stock, so that things are usable out of the box, but any customization should require the config file.

Emulator build

This is great, especially if you don't have a USB gecko or a modchip that is easy to reflash (I personally use a Qoob Pro with the USB connector accessible at the back of the console).

When in "emu mode" it overloads the filesystem functions to use libfat which works on Wii.

Not a fan of this. We should keep things as close as possible, so let's implement fatfs support for the Wii SD card slot instead.

Also, the build is failing because things don't fit on Qoob SX, again. Don't worry about it too much though, I have one of those now and I know exactly what to do to fix it so most of the 128K of flash will be usable. As a prerequisite though, we're going to need a brand new flasher for the Qoob family and a new "preloader" component that will be needed for brick recovery.

@yo1dog
Copy link
Contributor Author

yo1dog commented Oct 28, 2024

Let's keep this open as a meta thing, and open a new PR for the cleanups, we'll get those sorted then move on to the next step.

Wilco. I'll start with the cleanup PR.

Without getting into too much detail because we will cover these once we get to them, some quick responses:

CLI path and parsing improvements

This must stay in sync with Swiss for compatibility reasons, so ideally all improvements should be done there, then synced back here.

wilco

Debug mode

For what it's worth, I want the current behavior to remain the default. ... You can't even assume the user has a working controller, especially with blueretro and wavebirds.

Agreed.

Also, with the new config file support users who want to boot into onboard IPL by default can explicitly configure it that way (DEFAULT=ONBOARD). Though it would require the SD card to always be present to read the config file. But I assume that is not an issue for most modded consoles.

I'd like to deprecate the hardcoded paths entirely, in large part because I want to discourage renaming files going forward, since that makes it a lot harder to tell what's what.

Agreed. That was exactly my motivation for adding config file support in the first place. "What is x.dol?"

When in "emu mode" it overloads the filesystem functions to use libfat which works on Wii.

Not a fan of this. We should keep things as close as possible, so let's implement fatfs support for the Wii SD card slot instead.

Agreed. Getting fatfs to work with Wii SD is way better.

It's been a while but pretty sure the only reason I used libfat was simply because it worked out of the box while fatfs did not and I am way out of my element making fatfs work. My justification at the time was that I was just trying to test application level logic and parity at the filesystem level was less important since it would be running on emulated hardware/filesystem anyway.

@9ary
Copy link
Member

9ary commented Oct 28, 2024

Sounds like we're on the same page.

Though it would require the SD card to always be present to read the config file. But I assume that is not an issue for most modded consoles.

A true stealth mode is possible by saving the setting to SRAM (with SYS_Get/SetBootMode()) .

- Condense 2 instances of scanning and assigning `all_buttons_held` into a single function.
- Move shortcut definitions to its own file.
- Add a special shortcut definition for default `ipl.dol`.
- This prepares for future in which shortcuts are referenced rather than just paths and prevents requiring explicit handling of the special no-shortcut/default case.
- Defines the `BOOT_PAYLOAD` struct for containerizing boot data (`dol` and `dol_argc`).
- Removes boot data from global scope.
- Splits `load_parse_cli` into `read_cli_file` and `parse_cli_file`.
- Moves DOL file reading to `read_dol_file`.
- Reference shortcuts rather just the shortcut's paths.
- Prepares for future in which shortcuts define more than just a path.
- Moves finding and reading of shortcut DOL and CLI files to `load_shortcut_files`.
- Moves all filesystem reading and handling code to its own `filesystem.c` file.
- `FS_RESULT` enum extends and replaces `FRESULT` enum.
- Colapses `utils.c` into `filesystem.c`.
- `dol_alloc` function removed. Filesystem and USB geko routines handle malloc independently.
- Dropped `_size` param from `read_cli_file` in favor of `strenlen`
- Rather than track `argc` and `argv` array and combine into `__argv` struct later, create `__argv` struct immediately.
- Moves CLI parsing to its own file.
- Renames `parse_cli_file` to `parse_cli_args` as it is source agnostic.
- Silence erroneous `TB_BUS_CLOCK` undefined error in some IDEs.
- Group global state to top of `main.c`.
- Copy and modify rather than overwriting DOL path for CLI path in `read_cli_file`.
- `dol` -> `dol_file`, `cli` -> `cli_file`, and other variable name clarifications.
- Add comments to describe function return codes.
- Add various comments.
- Various stylistic changes and delinting for consistency.
- Better parsing algo which ignores insignificant white space in CLI args.
- Will only attempt to rewrite DOL path to CLI path if it has `.dol` extension.
- Debug mode replaces "hold Dpad-Down to delay exit" for better debugging experience.
- Debug mode is enabled when Dpad-Down or Reset is held on boot.
- Debug mode always prompts before exiting.
- Debug mode increases logging verbosity.
- Replaces `VERBOSE_LOGGING` define with `debug_enabled` global state flag.
- Added additional logging and improved specificity of existing.
- Use more verbose device names in logging.
- Handle failure to find shortcuts and failure to load shortcuts separately.
- We can now explicitly decide when loading attempts should stop.
- This change decides to stop loading attempts after a shortcut was found but failed to load.
- `--debug` flag enables debug mode.
- `--ask` flag waits for initial input.
- Update `parse_cli_args` to accept array of strings.
- Prepares for future in which CLI args may come from multiple sources.
- Allows for an `gekkoboot.ini` file at the root of devices to configure behaviors.
- Rather than shortcuts requiring DOLs to be renamed to hardcoded filenames (`a.dol`), the config file can specify the mapping of button to DOL filepaths.
- Besides DOLs, config can also specify shortcuts for explicitly booting into onboard IPL or USB Gecko (in the future).
- Config can specify CLI args for DOLs.
- Config can enable debug mode.
- Allows config to specify `USBGECKO` shortcut.
- Prints warning when DOL path does not have `.dol` or `.dol+cli` extension.
- Allows build compatible with Dolphin emulator for easy testing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants