mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[FREELDR] linuxboot: It doesn't need the BIOS boot drive number and partition.
Also document a little bit the RootDevice field in the boot sector; add SAL2 annotations.
This commit is contained in:
parent
c25a0e1919
commit
e5517176b8
4 changed files with 51 additions and 87 deletions
|
@ -23,8 +23,6 @@
|
|||
|
||||
EXTERN DiskStopFloppyMotor:PROC
|
||||
EXTERN Relocator16Boot:PROC
|
||||
EXTERN FrldrBootDrive:BYTE
|
||||
EXTERN FrldrBootPartition:DWORD
|
||||
|
||||
.code64
|
||||
|
||||
|
@ -32,12 +30,11 @@ Regs:
|
|||
.space REGS_SIZE
|
||||
|
||||
/*
|
||||
* VOID __cdecl BootLinuxKernel(
|
||||
* IN ULONG KernelSize<ecx>,
|
||||
* IN PVOID KernelCurrentLoadAddress<rdx>,
|
||||
* IN PVOID KernelTargetLoadAddress<r8>,
|
||||
* IN UCHAR DriveNumber<r9b>,
|
||||
* IN ULONG PartitionNumber<rsp+40>);
|
||||
* VOID __cdecl
|
||||
* BootLinuxKernel(
|
||||
* _In_ ULONG KernelSize<ecx>,
|
||||
* _In_ PVOID KernelCurrentLoadAddress<rdx>,
|
||||
* _In_ PVOID KernelTargetLoadAddress<r8>);
|
||||
*/
|
||||
PUBLIC BootLinuxKernel
|
||||
BootLinuxKernel:
|
||||
|
@ -47,7 +44,6 @@ BootLinuxKernel:
|
|||
mov dword ptr [r11 + 8], ecx
|
||||
mov qword ptr [r11 + 16], rdx
|
||||
mov qword ptr [r11 + 24], r8
|
||||
mov byte ptr [r11 + 32], r9b
|
||||
|
||||
/* Save non-volatile registers */
|
||||
push rsi
|
||||
|
@ -67,25 +63,6 @@ BootLinuxKernel:
|
|||
mov word ptr [Regs + REGS_FS], ax
|
||||
mov word ptr [Regs + REGS_GS], ax
|
||||
|
||||
/* Set the boot drive */
|
||||
xor edx, edx
|
||||
mov dl, byte ptr [r11 + 32]
|
||||
test dl, dl
|
||||
jnz set_part
|
||||
mov dl, byte ptr /*ds:*/[FrldrBootDrive]
|
||||
|
||||
/* Set the boot partition */
|
||||
set_part:
|
||||
mov eax, dword ptr [r11 + 40]
|
||||
test eax, eax
|
||||
jnz continue
|
||||
mov eax, dword ptr /*ds:*/[FrldrBootPartition]
|
||||
continue:
|
||||
/* Store the 1-byte truncated partition number in DH */
|
||||
mov dh, al
|
||||
|
||||
mov dword ptr [Regs + REGS_EDX], edx
|
||||
|
||||
/*
|
||||
* Relocate the kernel image to its final destination (can be as low as 0x10000).
|
||||
* The reason we can overwrite low memory is because this code executes
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
|
||||
EXTERN _DiskStopFloppyMotor:PROC
|
||||
EXTERN _Relocator16Boot:PROC
|
||||
EXTERN _FrldrBootDrive:BYTE
|
||||
EXTERN _FrldrBootPartition:DWORD
|
||||
|
||||
.code32
|
||||
|
||||
|
@ -32,12 +30,11 @@ Regs:
|
|||
.space REGS_SIZE
|
||||
|
||||
/*
|
||||
* VOID __cdecl BootLinuxKernel(
|
||||
* IN ULONG KernelSize,
|
||||
* IN PVOID KernelCurrentLoadAddress,
|
||||
* IN PVOID KernelTargetLoadAddress,
|
||||
* IN UCHAR DriveNumber,
|
||||
* IN ULONG PartitionNumber);
|
||||
* VOID __cdecl
|
||||
* BootLinuxKernel(
|
||||
* _In_ ULONG KernelSize,
|
||||
* _In_ PVOID KernelCurrentLoadAddress,
|
||||
* _In_ PVOID KernelTargetLoadAddress);
|
||||
*/
|
||||
PUBLIC _BootLinuxKernel
|
||||
_BootLinuxKernel:
|
||||
|
@ -52,25 +49,6 @@ _BootLinuxKernel:
|
|||
mov word ptr [Regs + REGS_FS], ax
|
||||
mov word ptr [Regs + REGS_GS], ax
|
||||
|
||||
/* Set the boot drive */
|
||||
xor edx, edx
|
||||
mov dl, byte ptr [esp + 16]
|
||||
test dl, dl
|
||||
jnz set_part
|
||||
mov dl, byte ptr ds:[_FrldrBootDrive]
|
||||
|
||||
/* Set the boot partition */
|
||||
set_part:
|
||||
mov eax, dword ptr [esp + 20]
|
||||
test eax, eax
|
||||
jnz continue
|
||||
mov eax, dword ptr ds:[_FrldrBootPartition]
|
||||
continue:
|
||||
/* Store the 1-byte truncated partition number in DH */
|
||||
mov dh, al
|
||||
|
||||
mov dword ptr [Regs + REGS_EDX], edx
|
||||
|
||||
/*
|
||||
* Relocate the kernel image to its final destination (can be as low as 0x10000).
|
||||
* The reason we can overwrite low memory is because this code executes
|
||||
|
|
|
@ -129,18 +129,17 @@ typedef struct
|
|||
#include <poppack.h>
|
||||
|
||||
// Implemented in linux.S
|
||||
VOID __cdecl BootLinuxKernel(
|
||||
IN ULONG KernelSize,
|
||||
IN PVOID KernelCurrentLoadAddress,
|
||||
IN PVOID KernelTargetLoadAddress,
|
||||
IN UCHAR DriveNumber,
|
||||
IN ULONG PartitionNumber);
|
||||
VOID __cdecl
|
||||
BootLinuxKernel(
|
||||
_In_ ULONG KernelSize,
|
||||
_In_ PVOID KernelCurrentLoadAddress,
|
||||
_In_ PVOID KernelTargetLoadAddress);
|
||||
|
||||
ARC_STATUS
|
||||
LoadAndBootLinux(
|
||||
IN ULONG Argc,
|
||||
IN PCHAR Argv[],
|
||||
IN PCHAR Envp[]);
|
||||
_In_ ULONG Argc,
|
||||
_In_ PCHAR Argv[],
|
||||
_In_ PCHAR Envp[]);
|
||||
|
||||
#endif /* _M_IX86 || _M_AMD64 */
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
/*
|
||||
* The x86 Linux Boot Protocol is explained at:
|
||||
* https://www.kernel.org/doc/Documentation/x86/boot.txt
|
||||
* https://www.linux.it/~rubini/docs/boot/boot.html
|
||||
*/
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||
|
@ -84,21 +85,29 @@ RemoveQuotes(
|
|||
|
||||
ARC_STATUS
|
||||
LoadAndBootLinux(
|
||||
IN ULONG Argc,
|
||||
IN PCHAR Argv[],
|
||||
IN PCHAR Envp[])
|
||||
_In_ ULONG Argc,
|
||||
_In_ PCHAR Argv[],
|
||||
_In_ PCHAR Envp[])
|
||||
{
|
||||
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];
|
||||
|
||||
#if DBG
|
||||
/* Ensure the boot type is the one expected */
|
||||
ArgValue = GetArgumentValue(Argc, Argv, "BootType");
|
||||
if (!ArgValue || !*ArgValue || _stricmp(ArgValue, "Linux") != 0)
|
||||
{
|
||||
ERR("Unexpected boot type '%s', aborting\n", ArgValue ? ArgValue : "n/a");
|
||||
return EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
Description = GetArgumentValue(Argc, Argv, "LoadIdentifier");
|
||||
if (Description && *Description)
|
||||
RtlStringCbPrintfA(LinuxBootDescription, sizeof(LinuxBootDescription), "Loading %s...", Description);
|
||||
|
@ -125,10 +134,10 @@ LoadAndBootLinux(
|
|||
ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
|
||||
if (ArgValue && *ArgValue)
|
||||
{
|
||||
DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
|
||||
UCHAR DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
|
||||
|
||||
/* Retrieve the boot partition (not optional and cannot be zero) */
|
||||
PartitionNumber = 0;
|
||||
ULONG PartitionNumber = 0;
|
||||
ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
|
||||
if (ArgValue && *ArgValue)
|
||||
PartitionNumber = atoi(ArgValue);
|
||||
|
@ -152,17 +161,6 @@ LoadAndBootLinux(
|
|||
}
|
||||
}
|
||||
|
||||
/* If we haven't retrieved the BIOS drive and partition numbers above, do it now */
|
||||
if (PartitionNumber == 0)
|
||||
{
|
||||
/* Retrieve the BIOS drive and partition numbers */
|
||||
if (!DissectArcPath(BootPath, NULL, &DriveNumber, &PartitionNumber))
|
||||
{
|
||||
/* This is not a fatal failure, but just an inconvenience: display a message */
|
||||
TRACE("DissectArcPath(%s) failed to retrieve BIOS drive and partition numbers.\n", BootPath);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the kernel name */
|
||||
LinuxKernelName = GetArgumentValue(Argc, Argv, "Kernel");
|
||||
if (!LinuxKernelName || !*LinuxKernelName)
|
||||
|
@ -240,9 +238,22 @@ LoadAndBootLinux(
|
|||
goto LinuxBootFailed;
|
||||
}
|
||||
|
||||
// If the default root device is set to FLOPPY (0000h), change to /dev/fd0 (0200h)
|
||||
if (LinuxBootSector->RootDevice == 0x0000)
|
||||
LinuxBootSector->RootDevice = 0x0200;
|
||||
/*
|
||||
* If the default root device is set to FLOPPY (0000h), change to /dev/fd0 (0200h).
|
||||
* For a list of majors, see
|
||||
* https://github.com/torvalds/linux/blob/master/include/uapi/linux/major.h
|
||||
* For some examples of (decoded) root devices values, see
|
||||
* https://github.com/torvalds/linux/blob/cc89c63e2/include/linux/root_dev.h
|
||||
*
|
||||
* NOTE: The RootDevice field is deprecated since commits
|
||||
* https://github.com/torvalds/linux/commit/079f85e62
|
||||
* https://github.com/torvalds/linux/commit/7448e8e5d
|
||||
*/
|
||||
#define NODEV 0
|
||||
#define FLOPPY_MAJOR 2
|
||||
#define makedev(maj, min) (((maj) << 8) | (min))
|
||||
if (LinuxBootSector->RootDevice == NODEV)
|
||||
LinuxBootSector->RootDevice = makedev(FLOPPY_MAJOR, 0);
|
||||
|
||||
if (LinuxSetupSector->Version >= 0x0202)
|
||||
{
|
||||
|
@ -271,8 +282,7 @@ LoadAndBootLinux(
|
|||
BootLinuxKernel(LinuxKernelSize, LinuxKernelLoadAddress,
|
||||
(LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
|
||||
? (PVOID)LINUX_KERNEL_LOAD_ADDRESS /* == 0x100000 */
|
||||
: (PVOID)0x10000,
|
||||
DriveNumber, PartitionNumber);
|
||||
: (PVOID)0x10000);
|
||||
/* Must not return! */
|
||||
return ESUCCESS;
|
||||
|
||||
|
|
Loading…
Reference in a new issue