[FREELDR] Re-integrate the ASM files (and corresponding C code) in MSVC builds, that were previously compiled just for GCC builds. (#1224)

- Multiboot support added back in FreeLdr MSVC builds so that it can be
  booted using e.g. GRUB. See CORE-15563.

- Re-introduce the disk drive mapper code.
This commit is contained in:
Hermès Bélusca-Maïto 2019-01-20 02:47:25 +01:00
parent ed83552229
commit 6b1e1df5c9
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
9 changed files with 76 additions and 101 deletions

View file

@ -159,14 +159,19 @@ list(APPEND FREELDR_BOOTMGR_SOURCE
video/palette.c video/palette.c
video/video.c) video/video.c)
list(APPEND FREELDR_BASE_ASM_SOURCE)
if(ARCH STREQUAL "i386") if(ARCH STREQUAL "i386")
list(APPEND FREELDR_BASE_ASM_SOURCE
arch/i386/multiboot.S)
list(APPEND FREELDR_COMMON_ASM_SOURCE list(APPEND FREELDR_COMMON_ASM_SOURCE
arch/i386/drvmap.S
arch/i386/entry.S arch/i386/entry.S
arch/i386/int386.S arch/i386/int386.S
arch/i386/pnpbios.S arch/i386/pnpbios.S
arch/i386/i386trap.S arch/i386/i386trap.S
arch/i386/linux.S arch/i386/linux.S)
arch/i386/mb.S)
list(APPEND FREELDR_NTLDR_SOURCE list(APPEND FREELDR_NTLDR_SOURCE
ntldr/arch/i386/winldr.c ntldr/arch/i386/winldr.c
@ -202,9 +207,6 @@ if(ARCH STREQUAL "i386")
arch/i386/xboxrtc.c arch/i386/xboxrtc.c
arch/i386/xboxvideo.c arch/i386/xboxvideo.c
disk/scsiport.c) disk/scsiport.c)
if(NOT MSVC)
list(APPEND FREELDR_COMMON_ASM_SOURCE arch/i386/drvmap.S)
endif()
elseif(ARCH STREQUAL "amd64") elseif(ARCH STREQUAL "amd64")
list(APPEND FREELDR_COMMON_ASM_SOURCE list(APPEND FREELDR_COMMON_ASM_SOURCE
@ -271,13 +273,15 @@ set(PCH_SOURCE
add_pch(freeldr_common include/freeldr.h PCH_SOURCE) add_pch(freeldr_common include/freeldr.h PCH_SOURCE)
add_dependencies(freeldr_common bugcodes asm xdk) add_dependencies(freeldr_common bugcodes asm xdk)
if(ARCH STREQUAL "i386" AND NOT MSVC)
list(APPEND FREELDR_BASE_SOURCE arch/i386/multiboot.S)
## GCC builds need this extra thing for some reason... ## GCC builds need this extra thing for some reason...
if(ARCH STREQUAL "i386" AND NOT MSVC)
target_link_libraries(freeldr_common mini_hal) target_link_libraries(freeldr_common mini_hal)
endif() endif()
add_asm_files(freeldr_base_asm ${FREELDR_BASE_ASM_SOURCE})
list(APPEND FREELDR_BASE_SOURCE list(APPEND FREELDR_BASE_SOURCE
${freeldr_base_asm}
bootmgr.c # This file is compiled with custom definitions bootmgr.c # This file is compiled with custom definitions
freeldr.c freeldr.c
ntldr/setupldr.c ## Strangely enough this file is needed in GCC builds ntldr/setupldr.c ## Strangely enough this file is needed in GCC builds

View file

@ -20,21 +20,20 @@
#include <freeldr.h> #include <freeldr.h>
#include <debug.h> #include <debug.h>
DBG_DEFAULT_CHANNEL(WARNING); DBG_DEFAULT_CHANNEL(DISK);
BOOLEAN DriveMapInstalled = FALSE; // Tells us if we have already installed our drive map int 13h handler code BOOLEAN DriveMapInstalled = FALSE; // Tells us if we have already installed our drive map int 13h handler code
ULONG OldInt13HandlerAddress = 0; // Address of BIOS int 13h handler ULONG OldInt13HandlerAddress = 0; // Address of BIOS int 13h handler
ULONG DriveMapHandlerAddress = 0; // Linear address of our drive map handler ULONG DriveMapHandlerAddress = 0; // Linear address of our drive map handler
ULONG DriveMapHandlerSegOff = 0; // Segment:offset style address of our drive map handler ULONG DriveMapHandlerSegOff = 0; // Segment:offset style address of our drive map handler
#ifndef _MSC_VER
VOID DriveMapMapDrivesInSection(PCSTR SectionName) VOID DriveMapMapDrivesInSection(PCSTR SectionName)
{ {
CHAR SettingName[80]; CHAR SettingName[80];
CHAR SettingValue[80]; CHAR SettingValue[80];
CHAR Drive1[80]; CHAR Drive1[80];
CHAR Drive2[80]; CHAR Drive2[80];
ULONG SectionId; ULONG_PTR SectionId;
ULONG SectionItemCount; ULONG SectionItemCount;
ULONG Index; ULONG Index;
ULONG Index2; ULONG Index2;
@ -143,7 +142,6 @@ BOOLEAN DriveMapIsValidDriveString(PCSTR DriveString)
return TRUE; return TRUE;
} }
#endif
UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName) UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName)
{ {
@ -172,7 +170,6 @@ UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName)
return BiosDriveNumber; return BiosDriveNumber;
} }
#ifndef _MSC_VER
VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap) VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap)
{ {
ULONG* RealModeIVT = (ULONG*)0x00000000; ULONG* RealModeIVT = (ULONG*)0x00000000;
@ -226,4 +223,3 @@ VOID DriveMapRemoveInt13Handler(VOID)
DriveMapInstalled = FALSE; DriveMapInstalled = FALSE;
} }
} }
#endif

