[DOCUMENT] Re: Intel Macs that boot FreeBSD?

Bruce M Simpson bms at spc.org
Sat Apr 8 10:32:31 UTC 2006


I wrote a document which explains exactly which BIOS calls FreeBSD
uses to boot.

Unfortunately there is a bit of an ongoing re-jig with my web stuff so
it isn't up anywhere but I will repost it here.

BMS
-------------- next part --------------
-----------------------------------------
FreeBSD BIOS Coupling on i386 
Bruce M. Simpson <bms at spc.org> 2002-12-27
-----------------------------------------

Copyright (c) 2002 Bruce M. Simpson, All rights reserved.

Redistribution and use are freely permitted provided that the above
copyright notice and this paragraph are duplicated in all forms.

Introduction
------------
This file is intended purely as a source of technical information
on how closely coupled the FreeBSD/i386 boot process is to the BIOS
and legacy i386 hardware.

It should be of interest to anybody considering implementing their
own BIOS and who wishes to be able to boot FreeBSD with it.

FreeBSD Boot Process
--------------------
The FreeBSD OS employs a three stage boot loader. Here we consider the
most common case: booting from a hard disk recognised by the BIOS.

The flow of execution runs thus: boot0 is loaded from the MBR, which then
looks for the first FreeBSD DOS partition; boot1 is loaded from the BPB,
which then loads and invokes boot2 from the boot sectors inside the FreeBSD
disk label; then boot2 attempts to load and invoke the FreeBSD Loader from
the root slice. Finally, the loader invokes the kernel.

boot0/boot0sio
--------------
 - Master Boot Record (MBR) boot loader
  - Permits selection of DOS partition to boot from
  - Loaded from INT 19h (Bootstrap Loader) by BIOS
  - Self-relocates to 0000:7C00 (well clear of BIOS Data Area)
  - Loads boot sector from selected partition into segment 0, and
    performs a near jmp through BX to it

  BIOS functions used:
  Int Fn  SFn  Description
  ------------------------------------------------------------------
  10h 0Eh n/a  Write Character in Teletype Mode (boot0)
  13h 02h n/a  Read Disk Sectors
  13h 03h n/a  Write Disk Sectors
  13h 42h n/a  Extended Read Sectors
  13h 43h n/a  Extended Write Sectors
  14h 00h n/a  Initialize Serial Port	(boot0sio)
  14h 01h n/a  Send Byte		(boot0sio)
  14h 02h n/a  Receive Byte		(boot0sio)
  14h 03h n/a  Read Status		(boot0sio)
  16h 00h n/a  Read Keyboard Input	(boot0)
  16h 01h n/a  Check Keyboard Status	(boot0)
  1Ah 00h n/a  Get System Time

  BIOS parameters accepted:
  Register   Description
  -------------------------------
     dl      BIOS Drive Number (when invoked via INT 19h IPL)

boot1
-----
 - BIOS Parameter Block (BPB) boot loader
  - Resides in the BPB of the first FreeBSD partition on the disk
  - Loaded and invoked by boot0 at 0000:7C00
  - Self-relocates on load to 0000:0700 (above BIOS data area and IDT)
  - Enables A20 by itself using the AT keyboard controller method
  - Reads and relocates boot2 to low memory to continue boot process
  - boot1 is kept resident in memory, and V86 mode is used to call into
    the real mode xread routine in this segment.

  BIOS functions used:
  Int Fn  SFn  Description
  ------------------------------------------------------------------
  10h 0Eh n/a  Write Character in Teletype Mode
  13h 00h n/a  Disk Controller Reset
  13h 02h n/a  Read Disk Sectors
  13h 08h n/a  Read Disk Drive Parameters
  13h 41h n/a  Check If Extensions Present
  13h 42h n/a  Extended Read Sectors
  13h 43h n/a  Extended Write Sectors
  16h 00h n/a  Read Keyboard Input

boot2 meta-binary
-----------------
btxldr, btx, and boot2 are actually compiled into the same binary.
Many things are going on in here.

