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

Reply via email to