1
0
tetros/bios/main.asm
Mark cf60d6734a
All checks were successful
CI / Typos (push) Successful in 13s
CI / Clippy (push) Successful in 32s
CI / Build (push) Successful in 1m15s
Comments
2025-03-04 19:41:22 -08:00

65 lines
1.7 KiB
NASM

sectalign off
; The following code expects two external macros:
; STAGE3, a path to the stage3 binary
; STAGE2_SECTOR, the location of stage 2
; on the disk, in 512-byte sectors.
;
; Both of these are set in the makefile.
; BIOS loads stage 1 at 0x7C00
ORG 0x7C00
SECTION .text
; Stage 1 is MBR code, and should fit in LBA 0
; (i.e, in the first 512 bytes).
%include "stage1.asm"
; Stage 1 is at most 440 bytes
; This limit is set by the GPT spec.
; See https://uefi.org/specs/UEFI/2.10/05_GUID_Partition_Table_Format.html
;
; This `times` will throw an error if the subtraction is negative.
times 440-($-$$) db 0
db 0xee
; Pad until 512
times 510-($-$$) db 0
; MBR signature.
; This tells the BIOS that this disk is bootable.
db 0x55
db 0xaa
; Include stage 2. This is loaded into memory by stage 1.
; (stage 1 loads both stage 2 and stage 3)
;
; Stage 2 sets up protected mode, sets up the GDT,
; and initializes a minimal environment for stage 3.
;
; On a "real" boot disk, this data will not immediately follow stage 1.
; It would be stored in a special disk partition.
;
; We don't need this kind of complexity here, though, so we store
; stage 2 right after stage 1. (This is why STAGE2_SECTOR is 1.)
;
; This is nice, because the layout of the code on our boot disk
; matches the layout of the code in memory. THIS IS NOT USUALLY THE CASE.
stage2:
%include "stage2.asm"
align 512, db 0
stage2.end:
; Pad to 0x3000.
; This makes sure that state3 is loaded at the address
; the linker expects. Must match the value in `tetros/linkers/x86-unknown-none.ld`.
times (0x8000 - 0x7c00)-($-$$) db 0
; Include stage 3, the binary compiled from Rust sources.
stage3:
%defstr STAGE3_STR %[STAGE3]
incbin STAGE3_STR
align 512, db 0
.end: