[LinuxBIOS] Specifications

Corey Osgood corey.osgood at gmail.com
Tue Jun 12 21:00:18 CEST 2007


Brendan Trotter wrote:
> Hi,
>
> On 6/12/07, Stefan Reinauer <stepan at coresystems.de> wrote:
>   
>> * Brendan Trotter <btrotter at gmail.com> [070612 12:43]:
>>     
>>>> check LinuxBIOSv2/util/lbtdump
>>>>         
>>>  I've found "src/include/boot/linuxbios_tables.h" and have also looked
>>>  at the source for LinuxBIOSv2/util/lbtdump.
>>>
>>>  However, I fail to see how any source code can be considered a viable
>>>  alternative to documentation for something that is (hopefully) a
>>>  non-proprietory common standard. Reverse engineering (including
>>>  relying on assumptions derived from the source code of any specific
>>>  implementation) is what people do when they have no documentation and
>>>  are willing to stumble around in the dark hoping to implement
>>>  something that works until the wind changes.
>>>       
>> Yes, no doubt. You are perfectly right, and we are looking forward to
>> your patches to fix this problem. Of course you do not have to reverse
>> engineer, but just read the code, as we are non-proprietary. And of
>> course we are always here to be asked.
>>     
>
> Hehe - by the time you've finished answering all my questions you'd
> wish you'd written the documentation beforehand... ;-)
>   

Probably, but personally I'd rather see Stefan devote his time to the
great work they're doing on v3 ;) I'll try to help a little, although my
knowledge of the inner workings of LB is somewhat limited.

> Is "uint32_t" always little-endian or is it architecture specific
> (reverse engineering ruled out "always big-endian"), 

Yes, it should be dependent on the architecture

> and would the
> "lb_header.signature" field always have an ASCII 'L' at the lowest
> address (or is that architecture specific too)?
>   

no idea...
> The source file "util/lbtdump/lbtdump.c" does this:
>
> 		if (head->header_bytes != sizeof(*head)) {
> 			fprintf(stderr, "Header bytes of %d are incorrect\n",
> 				head->header_bytes);
> 			continue;
> 		}
>
> >From this can I assume that the size of the LinuxBIOS Table header
> will always be 24 bytes, and the LinuxBIOS Table header will never be
> extended in the future (or is this just a bug that makes "lbtdump"
> unable to handle forward/backward compatability)?
>
> The file "src/include/boot/linuxbios_tables.h" defines 3 types of memory ranges:
>
> #define LB_MEM_RAM       1	/* Memory anyone can use */
> #define LB_MEM_RESERVED  2	/* Don't use this memory region */
> #define LB_MEM_TABLE     16	/* Ram configuration tables are kept in */
>
> The file "util/lbtdump/lbtdump.c" doesn't agree:
>
> 		switch(rec->map[i].type) {
> 		case 1: mem_type = "ram"; break;
> 		case 3: mem_type = "acpi"; break;
> 		case 4: mem_type = "nvs"; break;
> 		default:
> 		case 2: mem_type = "reserved"; break;
> 		}
>
> Can I assume that the defines in "linuxbios_tables.h" are out-of-date,
> and that the memory type field is the same as specified by version 2
> of the ACPI specification (but perhaps not version 3, as that defines
> a new "5 = faulty RAM" type)? If "linuxbios_tables.h" is out-of-date,
> is "16 = RAM configuration tables are stored in" still possible on
> older versions of LinuxBIOS (and how would I detect which version of
> LinuxBIOS is present, considering there's no version number in the
> LinuxBIOS Table header)?
>
> What is the LB_TAG_HWRPB structure. Is it something to do with a
> "Hardware Restart Parameter Block", and what does it contain? For e.g.
> would a value of zero indicate that the computer was shutdown
> correctly before boot, and a non-zero value indicate that the computer
> crashed or had hardware problems?
>
>   

Again, no clue really..

> Would I also be correct to assume that a payload doesn't need to care
> about any of the "cmos_entries" and "cmos_enums", unless a BIOS
> setup/configuration utility is being built into the payload?
> Alternatively, could/would a payload search for strings to find CMOS
> values (e.g. search for the cmos_entry with the name string
> "power_on_after_fail" to see if additional hardware testing can be
> skipped, search for "baud_rate" to determine the serial port
> configuration, etc)?
>   

My *understanding* is that different vendors do different things with
the cmos, so payloads couldn't count on them for the vendor bios, so
they don't for linuxbios either. I suppose a payload *could* do this
with linuxbios, if the project wanted to, but I can't think of any that
does, although openbios may. Anything cmos-related, such as power on
after fail, should currently be handled between linuxbios and a
userspace utility, like lxbios.

>   
>> It is of course not unique. It is the index of the vendor name within
>> the strings array of struct lb_mainboard. Since we're not trying to
>> close things down, we don't have to work with magic numbers. So nothing
>> needs to stay unique.
>>     
>
> Of course - it's similar to the way SMI/DMI does strings, yet are the
> strings themselves guaranteed to be unique, or is it possible for one
> manufacturer to use an identifying string in the future that another
> (possibly out of business) manufacturer had used in the past?
>   

This is something google would be good for, I can't come up with a good
answer. Yes, they SHOULD always be unique, given that there are 65536
possible combinations, but whether there's some sort of registration or
assignment system or it's at the manufacturers disposal, I don't know.

> Motherboard manufacturer identification is one of the things that
> (IMHO) should be unique. The motherboard part number string should
> also be unique for that manufacturer ID. Otherwise it'd be difficult
> for payloads/utilities/OSs to use these IDs to avoid any hardware
> problems in specific motherboards.
>   

Manufacturers are often very lax about this, in some cases motherboards
have 5 or more different (subsystem) device IDs on the same board, or in
others they don't bother setting most of them. This is one area where
mainboard manufacturers need to clean up.

>>>>> I assume there may also be ACPI, MP specification, PIRQ routing and/or
>>>>> (possibly) SMI/DMI tables, and I'm guessing that (if present) these
>>>>> tables can be searched for using the same methods as described in
>>>>> their corresponding specifications.
>>>>>           
>>>> They're not used by payloads (except the Linux kernel)
>>>>         
>>>  Surely LinuxBIOS isn't intended as a "Linux only" BIOS though....
>>>       
>> Of course not. ACPI is not really useful for payloads though, unless the
>> payload wants to carry a full blown ACPI interpreter. Which rules out
>> basically anything but an OS.
>>     
>
> I can think of a variety of uses, ranging from utilities that do
> nothing more than display hardware information, to diagnostics, to
> benchmarking, to hyper-visors, to full OSs...
>
>   
>>>>> - are AP CPUs started (or waiting for a SIPI sequence)?
>>>>>           
>>>> yes, hardware is completely up when linuxbios is done.
>>>>         
>>>  I tried it on a dual CPU Bochs emulation (second CPU was left in "wait
>>>  for SIPI" state) - I'm guessing I need to enable multi-CPU support
>>>  via. some compile time option for the "emulation/qemu-i386" target?
>>>       
>> Yes, the emulation/qemu-i386 is per default not supporting SMP.
>>     
>
> I'm becoming skeptical here. I can't find anything in LinuxBIOS source
> code that starts AP CPUs, but in "src/arch/i386/smp/mpspec.c" I did
> find:
>
> /* If we assume a symmetric processor configuration we can
>  * get all of the information we need to write the processor
>  * entry from the bootstrap processor.
>  * Plus I don't think linux really even cares.
>  * Having the proper apicid's in the table so the non-bootstrap
>  *  processors can be woken up should be enough.
>  */
>
> It might be possible that no AP CPUs are ever started, and are instead
> left in a "wait for SIPI" default state, assumed to be identical to
> the BSP, and even assumed to be working (no BIST checks).
>
> AFAIK the normal approach is to send a broadcast INIT-SIPI sequence
> and wait to see which AP CPUs start (if any), and then either record
> details somewhere or have each AP CPU add itself to the MP
> specification and ACPI tables, then setup their MTTRs, thermal
> monitoring, HT links, SMBASE, etc before sending the APs back to the
> "wait for SIPI" state - i.e. in theory it should be mostly
> "configuration-less".
>
> In any case, I'm guessing I need to get LinuxBIOS to generate MP
> specification and ACPI tables to suit the number of CPUs being
> emulated by Bochs/Qemu. Is this as simple as adding something like
> "option CPUs = ?" to the "targets/emulation/qemu-i386/Config.lb" file?
> I'm guessing it's more involved than this, as I couldn't find an
> example in the "Config.lb" of other targets.
>   

Please check out the k8 code, especially init_cpus.c, I think you'll
find what you're looking for there. Afaik, the k8 is the only
smp-supported cpu for the moment.

>   
>>>  Either:
>>>  a) PCI buses and bridges aren't guaranteed to be enumerated, or
>>>  b) PCI buses and bridges are guaranteed to be enumerated but PCI
>>>  devices aren't guaranteed to be assigned resources, or
>>>  c) PCI buses and bridges are guaranteed to be enumerated and PCI
>>>  devices are guaranteed to have resources assigned (including ROMs)
>>>  d) PCI buses and bridges are guaranteed to be enumerated and PCI
>>>  devices are guaranteed to have resources assigned (except ROMs)
>>>       
>>>  "They have their resources." would mean either c) or d), where each
>>>  device may or may not be in a power saving state (if supported by the
>>>  device), and may or may not be still configured to use MSI (if
>>>  supported by the device)....
>>>       
>> yes, either c or d. You choose.
>>     
>
> You mean all LinuxBIOS developers are willing to make sure all PCI
> device ROMs either have physical addresses assigned or don't have
> physical addresses assigned based on my advice? Perhaps I've
> misunderstood... :-)
>   

I think I have too...

>>>> Not at the moment. But in General this is easy. If no VGA class PCI
>>>> device is there, the machine is 99.99% headless.
>>>>         
>>>  And if a VGA class PCI device is present, you've got no idea if no
>>>  monitor is attached...
>>>       
>> Obviously not. and if the device does not do EDD you have no reliable
>> way of finding out either.
>>     
>
> There's a simple and easy way to find out if a monitor is attached or
> not, and it doesn't involve messing about with EDD - simply give the
> end-user the option of setting (or not setting) a value in the CMOS.
>   

This is already an option, to have vga you run the vga rom and send
output to the monitor. Otherwise, you keep serial output and don't
bother with the rom.

> My (limited) reverse engineering has already shown that there's CMOS
> entries for a serial port (possibly intended for setting up a serial
> cable to communicate with a terminal emulator?).
>   

Why reverse engineer? The source code is openly available ;) BTW, we use
the serial port as our main debugging source, LinuxBIOS initially sets
it up in the pre-ram init code, usually to 115200 8N1. Then the post-ram
code reads from the cmos to determine if that speed should be changed or
if serial output should be turned off entirely in favor of vga.

Hope I've been a little help

-Corey




More information about the coreboot mailing list