[FREELDR/x64] Add Multiboot header

This commit is contained in:
Daniel Victor 2024-10-07 15:33:37 -03:00 committed by Timo Kreuzer
parent 398486f5f6
commit b524c18a3e
4 changed files with 74 additions and 52 deletions

View file

@ -5,7 +5,7 @@
#include <arch/pc/pcbios.h> #include <arch/pc/pcbios.h>
EXTERN BootMain:PROC EXTERN BootMain:PROC
// EXTERN cmdline:DWORD EXTERN cmdline:DWORD
EXTERN DiskStopFloppyMotor:PROC EXTERN DiskStopFloppyMotor:PROC
@ -71,8 +71,7 @@ FrldrStartup:
rep stosq rep stosq
/* Pass the command line to BootMain */ /* Pass the command line to BootMain */
// mov rcx, offset cmdline mov rcx, offset cmdline
xor rcx, rcx
/* GO! */ /* GO! */
call BootMain call BootMain

View file

@ -1,27 +1,16 @@
/* /*
* FreeLoader * PROJECT: FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com> * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* * PURPOSE: Support for the Multiboot v1 specification.
* This program is free software; you can redistribute it and/or modify * COPYRIGHT: Copyright 1998-2002 Brian Palmer <brianp@sginet.com>
* it under the terms of the GNU General Public License as published by * Copyright 2024 Daniel Victor <ilauncherdeveloper@gmail.com>
* 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.
*/ */
#include <asm.inc> #include <asm.inc>
#include <arch/pc/x86common.h> #include <arch/pc/x86common.h>
#include <multiboot.h> #include <multiboot.h>
/* Multiboot support /* Multiboot v1 support
* *
* Allows freeldr to be loaded as a "multiboot kernel" by * Allows freeldr to be loaded as a "multiboot kernel" by
* other boot loaders like GRUB. * other boot loaders like GRUB.
@ -47,6 +36,16 @@
#define INITIAL_BASE HEX(200000) #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 #ifdef _USE_ML
EXTERN __bss_start__:DWORD EXTERN __bss_start__:DWORD
EXTERN __bss_end__:DWORD EXTERN __bss_end__:DWORD
@ -54,8 +53,7 @@ EXTERN __bss_end__:DWORD
#ifdef _USE_ML #ifdef _USE_ML
.MBDATA SEGMENT PUBLIC 'DATA' .MBDATA SEGMENT 'DATA'
//ASSUME nothing
#endif #endif
/* Align to 32 bits boundary */ /* Align to 32 bits boundary */
@ -85,8 +83,12 @@ MultibootHeader:
#endif #endif
#ifdef _M_IX86
.code32 .code32
ASSUME ES:NOTHING, FS:NOTHING, GS:NOTHING ASSUME ES:NOTHING, FS:NOTHING, GS:NOTHING
#else
.code64
#endif
MultibootEntry: MultibootEntry:
cld cld
@ -98,36 +100,35 @@ MultibootEntry:
/* Save multiboot info structure */ /* Save multiboot info structure */
mov esi, ebx mov esi, ebx
mov edi, offset MultibootInfo + INITIAL_BASE - FREELDR_BASE mov edi, offset MultibootInfo + INITIAL_BASE - FREELDR_BASE
mov ecx, (MB_INFO_SIZE / 4) mov ecx, MB_INFO_SIZE
rep movsd rep movsb
mov dword ptr ds:[MultibootInfo + INITIAL_BASE - FREELDR_BASE + MB_INFO_MMAP_ADDR_OFFSET], 0 mov dword ptr [MultibootInfo + INITIAL_BASE - FREELDR_BASE + MB_INFO_MMAP_ADDR_OFFSET], 0
mov dword ptr ds:[_MultibootInfoPtr + INITIAL_BASE - FREELDR_BASE], offset MultibootInfo mov dword ptr [_MultibootInfoPtr + INITIAL_BASE - FREELDR_BASE], offset MultibootInfo
/* See if the memory map was passed in */ /* 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 jz mbchk_command_line
/* Check memory map length */ /* 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 test ecx, ecx
jz mbchk_command_line jz mbchk_command_line
cmp ecx, MB_MMAP_SIZE cmp ecx, MB_MMAP_SIZE
jg mbchk_command_line jg mbchk_command_line
/* Check memory map address */ /* 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 test esi, esi
jz mbchk_command_line jz mbchk_command_line
/* Save memory map structure */ /* Save memory map structure */
mov edi, offset MultibootMemoryMap + INITIAL_BASE - FREELDR_BASE mov edi, offset MultibootMemoryMap + INITIAL_BASE - FREELDR_BASE
shr ecx, 2 rep movsb
rep movsd
/* Relocate memory map address */ /* 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: mbchk_command_line:
/* Save 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 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 edi, offset cmdline + INITIAL_BASE - FREELDR_BASE
mov ecx, CMDLINE_SIZE - 1 mov ecx, CMDLINE_SIZE - 1
mb1: mb1:
@ -140,15 +141,18 @@ mb1:
mb2: mb2:
/* See if the boot device was passed in */ /* 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 */ /* If no boot device known, assume first partition of first harddisk */
mov dx, HEX(0180) mov dx, HEX(0180)
jz mb3 jz mb3
/* Load boot drive into DL, boot partition into DH */ /* 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 bswap edx
cmp dh, HEX(FF)
jz mb3
inc dh inc dh
mb3: mb3:
@ -156,15 +160,14 @@ mb3:
mov esi, INITIAL_BASE mov esi, INITIAL_BASE
mov edi, FREELDR_BASE mov edi, FREELDR_BASE
mov ecx, offset __bss_start__ - FREELDR_BASE mov ecx, offset __bss_start__ - FREELDR_BASE
shr ecx, 2 rep movsb
rep movsd
/* Load segment registers for real-address mode */ /* Load segment registers for real-address mode */
#ifdef _USE_ML mov edi, offset gdtptr
lgdt fword ptr ds:[gdtptr] lgdt lXdtPrefix [rdi]
#else mov edi, offset idtptr
lgdt ds:[gdtptr] lidt lXdtPrefix [rdi]
#endif
mov ax, HEX(10) mov ax, HEX(10)
mov ds, ax mov ds, ax
mov es, ax mov es, ax
@ -180,16 +183,14 @@ mbfail:
mbstop: mbstop:
jmp short mbstop /* We should never get here */ jmp short mbstop /* We should never get here */
.code16
mb4: mb4:
/* Disable protected mode */ /* Disable protected mode */
mov eax, cr0 mov rax, cr0
and eax, CR0_PE_CLR data32 and eax, CR0_PE_CLR
mov cr0, eax mov cr0, rax
/* Jump to real entry point */ /* Jump to real entry point */
ljmp16 0, FREELDR_BASE ljmp16 0, FREELDR_BASE
.endcode16
/* Force 8-byte alignment */ /* Force 8-byte alignment */
@ -201,8 +202,14 @@ gdt:
/* GDT table pointer */ /* GDT table pointer */
gdtptr: gdtptr:
.word HEX(17) /* Limit */ .word HEX(17) /* Limit */
.long gdt /* Base Address */ .long gdt /* Base Address */
/* Force 8-byte alignment */
.align 8
idtptr:
.word HEX(3FF) /* Limit */
.long HEX(0) /* Base Address */
PUBLIC _MultibootInfoPtr PUBLIC _MultibootInfoPtr
_MultibootInfoPtr: _MultibootInfoPtr:

