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

Finish stage-0 boot features #300

Merged
merged 16 commits into from Feb 15, 2021

Conversation

samueldr
Copy link
Member

@samueldr samueldr commented Feb 11, 2021

We were left with the following issues to deal with:

This PR implements both features.


Skip generation kernel

It is possible to continue booting with the kernel used to boot the stage-0 bootloader. It will be useful for the three following scenarios:

  • Validating kexec did not cause an issue with the booted system
  • Recovering a system where none of the generation kernels boot properly
  • Testing a kernel build without making a generation

Use generation DTB

Self-explanatory... Or is it?

Each generation could have their own DTB, sometimes with fixes. Re-installing the bootloader to use the fresher DTB is not really a nice thing to have to do.

This change makes it so the call to kexec uses the --dtb flag.

But wait, there's more!

The kernel assumes some entries will be added to the FDT (in-memory device tree), like the /memory node. kexec does nothing to help you forward required entries.

This is where fdt-forward comes into play. It is used to get the nodes and properties from the running system.

For the pinephone, you can observe it forwards a property for the Wi-Fi adapter mac address. The bootloader is expected to add a few properties like this depending on the device.

Finally, since we can, let's add some nodes about the current stage-0 boot. This is not strictly needed, but it the basic boolean node can be used as a method to confirm kexec was used. We can also add other properties if it ends up being useful.

fdt-forward?

Are you concerned about what seems like a weird script? I understand. In the end it is much easier to deal with than having to work with libfdt in C or with other language bindings.

I am open to contributions that allows doing the same kind of manipulations. The basic requirements are:

  • graft a full node from a DT to another DT (source and binary)
  • graft a property with a qualified path from a DT to another DT (source and binary)

The header and to_dtb features are only for convenience.

For the time being, this is not perfect, but totally does what is needed.

%Q{/ { mobile-nixos,stage-0,timestamp = #{Time.now.to_s.to_json}; };},
%Q{/ { mobile-nixos,stage-0,uname = #{`uname -a`.to_json}; };},
%Q{/ { mobile-nixos,stage-0,uptime = #{`uptime`.to_json}; };},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to_json?

Because it will produce and escape strings well enough for use inside DTS files. The required escapes are basically compatible.

@samueldr samueldr added the type: enhancement New feature or request label Feb 11, 2021
@samueldr
Copy link
Member Author

Why shell script for map-dtbs rather than Ruby? Because this is used in building a generation in the target NixOS system. This target system should not require Ruby/mruby in its build closure.


Why shell script for fdt-forward? It required chaining calls to different command-line utilities (fdtgrep and dtc). It would have been possible to write a script for that in mruby, but calling an mruby script in stage-1 has bad ergonomics at the time. Alternatively it could be a class that is used directly in the init, but it'd be better if it was FFI bindings to libfdt rather than chaining misc executables.

@samueldr samueldr merged commit 62297b2 into NixOS:master Feb 15, 2021
@samueldr samueldr deleted the feature/stage-0-finishing-touches branch February 15, 2021 21:19
samueldr added a commit to samueldr-wip/mobile-nixos-wip that referenced this pull request Jul 31, 2022
In NixOS#300 I "fixed" stage-0 by adding a switch to toggle between it being
enabled and disabled in the recovery menu. *That* works as expected.

In 2a46962 one can observe that the
`#will_kexec?` method will use data that will only come from the
`choice` made from the recovery interface. The `@use_generation_kernel`
member is not set at any other point.

With ruby semantics, this means that the `if` is false, so *unless* you
choose to boot using the recovery menu, it will never trigger `kexec`.

Why has this gone through this way? Most likely because my main testing
target was configured so it *always* went to the recovery menu at the
time, meaning that I never saw the default behaviour.
samueldr added a commit to samueldr-wip/mobile-nixos-wip that referenced this pull request Jul 31, 2022
In NixOS#300 I "fixed" stage-0 by adding a switch to toggle between it being
enabled and disabled in the recovery menu. *That* works as expected.

In 2a46962 one can observe that the
`#will_kexec?` method will use data that will only come from the
`choice` made from the recovery interface. The `@use_generation_kernel`
member is not set at any other point.

With ruby semantics, this means that the `if` is false, so *unless* you
choose to boot using the recovery menu, it will never trigger `kexec`.

Why has this gone through this way? Most likely because my main testing
target was configured so it *always* went to the recovery menu at the
time, meaning that I never saw the default behaviour.
samueldr added a commit to samueldr-wip/mobile-nixos-wip that referenced this pull request Jul 31, 2022
In NixOS#300 I "fixed" stage-0 by adding a switch to toggle between it being
enabled and disabled in the recovery menu. *That* works as expected.

In 2a46962 one can observe that the
`#will_kexec?` method will use data that will only come from the
`choice` made from the recovery interface. The `@use_generation_kernel`
member is not set at any other point.

With ruby semantics, this means that the `if` is false, so *unless* you
choose to boot using the recovery menu, it will never trigger `kexec`.

Why has this gone through this way? Most likely because my main testing
target was configured so it *always* went to the recovery menu at the
time, meaning that I never saw the default behaviour.
wentam pushed a commit to wentam/mobile-nixos that referenced this pull request Feb 26, 2023
In NixOS#300 I "fixed" stage-0 by adding a switch to toggle between it being
enabled and disabled in the recovery menu. *That* works as expected.

In 2a46962 one can observe that the
`#will_kexec?` method will use data that will only come from the
`choice` made from the recovery interface. The `@use_generation_kernel`
member is not set at any other point.

With ruby semantics, this means that the `if` is false, so *unless* you
choose to boot using the recovery menu, it will never trigger `kexec`.

Why has this gone through this way? Most likely because my main testing
target was configured so it *always* went to the recovery menu at the
time, meaning that I never saw the default behaviour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant