[FREELDR] Limit the usage of DiskStopFloppyMotor() in hardware/platform-specific...
[reactos.git] / boot / freeldr / freeldr / linuxboot.c
index c2c8f97..48ebf53 100644 (file)
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+/*
+ * The x86 Linux Boot Protocol is explained at:
+ * https://www.kernel.org/doc/Documentation/x86/boot.txt
+ */
+
 #ifndef _M_ARM
 
 #ifdef _M_IX86
@@ -24,8 +29,8 @@
 /* INCLUDES *******************************************************************/
 
 #include <freeldr.h>
-#include <debug.h>
 
+#include <debug.h>
 DBG_DEFAULT_CHANNEL(LINUX);
 
 /* GLOBALS ********************************************************************/
@@ -38,104 +43,189 @@ ULONG   SetupSectorSize = 0;
 BOOLEAN NewStyleLinuxKernel = FALSE;
 ULONG   LinuxKernelSize = 0;
 ULONG   LinuxInitrdSize = 0;
-CHAR    LinuxKernelName[260];
-CHAR    LinuxInitrdName[260];
-BOOLEAN LinuxHasInitrd = FALSE;
-CHAR    LinuxCommandLine[260] = "";
+PCSTR   LinuxKernelName = NULL;
+PCSTR   LinuxInitrdName = NULL;
+PSTR    LinuxCommandLine = NULL;
 ULONG   LinuxCommandLineSize = 0;
 PVOID   LinuxKernelLoadAddress = NULL;
 PVOID   LinuxInitrdLoadAddress = NULL;
 CHAR    LinuxBootDescription[80];
-CHAR    LinuxBootPath[260] = "";
 
 /* FUNCTIONS ******************************************************************/
 
-BOOLEAN RemoveQuotes(PCHAR QuotedString)
+static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile);
+static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile);
+static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile);
+static BOOLEAN LinuxCheckKernelVersion(VOID);
+static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile);
+
+static VOID
+RemoveQuotes(
+    IN OUT PSTR QuotedString)
 {
-    CHAR  TempString[200];
-    PCHAR p;
-    PSTR  Start;
+    PCHAR  p;
+    PSTR   Start;
+    SIZE_T Size;
 
     /* Skip spaces up to " */
     p = QuotedString;
-    while (*p == ' ' || *p == '"')
-        p++;
+    while (*p == ' ' || *p == '\t' || *p == '"')
+        ++p;
     Start = p;
 
     /* Go up to next " */
-    while (*p != '"' && *p != ANSI_NULL)
-        p++;
+    while (*p != ANSI_NULL && *p != '"')
+        ++p;
+    /* NULL-terminate */
     *p = ANSI_NULL;
 
-    /* Copy result */
-    strcpy(TempString, Start);
-    strcpy(QuotedString, TempString);
-
-    return TRUE;
+    /* Move the NULL-terminated string back into 'QuotedString' in place */
+    Size = (strlen(Start) + 1) * sizeof(CHAR);
+    memmove(QuotedString, Start, Size);
 }
 
-VOID
-LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
-                 IN USHORT OperatingSystemVersion)
+ARC_STATUS
+LoadAndBootLinux(
+    IN ULONG Argc,
+    IN PCHAR Argv[],
+    IN PCHAR Envp[])
 {
-    PCSTR SectionName = OperatingSystem->SystemPartition;
-    PCSTR Description = OperatingSystem->LoadIdentifier;
-    PFILE LinuxKernel = 0;
-    PFILE LinuxInitrdFile = 0;
-
-    UiDrawBackdrop();
-
-    if (Description)
-        sprintf(LinuxBootDescription, "Loading %s...", Description);
+    ARC_STATUS Status;
+    PCSTR Description;
+    PCSTR ArgValue;
+    PCSTR BootPath;
+    UCHAR DriveNumber = 0;
+    ULONG PartitionNumber = 0;
+    ULONG LinuxKernel = 0;
+    ULONG LinuxInitrdFile = 0;
+    FILEINFORMATION FileInfo;
+    CHAR ArcPath[MAX_PATH];
+
+    Description = GetArgumentValue(Argc, Argv, "LoadIdentifier");
+    if (Description && *Description)
+        RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription), "Loading %s...", Description);
     else
         strcpy(LinuxBootDescription, "Loading Linux...");
 
