From f81e895fe17baa999c8748a7e56aa1ec721124ed Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Sat, 27 Sep 2025 14:07:17 +0200 Subject: [PATCH] Add MBR boot code --- CMakeLists.txt | 1 + boot/CMakeLists.txt | 1 + boot/bootsect/CMakeLists.txt | 5 ++ boot/bootsect/amd64/mbrboot.S | 142 ++++++++++++++++++++++++++++++++++ xtldr/modules/xtos_o/xtos.cc | 21 ++--- 5 files changed, 154 insertions(+), 16 deletions(-) create mode 100644 boot/CMakeLists.txt create mode 100644 boot/bootsect/CMakeLists.txt create mode 100644 boot/bootsect/amd64/mbrboot.S diff --git a/CMakeLists.txt b/CMakeLists.txt index 92e0253..136dafb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,7 @@ add_compiler_flags(-D__RELFILE__="&__FILE__[__FILE__[0] == '.' ? sizeof \\\"${_P set_disk_image_size(32) # Build all subprojects +add_subdirectory(boot) add_subdirectory(bootdata) add_subdirectory(drivers) add_subdirectory(sdk) diff --git a/boot/CMakeLists.txt b/boot/CMakeLists.txt new file mode 100644 index 0000000..074d682 --- /dev/null +++ b/boot/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(bootsect) diff --git a/boot/bootsect/CMakeLists.txt b/boot/bootsect/CMakeLists.txt new file mode 100644 index 0000000..7cd510f --- /dev/null +++ b/boot/bootsect/CMakeLists.txt @@ -0,0 +1,5 @@ +# XT Boot Sector +PROJECT(BOOTSECT) + +# Compile boot sectors +compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/${ARCH}/mbrboot.S 0x7C00 Start) diff --git a/boot/bootsect/amd64/mbrboot.S b/boot/bootsect/amd64/mbrboot.S new file mode 100644 index 0000000..1ce0232 --- /dev/null +++ b/boot/bootsect/amd64/mbrboot.S @@ -0,0 +1,142 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: boot/bootsect/amd64/mbrboot.S + * DESCRIPTION: XT Boot Loader MBR boot code + * DEVELOPERS: Rafal Kupiec + */ + +.text +.code16 + + +.global Start +Start: + /* Set segments and stack */ + cli + cld + xorw %ax, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw $0x7C00, %bp + movw %bp, %sp + sti + + /* Relocate MBR to 1FE0:7C00 */ + movw $0x1FE0, %ax + movw %ax, %es + movw %bp, %si + movw %bp, %di + movw $256, %cx + rep movsw + + /* Jump to the relocated MBR code */ + jmp $0x1FE0, $RealStart + +RealStart: + /* Set segments */ + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + + /* Print welcome message */ + call Print + .asciz "Starting XTOS boot loader...\r\n" + + /* Get BIOS boot drive and partition table offset */ + lea 0x1BE(%bp), %si + movb %dl, .BootDrive + xorw %cx, %cx + +FindActivePartition: + /* Look for active partition */ + movb (%si), %al + cmpb $0x80, %al + je PartitionFound + addw $16, %si + incw %cx + cmpw $4, %cx + jne FindActivePartition + jmp PartitionNotFound + +PartitionFound: + /* Save LBA start */ + movl 8(%si), %eax + movl %eax, .LbaStart + + /* Prepare Disk Address Packet (DAP) */ + lea .Dap, %si + movb $0x10, 0(%si) + movb $0x00, 1(%si) + movw $1, 2(%si) + movw $0x7C00, 4(%si) + movw $0x0000, 6(%si) + movl .LbaStart, %eax + movl %eax, 8(%si) + + /* Read Volume Boot Record (VBR) */ + movb $0x42, %ah + movb .BootDrive, %dl + int $0x13 + jc VbrReadFail + + /* Verify VBR signature */ + cmpw $0xAA55, (0x7C00 + 0x01FE) + jne InvalidSignature + + /* Jump to the VBR code */ + jmp $0x0000, $0x7C00 + +InvalidSignature: + /* Invalid signature error */ + call Print + .asciz "Invalid partition signature!" + jmp HaltSystem + +PartitionNotFound: + /* Active partition not found error */ + call Print + .asciz "Bootable partition not found!" + jmp HaltSystem + +VbrReadFail: + /* VBR read failed error */ + call Print + .asciz "VBR read failed!" + jmp HaltSystem + +HaltSystem: + /* Disable interrupts and stop the CPU */ + cli + hlt + jmp HaltSystem + +PutChar: + /* Simple routine to print error messages */ + xor %bx, %bx + movb $0x0E, %ah + int $0x10 +Print: + pop %si + lodsb + push %si + cmp $0, %al + jne PutChar + ret + +.BootDrive: + /* Storage for the boot drive number */ + .byte 0 + +.Dap: + /* Storage for the Disk Address Packet (DAP) */ + .fill 16, 1, 0 + +.LbaStart: + /* Storage for the LBA start */ + .long 0 + +/* Fill the rest of the MBR with zeros and add MBR signature at the end */ +.fill (510 - (. - Start)), 1, 0 +.word 0xAA55 diff --git a/xtldr/modules/xtos_o/xtos.cc b/xtldr/modules/xtos_o/xtos.cc index 60bbf7c..2003161 100644 --- a/xtldr/modules/xtos_o/xtos.cc +++ b/xtldr/modules/xtos_o/xtos.cc @@ -414,7 +414,6 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, { PKERNEL_INITIALIZATION_BLOCK LoaderBlock; EFI_PHYSICAL_ADDRESS Address; - // PVOID RuntimeServices; EFI_STATUS Status; UINT BlockPages; UINT ParametersSize; @@ -445,20 +444,10 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, /* Set LoaderInformation block properties */ LoaderBlock->LoaderInformation.DbgPrint = (PVOID)XtLdrProtocol->Debug.Print; - /* Attempt to find virtual address of the EFI Runtime Services */ - // Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices); - // if(Status == STATUS_EFI_SUCCESS) - // { - /* Set FirmwareInformation block properties */ - LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; - LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = 0; //EfiSystemTable->Hdr.Revision; - LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR; - // } - // else - // { - // /* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */ - // LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid; - // } + /* Set FirmwareInformation block properties */ + LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi; + // LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision; + LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR; /* Copy parameters to kernel initialization block */ LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK)); @@ -663,7 +652,7 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir, /* Add kernel image memory mapping */ Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress, ImageContext->PhysicalAddress, ImageContext->ImagePages, - LoaderExceptionBlock); // 0 is LoaderExceptionBlock?! Should be LoaderSystemCode? + LoaderSystemCode); if(Status != STATUS_EFI_SUCCESS) { return Status;