View file

@ -17,7 +17,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 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>
@ -25,8 +24,8 @@
PUBLIC _DriveMapInt13HandlerStart PUBLIC _DriveMapInt13HandlerStart
_DriveMapInt13HandlerStart: _DriveMapInt13HandlerStart:
Int13Handler:
Int13Handler:
push bp push bp
mov bp, sp mov bp, sp
push ax push ax
@ -40,14 +39,14 @@ Int13Handler:
mov word ptr cs:[CallersFlags - Int13Handler], ax mov word ptr cs:[CallersFlags - Int13Handler], ax
/* Save the drive number they passed in */ /* Save the drive number they passed in */
mov cs:[PassedInDriveNumber - Int13Handler], dl mov byte ptr cs:[PassedInDriveNumber - Int13Handler], dl
/* Now we need to perform the mapping */ /* Now we need to perform the mapping */
xor cx, cx xor cx, cx
mov si, offset Int13HandlerMapCount - Int13Handler mov si, offset Int13HandlerMapCount - Int13Handler
/* Get the count of drives in the map list */ /* Get the count of drives in the map list */
mov cl, cs:[si] mov cl, byte ptr cs:[si]
inc si inc si
/* If the map list is empty then just call the old int 13h handler */ /* If the map list is empty then just call the old int 13h handler */
@ -56,8 +55,8 @@ Int13Handler:
GetMappedDriveNumberLoop: GetMappedDriveNumberLoop:
/* Get the next drive number in the list */ /* Get the next drive number in the list (store it in AX) */
lods ax, cs:[si] lods word ptr cs:[si]
/* Check to see if it's the one they are calling int 13h for */ /* Check to see if it's the one they are calling int 13h for */
cmp dl, al cmp dl, al
@ -84,7 +83,6 @@ CallOldInt13Handler:
/* Put flags onto stack */ /* Put flags onto stack */
push word ptr cs:[CallersFlags - Int13Handler] push word ptr cs:[CallersFlags - Int13Handler]
/* Call old int 13h handler with new drive number */ /* Call old int 13h handler with new drive number */
.byte HEX(9a) /* lcall */ .byte HEX(9a) /* lcall */
PUBLIC _DriveMapOldInt13HandlerAddress PUBLIC _DriveMapOldInt13HandlerAddress
@ -100,7 +98,7 @@ _DriveMapOldInt13HandlerAddress:
pop ax pop ax
/* Restore the callers drive number */ /* Restore the callers drive number */
mov dl, cs:[PassedInDriveNumber - Int13Handler] mov dl, byte ptr cs:[PassedInDriveNumber - Int13Handler]
pop bp pop bp
@ -112,6 +110,7 @@ CallersFlags:
PassedInDriveNumber: PassedInDriveNumber:
.byte 0 .byte 0
/* See the DRIVE_MAP_LIST structure in include/arch/i386/drivemap.h */
PUBLIC _DriveMapInt13HandlerMapList PUBLIC _DriveMapInt13HandlerMapList
_DriveMapInt13HandlerMapList: _DriveMapInt13HandlerMapList:
Int13HandlerMapCount: Int13HandlerMapCount:
@ -139,3 +138,7 @@ Int13HandlerDriveNew4:
PUBLIC _DriveMapInt13HandlerEnd PUBLIC _DriveMapInt13HandlerEnd
_DriveMapInt13HandlerEnd: _DriveMapInt13HandlerEnd:
.endcode16
END

