Skip to content

Conversation

@phodina
Copy link

@phodina phodina commented Jan 25, 2026

@isbm thanks for this project, here's small MR with demo ;-)

  • add mp4 of rendered asciinema showing the booting
  • Nix flake support for building packages
    (support for aarch64-linux and x86_64-linux platforms)
  • GitHub workflow for building Nix packages across multiple platforms
  • Add support for overlayfs to support read-only rootfs
  • Handle missing kernel modules gracefuly in runtime
  • Add kernel config validation
  • Add arguments to specify and validate the filesystem
    and block device for rootfs during creation
  • Support block devices using also labels
  • Add Nix definitions for u-boot and latest stable kernel
  • Add support to run qemu-system-aarch64
  • Add example minimal Nixos system to boot

@isbm
Copy link
Member

isbm commented Jan 25, 2026

@phodina whoa! Awesome work. Now I owe you to ditch Ubuntu and go to Nix. 😛

If you would present that at https://fosdem.org/2026/schedule/track/nix-and-nixos/ then I would merge that as is. 😆 Otherwise, seems not everything is through: would you please double-check actions? I am not sure aarch64/darwin will do here...

Also, please make check && make fix so Clippy is happy (insanity check test) — seems if you make fix that, it should just do automatically. Also please ensure you are compiling with the latest/greatest Rust.

P.S. Absolutely cool!

@isbm isbm requested a review from Ichmed January 25, 2026 00:24
@isbm
Copy link
Member

isbm commented Jan 25, 2026

@Ichmed could you take a second look, please?

@phodina
Copy link
Author

phodina commented Jan 25, 2026

Also, please make check && make fix so Clippy is happy (insanity check test) — seems if you make fix that, it should just do automatically. Also please ensure you are compiling with the latest/greatest Rust.

Sure will run the Clippy check to pass. Regarding the Darwin, i do own a Mac Mini M1 machine to test but it runs Asahi Linux :D
The CI seems to keep the nixbld users as an artifact as running it in non-daemon mode is no longer supported. So will probably drop this, if anyone is interested can look into that.

I intend to use it mainly for Mobile Nixos (surprise :) mobile-nixos/mobile-nixos#853 and also later for embedded systems.

The pull request stalls as the initramfs there uses Ruby. It offers a lot of features but having embedded background I appreciate the effort but IMHO don't thing Ruby is good choice.

Mostly I'm used to busybox+shell scripts style initramfs but for some time I thought about single binary init system also written in Rust. So thanks for bootstrapping the effort!

Also noticed OpenSUSE on your profile, what's you affiliation?

@isbm
Copy link
Member

isbm commented Jan 25, 2026

Sure will run the Clippy check to pass.

Yes! Please rebase on master and then make check.

So will probably drop this, if anyone is interested can look into that.

Yes, I was about to suggest that. Let's just drop that for now.

I intend to use it mainly for Mobile Nixos (surprise :) mobile-nixos/mobile-nixos#853 and also later for embedded systems.

❤️!

The pull request stalls as the initramfs there uses Ruby. It offers a lot of features but having embedded background I appreciate the effort but IMHO don't thing Ruby is good choice.

"Embedded system" and "lots of features"? An embedded system must have only what it must use. Basically, you should have no /bin/ls because why would you need that, if you do know your system? Busybox is actually "too much" and you probably want to compile it only with a clinic minimum applets that it gives you a bit oxygen to live and that's all.

Mostly I'm used to busybox+shell scripts style initramfs but for some time I thought about single binary init system also written in Rust. So thanks for bootstrapping the effort!
Also noticed OpenSUSE on your profile, what's you affiliation?

