I have in mind a custom machine for a practical purpose:
I want to boot to a calibration program to gather system parameters, save that data somewhere, then boot the operating system using stored calibration data to set certain defaults.
This wouldn't have to be done at every boot, only initial boot and after a significant hardware change.
The calibration program itself I plan to write on my own. Mostly I want to interactively collect data on screen resolution (characters, pixels), input configuration (user selected keys, mouse, joysticks, etc) and audio throughput (mic check, speaker configuration, protocol, resampling). My purpose is a generic console device but the design could be useful for industrial applications or other purposes.
Is it possible, and how could I, use a bootloader like GRUB(2) to load an operating system in two stages, retaining collected data between them?
Would it be possible to script GRUB, if data retention isn't possible, so as to generate a kernel load line on-the-fly after running callibration programs?
How about when you are running from the initrd? At that point, you are running a kernel, you are running from a RAM disk, you can mount volumes, presumably write to them, then the initrd environment starts the main OS.
I am not an expert in this and have no specific instructions, but hooks in the initrd are my first inclination. If you need to start earlier, before the kernel loads, you might create a grub module and invoke it from the grub.cfg script. It, too, is doable; I've not the first idea how.
Last edited by ewaller (2013-07-29 05:48:59)
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
You assume people are rational and influenced by evidence. You must not work with the public much. -- Trilby
How to Ask Questions the Smart Way
If you use UEFI, then you could write it as an efi application to be launched from your ESP. But again... no idea how you would do that either.
Well, there's necessarily going to be two parts: 1) Generating the config, and 2) reading & using the config. You want to do 1 yourself, so nothing much to be said about that. As for 2, you have a few options – pass kernel parameters, fiddle with sysctl, /sys or /run, or edit config files in /etc or elsewhere. Which of these options is going to work well for you (or at all) depends on what you're doing.
I suppose passing kernel parameters would be easiest – you'd just load your pre-OS, gather data, then chainload another instance of GRUB/some other loader that would simply boot kernel with given parameters. This is probably also going to be most limited. For manipulating one of the runtime filesystems, you'll probably have to go the “doing stuff from the initrd” way. Working from initrd should also work well for writing config files to the disk, although you could possibly do that from your pre-OS as well – but that'd require you to somehow gain access to the filesystem – if your pre-OS is going to be some flavour of Linux as well, it shouldn't be hard; if it's going to be completely custom-written kernel, you'd have to roll your own filesystem driver.
You could also have your calibration program split in two parts. First would run before Linux and would generate the config, then store it somewhere – in a file, if you have access to the filesystem, or perhaps just dump it into a raw partition you created specially for this purpose. The second part would then be a normal Linux app – possibly launched by systemd as a startup service, or it could run from initrd – that would read the config and apply it somehow.
Last edited by Oxyd (2013-07-29 08:23:33)
“UNIX systems generally have a good, though not impeccable, record for software reliability. The typical period between software crashes […] is well over a fortnight of continuous operation.” ~ Dennis M. Ritchie, The UNIX Time-sharing System--A Retrospective
Thank you for the advice!
Maybe this won't be as complex as I first thought.
A two-stage initrd sounds like the best option, using the runtime filesystem to save and load calibration data (most likely from /etc/somewhere/), if that can be done safely with regard to the infinite diversity in infinite combinations that is "the runtime filesystem".
In the first stage check if calibration data file(s) exists and exit if they do, triggering the rest of the boot process.
If they do not, prompt to connect all needed devices (on a timer or until a keypress) and then run hardware detection scripts (only for connection ports, input devices, monitors, and audio devices), then run interactive calibration:
0. if a bluetooth transciever was detected, prompt again to connect all needed bluetooth devices
1. if a keyboard is connected, get the correct international keyboard layout.
--(ala "loadkeys layout" in arch's install); ask the user to select their country on a map, then veryfiy layout by typing a specific sequence of characters (ala Typing of the Dead).
2. if a joystick is connnected, get the purpose of each button and range of analog functions.
--script sane defaults (ala mupen64plus), then run a test program that would allow the user to manipulate each function for verification.
--if the user would like to change the configuration, provide a graphic means of doing so showing the controller and mapped keys.
3. if a monitor is connected, find the optimum resolution.
--ideally the screen mode would never be changed from this resolution and anything requiring a different resolution would be scaled (ala SteamOS's modeswitch-inhibitor)
4. if a soundcard is detected, find the optimum speaker configuration
--how many speakers
Once this is done, write calibration data to file(s), then exit and trigger the rest of the boot process.
My original plan here was to boot directly to a multi-system emulator, such as mednafen or higan, but after playing with SteamOS I realized this could be expanded on.
From this point on, whenever the user installs a new game software package through the (custom) package manager, scripts (ala winetricks) can set up it's configuration to match the saved calibration data.
So, in addition to the two-stage initrd and calibration software, this means making config scripts for every possible game software package and a custom package manager, or a plugin for an existing package manager, that would apply them, plus a config utility for within the OS. I'm not saying it will never happen, but considering my complete lack of experience it could be a few years
Valve is already doing some of what I have in mind: Their steam client is essentially a package manager for their games which allows the user to set a configuration to apply to all steam games. SteamOS's compositor and modeswitch-inhibitor (theoretically) keep the screen from changing resolution (and thus flashing, breaking x, etc) and scale games to the configured resolution (at the cost of requiring composition). Unfortunately the "big picture" doesn't make for a very practical desktop and can't really be used for non-steam games (you can add non-steam games to the library, but the only "benefit" of this is the steam opengl overlay).