View file

@ -25,7 +25,7 @@ EXTERN _BootMain:PROC
EXTERN _InitIdt:PROC EXTERN _InitIdt:PROC
EXTERN _i386Idt:DWORD EXTERN _i386Idt:DWORD
//EXTERN _i386idtptr:FWORD //EXTERN _i386idtptr:FWORD
// EXTERN cmdline:DWORD EXTERN cmdline:DWORD
#ifdef _USE_ML #ifdef _USE_ML
EXTERN __bss_start__:DWORD EXTERN __bss_start__:DWORD
@ -89,8 +89,7 @@ ASSUME /*CS:_TEXT,*/ DS:_DATA, ES:_DATA, FS:_DATA, GS:_DATA, SS:_DATA
call _InitIdt call _InitIdt
/* Pass the command line to BootMain */ /* Pass the command line to BootMain */
// mov eax, offset cmdline mov eax, offset cmdline
xor eax, eax
/* GO! */ /* GO! */
push eax push eax

View file

@ -1,51 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
*
* 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.
*/
#include <asm.inc>
#include <arch/pc/x86common.h>
#include <multiboot.h>
.code32
PUBLIC _PageDirectoryStart
PUBLIC _startup_pagedirectory
PUBLIC _lowmem_pagetable
PUBLIC _kernel_pagetable
PUBLIC _apic_pagetable
PUBLIC _PageDirectoryEnd
#ifndef _USE_ML
.bss
#endif
_PageDirectoryStart:
_startup_pagedirectory:
.fill 4096, 1, 0
_lowmem_pagetable:
.fill 4096, 1, 0
_kernel_pagetable:
.fill 2*4096, 1, 0
_apic_pagetable:
.fill 4096, 1, 0
_PageDirectoryEnd:
END

View file