+    UiDrawBackdrop();
     UiDrawStatusText(LinuxBootDescription);
     UiDrawProgressBarCenter(0, 100, LinuxBootDescription);
 
-    /* Parse the .ini file section */
-    if (!LinuxParseIniSection(SectionName))
+    /* Find all the message box settings and run them */
+    UiShowMessageBoxesInArgv(Argc, Argv);
+
+    /*
+     * Check whether we have a "BootPath" value (takes precedence
+     * over both "BootDrive" and "BootPartition").
+     */
+    BootPath = GetArgumentValue(Argc, Argv, "BootPath");
+    if (!BootPath || !*BootPath)
+    {
+        /* We don't have one, check whether we use "BootDrive" and "BootPartition" */
+
+        /* Retrieve the boot drive (optional, fall back to using default path otherwise) */
+        ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
+        if (ArgValue && *ArgValue)
+        {
+            DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
+
+            /* Retrieve the boot partition (not optional and cannot be zero) */
+            PartitionNumber = 0;
+            ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
+            if (ArgValue && *ArgValue)
+                PartitionNumber = atoi(ArgValue);
+            if (PartitionNumber == 0)
+            {
+                UiMessageBox("Boot partition cannot be 0!");
+                goto LinuxBootFailed;
+                // return EINVAL;
+            }
+
+            /* Construct the corresponding ARC path */
+            ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
+            *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
+
+            BootPath = ArcPath;
+        }
+        else
+        {
+            /* Fall back to using the system partition as default path */
+            BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
+        }
+    }
+
+    /* Get the kernel name */
+    LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
+    if (!LinuxKernelName || !*LinuxKernelName)
+    {
+        UiMessageBox("Linux kernel filename not specified for selected OS!");
         goto LinuxBootFailed;
+    }
+
+    /* Get the initrd name (optional) */
+    LinuxInitrdName = GetArgumentValue(Argc, Argv, "Initrd");
+
+    /* Get the command line (optional) */
+    LinuxCommandLineSize = 0;
+    LinuxCommandLine = GetArgumentValue(Argc, Argv, "CommandLine");
+    if (LinuxCommandLine && *LinuxCommandLine)
+    {
+        RemoveQuotes(LinuxCommandLine);
+        LinuxCommandLineSize = (ULONG)strlen(LinuxCommandLine) + 1;
+        LinuxCommandLineSize = min(LinuxCommandLineSize, 260);
+    }
 
     /* Open the kernel */
-    LinuxKernel = FsOpenFile(LinuxKernelName);
-    if (!LinuxKernel)
+    Status = FsOpenFile(LinuxKernelName, BootPath, OpenReadOnly, &LinuxKernel);
+    if (Status != ESUCCESS)
     {
-        UiMessageBox("Linux kernel \'%s\' not found.", LinuxKernelName);
+        UiMessageBox("Linux kernel '%s' not found.", LinuxKernelName);
         goto LinuxBootFailed;
     }
 
     /* Open the initrd file image (if necessary) */
-    if (LinuxHasInitrd)
+    if (LinuxInitrdName)
     {
-        LinuxInitrdFile = FsOpenFile(LinuxInitrdName);
-        if (!LinuxInitrdFile)
+        Status = FsOpenFile(LinuxInitrdName, BootPath, OpenReadOnly, &LinuxInitrdFile);
+        if (Status != ESUCCESS)
         {
-            UiMessageBox("Linux initrd image \'%s\' not found.", LinuxInitrdName);
+            UiMessageBox("Linux initrd image '%s' not found.", LinuxInitrdName);
             goto LinuxBootFailed;
         }
     }
 
-    /* Read the boot sector */
+    /* Load the boot sector */
     if (!LinuxReadBootSector(LinuxKernel))
         goto LinuxBootFailed;
 
