x86 Bootloader

CT, Marvin Borner, TGI13.1

Inhalt

  • Was ist/macht ein Bootloader?
  • Boot-Ablauf
  • Umsetzung
  • Protokolle
  • x86-Architektur
  • Code
  • Demo
  • Fazit

Was ist ein Bootloader?

Bindeglied in Boot-Prozess

Boot-Prozess Beispiel (Legacy)

Was macht ein Bootloader?

  • Initialisiert CPU, GPU, I/O
  • Simple Treiber (Festplatte, Grafik)
  • Häufig GUI zur Auswahl und Konfiguration
  • Sucht nach Hardware-Infos
  • Lädt gewählten Kernel mit Infos

Ablauf

Basic Input Output System

  • Hardware Initialisierung
  • Stellt BIOS interrupts zur Verfügung

Power On Self Test

  • Diagnose
  • Bootbares Gerät?

Master Boot Record

  • 512B :O
  • Magic 0xAA55
  • Von BIOS zu 0x7C00
  • Bei Festplatten: Partitionstabelle @445
  • → Rest ist implementationsabhängig

Umsetzung

Festplatte

1. Stage: MBR; 0x7C00-0x7E00

  • Generelle Diagnose
  • CPU von Real (16 Bit) zu Protected mode (32 Bit)
  • Lädt 2. Stage von boot disk

2. Stage: 0x7E00-0xFC00 (~32KiB)

  • Diagnose (memory, disk, ...)
  • Initialisierung (A20, GDT, IDT, Register, ...)
  • Partition und Festplatte suchen
  • Dateisystem erkennen und konfigurieren
  • GUI für Auswahl mittels config Datei
  • Kernel laden

Protokolle

  • Multiboot 1/2
  • Linux, Windows, Mac OS

x86-Architektur

Grundlegende Register

64bit 32bit 16bit 8bit-h 8bit-l Verwendung
rax eax ax ah al Accumulator
rbx ebx bx bh bl Base
rcx ecx cx ch cl Counter
rdx edx dx dh dl Data
rbp ebp bp / / Base pointer
rsp esp sp / / Stack pointer
rip eip ip / / Instruction pointer

Sprachen

  • ASM in MBR: Kann direkt mit Registern umgehen, kein Bootstrapping/Overhead
  • C in 2. Stage: Lowlevel (__asm__, *(u8*)0x7E00), kein Interpreter

1. Stage (MBR)


org 0x7C00
bits 16
mbr:
    ; Register leeren (manche BIOS sind komisch)
    xor bx, bx
    mov ds, bx
    mov es, bx
    mov ss, bx
    ; Manche Register sind wichtig (z.B. dl mit boot disk)

    mov sp, 0x7C00 ; Stack: 0x7C00 -> wächst nach unten

    ; Text mode VGA mit BIOS interrupts leeren
    mov ax, SCREEN_CLEAR
    int SCREEN_INT

    call disk_support ; Ist disk unterstützt?

    jmp load_stage ; 2. Stage laden und ausführen
                        

bits 16
load_stage:
    mov bx, loader
    mov [dap.dest], bx
    call disk_read ; Nutzt dap, dl und BIOS INTs

    lgdt [gdt] ; Lade GDT

    ; Protected mode (32-Bit)
    mov eax, cr0
    or ax, 1 ; PE (Protection Enable) Bit
    mov cr0, eax

    ; 0x08 GDT offset -> 1. Eintrag -> Code segment (cs)
    jmp 0x08:protected

bits 32
protected:
    ; Segment register auf 2. GDT Eintrag (non-executable)
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

    push dx ; Disk (in dl) zu kernel pushen
    call loader ; Zweite Stage!

[...]
dw 0xAA55 ; MBR magic
loader: incbin "build/loader.bin" ; 2. Stage (C)
                        

Demo

Fazit

  • Schwierig jede Hardware zu unterstützen
  • Lieber GRUB/...

Fragen?

  • Segmentation, GDT
  • Interrupts, IDT, PIC
  • Multiboot 1/2
  • Mehr Code-Beispiele

Quellen

Bilder


  • https://en.wikipedia.org/wiki/BIOS#/media/File:Legacy_BIOS_boot_process.png

Informationen (aufgerufen 13.07.2021)


  • https://en.wikipedia.org/wiki/Bootloader
  • https://en.wikipedia.org/wiki/BIOS
  • https://wiki.osdev.org/
  • https://github.com/marvinborner/Melvix
  • Intel 64 and IA-32 Architectures Software Developer's Manual