From c599bf3ed658bc606d112be99d06f7580aa310f7 Mon Sep 17 00:00:00 2001 From: pantonshire Date: Sun, 7 Jul 2024 16:34:54 +0100 Subject: [PATCH] use labels for stack variables --- boot0.s | 118 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 51 deletions(-) diff --git a/boot0.s b/boot0.s index ebb2835..5b145a7 100644 --- a/boot0.s +++ b/boot0.s @@ -12,26 +12,34 @@ ; R | 0x0c8000 - 0x0f0000: bios expansiosn ; R | 0x0f0000 - 0x100000: motherboard bios -; BASE STACK FRAME -; -------------------------------------------------------------------- -; bp - 0x02: drive number -; bp - 0x04: sectors per track -; bp - 0x06: number of heads -; bp - 0x08: partition array starting LBA -; bp - 0x0a: number of GPT partitions (saturated to 16-bits) -; bp - 0x0c: sector stride when loading GPT entries -; bp - 0x0e: byte stride when loading GPT entries -; bp - 0x10: entries per sector when loding GPT entries -; bp - 0x12: current entry index -; bp - 0x14: current entry index within the current sector -; bp - 0x16: number of sectors loaded -; bp - 0x18: current LBA - ; BIOS puts our boot sector at 0000:7c00 org 0x7c00 ; We're (probably) in real mode bits 16 +; BASE STACK FRAME VARIABLE OFFSETS +; -------------------------------------------------------------------- +; The boot drive number given to us by the BIOS. +BOOT_DRIVE equ 0x02 +; Boot drive geometry +SECTORS_PER_TRACK equ 0x04 +N_HEADS equ 0x06 +; Starting LBA of the GPT partition entries array. +GPT_ENTRIES_START_LBA equ 0x08 +; Number of GPT entries, saturated to 16 bits. +GPT_N_ENTRIES_16 equ 0x0a +; Number of sectors to advance by once we've read every GPT entry in the current sector. +GPT_SECTOR_STRIDE equ 0x0c +; Number of bytes to advance by in the current sector once we've read a GPT entry. +GPT_BYTE_STRIDE equ 0x0e +; Number of GPT entries which can fit in a single sector. +GPT_ENTRIES_PER_SECTOR equ 0x10 +GPT_CURRENT_ENTRY_IDX equ 0x12 +GPT_SECTOR_ENTRY_IDX equ 0x14 +GPT_SECTORS_LOADED equ 0x16 +GPT_CURRENT_LBA equ 0x18 +STAGE2_GPT_ENTRY_ADDR equ 0x1a + ; Disable interrupts cli @@ -79,8 +87,8 @@ bits 16 call .read_lba ; Check the GPT header magic "EFI PART" - mov cx, 8 - mov si, .gpt_magic + mov cx, GPT_MAGIC_LEN + mov si, gpt_magic mov di, 0x7e00 repe cmpsb jne .panic @@ -155,55 +163,59 @@ bits 16 ; Set up stack variables for our second stage search loop. xor ax, ax - push ax ; Current entry - push ax ; Current entry within the current sector - push ax ; First LBA loaded? - mov ax, [bp - 0x08] ; Starting LBA - push ax ; Current LBA + push ax ; Current entry + push ax ; Current entry within the current sector + push ax ; Number of sectors loaded + mov ax, [bp - GPT_ENTRIES_START_LBA] + push ax ; Current LBA ; Search for the partition storing our second stage. .loop_find_stage2: - mov dx, [bp - 0x12] - cmp [bp - 0x0a], dx + mov dx, [bp - GPT_CURRENT_ENTRY_IDX] + cmp [bp - GPT_N_ENTRIES_16], dx ; Panic if we've run out of partitions and haven't found the second stage yet. jbe .panic ; If we haven't loaded any sectors yet, load the first one. - cmp word [bp - 0x16], 0 ; Load number of sectors loaded + cmp word [bp - GPT_SECTORS_LOADED], 0 je .load_first_lba ; If there's still more entries in the current sector, skip loading a new sector - mov ax, [bp - 0x14] ; Load current entry index within the current sector - cmp [bp - 0x10], ax ; Compare to entries per sector + mov ax, [bp - GPT_SECTOR_ENTRY_IDX] ; Load current entry index within the current sector + cmp [bp - GPT_ENTRIES_PER_SECTOR], ax ; Compare to entries per sector ja .process_current_entry - mov ax, [bp - 0x0c] ; Load sector stride - add word [bp - 0x18], ax ; Increment current LBA by sector stride - mov word [bp - 0x14], 0 ; Reset the current entry index within the current sector + mov ax, [bp - GPT_SECTOR_STRIDE] ; Load sector stride + add word [bp - GPT_CURRENT_LBA], ax ; Increment current LBA by sector stride + mov word [bp - GPT_SECTOR_ENTRY_IDX], 0 ; Reset the current entry index within the current sector .load_first_lba: - mov ax, [bp - 0x18] ; Load current LBA - mov bx, 0x8000 ; Read sector just past end of the GPT header so we can keep it around + ; Read the current LBA to 0x8000 (just past the end of the GPT header) + mov ax, [bp - GPT_CURRENT_LBA] + mov bx, 0x8000 call .read_lba - inc word [bp - 0x16] ; Increment number of sectors loaded + ; Increment number of sectors loaded + inc word [bp - GPT_SECTORS_LOADED] .process_current_entry: - mov ax, [bp - 0x14] ; Load current entry index within current sector + ; Calculate the address of the current GPT entry. + mov ax, [bp - GPT_SECTOR_ENTRY_IDX] ; Load current entry index within current sector xor dx, dx - mul word [bp - 0x0e] ; Get the byte offset in the current sector of the current entry - add ax, 0x8000 ; Convert offset to address (we loaded the sector at 0x8000) + mul word [bp - GPT_BYTE_STRIDE] ; Get the byte offset in the current sector of the current entry + add ax, 0x8000 ; Convert offset to address (we loaded the sector at 0x8000) - mov cx, 16 ; GUID is 16 bytes - mov si, .guid_linux + ; Compare entry GUID to our stage 2 partition GUID. + mov cx, GUID_LEN + mov si, guid_linux mov di, ax repe cmpsb je .found_stage2 ; Next iteration - inc word [bp - 0x12] ; Increment current entry index - inc word [bp - 0x14] ; Increment current entry index within the current sector + inc word [bp - GPT_CURRENT_ENTRY_IDX] ; Increment current entry index + inc word [bp - GPT_SECTOR_ENTRY_IDX] ; Increment current entry index within the current sector jmp .loop_find_stage2 .found_stage2: - push ax ; address of the GPT entry for stage 2 + push ax ; Address of the GPT entry for stage 2 mov si, ax ; Load partition LBA start. @@ -251,17 +263,21 @@ bits 16 xor dx, dx ; FIXME: we should probably get our globals from somewhere else, in case we want to change bp for ; a function call - div word [bp - 0x04] ; Divide by sectors per track. dx = mod (sector - 1), ax = div (temp) + ; Divide by sectors per track. dx = mod (sector - 1), ax = div (temp) + div word [bp - SECTORS_PER_TRACK] + ; Put the sector into cx (the bios call will use cl) mov cx, dx - inc cx ; Put sector into cx (bios will read sector from cl) + inc cx xor dx, dx - div word [bp - 0x06] ; Divide by number of heads. dx = mod (head), ax = div (cylinder) + ; Divide by number of heads. dx = mod (head), ax = div (cylinder) + div word [bp - N_HEADS] mov dh, dl mov ch, al - mov dl, byte [bp - 0x02] ; Load drive number + mov dl, byte [bp - BOOT_DRIVE] mov ah, 0x02 mov al, 1 - int 0x13 ; Read sector + ; Read sector + int 0x13 jc .panic ret @@ -288,12 +304,12 @@ bits 16 ; - Boot from UEFI ; - Boot on non-GPT partitioned disk -.gpt_magic: - db "EFI PART" +gpt_magic db "EFI PART" +GPT_MAGIC_LEN equ $ - gpt_magic -.guid_linux: - db 0xaf, 0x3d, 0xc6, 0x0f, 0x83, 0x84, 0x72, 0x47, \ - 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4 +guid_linux db 0xaf, 0x3d, 0xc6, 0x0f, 0x83, 0x84, 0x72, 0x47, \ + 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4 +GUID_LEN equ $ - guid_linux ; MBR bootstrap field is 440 bytes long %if ($ - $$) > 440