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/CMakeLists.txt?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/amd64/entry.S?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/i386/entry.S?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/i386/i386bug.c?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/i386/pcmem.c?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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.c?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/include/arch/pc/x86common.h?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/include/debug.h?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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/meminit.c?rev=64815&r1=64814&r2=64815&view=diff
==============================================================================
--- 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);
 


Reply via email to