; Copyright (c) 2023 Elaina Claus ; ; Permission is hereby granted, free of charge, to any person obtaining a copy ; of this software and associated documentation files (the "Software"), to deal ; in the Software without restriction, including without limitation the rights ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ; copies of the Software, and to permit persons to whom the Software is ; furnished to do so, subject to the following conditions: ; ; The above copyright notice and this permission notice shall be included in all ; copies or substantial portions of the Software. ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ; SOFTWARE. [BITS 16] [ORG 0x7C00] [CPU KATMAI] jmp short init nop phy_bpb_start: ; fill BPB area with 0x00 since we skip writing this part to disk ; but we need it for the 'jmp short entry; nop' above times 33 db 0x00 phy_ebpb_start: ; fill BPB area with 0x00 since we skip writing this part to disk ; but we need it for the 'jmp short entry; nop' above times 54 db 0x00 %include "cdecl16.inc" %include "entry.inc" init: cli ; We do not want to be interrupted xor ax, ax ; 0 AX mov ds, ax ; Set segment registers to 0 mov es, ax ; * mov ss, ax ; Set Stack Segment to 0 mov sp, STACK_START ; Setup stack mov bp, sp ; base ptr = stack ptr mov bx, VBR_ENTRY ; move Bx to the new start of the initial boot sector sti ; all done with inital setup and relocation, reenable interupts jmp 0:main ; fix up cs:ip just in case and jump to relocated code nop %include "config.inc" %include "memory.inc" %include "kmem_func.inc" %include "partition_table.inc" %include "errors.inc" %include "fat32/bpb.inc" main: mov [bsDriveNumber], dl ; BIOS passes drive number in DL mov [partition_offset], si ; save passed partition entry offset .check_FAT_size: ; we only support a very specific setup of FAT32 cmp dword [bsSectorHuge], 0 ; SectorsHuge will not be set if FAT12/16 ja main.load_stage2 ERROR VBR_ERROR_WRONG_FAT_SIZE ; read sectors 1-63 to stage2 entry point .load_stage2: xor ax, ax push ax ; upper_lower_lba = 0 mov ax , 1 push ax ; lower_lower_lba = 1 xor ax, ax push ax ; offset = 0 ; 07E0:0 mov ax, STAGE2_ENTRY shr ax, 4 push ax ; segment = 7E0 ;uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset, ; uint16_t lower_lower_lba, uint16_t upper_lower_lba) call read_stage2_raw add sp, 0x8 .check_sig: mov ax, 0x7E0 mov fs, ax cmp dword [fs:0x7FFC], 0xDEADBEEF je main.sig_ok ERROR VBR_ERROR_NO_SIGNATURE ; no signature present in stage2 .sig_ok: mov ax, fat32_bpb_SIZE ; size in byte push ax mov ax, phy_bpb_start ; start of bpb push ax mov ax, fat32_bpb ; defined in memory.inc, destination push ax call kmemcpy ; copy bpb to memory add sp, 0x6 mov ax, fat32_ebpb_SIZE ; 72 bytes of data push ax mov ax, phy_ebpb_start ; start of ebpb push ax mov ax, fat32_ebpb ; defined in memory.inc, destination push ax call kmemcpy ; copy ebpb to memory add sp, 0x6 mov si, [partition_offset] mov dl, [bsDriveNumber] jmp 0:0x7E00 stop: hlt jmp short stop ; Wrapper for AH=0x42 INT13h (Extended Read) ; ; BIOS call details ; AH = 42h ; DL = drive number ; DS:SI -> disk address packet ; ; Return: ; CF clear if successful ; AH = 00h ; CF set on error ; AH = error code ; disk address packet's block count field set to number of blocks ; successfully transferred ; ; ; uint8_t read_disk_raw(uint16_t buf_segment, uint16_t buf_offset, ; uint16_t lower_lower_lba, uint16_t upper_lower_lba) read_stage2_raw: __CDECL16_ENTRY .func: mov ax, 0x10 push ax ; len = 16 bytes xor ax, ax push ax ; val = 0 mov ax, lba_packet push ax ; dest = lba_packet address call kmemset add sp, 0x06 mov byte [lba_packet + LBAPkt_t.size], 0x10 mov word [lba_packet + LBAPkt_t.xfer_size], STAGE2_SECTOR_COUNT mov ax, [bp + 10] shl eax, 16 mov ax, [bp + 8] mov dword [lba_packet + LBAPkt_t.lower_lba], eax mov ax, [bp + 6] mov word [lba_packet + LBAPkt_t.offset], ax mov ax, [bp + 4] mov word [lba_packet + LBAPkt_t.segment], ax mov si, lba_packet mov ah, 0x42 mov dl, byte [bsDriveNumber] int 0x13 jnc .endf ERROR VBR_ERROR_DISK_READ_ERR .endf: __CDECL16_EXIT ret ; Data ; ############# ; ; Locals ; ; ############# ; offset from the begining of sector 0 to the active partition. partition_offset: dw 0x0000 %assign bytes_remaining (420 - ($ - $$)) %warning VBR has bytes_remaining bytes remaining for code (MAX: 420 bytes) times (510 - ($ - $$)) nop ; Fill the rest of sector with nop BootSig: dw 0xAA55 ; Add boot signature at the end of bootloader