I have successfully booted into a NetBSD kernel with a custom ramdisk that has a statically linked init that does nothing.
Baby steps!
Discussion
I have successfully booted into a NetBSD kernel with a custom ramdisk that has a statically linked init that does nothing.
Baby steps!
Looking at runit, it's runlevels and scripts, and manual dependency management and stuff, and that does not spark joy.
Yes, it is lean and all, but doing anything more advanced like using cgroupsv2 on Linux is a pain in the ass at best.
Nope.
mouse makes rocks do math (sickos edition)
@algernon
cgroups? I thought you were making a NetBSD distribution
@wolf480pl I am. But the goal is to be portable, and run on Linux too, and use features available on the host platform.
nitro is also a bunch of scripts, and suggests using runit's chpst for changing the service's process state (uid/gid/pwd/chroot/etc).
I like the look of nitro more than runit, but I do not want scripts. I want as little scripting in my init as possible, and definitely not shell scripts, save for a few exceptional cases (but even then, systemd-style ExecStart that just runs a script is what I'd aim for).
dinit appears to use a service description file, rather than shell scripts, so this is promising so far. It supports dependencies, working directory, environment files, running as a user - all the good stuff, and it supports the systemd socket activation protocol too, a nice boon!
Also supports redirecting stdout/stderr, though... unsure if it supports redirecting them to different places, or only one of them.
This looks like a suitable option so far. Maybe not perfect, but should be good enough for initial experimentation.
So... my next stage would be to cobble together a ramdisk that has static dinit, and a few other static binaries to mount tmpfs on /. I'm starting with static binaries, because then I don't need to copy shared libs and stuff.
Eventually, the ramdisk will by dynamically linked too. I think. There's a scenario where it will be just a statically compiled Rust program that bootstraps everything and execs the real init.
Neat, make CFLAGS=-static LDFLAGS=-static in pkgsrc/sysutils/dinit yields a statically linked binary.
This alone is not enough, though. I need tools to set up /! Luckily, /rescue has a bunch of statically linked stuff, I can use those for now.
New distribution name dropped!
fuck as the org on my forgeMeanwhile, the ramdisk is 1.8GiB, because of all the static stuff. Urgh. That's not going to fly longterm.
Hrm. There's something funky going on with the ramdisk. It gets loaded on boot, but netbsd continues booting from ld0 instead of the ramdisk.
Even with boot -m, it fails. Hm.
Oh. I guess I will need a /dev.
Oh. Maybe I need a new kernel?
It's weird, because my static init booted from ramdisk, but if I put dinit there, it boots from the real system, and I see no indicaton of the ramdisk even being tried.
Booting with -a asks for the rootfs, md0 is not an option. Allright. Lets do this the hard way then.
When booting my tiny static initd that does nothing, root is on md0a. Hmm.
Looks like this has to do with the size of the ramdisk. a 21.6MiB disk works fine.
Interesting... MEMORY_DISK_DYNAMIC is enabled, so the ramdisk size shouldn't matter, as far as I understand things.
Nevertheless, I'll try a new approach: I'll write a very small init that bootstraps things, and execs dinit.
I need to figure out how to write to the console during early boot.
The solution is populating /dev.
Nice. I wrote a small C program that mounts /, and execs the NetBSD init. This is fine short-term. All I really need from the ramdisk's init is to mount / and the store (name tbd, not /store, perhaps /polyamory, or /fuckery?), and then execs the real init.
It will need to do a lot more long term, but I'm very far from that.
Next up: Don't ship /dev, mknod(2) the few device nodes my rd-initd needs.
Or, you know... I'll just ship /dev in the ramdisk, because that's easier. I'll address that part later.
What to do next... I suppose making it boot with dinit would be the logical next step, and then I can try building a minimal system in the store, boot that up, and go from there.
Whee!
Booted with dinit, kind of. Only have two services so far: mount -a and getty on constty, but we're getting there, this is enough to validate the approach.
Now to figure out the next step!
Previously, I considered setting up a hand-built store, and going from there, but... that's a very big leap: it involves not only moving netbsd's userland to the store, I'd also have to write the "lets reconstruct the ephemeral parts of /".
Like, the goal is to have / on tmpfs...
Idea is turning out to be harder than anticipated, because I have to figure out how to mount mfs on /, and mfs_args has a caddr_t base member, and what's that, and how does that and size relate to the parameters given to mount_mfs?
And where's the source of mount_mfs? Because I can't find it in /usr/src/sbin/...
Since I don't want to use NetBSD's initd, lets look at the init systems available in pkgsrc!
We have
dinit,nitro,runit, as far as I can tell, andsysvinitinpkgsrc-wip. I will not be usingsysvinit, so lets have a quick thread about the other three!