-    /* Read the setup sector */
+    /* Load the setup sector */
     if (!LinuxReadSetupSector(LinuxKernel))
         goto LinuxBootFailed;
 
     /* Calc kernel size */
-    LinuxKernelSize = FsGetFileSize(LinuxKernel) - (512 + SetupSectorSize);
+    Status = ArcGetFileInformation(LinuxKernel, &FileInfo);
+    if (Status != ESUCCESS || FileInfo.EndingAddress.HighPart != 0)
+        LinuxKernelSize = 0;
+    else
+        LinuxKernelSize = FileInfo.EndingAddress.LowPart - (512 + SetupSectorSize);
 
-    /* Get the file size */
-    LinuxInitrdSize = FsGetFileSize(LinuxInitrdFile);
+    /* Get the initrd file image (if necessary) */
+    LinuxInitrdSize = 0;
+    if (LinuxInitrdName)
+    {
+        Status = ArcGetFileInformation(LinuxInitrdFile, &FileInfo);
+        if (Status != ESUCCESS || FileInfo.EndingAddress.HighPart != 0)
+            LinuxInitrdSize = 0;
+        else
+            LinuxInitrdSize = FileInfo.EndingAddress.LowPart;
+    }
 
-    /* Read the kernel */
+    /* Load the kernel */
     if (!LinuxReadKernel(LinuxKernel))
         goto LinuxBootFailed;
 
-    /* Read the initrd (if necessary) */
-    if (LinuxHasInitrd)
+    /* Load the initrd (if necessary) */
+    if (LinuxInitrdName)
     {
         if (!LinuxReadInitrd(LinuxInitrdFile))
             goto LinuxBootFailed;
@@ -162,11 +252,12 @@ LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
 
     RtlCopyMemory((PVOID)0x90000, LinuxBootSector, 512);
     RtlCopyMemory((PVOID)0x90200, LinuxSetupSector, SetupSectorSize);
-    RtlCopyMemory((PVOID)0x99000, LinuxCommandLine, LinuxCommandLineSize);
+    RtlCopyMemory((PVOID)0x99000,
+                  LinuxCommandLine ? LinuxCommandLine : "",
+                  LinuxCommandLine ? LinuxCommandLineSize : sizeof(ANSI_NULL));
 
     UiUnInitialize("Booting Linux...");
-
-    DiskStopFloppyMotor();
+    IniCleanup();
 
     if (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
         BootNewLinuxKernel();
@@ -177,10 +268,10 @@ LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
 LinuxBootFailed:
 
     if (LinuxKernel)
-        FsCloseFile(LinuxKernel);
+        ArcClose(LinuxKernel);
 
     if (LinuxInitrdFile)
-        FsCloseFile(LinuxInitrdFile);
+        ArcClose(LinuxInitrdFile);
 
     if (LinuxBootSector != NULL)
         MmFreeMemory(LinuxBootSector);
@@ -196,69 +287,35 @@ LinuxBootFailed:
 
     LinuxBootSector = NULL;
     LinuxSetupSector = NULL;
-    LinuxKernelLoadAddress = NULL;
-    LinuxInitrdLoadAddress = NULL;
     SetupSectorSize = 0;
     NewStyleLinuxKernel = FALSE;
     LinuxKernelSize = 0;
-    LinuxHasInitrd = FALSE;
-    strcpy(LinuxCommandLine, "");
+    LinuxInitrdSize = 0;
+    LinuxKernelName = NULL;
+    LinuxInitrdName = NULL;
+    LinuxCommandLine = NULL;
     LinuxCommandLineSize = 0;
-}
-
-BOOLEAN LinuxParseIniSection(PCSTR SectionName)
-{
-    ULONG_PTR SectionId;
-
-    /* Find all the message box settings and run them */
-    UiShowMessageBoxesInSection(SectionName);
-
-    /* Try to open the operating system section in the .ini file */
-    if (!IniOpenSection(SectionName, &SectionId))
-    {
-        UiMessageBox("Section [%s] not found in freeldr.ini.", SectionName);
-        return FALSE;
-    }
-
-    if (!IniReadSettingByName(SectionId, "BootPath", LinuxBootPath, sizeof(LinuxBootPath)))
-    {
-        UiMessageBox("Boot path not specified for selected OS!");
-        return FALSE;
-    }
-
-    /* Get the kernel name */
-    if (!IniReadSettingByName(SectionId, "Kernel", LinuxKernelName, sizeof(LinuxKernelName)))
-    {
-        UiMessageBox("Linux kernel filename not specified for selected OS!");
-        return FALSE;
-    }
-
-    /* Get the initrd name */
-    if (IniReadSettingByName(SectionId, "Initrd", LinuxInitrdName, sizeof(LinuxInitrdName)))
-    {
-        LinuxHasInitrd = TRUE;
-    }
-
-    /* Get the command line */
-    if (IniReadSettingByName(SectionId, "CommandLine", LinuxCommandLine, sizeof(LinuxCommandLine)))
-    {
-        RemoveQuotes(LinuxCommandLine);
-        LinuxCommandLineSize = strlen(LinuxCommandLine) + 1;
-    }
+    LinuxKernelLoadAddress = NULL;
+    LinuxInitrdLoadAddress = NULL;
+    *LinuxBootDescription = ANSI_NULL;
 
-    return TRUE;
+    return ENOEXEC;
 }
 
-BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile)
+static BOOLEAN LinuxReadBootSector(ULONG LinuxKernelFile)
 {
+    LARGE_INTEGER Position;
+
     /* Allocate memory for boot sector */
     LinuxBootSector = MmAllocateMemoryWithType(512, LoaderSystemCode);
     if (LinuxBootSector == NULL)
         return FALSE;
 
-    /* Read linux boot sector */
-    FsSetFilePointer(LinuxKernelFile, 0);
-    if (!FsReadFile(LinuxKernelFile, 512, NULL, LinuxBootSector))
+    /* Load the linux boot sector */
+    Position.QuadPart = 0;
+    if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
+        return FALSE;
+    if (ArcRead(LinuxKernelFile, LinuxBootSector, 512, NULL) != ESUCCESS)
         return FALSE;
 
     /* Check for validity */
@@ -270,30 +327,32 @@ BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile)
 
     // DbgDumpBuffer(DPRINT_LINUX, LinuxBootSector, 512);
 