10 years worked there making SLES. Actually microhop was made exactly for this: ditch that enormously "Yuuge!" initramfs of their distro (it has systemd — yes, it does, — and probably a SIEMENS dishwasher drivers too, because why wouldn't they?). So I could just boot their literally unbootable distro on my old Rpi. Microhop was also made to boot systems as fast as they can be booted.

Feel free to add stuff to it. 😉

@isbm
Copy link
Member

isbm commented Jan 25, 2026

@phodina BTW, there is also a very good reason why we don't update embedded systems with the packages: they introduce config drift and then you risk bricking your device. There are some distros on the market with pkgs, but this is a very tricky/risky business.

I am not entirely sure NixOS is a good idea for the embedded in general, as it looks to be overlybloated, but trying? — why not... Maybe it is a good idea, I still need to explore that. RedHat's OS Tree is actually a right thing to do, but it is also way too bloated at the moment. Canonocal's Ubuntu Core is a good idea too, but the implementation is catastrophically bad.

So the best of best for now I would suggest this: https://elbe-rfs.org/new_site/index.html
(yes, they do need microhop!)

Petr Hodina added 2 commits January 26, 2026 01:38
We are interested in machine architecture and want to get:

```
$ uname -m
aarch64

$ uname -m
x86_64
```

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
@phodina
Copy link
Author

phodina commented Jan 26, 2026

Yes! Please rebase on master and then make check.

Done ;-)

Dropped support for Darwin, WSL2 not tested but normally packages build there in nix work.

"Embedded system" and "lots of features"? An embedded system must have only what it must use. Basically, you should have no /bin/ls because why would you need that, if you do know your system? Busybox is actually "too much" and you probably want to compile it only with a clinic minimum applets that it gives you a bit oxygen to live and that's all.

Totally agree with you on the just boot the system as fast as possible. It should not be swiss knife nor have there kitchen sink otherwise it's prone to failure or worse attack vector.

However, I do understand the need to have some features. The mobile phones are locked down and the bootloaders can't be changed.

So the idea with mobile nixos is to have u-boot chainloaded by the abl usually the lk into memory. This build also will bear any non upstreamable patches so the Linux kernel could be fully mainline (one day :) and along the initramfs will be packed in Android boot image.

Now back to features. I also don't like the feature creep but there are some that should be implemented in the initramfs. Definitely the LUKS unlock. Which on phone requires the framebuffer passed by Android bootloader and the touchscreen.

Sure the u-boot could unlock the LUKS partition but the issue is the key input. Storing it in the Android boot image renders the encrypted storage useless. So it has to be stored somewhere else or passed as input from user.

Both options require drivers or components currently not present in u-boot. Porting them from the kernel for different phones is not fun and IMHO overkill.

So better to draw keyboard and text input in the initramfs for the LUKS key.

In similar fashion if we would be able to store the key in the TrustZone we could use the tee-supplicant (or the proprietary qseecom on Qualcomm :P) which requires userspace service and kernel driver.

As an alternative NFC with some security token e.g. Yubikey could be also used. That would also require the NFC driver and daemon.

So even though I agree with the minimal and fast boot approach there are some valid usecases where it will require more functionality which could be gated using the rust features.

Other stuff like which slot to boot can be handled by the u-boot.

Also I'm aware that the initramfs, kernel, bootloader are risky parts to update. In embedded systems and Android there are usually slots - A and B. So if the company does due diligence on the Q&A of the OTA updates the device should not be bricked. Ideally it should not be updated frequently in the field.

I am not entirely sure NixOS is a good idea for the embedded in general, as it looks to be overlybloated, but trying? — why not... Maybe it is a good idea, I still need to explore that. RedHat's OS Tree is actually a right thing to do, but it is also way too bloated at the moment. Canonocal's Ubuntu Core is a good idea too, but the implementation is catastrophically bad.

Build mostly in the past systems either through buildroot, OpenWrt or Yocto. Since it was custom hardware and SoC which was far better supported in the vendor SDK there was no intention to reduce the size and time of the build (what a waste of resources).

Well I like Yocto, but then for each device you build custom image, which if you are a bigger company and don't care about the updates for the product is guess fine.

But for normal system I'd either go with Debian based system or NixOS. Sure it's not targeted for that but the descriptive language, remote builders and also certain immutability with generations has an edge (at least for me).

So specifically on phones it would allow me and others to try the latest features on next kernel and if it breaks just reboot and pick older generation that works.

The first devices, that were initially called embedded Linux, had about 4MiB flash and around 16MiB of RAM. With these constrains in mind people started to hack a root file system for their devices. If they had bad luck you had to start with building a cross toolchain first.
I do remember the routers with these kinds of hardware resources. And I'd like to also limit the resources needed to boot and run the system. Also with the RAM prices it might pursue more vendors to do the same :)

The reason I asked about the OpenSUSE affiliation is that with David Heidlberg we are trying to get the Linux next kernel running on mobile phones and SUSE in Prague helps us by providing spaces for hackadays. Big thanks to @lkocman for making this happen!

