From b524c18a3ea5a308dd1cbd11b66040d20065548e Mon Sep 17 00:00:00 2001 From: Daniel Victor Date: Mon, 7 Oct 2024 15:33:37 -0300 Subject: [PATCH] [FREELDR/x64] Add Multiboot header --- boot/freeldr/freeldr/arch/amd64/entry.S | 5 +- boot/freeldr/freeldr/arch/i386/multiboot.S | 101 +++++++++++---------- boot/freeldr/freeldr/pcat.cmake | 3 + sdk/include/asm/asm.inc | 17 +++- 4 files changed, 74 insertions(+), 52 deletions(-) diff --git a/boot/freeldr/freeldr/arch/amd64/entry.S b/boot/freeldr/freeldr/arch/amd64/entry.S index f05d144ce55..7a6537f21c9 100644 --- a/boot/freeldr/freeldr/arch/amd64/entry.S +++ b/boot/freeldr/freeldr/arch/amd64/entry.S @@ -5,7 +5,7 @@ #include EXTERN BootMain:PROC -// EXTERN cmdline:DWORD +EXTERN cmdline:DWORD EXTERN DiskStopFloppyMotor:PROC @@ -71,8 +71,7 @@ FrldrStartup: rep stosq /* Pass the command line to BootMain */ - // mov rcx, offset cmdline - xor rcx, rcx + mov rcx, offset cmdline /* GO! */ call BootMain diff --git a/boot/freeldr/freeldr/arch/i386/multiboot.S b/boot/freeldr/freeldr/arch/i386/multiboot.S index e176a64d54c..556bc630838 100644 --- a/boot/freeldr/freeldr/arch/i386/multiboot.S +++ b/boot/freeldr/freeldr/arch/i386/multiboot.S @@ -1,27 +1,16 @@ /* - * FreeLoader - * Copyright (C) 1998-2002 Brian Palmer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * PROJECT: FreeLoader + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Support for the Multiboot v1 specification. + * COPYRIGHT: Copyright 1998-2002 Brian Palmer + * Copyright 2024 Daniel Victor */ #include #include #include -/* Multiboot support +/* Multiboot v1 support * * Allows freeldr to be loaded as a "multiboot kernel" by * other boot loaders like GRUB. @@ -47,6 +36,16 @@ #define INITIAL_BASE HEX(200000) +#ifdef _M_IX86 +#define rax eax +#define rbx ebx +#define rcx ecx +#define rdi edi +#define rdx edx +#define rsi esi +#endif + + #ifdef _USE_ML EXTERN __bss_start__:DWORD EXTERN __bss_end__:DWORD @@ -54,8 +53,7 @@ EXTERN __bss_end__:DWORD #ifdef _USE_ML -.MBDATA SEGMENT PUBLIC 'DATA' -//ASSUME nothing +.MBDATA SEGMENT 'DATA' #endif /* Align to 32 bits boundary */ @@ -85,8 +83,12 @@ MultibootHeader: #endif +#ifdef _M_IX86 .code32 ASSUME ES:NOTHING, FS:NOTHING, GS:NOTHING +#else +.code64 +#endif MultibootEntry: cld @@ -98,36 +100,35 @@ MultibootEntry: /* Save multiboot info structure */ mov esi, ebx mov edi, offset MultibootInfo + INITIAL_BASE - FREELDR_BASE - mov ecx, (MB_INFO_SIZE / 4) - rep movsd - mov dword ptr ds:[MultibootInfo + INITIAL_BASE - FREELDR_BASE + MB_INFO_MMAP_ADDR_OFFSET], 0 - mov dword ptr ds:[_MultibootInfoPtr + INITIAL_BASE - FREELDR_BASE], offset MultibootInfo + mov ecx, MB_INFO_SIZE + rep movsb + mov dword ptr [MultibootInfo + INITIAL_BASE - FREELDR_BASE + MB_INFO_MMAP_ADDR_OFFSET], 0 + mov dword ptr [_MultibootInfoPtr + INITIAL_BASE - FREELDR_BASE], offset MultibootInfo /* See if the memory map was passed in */ - test dword ptr ds:[ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_MEMORY_MAP + test dword ptr [rbx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_MEMORY_MAP jz mbchk_command_line /* Check memory map length */ - mov ecx, dword ptr ds:[ebx + MB_INFO_MMAP_LEN_OFFSET] + mov rcx, [rbx + MB_INFO_MMAP_LEN_OFFSET] test ecx, ecx jz mbchk_command_line cmp ecx, MB_MMAP_SIZE jg mbchk_command_line /* Check memory map address */ - mov esi, dword ptr ds:[ebx + MB_INFO_MMAP_ADDR_OFFSET] + mov rsi, [rbx + MB_INFO_MMAP_ADDR_OFFSET] test esi, esi jz mbchk_command_line /* Save memory map structure */ mov edi, offset MultibootMemoryMap + INITIAL_BASE - FREELDR_BASE - shr ecx, 2 - rep movsd + rep movsb /* Relocate memory map address */ - mov dword ptr ds:[MultibootInfo + INITIAL_BASE - FREELDR_BASE + MB_INFO_MMAP_ADDR_OFFSET], offset MultibootMemoryMap + mov dword ptr [MultibootInfo + INITIAL_BASE - FREELDR_BASE + MB_INFO_MMAP_ADDR_OFFSET], offset MultibootMemoryMap mbchk_command_line: /* Save command line */ - test dword ptr ds:[ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE + test dword ptr [rbx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE jz mb2 - mov esi, dword ptr ds:[ebx + MB_INFO_COMMAND_LINE_OFFSET] + mov rsi, [rbx + MB_INFO_COMMAND_LINE_OFFSET] mov edi, offset cmdline + INITIAL_BASE - FREELDR_BASE mov ecx, CMDLINE_SIZE - 1 mb1: @@ -140,15 +141,18 @@ mb1: mb2: /* See if the boot device was passed in */ - test dword ptr ds:[ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_BOOT_DEVICE + test dword ptr [rbx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_BOOT_DEVICE /* If no boot device known, assume first partition of first harddisk */ mov dx, HEX(0180) jz mb3 /* Load boot drive into DL, boot partition into DH */ - mov edx, dword ptr ds:[ebx + MB_INFO_BOOT_DEVICE_OFFSET] + mov rdx, [rbx + MB_INFO_BOOT_DEVICE_OFFSET] bswap edx + + cmp dh, HEX(FF) + jz mb3 inc dh mb3: @@ -156,15 +160,14 @@ mb3: mov esi, INITIAL_BASE mov edi, FREELDR_BASE mov ecx, offset __bss_start__ - FREELDR_BASE - shr ecx, 2 - rep movsd + rep movsb /* Load segment registers for real-address mode */ -#ifdef _USE_ML - lgdt fword ptr ds:[gdtptr] -#else - lgdt ds:[gdtptr] -#endif + mov edi, offset gdtptr + lgdt lXdtPrefix [rdi] + mov edi, offset idtptr + lidt lXdtPrefix [rdi] + mov ax, HEX(10) mov ds, ax mov es, ax @@ -180,16 +183,14 @@ mbfail: mbstop: jmp short mbstop /* We should never get here */ -.code16 mb4: /* Disable protected mode */ - mov eax, cr0 - and eax, CR0_PE_CLR - mov cr0, eax + mov rax, cr0 + data32 and eax, CR0_PE_CLR + mov cr0, rax /* Jump to real entry point */ ljmp16 0, FREELDR_BASE -.endcode16 /* Force 8-byte alignment */ @@ -201,8 +202,14 @@ gdt: /* GDT table pointer */ gdtptr: - .word HEX(17) /* Limit */ - .long gdt /* Base Address */ + .word HEX(17) /* Limit */ + .long gdt /* Base Address */ + + /* Force 8-byte alignment */ + .align 8 +idtptr: + .word HEX(3FF) /* Limit */ + .long HEX(0) /* Base Address */ PUBLIC _MultibootInfoPtr _MultibootInfoPtr: diff --git a/boot/freeldr/freeldr/pcat.cmake b/boot/freeldr/freeldr/pcat.cmake index ac18b0e00ec..020ae7e018a 100644 --- a/boot/freeldr/freeldr/pcat.cmake +++ b/boot/freeldr/freeldr/pcat.cmake @@ -110,6 +110,9 @@ if(ARCH STREQUAL "i386") endif() elseif(ARCH STREQUAL "amd64") + list(APPEND PCATLDR_BASE_ASM_SOURCE + arch/i386/multiboot.S) + list(APPEND PCATLDR_COMMON_ASM_SOURCE arch/amd64/entry.S arch/amd64/int386.S diff --git a/sdk/include/asm/asm.inc b/sdk/include/asm/asm.inc index 7b3df60e6b1..b1a29b8802e 100644 --- a/sdk/include/asm/asm.inc +++ b/sdk/include/asm/asm.inc @@ -172,6 +172,8 @@ ENDM .skip size, fill ENDM +#define lXdtPrefix fword ptr + ljmp MACRO segment, offset DB 0EAh DD offset @@ -320,12 +322,23 @@ ENDM #define REPEAT .rept #define ENDR .endr +#define lXdtPrefix + .macro ljmp segment, offset - jmp far ptr \segment:\offset + .byte 0xEA + .long offset + .word segment .endm .macro ljmp16 segment, offset - jmp far ptr \segment:\offset + .byte 0xEA + .word offset + .word segment +.endm + +.macro data32 opcode:vararg + .byte 0x66 + opcode .endm .macro retf