-    TRACE("SetupSectors: %d\n", LinuxBootSector->SetupSectors);
-    TRACE("RootFlags: 0x%x\n", LinuxBootSector->RootFlags);
-    TRACE("SystemSize: 0x%x\n", LinuxBootSector->SystemSize);
-    TRACE("SwapDevice: 0x%x\n", LinuxBootSector->SwapDevice);
-    TRACE("RamSize: 0x%x\n", LinuxBootSector->RamSize);
-    TRACE("VideoMode: 0x%x\n", LinuxBootSector->VideoMode);
-    TRACE("RootDevice: 0x%x\n", LinuxBootSector->RootDevice);
-    TRACE("BootFlag: 0x%x\n", LinuxBootSector->BootFlag);
+    TRACE("SetupSectors: %d\n"  , LinuxBootSector->SetupSectors);
+    TRACE("RootFlags:    0x%x\n", LinuxBootSector->RootFlags);
+    TRACE("SystemSize:   0x%x\n", LinuxBootSector->SystemSize);
+    TRACE("SwapDevice:   0x%x\n", LinuxBootSector->SwapDevice);
+    TRACE("RamSize:      0x%x\n", LinuxBootSector->RamSize);
+    TRACE("VideoMode:    0x%x\n", LinuxBootSector->VideoMode);
+    TRACE("RootDevice:   0x%x\n", LinuxBootSector->RootDevice);
+    TRACE("BootFlag:     0x%x\n", LinuxBootSector->BootFlag);
 
     return TRUE;
 }
 