BTXLDR
------
 - This is used to load the BTX framework.
 - It enters 'unreal' mode to allow the use of a 32-bit flat address
   space, thus permitting boot2 to be compiled using gcc.

  BIOS Data Area locations referenced:
  Address  Description
  ------------------------------------------------------------------
  40:13h   Main Memory Size
  40:49h   Video Mode
  40:50h   Video -- Cursor Position Page 0

  BTXLDR addresses the VGA video memory at B8000h directly.
  BTXLDR does not make any BIOS calls.

BTX and boot2
-------------
 - BTX sets up a small protected mode kernel. It's actually quite a good
   example of how to drive the i386.
 - A V86 monitor is used to redirect calls into the BIOS (and capture some),
   whilst remaining in protected mode.
 - INT 19h is used by the BTX client to reset the machine.

  BIOS Data Area locations referenced:
  Address  Description
  ------------------------------------------------------------------
  40:13h   Main Memory Size
  40:17h   Keyboard Shift Flags 1
  40:49h   Video Mode
  40:50h   Video -- Cursor Position Page 0
  40:72h   Warm Boot Flag

  Direct I/O Port Hardware Accesses:
  Port   Description
  ------------------------------------------------------------------
   0x20  8259 Master Interrupt Command Register
   0x21  8259 Master Interrupt Mask Register
   0xA0  8259 Slave Interrupt Command Register
   0xA1  8259 Slave Interrupt Mask Register
  0x3F8  UART 0 Transmit/Receive Buffer and Divisor LSB
  0x3F9  UART 0 Divisor MSB
  0x3FB  UART 0 Line Control
  0x3FC  UART 0 Modem Control
  0x3FD  UART 0 Line Status

  BIOS Calls intercepted by the V86 Monitor:
  Int Fn  SFn  Description
  ------------------------------------------------------------------
  15h 87h n/a  Access Extended Memory
  19h n/a n/a  Bootstrap Loader

  BIOS Calls passed through by the V86 Monitor:
  Int Fn  SFn  Description
  ------------------------------------------------------------------
  10h 0Eh n/a  Write Character in Teletype Mode
  12h 88h n/a  Base Memory Size
  13h 08h n/a  Read Disk Drive Parameters
  15h 88h n/a  Extended Memory Size
  16h 00h n/a  Read Keyboard Input
  16h 01h n/a  Check Keyboard Status

boot2
-----
boot2 is the BTX client. It uses the protected-mode kernel to call into
the BIOS through the V86 monitor. It understands enough of FreeBSD FFS
to load /boot/loader or /kernel on its own. The FORTH loader is preferable
for modern FreeBSD configurations. It uses the /boot.config file for
some settings of its own (such as forcing an autoboot on a CD installation).

It knows enough to load an ELF or an a.out executable.