@isbm
Copy link
Member

isbm commented Jan 26, 2026

Funny I demoed Microhop booting a SLES in 2024 at OpenSUSE Con. I also tried last year to show something at DevConf.cz in Brno, but RedHat, like Microsoft, is overly obsessed with AI at the moment, so let's wait when they fail and go back to normal.

Well, this is a big difference between "embedded system" and "general distro" which SUSE is making traditionally. You are NOT supposed to pull out a disk with an embedded system, plug it elsewhere and boot. But you ARE supposed to do that with a generic system. That's why adding even a braille driver in SUSE's case is the right thing to do. This is also why Microhop does not have that auto/update to kernel swappings, because by definition you are supposed to do all that routine fully manually: put a new kernel, pick your modules, reconstruct initrd, put all that together, bake an image and only then push the update.

That's why I was experimenting with bootr: another project that is working like RedHat's bootable containers, except very tiny and very small. So the idea is to push image updates over an existing system, just like you do with the containers. I stopped that because my focus now is elsewhere and I have only 24 hours and two arms. 😆

While writing this: there's still one forgotten-and-unused import. Typically make fix does the trick for you automagically.

P.S. @lkocman see you in Nue/Z-Bau at next OpenSUSE Con! 😛

@phodina
Copy link
Author

phodina commented Jan 26, 2026

While writing this: there's still one forgotten-and-unused import. Typically make fix does the trick for you automagically.

@isbm sorry missed the flags in actions so the warning that turned into error slipped through my fingers

That's why I was experimenting with bootr: another project that is working like RedHat's bootable containers, except very tiny and very small. So the idea is to push image updates over an existing system, just like you do with the containers. I stopped that because my focus now is elsewhere and I have only 24 hours and two arms

Good to know there are still great humans around and not just bots creating more boilerplate work :D

@phodina
Copy link
Author

phodina commented Jan 26, 2026

The only thing missing is support to copy over firmware files as these are needed on the sdm845 to boot the adreno GPU. Have a crude way to add those but will refactor that.

Otherwise would be cool to present this on FOSDEM booth. It will be more about the Mobile Nixos + other stuff but I think a bumble init system also deserves mention. What do you think? @isbm

Funny enough you can't pull the whole firmware to the boot.img as just the modem is almost 2x big as the partition itself :D

@isbm
Copy link
Member

isbm commented Jan 27, 2026

Otherwise would be cool to present this on FOSDEM booth.

Well, I think it is too late. 😢 But in any case, if you go to FOSDEM in just four days — I will be there too.

@isbm
Copy link
Member

isbm commented Jan 27, 2026

@phodina OK, looks good. Anything else from your side to this PR or more improvements coming in different PRs 😛 ?

@isbm isbm requested a review from Copilot January 27, 2026 13:39
@isbm isbm added documentation Improvements or additions to documentation enhancement New feature or request labels Jan 27, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Nix/NixOS tooling and a demo boot flow, plus runtime enhancements for mounting and kernel/initramfs generation (overlayfs support, cmdline-based root selection, and kernel config validation).

Changes:

  • Add overlayfs support and mount flag handling (incl. read-only root scenarios).
  • Add kernel cmdline parsing + improved device resolution (UUID/label/path) and more tolerant module loading.
  • Add Nix flake packaging, NixOS demo components (kernel/u-boot/rootfs/initramfs), and a GitHub Actions workflow to build Nix packages.

Reviewed changes