View file

@ -110,6 +110,9 @@ if(ARCH STREQUAL "i386")
endif() endif()
elseif(ARCH STREQUAL "amd64") elseif(ARCH STREQUAL "amd64")
list(APPEND PCATLDR_BASE_ASM_SOURCE
arch/i386/multiboot.S)
list(APPEND PCATLDR_COMMON_ASM_SOURCE list(APPEND PCATLDR_COMMON_ASM_SOURCE
arch/amd64/entry.S arch/amd64/entry.S
arch/amd64/int386.S arch/amd64/int386.S

View file

@ -172,6 +172,8 @@ ENDM
.skip size, fill .skip size, fill
ENDM ENDM
#define lXdtPrefix fword ptr
ljmp MACRO segment, offset ljmp MACRO segment, offset
DB 0EAh DB 0EAh
DD offset DD offset
@ -320,12 +322,23 @@ ENDM
#define REPEAT .rept #define REPEAT .rept
#define ENDR .endr #define ENDR .endr
#define lXdtPrefix
.macro ljmp segment, offset .macro ljmp segment, offset
jmp far ptr \segment:\offset .byte 0xEA
.long offset
.word segment
.endm .endm
.macro ljmp16 segment, offset .macro ljmp16 segment, offset
jmp far ptr \segment:\offset .byte 0xEA
.word offset
.word segment
.endm
.macro data32 opcode:vararg
.byte 0x66
opcode
.endm .endm
.macro retf .macro retf