@ -42,6 +42,18 @@
*/ */
#define INITIAL_BASE HEX(200000) #define INITIAL_BASE HEX(200000)
#ifdef _USE_ML
EXTERN __bss_start__:DWORD
EXTERN __bss_end__:DWORD
#endif
#ifdef _USE_ML
.MBDATA SEGMENT PUBLIC 'DATA'
ASSUME nothing
#endif
/* Align to 32 bits boundary */ /* Align to 32 bits boundary */
.align 4 .align 4
@ -54,7 +66,7 @@ MultibootHeader:
/* checksum */ /* checksum */
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
/* header_addr */ /* header_addr */
.long INITIAL_BASE + MultibootHeader - FREELDR_BASE .long MultibootHeader + INITIAL_BASE - FREELDR_BASE
/* load_addr */ /* load_addr */
.long INITIAL_BASE .long INITIAL_BASE
/* load_end_addr */ /* load_end_addr */
@ -62,15 +74,27 @@ MultibootHeader:
/* bss_end_addr */ /* bss_end_addr */
.long 0 .long 0
/* entry_addr */ /* entry_addr */
.long INITIAL_BASE + MultibootEntry - FREELDR_BASE .long MultibootEntry + INITIAL_BASE - FREELDR_BASE
#ifdef _USE_ML
.MBDATA ENDS
#endif
.code32
ASSUME ES:NOTHING, FS:NOTHING, GS:NOTHING
MultibootEntry: MultibootEntry:
cld cld
/* Check for valid multiboot signature */
cmp eax, MULTIBOOT_BOOTLOADER_MAGIC
jne mbfail
/* Save command line */ /* Save command line */
test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE test dword ptr ds:[ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_COMMAND_LINE
jz mb2 jz mb2
mov esi, [ebx + MB_INFO_COMMAND_LINE_OFFSET] mov esi, dword ptr ds:[ebx + 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:
@ -83,14 +107,14 @@ mb1:
mb2: mb2:
/* See if the boot device was passed in */ /* See if the boot device was passed in */
test dword ptr [ebx + MB_INFO_FLAGS_OFFSET], MB_INFO_FLAG_BOOT_DEVICE test dword ptr ds:[ebx + 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, [ebx + MB_INFO_BOOT_DEVICE_OFFSET] mov edx, dword ptr ds:[ebx + MB_INFO_BOOT_DEVICE_OFFSET]
bswap edx bswap edx
inc dh inc dh
@ -103,7 +127,11 @@ mb3:
rep movsd rep movsd
/* Load segment registers for real-address mode */ /* Load segment registers for real-address mode */
lgdt gdtptr #ifdef _USE_ML
lgdt fword ptr ds:[gdtptr]
#else
lgdt ds:[gdtptr]
#endif
mov ax, HEX(10) mov ax, HEX(10)
mov ds, ax mov ds, ax
mov es, ax mov es, ax
@ -114,6 +142,11 @@ mb3:
/* Jump to relocated code */ /* Jump to relocated code */
ljmp HEX(08), mb4 ljmp HEX(08), mb4
mbfail:
int 3
mbstop:
jmp short mbstop /* We should never get here */
.code16 .code16
mb4: mb4:
/* Disable protected mode */ /* Disable protected mode */
@ -123,26 +156,20 @@ mb4:
/* 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 */
.align 8 .align 8
gdt: gdt:
/* 16-bit flat CS (!) */ .word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
.word HEX(FFFF) .word HEX(FFFF), HEX(0000), HEX(9B00), HEX(008F) /* 08: 16-bit flat CS (!) */
.word HEX(0000) .word HEX(FFFF), HEX(0000), HEX(9300), HEX(0000) /* 10: 16-bit real mode DS */
.word HEX(9B00)
.word HEX(008F)
/* 16-bit real mode DS */ /* GDT table pointer */
.word HEX(FFFF)
.word HEX(0000)
.word HEX(9300)
.word HEX(0000)
/* GDT pointer */
gdtptr: gdtptr:
.word HEX(17) /* Limit */ .word HEX(17) /* Limit */
.long gdt - 8 /* Base Address */ .long gdt /* Base Address */
PUBLIC cmdline PUBLIC cmdline
cmdline: cmdline:

View file

@ -88,8 +88,8 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
} }
} }
#if defined(_M_IX86)
/* Install the drive mapper according to this section drive mappings */ /* Install the drive mapper according to this section drive mappings */
#if defined(_M_IX86) && !defined(_MSC_VER)
DriveMapMapDrivesInSection(SectionName); DriveMapMapDrivesInSection(SectionName);
#endif #endif

View file

@ -32,7 +32,7 @@
* Otherwise they are kept separated, unless an explicit /MERGE is used. * Otherwise they are kept separated, unless an explicit /MERGE is used.
*/ */
#pragma comment(linker, "/SECTION:.text,ERW /SECTION:.data,RW /MERGE:INIT=.text /MERGE:.edata=.rdata") #pragma comment(linker, "/SECTION:.text,ERW /SECTION:.data,RW /MERGE:.MBDATA=.text /MERGE:INIT=.text /MERGE:.edata=.rdata")
#endif #endif

View file

@ -77,6 +77,3 @@
#define LMODE_DS HEX(18) #define LMODE_DS HEX(18)
#define CMODE_CS HEX(30) #define CMODE_CS HEX(30)
//#endif //#endif
/* Makes "x" a global variable or label */
#define EXTERN(x) .global x; x: