From 3cdbb3f31d80840d3e3f895e0d3575d4fd3c5c5a Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Sun, 17 Aug 2008 02:01:30 +0000 Subject: [PATCH] FreeLDR-side of RAM Disk support for x86 based on actual NT implementation (instead of ARM-only hacks): 1) First, remove the hack in bootmgr.c that looked for a reactos.img. 2) Instead, read the command line to the kernel, and check for /RDIMAGEPATH. If found, load the ramdisk in the loader. 3) This uses the same routine as the previous hack, but enhances it with actual status and progress printouts. 4) Finally, update usetup to generate a ReactOS (RAM Disk) entry on DBG builds, under the WinLDR one. Also fixed a bug where, on MiniTUI, the text sent to UiDrawProgressBarCenter would be ignored. This patch does not result in working RAM disk support yet. To test the FreeLDR side of things, you need to create a ramdisk file: this is easy. Preferred way right now is to use qemu-img to create a standard QEMU image. Then install ReactOS on it and configure it. This is now your ramdisk. Make your image about 100MB; this is how much ReactOS requires to install right now. Now on your "official" QEMU image, you can delete everything except freeldr.sys and freeldr.ini. Or don't, if it's large enough. Now add the reactos.img to your official image. You should have at least 100MB free space. Now when you boot the ReactOS (RAM disk) entry, it should boot up until the kernel, which will panic since there's no ramdisk support yet. Note that you can't just create a QEMU image and drop files in it -- it must be properly formatted and have the ReactOS boot sector: The RAM disk isn't just a collection of files, it's an entire virtual drive, so that's why you must first officially install ReactOS on it. svn path=/trunk/; revision=35401 --- reactos/base/setup/usetup/bootsup.c | 34 +++++++++++++++- reactos/boot/freeldr/freeldr/bootmgr.c | 8 ---- reactos/boot/freeldr/freeldr/disk/ramdisk.c | 35 ++++++++++------ .../boot/freeldr/freeldr/include/ramdisk.h | 4 +- .../boot/freeldr/freeldr/reactos/reactos.c | 40 +++++++++++++++++-- reactos/boot/freeldr/freeldr/ui/minitui.c | 2 +- 6 files changed, 95 insertions(+), 28 deletions(-) diff --git a/reactos/base/setup/usetup/bootsup.c b/reactos/base/setup/usetup/bootsup.c index 5f7f135d1aa..aeb57bd70b4 100644 --- a/reactos/base/setup/usetup/bootsup.c +++ b/reactos/base/setup/usetup/bootsup.c @@ -387,6 +387,13 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath, INSERT_LAST, L"ReactOS_WinLdr", L"\"ReactOS (WinLdr)\""); + + /* ReactOS_Ram="ReactOS (RAM Disk)" */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"ReactOS_Ram", + L"\"ReactOS (RAM Disk)\""); #endif /* Create "ReactOS" section */ @@ -444,7 +451,7 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath, IniSection = IniCacheAppendSection(IniCache, L"ReactOS_WinLdr"); - /* BootType=ReactOS */ + /* BootType=Windows2003 */ IniCacheInsertKey(IniSection, NULL, INSERT_LAST, @@ -464,6 +471,31 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath, INSERT_LAST, L"Options", L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"); + + /* Create "ReactOS_WinLdr" section */ + IniSection = IniCacheAppendSection(IniCache, + L"ReactOS_Ram"); + + /* BootType=ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"BootType", + L"ReactOS"); + + /* SystemPath=ramdisk(0)\\ReactOS */ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"SystemPath", + L"ramdisk(0)\\ReactOS"); + + /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256*/ + IniCacheInsertKey(IniSection, + NULL, + INSERT_LAST, + L"Options", + L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256"); #endif /* Save the ini file */ diff --git a/reactos/boot/freeldr/freeldr/bootmgr.c b/reactos/boot/freeldr/freeldr/bootmgr.c index 904f1ef309b..878ed85025b 100644 --- a/reactos/boot/freeldr/freeldr/bootmgr.c +++ b/reactos/boot/freeldr/freeldr/bootmgr.c @@ -37,14 +37,6 @@ VOID RunLoader(VOID) return; } - // - // Check if we have a virtual RAM disk - // This is for x86 emulation -- on real hardware, the RAM disk will be - // located in one of the hardware memory descriptors as well as on the - // freeldr command-line - // - RamDiskCheckForVirtualFile(); - if (!IniFileInitialize()) { UiMessageBoxCritical("Error initializing .ini file"); diff --git a/reactos/boot/freeldr/freeldr/disk/ramdisk.c b/reactos/boot/freeldr/freeldr/disk/ramdisk.c index ee087967b6e..fe624850a5a 100644 --- a/reactos/boot/freeldr/freeldr/disk/ramdisk.c +++ b/reactos/boot/freeldr/freeldr/disk/ramdisk.c @@ -27,7 +27,7 @@ RamDiskGetDataAtOffset(IN PVOID Offset) // // Return data from our RAM Disk // - assert(((ULONG_PTR)gRamDiskBase + (ULONG_PTR)Offset) < + ASSERT(((ULONG_PTR)gRamDiskBase + (ULONG_PTR)Offset) < ((ULONG_PTR)gRamDiskBase + (ULONG_PTR)gRamDiskSize)); return (PVOID)((ULONG_PTR)gRamDiskBase + (ULONG_PTR)(Offset)); } @@ -83,35 +83,41 @@ RamDiskReadLogicalSectors(IN ULONG Reserved, VOID NTAPI -RamDiskCheckForVirtualFile(VOID) +RamDiskLoadVirtualFile(IN PCHAR FileName) { PFILE RamFile; ULONG TotalRead, ChunkSize; - + PCHAR MsgBuffer = "Loading ramdisk..."; + ULONG PercentPerChunk, Percent; + + // + // Display progress + // + UiDrawProgressBarCenter(1, 100, MsgBuffer); + // // Try opening the ramdisk file (this assumes the boot volume was opened) - // - RamFile = FsOpenFile("reactos.img"); + // + RamFile = FsOpenFile(FileName); if (RamFile) { // // Get the file size // gRamDiskSize = FsGetFileSize(RamFile); - TuiPrintf("Found virtual ramdisk (%dKB)\n", gRamDiskSize / 1024); if (!gRamDiskSize) return; // // Allocate memory for it // ChunkSize = 8 * 1024 * 1024; + Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize); gRamDiskBase = MmAllocateMemory(gRamDiskSize); if (!gRamDiskBase) return; - + // // Read it in chunks // - TuiPrintf("Loading ramdisk @ 0x%x...", gRamDiskBase); for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize) { // @@ -124,11 +130,17 @@ RamDiskCheckForVirtualFile(VOID) // ChunkSize = gRamDiskSize - TotalRead; } - + + // + // Draw progress + // + UiDrawProgressBarCenter(Percent, 100, MsgBuffer); + Percent += PercentPerChunk; + // // Copy the contents // - TuiPrintf("."); + if (!FsReadFile(RamFile, ChunkSize, NULL, @@ -137,10 +149,9 @@ RamDiskCheckForVirtualFile(VOID) // // Fail // - TuiPrintf("Failed to read ramdisk\n"); + UiMessageBox("Failed to read ramdisk\n"); } } - TuiPrintf("\n"); } } diff --git a/reactos/boot/freeldr/freeldr/include/ramdisk.h b/reactos/boot/freeldr/freeldr/include/ramdisk.h index f53e8861584..08378adfb6d 100644 --- a/reactos/boot/freeldr/freeldr/include/ramdisk.h +++ b/reactos/boot/freeldr/freeldr/include/ramdisk.h @@ -20,8 +20,8 @@ RamDiskSwitchFromBios( VOID NTAPI -RamDiskCheckForVirtualFile( - VOID +RamDiskLoadVirtualFile( + IN PCHAR FileName ); extern PVOID gRamDiskBase; diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index 1439f419dd9..c04373ad85e 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -40,7 +40,7 @@ char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0}; CHAR szHalName[255]; CHAR szBootPath[255]; CHAR SystemRoot[255]; -static CHAR szLoadingMsg[] = "Loading ReactOS..."; +static CHAR szLoadingMsg[] = "ReactOS is loading files..."; BOOLEAN FrLdrBootType; ULONG_PTR KernelBase; ROS_KERNEL_ENTRY_POINT KernelEntryPoint; @@ -576,6 +576,11 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) PVOID LoadBase; ULONG_PTR Base; ULONG Size; + + // + // Backdrop + // + UiDrawBackdrop(); // // Open the operating system section @@ -588,13 +593,40 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) return; } - UiDrawBackdrop(); - UiDrawStatusText("Detecting Hardware..."); - UiDrawProgressBarCenter(1, 100, szLoadingMsg); + // + // Read the command line + // + if (IniReadSettingByName(SectionId, "Options", value, sizeof(value))) + { + // + // Check if a ramdisk file was given + // + PCHAR File; + File = strstr(value, "/RDIMAGEPATH="); + if (File) + { + // + // Copy the file name and everything else after it + // + strcpy(szFileName, File + 13); + + // + // Null-terminate + // + *strstr(szFileName, " ") = ANSI_NULL; + + // + // Load the ramdisk + // + RamDiskLoadVirtualFile(szFileName); + } + } /* * Setup multiboot information structure */ + UiDrawProgressBarCenter(1, 100, szLoadingMsg); + UiDrawStatusText("Detecting Hardware..."); LoaderBlock.CommandLine = reactos_kernel_cmdline; LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart; LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd; diff --git a/reactos/boot/freeldr/freeldr/ui/minitui.c b/reactos/boot/freeldr/freeldr/ui/minitui.c index 47bd56f135d..bbc36a82dd8 100644 --- a/reactos/boot/freeldr/freeldr/ui/minitui.c +++ b/reactos/boot/freeldr/freeldr/ui/minitui.c @@ -65,7 +65,7 @@ VOID MiniTuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, UL // // Draw the "Loading..." text // - TuiDrawCenteredText(Left + 2, Top + 1, Right - 2, Top + 1, "ReactOS is loading files...", ATTR(7, 0)); + TuiDrawCenteredText(Left + 2, Top + 1, Right - 2, Top + 1, ProgressText, ATTR(7, 0)); // Draw the percent complete for (i=0; i<(Position*ProgressBarWidth)/Range; i++)