mainly just considering PATA/IDE (QEMU's default interface of choice)
glosses over memory model
Boot process:
Execution starts in the BIOS. QEMU's default BIOS image is SeaBIOS; Bochs can also use SeaBIOS but provides its own BIOS ROM by default (https://bochs.sourceforge.io/doc/docbook/user/bochsrc.html). We will use the SeaBIOS process as a reference: [https://www.seabios.org/Execution_and_code_flow]
- POST is conducted.
- Hardware initialization is performed by
device_hardware_setupinpost.c. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/post.c#L125-L135]device_hardware_setupcallsblock_setupinblock.c(among setup functions for other hardware devices) for setting up all kinds of block devices. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/block.c#L508-L523]block_setupcallsata_setupinata.c(among setup functions for other block storage types) to setup all ATA devices.ata_setup"Scan[s the] PCI bus for ATA adapters". [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/hw/ata.c#L1018-L1037]- Control is handed over to the PCI subsystem, which calls
init_drive_atainata.c[https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/hw/ata.c#L768-L820] for each ATA controller.- These are processed in sequential order by PCI bus. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/hw/pcidevice.c#L19-L84]
init_drive_atadetects any drives attached to the controller, including slave drives which have been daisy-chained.init_drive_atadetermines the priority of the drive, for boot order purposes.- Priorities can be assigned by configuring a boot order in the
bootorderfile. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/docs/Runtime_config.md#configuring-boot-order]. The 1-based index within the file is used as the priority [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/boot.c#L245-L296]. - If a boot order has not been configured, the default boot priority is assigned based on the type of media (e.g. Floppy, HD, CD). [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/boot.c#L460-L496] On QEMU, the order is provided by the emulator (e.g. configured from the command line).
- Priorities can be assigned by configuring a boot order in the
init_drive_atacallsboot_add_hdinboot.c[https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/boot.c#L593-L598], which adds a boot entry to a global listBootList. TheBootListis sorted as follows:- Boot entries with lower priorities are listed above those with higher priorities. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/boot.c#L524-L560]
- Boot entries with the same priorities are sorted based on their media type (like with the default boot priority).
- If tied here, I believe the order is sequential by ATA controller, then order of master, slave 1, slave 2, etc.
- The bootmenu is (optionally, depending on runtime configuration) shown by
interactive_bootmenuinboot.c. [https://github.com/coreboot/seabios/blob/ea1b7a0733906b8425d948ae94fba63c32b1d425/src/boot.c#L693-L791]- When the user selects an entry, it's moved to the top of the
BootList.
- When the user selects an entry, it's moved to the top of the
- Preparation is done for the boot phase by
preparebootinpost.c. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/post.c#L160-L179]preparebootcallsbcv_prepboot, which, for each boot entry in theBootList: [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/boot.c#L817-L855]- Runs the Boot Connection Vector if applicable, though I don't think it is for ATA.
- Assigns the drive a mapping in the internal two-dimensional
IDMaparray for all external drives being used. Implementation details: [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/block.h#L95-L100]- The first dimension is floppy disks, the second dimension is hard drives, and the third dimension is CDs.
- Floppy IDs start at
0x00, HD IDs start at0x80, and CD IDs start at0xE0.
- Adds a Boot Execution Vector to
BEV. The number of HDs and floppy disks is each limited to one.- The BEV seems to only be used for Plug-and-Play devices [https://etherboot.sourceforge.net/doc50/html/devman-3.html], though an entry is added regardless, with the vector being optional.
- Hardware initialization is performed by
- The boot phase (in SeaBIOS terms) loads the bootloader into memory:
- POST fires software interrupt 0x19 once done.
- The software interrupt is handled by
entry_19inromlayout.s; it is executing in 16-bit mode. [https://github.com/coreboot/seabios/blob/ea1b7a0733906b8425d948ae94fba63c32b1d425/src/romlayout.S#L576-L579] entry_19transitions to 32-bit mode and executeshandle_19and thendo_boot, both inboot.c.do_bootattempts to boot first boot entry inBEV. [https://github.com/coreboot/seabios/blob/ea1b7a0733906b8425d948ae94fba63c32b1d425/src/boot.c#L982-L1043]- If the boot entry is a HDD,
do_bootinvokesboot_diskwith HDD0x80(the first HDD). Now, remember:- We reordered the boot entries to our liking, back in
interactive_bootmenu. Regardless of the inital priorities the devices were given, our chosen boot HDD (or other media) has been moved to the top of theBootList, and accordingly is at the top ofBEV. BEVis restricted to just one HDD, so hardcoding the device ID to the first one is sufficient.
- We reordered the boot entries to our liking, back in
boot_diskreads the first sector of the HDD by firing software interrupt 0x13, "Fixed Disk Services Entry Point". Detour time!- This is the boot sector, which is comprised of the Master Boot Record.
- As is convention, the destination buffer is located at
0x0000:0x7C00. [https://wiki.osdev.org/Boot_Sequence] [https://en.wikipedia.org/wiki/Master_boot_record#BIOS_to_MBR_interface] - The software interrupt is handled by
handle_13indisk.c. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/disk.c#L739-L770] handle_13eventually dispatches the command usingdisk_13indisk.c. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/disk.c#L620-L656]disk_13issues the command to the device.boot_diskspecifies command0x20(ah=0x2->eax=0x20), not that this is necessarily the exact command issued.- Eventually we arrive at
ata_process_opinata.c, which defers toata_readwriteinata.c. [https://github.com/coreboot/seabios/blob/b0d61ecef66eb05bd7a4eb7ada88ec5dab06dfee/src/hw/ata.c#L554-L576] ata_readwritereads the data into a buffer, either with Direct Memory Access or Programmed Input/Output.
boot_diskchecks the MBR signature, and bails if it is not the magic number.boot_diskcallscall_boot_entry, which jumps to the beginning of the MBR!
QEMUEXTRA="--fw_cfg \"etc/show-boot-menu,string=1\""