Copilot reviewed 25 out of 28 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
syslib/src/fs.rs Adds mount-with-flags helper and overlayfs detection/mount support.
syslib/src/blk.rs Expands block device probing to include raw devices (not only partitions).
src/microhop.rs Adds mount mode support, cmdline-based root selection, and UUID/label device resolution.
src/main.rs Integrates overlayfs boot flow and pivots into overlay root when configured.
src/kmodprobe.rs Makes missing kernel modules a handled runtime condition (logs + returns).
src/cmdline.rs New cmdline parser for /proc/cmdline to support root=, rootfstype=, rootflags=.
rustfmt.toml Updates rustfmt configuration key for function parameter layout.
profile/src/cfg.rs Extends config schema with an overlayfs section and accessors.
nixos/u-boot.nix Adds Nix derivation to build u-boot for QEMU aarch64.
nixos/nixos-rootfs.nix Adds a minimal Nix-built squashfs rootfs for the demo boot flow.
nixos/microhop-config.nix Provides a microhop.conf for the QEMU demo (overlayfs + squashfs intent).
nixos/kernel.nix Adds a Nix-built kernel with an embedded config tailored for the demo.
nixos/initramfs-microgen.nix Builds an initramfs via microgen new with kernel-config validation inputs.
nixos/example-system.nix Adds an example NixOS system configuration intended for testing microhop.
microgen/src/rdpack.rs Makes initramfs packer create output directory before writing the archive.
microgen/src/rdgen.rs Allows initramfs generation without kernel modules (monolithic kernels).
microgen/src/main.rs Adds kernel config validation flow and new info listing commands.
microgen/src/kconfig_validator.rs New kernel .config validator with filesystem/block-device support lists.
microgen/src/clidef.rs Extends CLI flags for validation and supported-feature listing.
flake.nix Adds flake packaging for microhop/microgen and demo QEMU boot app for aarch64.
flake.lock Pins Nix inputs for reproducible builds.
etc/microhop.conf Updates sample config to document UUID/label specs and overlayfs configuration.
README.md Documents Nix build usage and links to changelog; references demo video.
Makefile Adjusts architecture detection to use uname -m.
CHANGELOG.md Introduces a changelog documenting new Nix/overlayfs/validation features.
.gitignore Ignores Nix result/ output.
.github/workflows/build.yml Adds CI workflow to build Nix packages across multiple platforms and publish releases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 239 to 248
let msg = if is_error {
format!("Block device {} is not enabled. Required for specified block device", blk_name)
} else {
format!("Block device {} is not validated (use --block-devices to validate)", blk_name)
};

if is_error {
result.add_error(config_option, &msg);
} else {
result.add_warning(config_option, &msg);
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Same as filesystem validation: when is_error is false, the message says the block device "is not validated", but the code did validate it and found it disabled (just downgraded to a warning). Consider rewording to avoid implying that no check was performed.

Copilot uses AI. Check for mistakes.
Comment on lines 209 to 213
let msg = if is_error {
format!("Filesystem {} is not enabled. Required for specified rootfs", fs_name)
} else {
format!("Filesystem {} is not validated (use --filesystems to validate)", fs_name)
};

if is_error {
result.add_error(config_option, &msg);
} else {
result.add_warning(config_option, &msg);
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

When is_error is false, the message says the filesystem "is not validated", but the code did validate it and found it disabled—it's just treated as a warning. This wording is misleading; consider changing the message to indicate the feature is disabled but only enforced as an error when --filesystems is provided.

Copilot uses AI. Check for mistakes.
Comment on lines 252 to 256
let msg = format!("Unknown block device type '{}'. Use --list-block-devices to see supported types", blktype);
if is_error {
result.add_error(blktype, &msg);
} else {
result.add_warning(blktype, &msg);
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The unknown block-device error suggests using --list-block-devices, but the CLI flag implemented for listing is microgen info --block-devices. Update the message to point to the correct command/flag.

Copilot uses AI. Check for mistakes.
@phodina
Copy link
Author

phodina commented Jan 27, 2026

@phodina OK, looks good. Anything else from your side to this PR or more improvements coming in different PRs 😛 ?

Added the last missing piece, adding the firmware files.

I went the way to specify file with records SRC:DST and specifying the base of the firmware in config file to limit the misuse of copying the files.

Well, I think it is too late. 😢 But in any case, if you go to FOSDEM in just four days — I will be there too.

Will be nice to see you there in person.

I meant only to mention it uses microhop as the initramfs and mention it on a flyer to the NixOS phones :)

@isbm
Copy link
Member

isbm commented Jan 27, 2026

@phodina seems like The System ™ isn't completely happy and seems some of these points are quite valid. Could you please take a look?

@phodina
Copy link
Author

phodina commented Jan 27, 2026

@isbm sure will look into it tomorrow :)

Petr Hodina added 5 commits January 28, 2026 16:56
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Petr Hodina added 25 commits February 1, 2026 01:13
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
…systems

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
…he generator)

Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Petr Hodina added 3 commits February 1, 2026 08:52
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants