BIOS(9)

πŸ’– BIOS(9) πŸ’–

okay so this is the BIOS(9) page from the Kernel Developer's Manual β€” section 9, the kernel-dev zone, iykyk. if you're poking at x86 PC BIOS stuff from inside the kernel, bestie, this is literally your page. 🫢


🌸 NAME 🌸

bios_sigsearch, bios32_SDlookup, bios32, bios_oem_strings β€” the whole little friend group that lets you interact with PC BIOS. πŸ’…


✨ SYNOPSIS ✨

#include <sys/param.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/pc/bios.h>

uint32_t
bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
    int sigofs);

int
bios32_SDlookup(struct bios32_SDentry *ent);

int
bios32(struct bios_regs *br, u_int offset, u_short segment);

BIOS_PADDRTOVADDR(addr);

BIOS_VADDRTOPADDR(addr);

extern struct bios32_SDentry PCIbios;
extern struct SMBIOS_table SMBIOStable;
extern struct DMI_table DMItable;

int
bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);

struct bios_oem_signature {
        char * anchor;          /* search anchor string in BIOS memory */
        size_t offset;          /* offset from anchor (may be negative) */
        size_t totlen;          /* total length of BIOS string to copy */
};
struct bios_oem_range {
        u_int from;             /* shouldn't be below 0xe0000 */
        u_int to;               /* shouldn't be above 0xfffff */
};
struct bios_oem {
        struct bios_oem_range range;
        struct bios_oem_signature signature[];
};

πŸ¦‹ DESCRIPTION πŸ¦‹

these functions are the general-purpose interface for dealing with BIOS functions and data that you run into on x86 PC-architecture systems. no cap, that's the whole vibe. ✨

  • bios_sigsearch() β€” searches the BIOS address space for a service signature, which is usually an uppercase ASCII sequence wrapped in underscores (iconic, honestly). the search kicks off at start, or at the beginning of the BIOS if start is zero. it compares siglen bytes of the BIOS image against sig at sigofs bytes offset from wherever you currently are. no match? the current location gets bumped forward by paralen bytes and it tries again. match found? you get back its effective physical address. nothing found at all? you get zero. πŸŽ€
  • bios_oem_strings() β€” searches a given BIOS memory range for one or more strings and then composes a printable concatenation of the ones it found. it wants a structure describing the BIOS address range (which has to live within 0xe0000 - 0xfffff), plus a { NULL, 0, 0 }-terminated array of bios_oem_signature structures. each of those defines the anchor string, an offset from the beginning of the match (which may be negative, yes, negative, we contain multitudes), and totlen β€” the number of bytes to collect from BIOS memory starting at that offset. unmatched anchors just get ignored (not mad, just disappointed), while matches get copied out of BIOS memory starting at their corresponding offset, with unprintable characters swapped for a space and consecutive spaces suppressed. that composed string lands in buffer up to the given maxlen bytes (including the trailing '\0', and any trailing space suppressed). if something goes wrong β€” like trying to read outside that BIOS range, other invalid input, or a buffer overflow β€” you get a negative integer back. otherwise you get the length of the composed string. and specifically: a return value of 0 means none of the given anchor strings were found in the specified BIOS memory range. periodt. πŸ’€
  • BIOS_VADDRTOPADDR() β€” hands you the effective physical address that corresponds to the kernel virtual address addr. 🫢
  • BIOS_PADDRTOVADDR() β€” hands you the kernel virtual address that corresponds to the effective physical address addr. 🫢
  • SMBIOStable β€” if it's not NULL, it points to a struct SMBIOS_table structure holding info read from the System Management BIOS table during system startup. ✨
  • DMItable β€” if it's not NULL, it points to a struct DMI_table structure holding info read from the Desktop Management Interface parameter table during system startup. ✨

πŸ‘‘ BIOS32 πŸ‘‘

so at system startup the BIOS gets scanned for the BIOS32 Service Directory (that's part of the PCI specification, bestie), and whether the directory exists gets recorded. after that you can use it to go find other services. it's giving treasure map energy. πŸ—ΊοΈ

  • bios32_SDlookup() β€” tries to locate the BIOS32 service that matches the 4-byte identifier passed in the ident field of the ent argument. πŸ”₯
  • bios32() β€” calls a bios32 function. this presumes the function can work inside the kernel segment (which is normally the case, so like, chill). the virtual address of the entrypoint goes in entry, and the register arguments to the function go in args. πŸ’…
  • PCIbios β€” if it's not NULL, it points to a struct bios32_SDentry structure describing the PCI BIOS entrypoint that was found during system startup. 🌈

πŸŽ€ reminder reminder: those BIOS ranges have hard limits β€” from shouldn't be below 0xe0000 and to shouldn't be above 0xfffff. respect the boundaries, bestie. πŸ™ˆ

and that's the whole page, no notes. this one's from Debian, dated August 9, 2005 β€” yeah it's vintage but it still ate, fr fr. mwah, go read some BIOS. πŸ’–βœ¨πŸŽ€πŸ¦‹πŸŒΈπŸ’…

πŸ“¦ where this page comes from