26#if defined(_M_IX86) || defined(_M_AMD64)
37#define LINUX_READ_CHUNK_SIZE 0x20000
39PLINUX_BOOTSECTOR LinuxBootSector =
NULL;
40PLINUX_SETUPSECTOR LinuxSetupSector =
NULL;
41ULONG SetupSectorSize = 0;
43ULONG LinuxKernelSize = 0;
44ULONG LinuxInitrdSize = 0;
48ULONG LinuxCommandLineSize = 0;
51CHAR LinuxBootDescription[80];
55static BOOLEAN LinuxReadBootSector(
ULONG LinuxKernelFile);
56static BOOLEAN LinuxReadSetupSector(
ULONG LinuxKernelFile);
71 while (*
p ==
' ' || *
p ==
'\t' || *
p ==
'"')
96 ULONG LinuxKernel = 0;
97 ULONG LinuxInitrdFile = 0;
104 if (!ArgValue || !*ArgValue ||
_stricmp(ArgValue,
"Linux") != 0)
106 ERR(
"Unexpected boot type '%s', aborting\n", ArgValue ? ArgValue :
"n/a");
115 strcpy(LinuxBootDescription,
"Loading Linux...");
129 if (!BootPath || !*BootPath)
135 if (ArgValue && *ArgValue)
142 if (ArgValue && *ArgValue)
147 goto LinuxBootFailed;
166 if (!LinuxKernelName || !*LinuxKernelName)
168 UiMessageBox(
"Linux kernel filename not specified for selected OS!");
169 goto LinuxBootFailed;
176 LinuxCommandLineSize = 0;
178 if (LinuxCommandLine && *LinuxCommandLine)
181 LinuxCommandLineSize = (
ULONG)
strlen(LinuxCommandLine) + 1;
182 LinuxCommandLineSize =
min(LinuxCommandLineSize, 260);
189 UiMessageBox(
"Linux kernel '%s' not found.", LinuxKernelName);
190 goto LinuxBootFailed;
199 UiMessageBox(
"Linux initrd image '%s' not found.", LinuxInitrdName);
200 goto LinuxBootFailed;
205 if (!LinuxReadBootSector(LinuxKernel))
206 goto LinuxBootFailed;
209 if (!LinuxReadSetupSector(LinuxKernel))
210 goto LinuxBootFailed;
217 LinuxKernelSize =
FileInfo.EndingAddress.LowPart - (512 + SetupSectorSize);
227 LinuxInitrdSize =
FileInfo.EndingAddress.LowPart;
231 if (!LinuxReadKernel(LinuxKernel))
232 goto LinuxBootFailed;
237 if (!LinuxReadInitrd(LinuxInitrdFile))
238 goto LinuxBootFailed;
253#define FLOPPY_MAJOR 2
254#define makedev(maj, min) (((maj) << 8) | (min))
255 if (LinuxBootSector->RootDevice ==
NODEV)
256 LinuxBootSector->RootDevice =
makedev(FLOPPY_MAJOR, 0);
258 if (LinuxSetupSector->Version >= 0x0202)
260 LinuxSetupSector->CommandLinePointer = 0x99000;
264 LinuxBootSector->CommandLineMagic = LINUX_COMMAND_LINE_MAGIC;
265 LinuxBootSector->CommandLineOffset = 0x9000;
268 if (NewStyleLinuxKernel)
269 LinuxSetupSector->TypeOfLoader = LINUX_LOADER_TYPE_FREELOADER;
271 LinuxSetupSector->LoadFlags = 0;
276 LinuxCommandLine ? LinuxCommandLine :
"",
277 LinuxCommandLine ? LinuxCommandLineSize :
sizeof(
ANSI_NULL));
282 BootLinuxKernel(LinuxKernelSize, LinuxKernelLoadAddress,
283 (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
284 ? (
PVOID)LINUX_KERNEL_LOAD_ADDRESS
297 if (LinuxBootSector !=
NULL)
300 if (LinuxSetupSector !=
NULL)
303 if (LinuxKernelLoadAddress !=
NULL)
306 if (LinuxInitrdLoadAddress !=
NULL)
309 LinuxBootSector =
NULL;
310 LinuxSetupSector =
NULL;
312 NewStyleLinuxKernel =
FALSE;
315 LinuxKernelName =
NULL;
316 LinuxInitrdName =
NULL;
317 LinuxCommandLine =
NULL;
318 LinuxCommandLineSize = 0;
319 LinuxKernelLoadAddress =
NULL;
320 LinuxInitrdLoadAddress =
NULL;
326static BOOLEAN LinuxReadBootSector(
ULONG LinuxKernelFile)
332 if (LinuxBootSector ==
NULL)
343 if (LinuxBootSector->BootFlag != LINUX_BOOT_SECTOR_MAGIC)
351 TRACE(
"SetupSectors: %d\n" , LinuxBootSector->SetupSectors);
352 TRACE(
"RootFlags: 0x%x\n", LinuxBootSector->RootFlags);
353 TRACE(
"SystemSize: 0x%x\n", LinuxBootSector->SystemSize);
354 TRACE(
"SwapDevice: 0x%x\n", LinuxBootSector->SwapDevice);
355 TRACE(
"RamSize: 0x%x\n", LinuxBootSector->RamSize);
356 TRACE(
"VideoMode: 0x%x\n", LinuxBootSector->VideoMode);
357 TRACE(
"RootDevice: 0x%x\n", LinuxBootSector->RootDevice);
358 TRACE(
"BootFlag: 0x%x\n", LinuxBootSector->BootFlag);
363static BOOLEAN LinuxReadSetupSector(
ULONG LinuxKernelFile)
366 UCHAR TempLinuxSetupSector[512];
376 LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
377 if (!LinuxCheckKernelVersion())
380 if (NewStyleLinuxKernel)
381 SetupSectorSize = 512 * LinuxBootSector->SetupSectors;
383 SetupSectorSize = 512 * 4;
387 if (LinuxSetupSector ==
NULL)
402 TRACE(
"SetupHeaderSignature: 0x%x (HdrS)\n", LinuxSetupSector->SetupHeaderSignature);
403 TRACE(
"Version: 0x%x\n", LinuxSetupSector->Version);
404 TRACE(
"RealModeSwitch: 0x%x\n", LinuxSetupSector->RealModeSwitch);
405 TRACE(
"SetupSeg: 0x%x\n", LinuxSetupSector->SetupSeg);
406 TRACE(
"StartSystemSeg: 0x%x\n", LinuxSetupSector->StartSystemSeg);
407 TRACE(
"KernelVersion: 0x%x\n", LinuxSetupSector->KernelVersion);
408 TRACE(
"TypeOfLoader: 0x%x\n", LinuxSetupSector->TypeOfLoader);
409 TRACE(
"LoadFlags: 0x%x\n", LinuxSetupSector->LoadFlags);
410 TRACE(
"SetupMoveSize: 0x%x\n", LinuxSetupSector->SetupMoveSize);
411 TRACE(
"Code32Start: 0x%x\n", LinuxSetupSector->Code32Start);
412 TRACE(
"RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
413 TRACE(
"RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
414 TRACE(
"BootSectKludgeOffset: 0x%x\n", LinuxSetupSector->BootSectKludgeOffset);
415 TRACE(
"BootSectKludgeSegment: 0x%x\n", LinuxSetupSector->BootSectKludgeSegment);
416 TRACE(
"HeapEnd: 0x%x\n", LinuxSetupSector->HeapEnd);
426 CHAR StatusText[260];
433 if (LinuxKernelLoadAddress != (
PVOID)LINUX_KERNEL_LOAD_ADDRESS)
437 if (LinuxKernelLoadAddress ==
NULL)
439 TRACE(
"Failed to allocate 0x%lx bytes for the kernel image.\n", LinuxKernelSize);
444 LoadAddress = LinuxKernelLoadAddress;
447 Position.QuadPart = 512 + SetupSectorSize;
450 for (BytesLoaded = 0; BytesLoaded < LinuxKernelSize; )
455 BytesLoaded += LINUX_READ_CHUNK_SIZE;
456 LoadAddress = (
PVOID)((
ULONG_PTR)LoadAddress + LINUX_READ_CHUNK_SIZE);
467 NewStyleLinuxKernel =
FALSE;
470 if (LinuxSetupSector->SetupHeaderSignature != LINUX_SETUP_HEADER_ID)
472 NewStyleLinuxKernel =
FALSE;
475 else if (LinuxSetupSector->Version < 0x0200)
477 NewStyleLinuxKernel =
FALSE;
480 else if (LinuxSetupSector->Version == 0x0200)
482 NewStyleLinuxKernel =
TRUE;
485 else if (LinuxSetupSector->Version >= 0x0201)
487 NewStyleLinuxKernel =
TRUE;
488 LinuxSetupSector->HeapEnd = 0x9000;
489 LinuxSetupSector->LoadFlags |= LINUX_FLAG_CAN_USE_HEAP;
492 if ((NewStyleLinuxKernel ==
FALSE) && (LinuxInitrdName))
494 UiMessageBox(
"Error: Cannot load a ramdisk (initrd) with an old kernel image.");
504 CHAR StatusText[260];
513 if (LinuxSetupSector->Version <= 0x0202)
516 C_ASSERT(LINUX_MAX_INITRD_ADDRESS < 0x100000000);
524 if (LinuxInitrdLoadAddress ==
NULL)
533 LinuxSetupSector->RamdiskAddress =
PtrToUlong(LinuxInitrdLoadAddress);
534 LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
536 TRACE(
"RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
537 TRACE(
"RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
539 if (LinuxSetupSector->Version >= 0x0203)
541 TRACE(
"InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax);
545 for (BytesLoaded = 0; BytesLoaded < LinuxInitrdSize; )
547 if (
ArcRead(LinuxInitrdFile, LinuxInitrdLoadAddress, LINUX_READ_CHUNK_SIZE,
NULL) !=
ESUCCESS)
550 BytesLoaded += LINUX_READ_CHUNK_SIZE;
551 LinuxInitrdLoadAddress = (
PVOID)((
ULONG_PTR)LinuxInitrdLoadAddress + LINUX_READ_CHUNK_SIZE);
ACPI_SIZE strlen(const char *String)
PSTR GetArgumentValue(_In_ ULONG Argc, _In_ PCHAR Argv[], _In_ PCSTR ArgumentName)
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition)
#define DriveMapGetBiosDriveNumber(DeviceName)
#define DBG_DEFAULT_CHANNEL(ch)
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
ARC_STATUS FsOpenFile(IN PCSTR FileName, IN PCSTR DefaultPath OPTIONAL, IN OPENMODE OpenMode, OUT PULONG FileId)
ARC_STATUS ArcClose(_In_ ULONG FileId)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
VOID MmFreeMemory(PVOID MemoryPointer)
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
VOID UiShowMessageBoxesInArgv(IN ULONG Argc, IN PCHAR Argv[])
VOID UiDrawBackdrop(ULONG DrawHeight)
VOID UiUpdateProgressBar(_In_ ULONG Percentage, _In_opt_ PCSTR ProgressText)
ULONG UiGetScreenHeight(VOID)
VOID UiUnInitialize(PCSTR BootText)
VOID UiDrawProgressBarCenter(_In_ PCSTR ProgressText)
VOID UiDrawStatusText(PCSTR StatusText)
VOID UiMessageBox(_In_ PCSTR Format,...)
#define makedev(major, minor)
static const WCHAR Description[]
static LPWSTR RemoveQuotes(LPWSTR str)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define memmove(s1, s2, n)
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define RtlCopyMemory(Destination, Source, Length)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_In_ ULONG _In_ ULONG PartitionNumber