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: