Or maybe, given
> typedef unsigned char u8;
> struct linuxbios_cmos {
> u8 linux_booted_ok; // Linux booted into runlevel 3
> u8 chipset_settings_index; // which chipset setting to use
> u8 chipset_settings_last_known_good; // last "aggressive" good set
> u8 pad[253];
> };
In LinuxBIOS:
#define LINUX_BOOTED_OK 0
#define LINUX_BOOTED_OK_DIRTY 0x80
#define CHIPSET_SETTINGS_INDEX 1
chipset_setup()
{
int ok;
int index;
index = read_cmos(LINUX_BOOTED_OK);
ok = (index & LINUX_BOOTED_OK_DIRTY) == 0;
index &= ~LINUX_BOOTED_OK_DIRTY;
if (!ok)
index = 0;
if (index > MAX_CHIPSET_INDEX)
index = 0;
write_cmos(LINUX_BOOTED_OK,
index | LINUX_BOOTED_OK_DIRTY);
setting = &setting_array[index];
chipset_init(setting);
}
Linux reads the LINUX_BOOTED_OK flag and clears the
LINUX_BOOTED_OK_DIRTY bit to force LinuxBIOS to not
reverse to index zero on next boot.
The booted Linux-kernel can select an alternative root filesystem
and/or kernel if the index is zero or a separate CMOS location can be
used to select, with some fail safe algorithm of course, the kernel
and root fs to use.
And as a bonus: if the CMOS checksum fails LinuxBIOS reverts to the
safe boot status!
--Jan