loader
------
 - This is the newer, advanced FreeBSD third stage bootstrap which has
   an embedded, Forth-like interpreter called FICL.
 - It is actually referred to as BOOT3 in the boot2 source.
 - Source is found under: /usr/src/sys/boot
 - Picks up i386 specific functions from i386/libi386, these handle
   interaction with the platform hardware, and the BIOS.

  BIOS Calls passed through by the V86 Monitor:
  Int Fn  SFn  Description
  ------------------------------------------------------------------
  10h 02h n/a  Set Cursor Position (from vidconsole.c)
  10h 03h n/a  Read Cursor Position and Type (from vidconsole.c)
  10h 06h n/a  Scroll Active Page Up (from vidconsole.c)
  10h 08h n/a  Read Character and Attribute (from vidconsole.c)
  10h 09h n/a  Write Character and Attribute (from vidconsole.c)
  10h 0Eh n/a  Write Character in Teletype Mode (from vidconsole.c)
  12h 88h n/a  Base Memory Size (from biosmem.c)
  13h 00h n/a  Disk Controller Reset (from bioscd.c, biosdisk.c)
  13h 02h n/a  Read Disk Sectors (from biosdisk.c)
  13h 08h n/a  Read Disk Drive Parameters (from biosdisk.c)
  13h 42h n/a  Extended Read Sectors (from bioscd.c, biosdisk.c)
  13h 4Bh 01h  Terminate Disk Emulation (from bioscd.c)
  15h 86h n/a  Wait (from time.c)
  15h 88h n/a  Extended Memory Size (from biosmem.c)
  15h E8h 01h  Get Extended Memory Info (from biosmem.c)
  15h E8h 20h  Get System Memory Map (from biosmem.c)
  16h 00h n/a  Read Keyboard Input (from vidconsole.c)
  16h 01h n/a  Check Keyboard Status (from vidconsole.c)
  1Ah 02h n/a  Read CMOS Time (from time.c)
  1Ah B1h 01h  PCI Test for PCI BIOS Present (from biospci.c)
  1Ah B1h 03h  PCI Find Device Matching Class Code (from biospci.c)
  1Ah B1h 0Ah  PCI Read Device Configuration DWORD (from biospci.c)
 
  - FreeBSD's import of ficl has functions which wrap the in/out
    instructions to allow them to be used from boot FORTH. The actions of
    any FORTH programs which use these bindings are not documented here.

  - biospnp.c wraps the PnP BIOS. The PnP specification dictates that
    there must be a $PnP structure in the BIOS image, which contains a
    real mode CS:IP vector to be used for calls into the PnP BIOS. This
    vector will vary according to the BIOS in use.

  - pxe.c uses v86 to bounce into routines inside the PXE UNDI BIOS which
    knows how to get the IP address, etc. These ROMs exist on the network
    card, which can reside on an ISA or PCI bus. PXE compliant cards have
    $PnP headers in the boot ROM. Again, the PnP BIOS specification details
    how the various boot vectors in this header work, when a PnP BIOS is
    loading a PnP compliant expansion ROM.

Kernel->BIOS entry points
-------------------------
 - Some BIOS extensions can be called from protected mode using the
   BIOS32 Service Directory. Others must be called from real mode.

 - We're lurking in: /usr/src/sys/i386

 - i386/bios.c, i386/bioscall.s and i386/vm86.c define the following:
   - bios16() -- Make a 16-bit BIOS call in real mode *no man page*
   - bios32() -- Make a 32-bit BIOS call in protected mode (bios(9))
   - bios32_SDlookup() -- Attempt to locate a BIOS32 service (bios(9))
   - bios_sigsearch() -- Search for a service signature in ROM (bios(9))
   - vm86_intcall() -- Make a 16-bit BIOS call in V86 mode *no man page*
   - vm86_datacall() -- Make a 16-bit BIOS call in V86 mode which returns
                        some data *no man page*
   - vm86_bioscall() -- Make a 16-bit BIOS call in V86 mode *no man page*
   - BIOS_PADDRTOVADDR() wraps a reference to BIOS Data Area memory.

  - Grepping for the relevant permutations of the above entry points
    will let you see where kernel drivers are entering the BIOS, or
    referencing the BIOS Data Area.

