25#if defined(_M_IX86) || defined(_M_AMD64)
36#define LINUX_READ_CHUNK_SIZE 0x20000
38PLINUX_BOOTSECTOR LinuxBootSector =
NULL;
39PLINUX_SETUPSECTOR LinuxSetupSector =
NULL;
40ULONG SetupSectorSize = 0;
42ULONG LinuxKernelSize = 0;
43ULONG LinuxInitrdSize = 0;
47ULONG LinuxCommandLineSize = 0;
50CHAR LinuxBootDescription[80];
54static BOOLEAN LinuxReadBootSector(
ULONG LinuxKernelFile);
55static BOOLEAN LinuxReadSetupSector(
ULONG LinuxKernelFile);
70 while (*
p ==
' ' || *
p ==
'\t' || *
p ==
'"')
95 UCHAR DriveNumber = 0;
97 ULONG LinuxKernel = 0;
98 ULONG LinuxInitrdFile = 0;
106 strcpy(LinuxBootDescription,
"Loading Linux...");
120 if (!BootPath || !*BootPath)
126 if (ArgValue && *ArgValue)
133 if (ArgValue && *ArgValue)
138 goto LinuxBootFailed;
162 TRACE(
"DissectArcPath(%s) failed to retrieve BIOS drive and partition numbers.\n", BootPath);
168 if (!LinuxKernelName || !*LinuxKernelName)
170 UiMessageBox(
"Linux kernel filename not specified for selected OS!");
171 goto LinuxBootFailed;
178 LinuxCommandLineSize = 0;
180 if (LinuxCommandLine && *LinuxCommandLine)
183 LinuxCommandLineSize = (
ULONG)
strlen(LinuxCommandLine) + 1;
184 LinuxCommandLineSize =
min(LinuxCommandLineSize, 260);
191 UiMessageBox(
"Linux kernel '%s' not found.", LinuxKernelName);
192 goto LinuxBootFailed;
201 UiMessageBox(
"Linux initrd image '%s' not found.", LinuxInitrdName);
202 goto LinuxBootFailed;
207 if (!LinuxReadBootSector(LinuxKernel))
208 goto LinuxBootFailed;
211 if (!LinuxReadSetupSector(LinuxKernel))
212 goto LinuxBootFailed;
219 LinuxKernelSize =
FileInfo.EndingAddress.LowPart - (512 + SetupSectorSize);
229 LinuxInitrdSize =
FileInfo.EndingAddress.LowPart;
233 if (!LinuxReadKernel(LinuxKernel))
234 goto LinuxBootFailed;
239 if (!LinuxReadInitrd(LinuxInitrdFile))
240 goto LinuxBootFailed;
244 if (LinuxBootSector->RootDevice == 0x0000)
245 LinuxBootSector->RootDevice = 0x0200;
247 if (LinuxSetupSector->Version >= 0x0202)
249 LinuxSetupSector->CommandLinePointer = 0x99000;
253 LinuxBootSector->CommandLineMagic = LINUX_COMMAND_LINE_MAGIC;
254 LinuxBootSector->CommandLineOffset = 0x9000;
257 if (NewStyleLinuxKernel)
258 LinuxSetupSector->TypeOfLoader = LINUX_LOADER_TYPE_FREELOADER;
260 LinuxSetupSector->LoadFlags = 0;
265 LinuxCommandLine ? LinuxCommandLine :
"",
266 LinuxCommandLine ? LinuxCommandLineSize :
sizeof(
ANSI_NULL));
271 BootLinuxKernel(LinuxKernelSize, LinuxKernelLoadAddress,
272 (LinuxSetupSector->LoadFlags & LINUX_FLAG_LOAD_HIGH)
273 ? (
PVOID)LINUX_KERNEL_LOAD_ADDRESS
287 if (LinuxBootSector !=
NULL)
290 if (LinuxSetupSector !=
NULL)
293 if (LinuxKernelLoadAddress !=
NULL)
296 if (LinuxInitrdLoadAddress !=
NULL)
299 LinuxBootSector =
NULL;
300 LinuxSetupSector =
NULL;
302 NewStyleLinuxKernel =
FALSE;
305 LinuxKernelName =
NULL;
306 LinuxInitrdName =
NULL;
307 LinuxCommandLine =
NULL;
308 LinuxCommandLineSize = 0;
309 LinuxKernelLoadAddress =
NULL;
310 LinuxInitrdLoadAddress =
NULL;
316static BOOLEAN LinuxReadBootSector(
ULONG LinuxKernelFile)
322 if (LinuxBootSector ==
NULL)
333 if (LinuxBootSector->BootFlag != LINUX_BOOT_SECTOR_MAGIC)
341 TRACE(
"SetupSectors: %d\n" , LinuxBootSector->SetupSectors);
342 TRACE(
"RootFlags: 0x%x\n", LinuxBootSector->RootFlags);
343 TRACE(
"SystemSize: 0x%x\n", LinuxBootSector->SystemSize);
344 TRACE(
"SwapDevice: 0x%x\n", LinuxBootSector->SwapDevice);
345 TRACE(
"RamSize: 0x%x\n", LinuxBootSector->RamSize);
346 TRACE(
"VideoMode: 0x%x\n", LinuxBootSector->VideoMode);
347 TRACE(
"RootDevice: 0x%x\n", LinuxBootSector->RootDevice);
348 TRACE(
"BootFlag: 0x%x\n", LinuxBootSector->BootFlag);
353static BOOLEAN LinuxReadSetupSector(
ULONG LinuxKernelFile)
356 UCHAR TempLinuxSetupSector[512];
366 LinuxSetupSector = (PLINUX_SETUPSECTOR)TempLinuxSetupSector;
367 if (!LinuxCheckKernelVersion())
370 if (NewStyleLinuxKernel)
371 SetupSectorSize = 512 * LinuxBootSector->SetupSectors;
373 SetupSectorSize = 512 * 4;
377 if (LinuxSetupSector ==
NULL)
392 TRACE(
"SetupHeaderSignature: 0x%x (HdrS)\n", LinuxSetupSector->SetupHeaderSignature);
393 TRACE(
"Version: 0x%x\n", LinuxSetupSector->Version);
394 TRACE(
"RealModeSwitch: 0x%x\n", LinuxSetupSector->RealModeSwitch);
395 TRACE(
"SetupSeg: 0x%x\n", LinuxSetupSector->SetupSeg);
396 TRACE(
"StartSystemSeg: 0x%x\n", LinuxSetupSector->StartSystemSeg);
397 TRACE(
"KernelVersion: 0x%x\n", LinuxSetupSector->KernelVersion);
398 TRACE(
"TypeOfLoader: 0x%x\n", LinuxSetupSector->TypeOfLoader);
399 TRACE(
"LoadFlags: 0x%x\n", LinuxSetupSector->LoadFlags);
400 TRACE(
"SetupMoveSize: 0x%x\n", LinuxSetupSector->SetupMoveSize);
401 TRACE(
"Code32Start: 0x%x\n", LinuxSetupSector->Code32Start);
402 TRACE(
"RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
403 TRACE(
"RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
404 TRACE(
"BootSectKludgeOffset: 0x%x\n", LinuxSetupSector->BootSectKludgeOffset);
405 TRACE(
"BootSectKludgeSegment: 0x%x\n", LinuxSetupSector->BootSectKludgeSegment);
406 TRACE(
"HeapEnd: 0x%x\n", LinuxSetupSector->HeapEnd);
416 CHAR StatusText[260];
423 if (LinuxKernelLoadAddress != (
PVOID)LINUX_KERNEL_LOAD_ADDRESS)
427 if (LinuxKernelLoadAddress ==
NULL)
429 TRACE(
"Failed to allocate 0x%lx bytes for the kernel image.\n", LinuxKernelSize);
434 LoadAddress = LinuxKernelLoadAddress;
437 Position.QuadPart = 512 + SetupSectorSize;
440 for (BytesLoaded = 0; BytesLoaded < LinuxKernelSize; )
445 BytesLoaded += LINUX_READ_CHUNK_SIZE;
446 LoadAddress = (
PVOID)((
ULONG_PTR)LoadAddress + LINUX_READ_CHUNK_SIZE);
457 NewStyleLinuxKernel =
FALSE;
460 if (LinuxSetupSector->SetupHeaderSignature != LINUX_SETUP_HEADER_ID)
462 NewStyleLinuxKernel =
FALSE;
465 else if (LinuxSetupSector->Version < 0x0200)
467 NewStyleLinuxKernel =
FALSE;
470 else if (LinuxSetupSector->Version == 0x0200)
472 NewStyleLinuxKernel =
TRUE;
475 else if (LinuxSetupSector->Version >= 0x0201)
477 NewStyleLinuxKernel =
TRUE;
478 LinuxSetupSector->HeapEnd = 0x9000;
479 LinuxSetupSector->LoadFlags |= LINUX_FLAG_CAN_USE_HEAP;
482 if ((NewStyleLinuxKernel ==
FALSE) && (LinuxInitrdName))
484 UiMessageBox(
"Error: Cannot load a ramdisk (initrd) with an old kernel image.");
494 CHAR StatusText[260];
503 if (LinuxSetupSector->Version <= 0x0202)
506 C_ASSERT(LINUX_MAX_INITRD_ADDRESS < 0x100000000);
514 if (LinuxInitrdLoadAddress ==
NULL)
523 LinuxSetupSector->RamdiskAddress =
PtrToUlong(LinuxInitrdLoadAddress);
524 LinuxSetupSector->RamdiskSize = LinuxInitrdSize;
526 TRACE(
"RamdiskAddress: 0x%x\n", LinuxSetupSector->RamdiskAddress);
527 TRACE(
"RamdiskSize: 0x%x\n", LinuxSetupSector->RamdiskSize);
529 if (LinuxSetupSector->Version >= 0x0203)
531 TRACE(
"InitrdAddressMax: 0x%x\n", LinuxSetupSector->InitrdAddressMax);
535 for (BytesLoaded = 0; BytesLoaded < LinuxInitrdSize; )
537 if (
ArcRead(LinuxInitrdFile, LinuxInitrdLoadAddress, LINUX_READ_CHUNK_SIZE,
NULL) !=
ESUCCESS)
540 BytesLoaded += LINUX_READ_CHUNK_SIZE;
541 LinuxInitrdLoadAddress = (
PVOID)((
ULONG_PTR)LinuxInitrdLoadAddress + LINUX_READ_CHUNK_SIZE);
ACPI_SIZE strlen(const char *String)
char * strcpy(char *DstString, const char *SrcString)
PCHAR GetArgumentValue(IN ULONG Argc, IN PCHAR Argv[], IN PCHAR ArgumentName)
BOOLEAN DissectArcPath(IN PCSTR ArcPath, OUT PCSTR *Path OPTIONAL, OUT PUCHAR DriveNumber, OUT PULONG PartitionNumber)
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition)
#define DriveMapGetBiosDriveNumber(DeviceName)
#define DBG_DEFAULT_CHANNEL(ch)
ARC_STATUS ArcClose(ULONG FileId)
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 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)
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,...)
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define RtlCopyMemory(Destination, Source, Length)
VOID UiShowMessageBoxesInArgv(IN ULONG Argc, IN PCHAR Argv[])
VOID UiUpdateProgressBar(_In_ ULONG Percentage, _In_opt_ PCSTR ProgressText)
VOID UiUnInitialize(PCSTR BootText)
VOID UiDrawBackdrop(VOID)
VOID UiDrawProgressBarCenter(_In_ PCSTR ProgressText)
VOID UiDrawStatusText(PCSTR StatusText)
VOID UiMessageBox(PCSTR Format,...)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_In_ ULONG _In_ ULONG PartitionNumber