Author: tkreuzer
Date: Sat Oct 18 21:12:12 2014
New Revision: 64815
URL:
http://svn.reactos.org/svn/reactos?rev=64815&view=rev
Log:
[FREELDR]
- Improve memory layout by moving the 32/64 bit stack to 0x7000-0xF000 and moving the
BIOSCALLBUFFER up a bit. This gives us 56 KB additional space for freeldr itself. This
allows to compile freeldr with /RTC1 (x86 only, the x64 version would get too big). And
yes, it works.
- Implement FrLdrBugCheckWithMessage to get some useful messages on the screen and use it
in MmCheckFreeldrImageFile
- Merge the .rtc section into the .text section, when we use RTC1
- Check the location of the Extended BIOS Data Area, add it to the memory descriptors and
make sure we have enough space to put freeldr in. If the location of the EBDA is too low,
print out a nice message on a blue screen :)
Modified:
trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt
trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S
trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S
trunk/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c
trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
trunk/reactos/boot/freeldr/freeldr/debug.c
trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
trunk/reactos/boot/freeldr/freeldr/include/debug.h
trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
Modified: trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/CMake…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/CMakeLists.txt [iso-8859-1] Sat Oct 18 21:12:12
2014
@@ -216,6 +216,7 @@
elseif(RUNTIME_CHECKS)
target_link_libraries(freeldr_pe runtmchk)
target_link_libraries(freeldr_pe_dbg runtmchk)
+ add_target_link_flags(freeldr_pe "/MERGE:.rtc=.text")
endif()
add_dependencies(freeldr_pe asm)
@@ -279,6 +280,7 @@
elseif(RUNTIME_CHECKS)
target_link_libraries(setupldr_pe runtmchk)
target_link_libraries(setupldr_pe_dbg runtmchk)
+ add_target_link_flags(setupldr_pe "/MERGE:.rtc=.text")
endif()
add_dependencies(setupldr_pe asm)
Modified: trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/amd64/entry.S [iso-8859-1] Sat Oct 18 21:12:12
2014
@@ -121,7 +121,7 @@
/* 64-bit stack pointer */
stack64:
- .double STACK64ADDR
+ .double STACKADDR
PUBLIC FrldrBootDrive
FrldrBootDrive:
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/entry.S [iso-8859-1] Sat Oct 18 21:12:12
2014
@@ -257,7 +257,7 @@
/* 32-bit stack pointer */
stack32:
- .long STACK32ADDR
+ .long STACKADDR
.align 4 /* force 4-byte alignment */
gdt:
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/i386bug.c [iso-8859-1] Sat Oct 18
21:12:12 2014
@@ -86,11 +86,11 @@
PrintText("Frames:\n");
#ifdef _M_IX86
for (Frame = (FRAME*)TrapFrame->Ebp;
- Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+ Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
Frame = Frame->Next)
#else
for (Frame = (FRAME*)TrapFrame->TrapFrame;
- Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+ Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
Frame = Frame->Next)
#endif
{
@@ -171,6 +171,44 @@
InstructionPointer[6], InstructionPointer[7]);
}
+VOID
+NTAPI
+FrLdrBugCheckWithMessage(
+ ULONG BugCode,
+ PCHAR File,
+ ULONG Line,
+ PSTR Format,
+ ...)
+{
+ CHAR Buffer[1024];
+ va_list argptr;
+
+ /* Blue screen for the win */
+ MachVideoClearScreen(SCREEN_ATTR);
+ i386_ScreenPosX = 0;
+ i386_ScreenPosY = 0;
+
+ PrintText("A problem has been detected and FreeLoader boot has been
aborted.\n\n");
+
+ PrintText("%ld: %s\n\n", BugCode, BugCodeStrings[BugCode]);
+
+ if (File)
+ {
+ PrintText("Location: %s:%ld\n\n", File, Line);
+ }
+
+ va_start(argptr, Format);
+ _vsnprintf(Buffer, sizeof(Buffer), Format, argptr);
+ va_end(argptr);
+ Buffer[sizeof(Buffer) - 1] = 0;
+
+ i386PrintText(Buffer);
+
+ _disable();
+ __halt();
+ for (;;);
+}
+
void
NTAPI
FrLdrBugCheckEx(
Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] Sat Oct 18 21:12:12
2014
@@ -28,15 +28,15 @@
DBG_DEFAULT_CHANNEL(MEMORY);
#define MAX_BIOS_DESCRIPTORS 32
+
+#define STACK_BASE_PAGE (STACKLOW / PAGE_SIZE)
#define FREELDR_BASE_PAGE (FREELDR_BASE / PAGE_SIZE)
#define DISKBUF_BASE_PAGE (DISKREADBUFFER / PAGE_SIZE)
-#define STACK_BASE_PAGE (STACKLOWLIMIT / PAGE_SIZE)
-#define STACK_END_PAGE (STACK32ADDR / PAGE_SIZE)
#define BIOSBUF_BASE_PAGE (BIOSCALLBUFFER / PAGE_SIZE)
+#define STACK_PAGE_COUNT (FREELDR_BASE_PAGE - STACK_BASE_PAGE)
#define FREELDR_PAGE_COUNT (DISKBUF_BASE_PAGE - FREELDR_BASE_PAGE)
-#define DISKBUF_PAGE_COUNT (STACK_BASE_PAGE - DISKBUF_BASE_PAGE)
-#define STACK_PAGE_COUNT (STACK_END_PAGE - STACK_BASE_PAGE)
+#define DISKBUF_PAGE_COUNT (0x10)
#define BIOSBUF_PAGE_COUNT (1)
BIOS_MEMORY_MAP PcBiosMemoryMap[MAX_BIOS_DESCRIPTORS];
@@ -45,11 +45,12 @@
FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] =
{
{ LoaderFirmwarePermanent, 0x00, 1 }, // realmode int vectors
- { LoaderFirmwareTemporary, 0x01, FREELDR_BASE_PAGE - 1 }, // freeldr
stack + cmdline
+ { LoaderFirmwareTemporary, 0x01, STACK_BASE_PAGE - 1 }, // freeldr
stack + cmdline
+ { LoaderOsloaderStack, STACK_BASE_PAGE, FREELDR_BASE_PAGE - STACK_BASE_PAGE },
// prot mode stack.
{ LoaderLoadedProgram, FREELDR_BASE_PAGE, FREELDR_PAGE_COUNT }, // freeldr
image
{ LoaderFirmwareTemporary, DISKBUF_BASE_PAGE, DISKBUF_PAGE_COUNT }, // Disk read
buffer for int 13h. DISKREADBUFFER
- { LoaderOsloaderStack, STACK_BASE_PAGE, STACK_PAGE_COUNT }, // prot mode
stack.
{ LoaderFirmwareTemporary, BIOSBUF_BASE_PAGE, BIOSBUF_PAGE_COUNT }, //
BIOSCALLBUFFER
+ { LoaderFirmwarePermanent, 0x9F, 0x1 }, // EBDA
{ LoaderFirmwarePermanent, 0xA0, 0x50 }, // ROM / Video
{ LoaderSpecialMemory, 0xF0, 0x10 }, // ROM / Video
{ LoaderSpecialMemory, 0xFFF, 1 }, // unusable memory
@@ -193,9 +194,63 @@
ULONG MapCount = 0;
ULONGLONG RealBaseAddress, RealSize;
TYPE_OF_MEMORY MemoryType;
+ ULONG Size;
ASSERT(PcBiosMapCount == 0);
TRACE("GetBiosMemoryMap()\n");
+
+ /* Make sure the usable memory is large enough. To do this we check the 16
+ bit value at address 0x413 inside the BDA, which gives us the usable size
+ in KB */
+ Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024;
+ if (Size < 0x9F000)
+ {
+ FrLdrBugCheckWithMessage(
+ MEMORY_INIT_FAILURE,
+ __FILE__,
+ __LINE__,
+ "The BIOS reported a usable memory range up to 0x%x, which is too
small!\n",
+ Size);
+ }
+
+ /* Get the address of the Extended BIOS Data Area (EBDA).
+ * Int 15h, AH=C1h
+ * SYSTEM - RETURN EXTENDED-BIOS DATA-AREA SEGMENT ADDRESS (PS)
+ *
+ * Return:
+ * CF set on error
+ * CF clear if successful
+ * ES = segment of data area
+ */
+ Regs.x.eax = 0x0000C100;
+ Int386(0x15, &Regs, &Regs);
+
+ /* If the function fails, there is no EBDA */
+ if (INT386_SUCCESS(Regs))
+ {
+ /* Check if this is high enough */
+ ULONG EbdaBase = (ULONG)Regs.w.es << 4;
+ if (EbdaBase < 0x9F000)
+ {
+ FrLdrBugCheckWithMessage(
+ MEMORY_INIT_FAILURE,
+ __FILE__,
+ __LINE__,
+ "The location of your EBDA is 0x%lx, which is too low!\n"
+ "If you see this, please report to the ReactOS team!",
+ EbdaBase);
+ }
+
+ /* Calculate the (max) size of the EBDA */
+ Size = 0xA0000 - EbdaBase;
+
+ /* Add the descriptor */
+ MapCount = AddMemoryDescriptor(PcMemoryMap,
+ MAX_BIOS_DESCRIPTORS,
+ (EbdaBase / MM_PAGE_SIZE),
+ (Size / MM_PAGE_SIZE),
+ LoaderFirmwarePermanent);
+ }
/* Int 15h AX=E820h
* Newer BIOSes - GET SYSTEM MEMORY MAP
Modified: trunk/reactos/boot/freeldr/freeldr/debug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/debug…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/debug.c [iso-8859-1] Sat Oct 18 21:12:12 2014
@@ -444,6 +444,7 @@
"TEST_BUGCHECK",
"MISSING_HARDWARE_REQUIREMENTS",
"FREELDR_IMAGE_CORRUPTION",
+ "MEMORY_INIT_FAILURE",
};
ULONG_PTR BugCheckInfo[5];
Modified: trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1]
(original)
+++ trunk/reactos/boot/freeldr/freeldr/include/arch/pc/x86common.h [iso-8859-1] Sat Oct 18
21:12:12 2014
@@ -11,13 +11,13 @@
//#endif
#define STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */
#define BSS_START HEX(6F00)
+#define STACKLOW HEX(7000)
+#define STACKADDR HEX(F000) /* The 32/64-bit stack top will be at 0000:F000, or
0xF000 */
#define FREELDR_BASE HEX(F800)
#define FREELDR_PE_BASE HEX(10000)
-#define DISKREADBUFFER HEX(80000) /* Buffer to store data read in from the disk via
the BIOS */
-#define STACKLOWLIMIT HEX(90000)
-#define STACK32ADDR HEX(98000) /* The 32-bit stack top will be at 9000:8000, or
0xA8000 */
-#define STACK64ADDR HEX(98000) /* The 64-bit stack top will be at 98000 */
-#define BIOSCALLBUFFER HEX(98000) /* Buffer to store temporary data for any Int386()
call */
+#define DISKREADBUFFER HEX(8E000) /* Buffer to store data read in from the disk via
the BIOS */
+#define BIOSCALLBUFFER HEX(9E000) /* Buffer to store temporary data for any Int386()
call */
+/* 9F000- 9FFFF is reserved for the EBDA */
#define DISKREADBUFFER_SIZE HEX(10000)
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any
Int386() call */
Modified: trunk/reactos/boot/freeldr/freeldr/include/debug.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/debug.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/debug.h [iso-8859-1] Sat Oct 18 21:12:12
2014
@@ -124,12 +124,22 @@
NTAPI
FrLdrBugCheck(ULONG BugCode);
+VOID
+NTAPI
+FrLdrBugCheckWithMessage(
+ ULONG BugCode,
+ PCHAR File,
+ ULONG Line,
+ PSTR Format,
+ ...);
+
/* Bugcheck codes */
enum _FRLDR_BUGCHECK_CODES
{
TEST_BUGCHECK,
MISSING_HARDWARE_REQUIREMENTS,
FREELDR_IMAGE_CORRUPTION,
+ MEMORY_INIT_FAILURE,
};
extern char *BugCodeStrings[];
Modified: trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/mm/me…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] Sat Oct 18 21:12:12 2014
@@ -159,8 +159,8 @@
}
}
-
-BOOLEAN
+static
+VOID
MmCheckFreeldrImageFile()
{
PIMAGE_NT_HEADERS NtHeaders;
@@ -172,7 +172,11 @@
if (!NtHeaders)
{
ERR("Could not get NtHeaders!\n");
- return FALSE;
+ FrLdrBugCheckWithMessage(
+ FREELDR_IMAGE_CORRUPTION,
+ __FILE__,
+ __LINE__,
+ "Could not get NtHeaders!\n");
}
/* Check the file header */
@@ -184,12 +188,21 @@
(FileHeader->SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER)))
{
ERR("FreeLdr FileHeader is invalid.\n");
- BugCheckInfo[0] = FileHeader->Machine;
- BugCheckInfo[1] = FileHeader->NumberOfSections;
- BugCheckInfo[2] = FileHeader->PointerToSymbolTable;
- BugCheckInfo[3] = FileHeader->NumberOfSymbols;
- BugCheckInfo[4] = FileHeader->SizeOfOptionalHeader;
- return FALSE;
+ FrLdrBugCheckWithMessage(
+ FREELDR_IMAGE_CORRUPTION,
+ __FILE__,
+ __LINE__,
+ "FreeLdr FileHeader is invalid.\n"
+ "Machine == 0x%lx, expected 0x%lx\n"
+ "NumberOfSections == 0x%lx, expected 0x%lx\n"
+ "PointerToSymbolTable == 0x%lx, expected 0\n"
+ "NumberOfSymbols == 0x%lx, expected 0\n"
+ "SizeOfOptionalHeader == 0x%lx, expected 0x%lx\n",
+ FileHeader->Machine, IMAGE_FILE_MACHINE_NATIVE,
+ FileHeader->NumberOfSections, FREELDR_SECTION_COUNT,
+ FileHeader->PointerToSymbolTable,
+ FileHeader->NumberOfSymbols,
+ FileHeader->SizeOfOptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER));
}
/* Check the optional header */
@@ -201,15 +214,22 @@
(OptionalHeader->SectionAlignment != OptionalHeader->FileAlignment))
{
ERR("FreeLdr OptionalHeader is invalid.\n");
- BugCheckInfo[0] = 0x80000000 | (OptionalHeader->Subsystem << 16) |
OptionalHeader->Magic;
- BugCheckInfo[1] = OptionalHeader->ImageBase;
- BugCheckInfo[2] = OptionalHeader->SizeOfImage;
- BugCheckInfo[3] = OptionalHeader->SectionAlignment;
- BugCheckInfo[4] = OptionalHeader->FileAlignment;
- return FALSE;
- }
-
- return TRUE;
+ FrLdrBugCheckWithMessage(
+ FREELDR_IMAGE_CORRUPTION,
+ __FILE__,
+ __LINE__,
+ "FreeLdr OptionalHeader is invalid.\n"
+ "Magic == 0x%lx, expected 0x%lx\n"
+ "Subsystem == 0x%lx, expected 1 (native)\n"
+ "ImageBase == 0x%lx, expected 0x%lx\n"
+ "SizeOfImage == 0x%lx, maximum 0x%lx\n"
+ "SectionAlignment 0x%lx doesn't match FileAlignment 0x%lx\n",
+ OptionalHeader->Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC,
+ OptionalHeader->Subsystem,
+ OptionalHeader->ImageBase, FREELDR_PE_BASE,
+ OptionalHeader->SizeOfImage, MAX_FREELDR_PE_SIZE,
+ OptionalHeader->SectionAlignment, OptionalHeader->FileAlignment);
+ }
}
BOOLEAN MmInitializeMemoryManager(VOID)
@@ -221,10 +241,7 @@
TRACE("Initializing Memory Manager.\n");
/* Check the freeldr binary */
- if (!MmCheckFreeldrImageFile())
- {
- FrLdrBugCheck(FREELDR_IMAGE_CORRUPTION);
- }
+ MmCheckFreeldrImageFile();
BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);