Boot-time Kernel->BIOS Communication
------------------------------------
 - i386 specific low level code is in: /usr/src/sys/i386/i386
 - Early boot initialization is handled in: locore.s
 - loader enters kernel at the entry point 'newboot'
 - The kernel reloads the GDT whilst bringing up the system. vm86
   descriptors are created as part of the system-wide GDT. These are used
   to call into the BIOS or other real mode expansion ROMs later on.

 - Most of the kernel coupling is to the loader and not the BIOS, which
   is a good thing. That is, handling the BIOS directly has been farmed
   out to the loader, which passes this information to the kernel using
   a boot information structure, _bootinfo, which it fills in after
   loading the kernel.

 - The kernel does make a limited number of BIOS calls during boot,
   these are mainly made within machdep.c to discover the BIOS's
   idea of the system memory map:

    Int Fn  SFn  Description
    ------------------------------------------------------------------
    12h 88h n/a  Base Memory Size
    15h 88h n/a  Extended Memory Size
    15h E8h 01h  Get Extended Memory Info
    15h E8h 20h  Get System Memory Map
  
  - If you set bootverbose to 1 from the loader, you can see the SMAP
    initialization being printed out on the console.

 - isa/mca_machdep.c makes these calls via vm86_intcall():

    Int Fn  SFn  Description
    ------------------------------------------------------------------
    15h C0h n/a  Return System BIOS Configuration

   - This is used to discover a MicroChannel Bus (MCA) machine.

 - isa/pci_cfgreg.c makes these calls via bios32():

    Int Fn  SFn  Description
    ------------------------------------------------------------------
    1Ah B1h 01h  PCI Test for PCI BIOS Present
    1Ah B1h 0Fh  PCI Route Device Interrupt

   - This is necessary as the board specific knowledge/code to route
     interrupts according to the northbridge/southbridge pair is contained
     within the BIOS on i386 machines. Note however that configuration
     register access is a well defined process on the i386 which doesn't
     require assistance from the BIOS.

 - The kernel doesn't specifically call into the BIOS after boot, unless
   separate initialization is required on behalf of drivers (e.g. APM).
   These are considered separately; please see below.

Run-time Kernel->BIOS Communication
-----------------------------------
 - apm/apm.c makes these BIOS calls in 16- or 32-bit mode depending
   on whether or not the APM BIOS supports 32-bit invocation:

    Int Fn  SFn  Description
    ------------------------------------------------------------------
    15h 53h nnh  APM BIOS Calls  (PC/AT)
    1Fh 9Ah nnh  APM BIOS Calls  (PC98)

 - i386/isa/vesa.c makes the following calls via vm86_[int|data]call():

    Int Fn  SFn  Description
    ------------------------------------------------------------------
    10h 00h n/a  Set Video Mode
    10h 4Fh 00h  VBE Initialize VESA BIOS
    10h 4Fh 01h  VBE Get Extended Modes
    10h 4Fh 02h  VBE Set Extended Mode
    10h 4Fh 04h  VBE Buffer Manipulation
    10h 4Fh 05h  VBE Window Manipulation
    10h 4Fh 06h  VBE Scanline Manipulation
    10h 4Fh 07h  VBE Linear Framebuffer Manipulation
    10h 4Fh 08h  VBE DAC Manipulation
    10h 4Fh 09h  VBE Palette Manipulation

 - dev/fb/vga.c uses the BIOS Data Area, primarily if there is no VESA
   BIOS present.

    BIOS Data Area locations referenced:
    Address  Description
    ------------------------------------------------------------------
    40:4Ah  Video Columns (BYTE)
    40:4Ch  Video Bytes per Page (WORD)
    40:4Dh  Video Current Page Offset (WORD)
    40:63h  Video I/O Port Number Base (WORD)
    40:84h  Video Number of Rows (BYTE)
    40:85h  Video Pixels per Character (WORD)
    40:87h  Video Options (BYTE)
    40:88h  Video Switches (BYTE)
    40:A8h  Video Parameter Control Block Pointer (DWORD) 

 - dev/kbd/atkbd.c makes the following calls via vm86_intcall(),
   and may reference a BIOS Data Area location as a result of INT 15h:

    Int Fn  SFn  Description
    ------------------------------------------------------------------
    15h C0h n/a  Return System BIOS Configuration
    16h 03h 06h  Get Typematic Rate
    16h 09h n/a  Get Typematic Capabilities  

 - XXX: The DMItable is documented in bios(9), but not implemented.
 - XXX: The SMBIOStable is documented in bios(9), but not implemented.
 - XXX: I haven't documented how ACPI is called yet.

References
----------
The Undocumented PC 2e
 van Gilluwe, Frank; Addison-Wesley; ISBN 0-201-47950-8

PC Intern 6e
 Tischer & Jennrich; Abacus; ISBN 1-55755-304-1

PCI System Architecture 4e
 Shanley & Anderson; Addison-Wesley; ISBN 0-201-30974-2


More information about the freebsd-current mailing list