-BOOLEAN LinuxReadSetupSector(PFILE LinuxKernelFile)
+static BOOLEAN LinuxReadSetupSector(ULONG LinuxKernelFile)
 {
+    LARGE_INTEGER Position;
     UCHAR TempLinuxSetupSector[512];
 
-    LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
-
-    /* Read first linux setup sector */
-    FsSetFilePointer(LinuxKernelFile, 512);
-    if (!FsReadFile(LinuxKernelFile, 512, NULL, TempLinuxSetupSector))
+    /* Load the first linux setup sector */
+    Position.QuadPart = 512;
+    if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
+        return FALSE;
+    if (ArcRead(LinuxKernelFile, TempLinuxSetupSector, 512, NULL) != ESUCCESS)
         return FALSE;
 
     /* Check the kernel version */
+    LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
     if (!LinuxCheckKernelVersion())
         return FALSE;
 
@@ -310,39 +369,42 @@ BOOLEAN LinuxReadSetupSector(PFILE LinuxKernelFile)
     /* Copy over first setup sector */
     RtlCopyMemory(LinuxSetupSector, TempLinuxSetupSector, 512);
 
-    /* Read in the rest of the linux setup sectors */
-    FsSetFilePointer(LinuxKernelFile, 1024);
-    if (!FsReadFile(LinuxKernelFile, SetupSectorSize - 512, NULL, (PVOID)((ULONG_PTR)LinuxSetupSector + 512)))
+    /* Load the rest of the linux setup sectors */
+    Position.QuadPart = 1024;
+    if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
+        return FALSE;
+    if (ArcRead(LinuxKernelFile, (PVOID)((ULONG_PTR)LinuxSetupSector + 512), SetupSectorSize - 512, NULL) != ESUCCESS)
         return FALSE;
 
     // DbgDumpBuffer(DPRINT_LINUX, LinuxSetupSector, SetupSectorSize);
 
     TRACE("SetupHeaderSignature: 0x%x (HdrS)\n", LinuxSetupSector->SetupHeaderSignature);
-    TRACE("Version: 0x%x\n", LinuxSetupSector->Version);
+    TRACE("Version:              0x%x\n", LinuxSetupSector->Version);
     TRACE("RealModeSwitch: 0x%x\n", LinuxSetupSector->RealModeSwitch);
-    TRACE("SetupSeg: 0x%x\n", LinuxSetupSector->SetupSeg);
+    TRACE("SetupSeg:       0x%x\n", LinuxSetupSector->SetupSeg);
     TRACE("StartSystemSeg: 0x%x\n", LinuxSetupSector->StartSystemSeg);
-    TRACE("KernelVersion: 0x%x\n", LinuxSetupSector->KernelVersion);
-    TRACE("TypeOfLoader: 0x%x\n", LinuxSetupSector->TypeOfLoader);
-    TRACE("LoadFlags: 0x%x\n", LinuxSetupSector->LoadFlags);
-    TRACE("SetupMoveSize: 0x%x\n", LinuxSetupSector->SetupMoveSize);
-    TRACE("Code32Start: 0x%x\n", LinuxSetupSector->Code32Start);
+    TRACE("KernelVersion:  0x%x\n", LinuxSetupSector->KernelVersion);
+    TRACE("TypeOfLoader:   0x%x\n", LinuxSetupSector->TypeOfLoader);
+    TRACE("LoadFlags:      0x%x\n", LinuxSetupSector->LoadFlags);
+    TRACE("SetupMoveSize:  0x%x\n", LinuxSetupSector->SetupMoveSize);
+    TRACE("Code32Start:    0x%x\n", LinuxSetupSector->Code32Start);
     TRACE("RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
-    TRACE("RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
-    TRACE("BootSectKludgeOffset: 0x%x\n", LinuxSetupSector->BootSectKludgeOffset);
+    TRACE("RamdiskSize:    0x%x\n", LinuxSetupSector->RamdiskSize);
+    TRACE("BootSectKludgeOffset:  0x%x\n", LinuxSetupSector->BootSectKludgeOffset);
     TRACE("BootSectKludgeSegment: 0x%x\n", LinuxSetupSector->BootSectKludgeSegment);
     TRACE("HeapEnd: 0x%x\n", LinuxSetupSector->HeapEnd);
 
     return TRUE;
 }
 
-BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile)
+static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
 {
+    PVOID LoadAddress;
+    LARGE_INTEGER Position;
     ULONG BytesLoaded;
     CHAR  StatusText[260];
-    PVOID LoadAddress;
 
-    sprintf(StatusText, "Loading %s", LinuxKernelName);
+    RtlStringCbPrintfA(StatusText, sizeof(StatusText), "Loading %s", LinuxKernelName);
     UiDrawStatusText(StatusText);
 
     /* Allocate memory for Linux kernel */
@@ -354,11 +416,13 @@ BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile)
 
     LoadAddress = LinuxKernelLoadAddress;
 
-    /* Read linux kernel to 0x100000 (1mb) */
-    FsSetFilePointer(LinuxKernelFile, 512 + SetupSectorSize);
+    /* Load the linux kernel at 0x100000 (1mb) */
+    Position.QuadPart = 512 + SetupSectorSize;
+    if (ArcSeek(LinuxKernelFile, &Position, SeekAbsolute) != ESUCCESS)
+        return FALSE;
     for (BytesLoaded=0; BytesLoaded<LinuxKernelSize; )
     {
-        if (!FsReadFile(LinuxKernelFile, LINUX_READ_CHUNK_SIZE, NULL, LoadAddress))
+        if (ArcRead(LinuxKernelFile, LoadAddress, LINUX_READ_CHUNK_SIZE, NULL) != ESUCCESS)
             return FALSE;
 
         BytesLoaded += LINUX_READ_CHUNK_SIZE;
@@ -370,7 +434,7 @@ BOOLEAN LinuxReadKernel(PFILE LinuxKernelFile)
     return TRUE;
 }
 
-BOOLEAN LinuxCheckKernelVersion(VOID)
+static BOOLEAN LinuxCheckKernelVersion(VOID)
 {
     /* Just assume old kernel until we find otherwise */
     NewStyleLinuxKernel = FALSE;
@@ -398,7 +462,7 @@ BOOLEAN LinuxCheckKernelVersion(VOID)
         LinuxSetupSector->LoadFlags |= LINUX_FLAG_CAN_USE_HEAP;
     }
 
-    if ((NewStyleLinuxKernel == FALSE) && (LinuxHasInitrd))
+    if ((NewStyleLinuxKernel == FALSE) && (LinuxInitrdName))
     {
         UiMessageBox("Error: Cannot load a ramdisk (initrd) with an old kernel image.");
         return FALSE;
@@ -407,12 +471,12 @@ BOOLEAN LinuxCheckKernelVersion(VOID)
     return TRUE;
 }
 
-BOOLEAN LinuxReadInitrd(PFILE LinuxInitrdFile)
+static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
 {
     ULONG        BytesLoaded;
     CHAR    StatusText[260];
 
-    sprintf(StatusText, "Loading %s", LinuxInitrdName);
+    RtlStringCbPrintfA(StatusText, sizeof(StatusText), "Loading %s", LinuxInitrdName);
     UiDrawStatusText(StatusText);
 
     // Allocate memory for the ramdisk
@@ -437,17 +501,17 @@ BOOLEAN LinuxReadInitrd(PFILE LinuxInitrdFile)
     LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
 
     TRACE("RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
-    TRACE("RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
+    TRACE("RamdiskSize:    0x%x\n", LinuxSetupSector->RamdiskSize);
 
     if (LinuxSetupSector->Version >= 0x0203)
     {
         TRACE("InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax);
     }
 
-    /* Read in the ramdisk */
+    /* Load the ramdisk */
     for (BytesLoaded=0; BytesLoaded<LinuxInitrdSize; )
     {
-        if (!FsReadFile(LinuxInitrdFile, LINUX_READ_CHUNK_SIZE, NULL, (PVOID)LinuxInitrdLoadAddress))
+        if (ArcRead(LinuxInitrdFile, (PVOID)LinuxInitrdLoadAddress, LINUX_READ_CHUNK_SIZE, NULL) != ESUCCESS)
             return FALSE;
 
         BytesLoaded += LINUX_READ_CHUNK_SIZE;