From: Brian Palmer Date: Mon, 22 Jul 2002 03:44:08 +0000 (+0000) Subject: Added BIOS drive mapping functionality X-Git-Tag: ReactOS-0.0.20~32 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=1aa76f94bd3aeee56ae8b109ec9edfa6de4ac47b Added BIOS drive mapping functionality svn path=/trunk/; revision=3284 --- diff --git a/freeldr/FREELDR.INI b/freeldr/FREELDR.INI index 22afd4fafbd..13589d44a49 100644 --- a/freeldr/FREELDR.INI +++ b/freeldr/FREELDR.INI @@ -53,6 +53,7 @@ ; BootType - sets the boot type: ReactOS, Linux, BootSector, Partition, Drive ; BootDrive - sets the boot drive: 0 - first floppy, 1 - second floppy, 0x80 - first hard disk, 0x81 - second hard disk ; BootPartition - sets the boot partition +; DriveMap - maps a BIOS drive number to another (i.e. DriveMap=hd1,hd0 maps harddisk1 to harddisk0 or DriveMap=fd1,fd0) ; [BootSector OSType] Section Commands: ; diff --git a/freeldr/freeldr/CHANGELOG b/freeldr/freeldr/CHANGELOG index 6d9d22f805a..03cc948591e 100644 --- a/freeldr/freeldr/CHANGELOG +++ b/freeldr/freeldr/CHANGELOG @@ -1,7 +1,10 @@ +Changes in v1.6 (7/21/2002) (brianp) + +- Added BIOS drive mapping functionality + Changes in v1.5 (7/13/2002) - If symbols are available then pass them to the OS as multiboot modules -- Added separate configuration for a SETUPLDR version Changes in v1.4 (6/27/2002) diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 378d8678059..4067109b1ff 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -112,7 +112,8 @@ else ############################################# # COMPILER COMMAND LINE OPTIONS # -COMPILER_OPTIONS = -Wall -nostdlib -fno-builtin -O1 -MD +COMPILER_OPTIONS = -Wall -nostdlib -nostdinc -fno-builtin -O1 -MD +# FreeLoader does not use any of the standard libraries, includes, or built-in functions ############################################# # COMPILER DEFINES @@ -180,9 +181,10 @@ ARCH_OBJS = fathelp.o \ linux.o \ mb.o \ mem.o \ - diskint13.o \ + biosdisk.o \ rtlcode.o \ - biosvid.o + biosvid.o \ + drvmap.o RTL_OBJS = memory.o \ print.o \ @@ -234,6 +236,7 @@ FREELDR_OBJS= freeldr.o \ debug.o \ oslist.o \ bootmgr.o \ + drivemap.o \ version.o ############################################# diff --git a/freeldr/freeldr/arch/i386/diskint13.S b/freeldr/freeldr/arch/i386/biosdisk.S similarity index 100% rename from freeldr/freeldr/arch/i386/diskint13.S rename to freeldr/freeldr/arch/i386/biosdisk.S diff --git a/freeldr/freeldr/arch/i386/drvmap.S b/freeldr/freeldr/arch/i386/drvmap.S new file mode 100644 index 00000000000..514ab9a3c66 --- /dev/null +++ b/freeldr/freeldr/arch/i386/drvmap.S @@ -0,0 +1,132 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + .text + .code16 + +#define ASM +#include + + +EXTERN(_DriveMapInt13HandlerStart) +Int13Handler: + + pushw %bp + movw %sp,%bp + pushw %ax + pushw %cx + pushw %si + + cld + + /* Get callers flags from stack */ + movw 0x06(%bp),%ax + movw %ax,%cs:(CallersFlags - Int13Handler) + + /* Save the drive number they passed in */ + movb %dl,%cs:(PassedInDriveNumber - Int13Handler) + + /* Now we need to perform the mapping */ + xorw %cx,%cx + movw $(Int13HandlerMapCount - Int13Handler),%si + /* Get the count of drives in the map list */ + movb %cs:(%si),%cl + incw %si + + /* If the map list is empty then just call the old int 13h handler */ + cmpb $0,%cl + jz CallOldInt13Handler + +GetMappedDriveNumberLoop: + + /* Get the next drive number in the list */ + lodsw %cs:(%si),%ax + /* Check to see if it's the one they are calling int 13h for */ + cmpb %al,%dl + /* If not get the next one */ + jne GetMappedDriveNumberLoopNext + + /* If we get here then we have found a mapped drive */ + /* Send new drive number on to the old int 13h handler */ + movb %ah,%dl + /* Call BIOS Int 13 Handler */ + jmp CallOldInt13Handler + +GetMappedDriveNumberLoopNext: + loop GetMappedDriveNumberLoop + +CallOldInt13Handler: + /* Restore the registers we changed off the stack */ + popw %si + popw %cx + popw %ax + + /* Put flags onto stack */ + pushw %cs:(CallersFlags - Int13Handler) + + /* Call old int 13h handler with new drive number */ + .byte 0x9a /* lcall */ +EXTERN(_DriveMapOldInt13HandlerAddress) + .word 0 + .word 0 + + /* Update the callers flags with the values the BIOS returned */ + pushw %ax + pushf + popw %ax + movw %ax,0x06(%bp) + popw %ax + /* Restore the callers drive number */ + movb %cs:(PassedInDriveNumber - Int13Handler),%dl + + popw %bp + + iret + +CallersFlags: + .word 0 + +PassedInDriveNumber: + .byte 0 + +EXTERN(_DriveMapInt13HandlerMapList) +Int13HandlerMapCount: + .byte 0 + +Int13HandlerDrive1: + .byte 0 +Int13HandlerDriveNew1: + .byte 0 + +Int13HandlerDrive2: + .byte 0 +Int13HandlerDriveNew2: + .byte 0 + +Int13HandlerDrive3: + .byte 0 +Int13HandlerDriveNew3: + .byte 0 + +Int13HandlerDrive4: + .byte 0 +Int13HandlerDriveNew4: + .byte 0 + +EXTERN(_DriveMapInt13HandlerEnd) diff --git a/freeldr/freeldr/bootmgr.c b/freeldr/freeldr/bootmgr.c index 99345499437..80296a0b52e 100644 --- a/freeldr/freeldr/bootmgr.c +++ b/freeldr/freeldr/bootmgr.c @@ -31,6 +31,7 @@ #include #include #include +#include VOID RunBootManager(VOID) { @@ -115,6 +116,9 @@ VOID RunBootManager(VOID) continue; } + // Install the drive mapper according to this sections drive mappings + DriveMapMapDrivesInSection(OperatingSystemSectionNames[SelectedOperatingSystem]); + if (stricmp(SettingValue, "ReactOS") == 0) { LoadAndBootReactOS(OperatingSystemSectionNames[SelectedOperatingSystem]); diff --git a/freeldr/freeldr/cache/cache.c b/freeldr/freeldr/cache/cache.c index c44d115d00e..8fb9140ab00 100644 --- a/freeldr/freeldr/cache/cache.c +++ b/freeldr/freeldr/cache/cache.c @@ -32,6 +32,7 @@ /////////////////////////////////////////////////////////////////////////////////////// CACHE_DRIVE CacheManagerDrive; BOOL CacheManagerInitialized = FALSE; +BOOL CacheManagerDataInvalid = FALSE; ULONG CacheBlockCount = 0; ULONG CacheSizeLimit = 0; ULONG CacheSizeCurrent = 0; @@ -45,11 +46,14 @@ BOOL CacheInitializeDrive(ULONG DriveNumber) // drive, in which case we'll invalidate the cache if ((CacheManagerInitialized == TRUE) && (DriveNumber == CacheManagerDrive.DriveNumber) && - (DriveNumber >= 0x80)) + (DriveNumber >= 0x80) && + (CacheManagerDataInvalid != TRUE)) { return TRUE; } + CacheManagerDataInvalid = FALSE; + // // If we have already been initialized then free // the old data @@ -120,6 +124,11 @@ BOOL CacheInitializeDrive(ULONG DriveNumber) return TRUE; } +VOID CacheInvalidateCacheData(VOID) +{ + CacheManagerDataInvalid = TRUE; +} + BOOL CacheReadDiskSectors(ULONG DiskNumber, ULONG StartSector, ULONG SectorCount, PVOID Buffer) { PCACHE_BLOCK CacheBlock; diff --git a/freeldr/freeldr/debug.c b/freeldr/freeldr/debug.c index d4a491a0f91..ef8e64f0e6b 100644 --- a/freeldr/freeldr/debug.c +++ b/freeldr/freeldr/debug.c @@ -27,28 +27,20 @@ //#define DEBUG_ULTRA //#define DEBUG_INIFILE //#define DEBUG_REACTOS -//#define DEBUG_CUSTOM -#define DEBUG_NONE +#define DEBUG_CUSTOM +//#define DEBUG_NONE -#ifdef DEBUG_ULTRA +#if defined (DEBUG_ULTRA) ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM | - DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS | - DPRINT_LINUX; -#endif - -#ifdef DEBUG_INIFILE + DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS | + DPRINT_LINUX; +#elif defined (DEBUG_INIFILE) ULONG DebugPrintMask = DPRINT_INIFILE; -#endif - -#ifdef DEBUG_REACTOS +#elif defined (DEBUG_REACTOS) ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY; -#endif - -#ifdef DEBUG_CUSTOM -ULONG DebugPrintMask = 0; -#endif - -#ifdef DEBUG_NONE +#elif defined (DEBUG_CUSTOM) +ULONG DebugPrintMask = DPRINT_WARNING; +#else //#elif defined (DEBUG_NONE) ULONG DebugPrintMask = 0; #endif @@ -253,7 +245,13 @@ VOID DebugPrint(ULONG Mask, char *format, ...) } else { - switch (c = *(format++)) + c = *(format++); + if (c == 'l') + { + c = *(format++); + } + + switch (c) { case 'd': case 'u': case 'x': diff --git a/freeldr/freeldr/drivemap.c b/freeldr/freeldr/drivemap.c new file mode 100644 index 00000000000..bfb46eb9214 --- /dev/null +++ b/freeldr/freeldr/drivemap.c @@ -0,0 +1,219 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +BOOL 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 DriveMapHandlerAddress = 0; // Linear address of our drive map handler +ULONG DriveMapHandlerSegOff = 0; // Segment:offset style address of our drive map handler + +VOID DriveMapMapDrivesInSection(PUCHAR SectionName) +{ + UCHAR SettingName[80]; + UCHAR SettingValue[80]; + UCHAR ErrorText[260]; + UCHAR Drive1[80]; + UCHAR Drive2[80]; + ULONG SectionId; + ULONG SectionItemCount; + ULONG Index; + ULONG Index2; + DRIVE_MAP_LIST DriveMapList; + + RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST)); + + if (!IniOpenSection(SectionName, &SectionId)) + { + return; + } + + // Get the number of items in this section + SectionItemCount = IniGetNumSectionItems(SectionId); + + // Loop through each one and check if its a DriveMap= setting + for (Index=0; Index= 4) + { + sprintf(ErrorText, "Max DriveMap count exceeded in section [%s]:\n\n%s=%s", SectionName, SettingName, SettingValue); + UiMessageBox(ErrorText); + continue; + } + + RtlZeroMemory(Drive1, 80); + RtlZeroMemory(Drive2, 80); + + strcpy(Drive1, SettingValue); + + // Parse the setting value and separate a string "hd0,hd1" + // into two strings "hd0" and "hd1" + for (Index2=0; Index2 '9') + { + return FALSE; + } + } + // Now make sure that they are not outrageous values (i.e. hd90874) + if ((atoi(&DriveString[2]) < 0) || (atoi(&DriveString[2]) > 0xff)) + { + return FALSE; + } + + return TRUE; +} + +ULONG DriveMapGetBiosDriveNumber(PUCHAR DeviceName) +{ + ULONG BiosDriveNumber = 0; + + // Convert the drive number string into a number + // 'hd1' = 1 + BiosDriveNumber = atoi(&DeviceName[2]); + + // If it's a hard disk then set the high bit + if ((DeviceName[0] == 'h' || DeviceName[0] == 'H') && + (DeviceName[1] == 'd' || DeviceName[1] == 'D')) + { + BiosDriveNumber |= 0x80; + } + + return BiosDriveNumber; +} + +VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap) +{ + PDWORD RealModeIVT = (PULONG)0x00000000; + PWORD BiosLowMemorySize = (PWORD)0x00000413; + + if (!DriveMapInstalled) + { + // Get the old INT 13h handler address from the vector table + OldInt13HandlerAddress = RealModeIVT[0x13]; + + // Decrease the size of low memory + (*BiosLowMemorySize)--; + + // Get linear address for drive map handler + DriveMapHandlerAddress = (ULONG)(*BiosLowMemorySize) << 10; + + // Convert to segment:offset style address + DriveMapHandlerSegOff = (DriveMapHandlerAddress << 12) & 0xffff0000; + } + + // Copy the drive map structure to the proper place + RtlCopyMemory(&DriveMapInt13HandlerMapList, DriveMap, sizeof(DRIVE_MAP_LIST)); + + // Set the address of the BIOS INT 13h handler + DriveMapOldInt13HandlerAddress = OldInt13HandlerAddress; + + // Copy the code to our reserved area + RtlCopyMemory((PVOID)DriveMapHandlerAddress, &DriveMapInt13HandlerStart, ((ULONG)&DriveMapInt13HandlerEnd - (ULONG)&DriveMapInt13HandlerStart)); + + // Update the IVT + RealModeIVT[0x13] = DriveMapHandlerSegOff; + + //CacheInvalidateCacheData(); + DriveMapInstalled = TRUE; +} + +VOID DriveMapRemoveInt13Handler(VOID) +{ + PDWORD RealModeIVT = (PULONG)0x00000000; + PWORD BiosLowMemorySize = (PWORD)0x00000413; + + if (DriveMapInstalled) + { + // Get the old INT 13h handler address from the vector table + RealModeIVT[0x13] = OldInt13HandlerAddress; + + // Increase the size of low memory + (*BiosLowMemorySize)++; + + DriveMapInstalled = FALSE; + } +} diff --git a/freeldr/freeldr/freeldr.c b/freeldr/freeldr/freeldr.c index d126640c440..1eef6920526 100644 --- a/freeldr/freeldr/freeldr.c +++ b/freeldr/freeldr/freeldr.c @@ -19,17 +19,9 @@ #include #include -#include -#include -#include #include -#include -#include #include -#include #include -#include -#include #include // Variable BootDrive moved to asmcode.S diff --git a/freeldr/freeldr/include/cache.h b/freeldr/freeldr/include/cache.h index ec7e6c5c9f4..0c310afe0df 100644 --- a/freeldr/freeldr/include/cache.h +++ b/freeldr/freeldr/include/cache.h @@ -22,6 +22,7 @@ #define __CACHE_H BOOL CacheInitializeDrive(ULONG DriveNumber); +VOID CacheInvalidateCacheData(VOID); BOOL CacheReadDiskSectors(ULONG DiskNumber, ULONG StartSector, ULONG SectorCount, PVOID Buffer); BOOL CacheForceDiskSectorsIntoCache(ULONG DiskNumber, ULONG StartSector, ULONG SectorCount); BOOL CacheReleaseMemory(ULONG MinimumAmountToRelease); diff --git a/freeldr/freeldr/include/drivemap.h b/freeldr/freeldr/include/drivemap.h new file mode 100644 index 00000000000..9d4630aa2be --- /dev/null +++ b/freeldr/freeldr/include/drivemap.h @@ -0,0 +1,43 @@ +/* + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DRIVEMAP_H +#define __DRIVEMAP_H + + +typedef struct +{ + BYTE DriveMapCount; // Count of drives currently mapped + + BYTE DriveMap[8]; // Map of BIOS drives + +} PACKED DRIVE_MAP_LIST, *PDRIVE_MAP_LIST; + +VOID DriveMapMapDrivesInSection(PUCHAR SectionName); +BOOL DriveMapIsValidDriveString(PUCHAR DriveString); // Checks the drive string ("hd0") for validity +ULONG DriveMapGetBiosDriveNumber(PUCHAR DeviceName); // Returns a BIOS drive number for any given device name (e.g. 0x80 for 'hd0') +VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap); // Installs the int 13h handler for the drive mapper +VOID DriveMapRemoveInt13Handler(VOID); // Removes a previously installed int 13h drive map handler + +extern PVOID DriveMapInt13HandlerStart; +extern PVOID DriveMapInt13HandlerEnd; +extern ULONG DriveMapOldInt13HandlerAddress; +extern DRIVE_MAP_LIST DriveMapInt13HandlerMapList; + +#endif // #defined __DRIVEMAP_H diff --git a/freeldr/freeldr/include/version.h b/freeldr/freeldr/include/version.h index 2bc929b8696..5c135396887 100644 --- a/freeldr/freeldr/include/version.h +++ b/freeldr/freeldr/include/version.h @@ -22,7 +22,7 @@ /* just some stuff */ -#define VERSION "FreeLoader v1.5" +#define VERSION "FreeLoader v1.6" #define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer " #define AUTHOR_EMAIL "" #define BY_AUTHOR "by Brian Palmer" @@ -35,7 +35,7 @@ // If you add major functionality then you increment the major version and zero the minor & patch versions // #define FREELOADER_MAJOR_VERSION 1 -#define FREELOADER_MINOR_VERSION 5 +#define FREELOADER_MINOR_VERSION 6 #define FREELOADER_PATCH_VERSION 0 diff --git a/freeldr/freeldr/mm/meminit.c b/freeldr/freeldr/mm/meminit.c index 0018f13dc3f..24e080718d6 100644 --- a/freeldr/freeldr/mm/meminit.c +++ b/freeldr/freeldr/mm/meminit.c @@ -112,7 +112,7 @@ BOOL MmInitializeMemoryManager(VOID) if (PageLookupTableAddress == 0) { // If we get here then we probably couldn't - // find a contigous chunk of memory big + // find a contiguous chunk of memory big // enough to hold the page lookup table printf("Error initializing memory manager!\n"); return FALSE; diff --git a/freeldr/freeldr/rtl/print.c b/freeldr/freeldr/rtl/print.c index e9101b6ce13..c8b8e2132a5 100644 --- a/freeldr/freeldr/rtl/print.c +++ b/freeldr/freeldr/rtl/print.c @@ -32,90 +32,110 @@ void print(char *str) /* * printf() - prints formatted text to stdout - * from: - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1996 Erich Boleyn + * originally from GRUB */ void printf(char *format, ... ) { - int *dataptr = (int *) &format; - char c, *ptr, str[16]; - - dataptr++; - - while ((c = *(format++))) - { - if (c != '%') - putchar(c); - else - switch (c = *(format++)) - { - case 'd': case 'u': case 'x': - *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0; - - ptr = str; - - while (*ptr) - putchar(*(ptr++)); - break; - - case 'c': putchar((*(dataptr++))&0xff); break; - - case 's': - ptr = (char *)(*(dataptr++)); - - while ((c = *(ptr++))) - putchar(c); - break; - } - } + int *dataptr = (int *) &format; + char c, *ptr, str[16]; + + dataptr++; + + while ((c = *(format++))) + { + if (c != '%') + { + putchar(c); + } + else + { + c = *(format++); + if (c == 'l') + { + c = *(format++); + } + + switch (c) + { + case 'd': case 'u': case 'x': + *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0; + + ptr = str; + + while (*ptr) + { + putchar(*(ptr++)); + } + break; + + case 'c': putchar((*(dataptr++))&0xff); break; + + case 's': + ptr = (char *)(*(dataptr++)); + + while ((c = *(ptr++))) + { + putchar(c); + } + break; + } + } + } } void sprintf(char *buffer, char *format, ... ) { - int *dataptr = (int *) &format; - char c, *ptr, str[16]; - char *p = buffer; - - dataptr++; - - while ((c = *(format++))) - { - if (c != '%') - { - *p = c; - p++; - } - else - switch (c = *(format++)) - { - case 'd': case 'u': case 'x': - *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0; - - ptr = str; - - while (*ptr) - { - *p = *(ptr++); - p++; - } - break; - - case 'c': - *p = (*(dataptr++))&0xff; - p++; - break; - - case 's': - ptr = (char *)(*(dataptr++)); - - while ((c = *(ptr++))) - { - *p = c; - p++; - } - break; - } - } - *p=0; + int *dataptr = (int *) &format; + char c, *ptr, str[16]; + char *p = buffer; + + dataptr++; + + while ((c = *(format++))) + { + if (c != '%') + { + *p = c; + p++; + } + else + { + c = *(format++); + if (c == 'l') + { + c = *(format++); + } + + switch (c) + { + case 'd': case 'u': case 'x': + *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0; + + ptr = str; + + while (*ptr) + { + *p = *(ptr++); + p++; + } + break; + + case 'c': + *p = (*(dataptr++))&0xff; + p++; + break; + + case 's': + ptr = (char *)(*(dataptr++)); + + while ((c = *(ptr++))) + { + *p = c; + p++; + } + break; + } + } + } + *p=0; }