X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/blobdiff_plain/c72f96312c1caabafff6f424aac70493d99faa38..790fa744f85c7dff5fe6f1905cd4268980c60dda:/EDK2/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c diff --git a/EDK2/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c index d3c8216..dc73764 100644 --- a/EDK2/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c +++ b/EDK2/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c @@ -32,11 +32,15 @@ #include #include #include +#include #include #include +UINTN g_iso_buf_size = 0; +BOOLEAN gMemdiskMode = FALSE; BOOLEAN gDebugPrint = FALSE; BOOLEAN gLoadIsoEfi = FALSE; +ventoy_ram_disk g_ramdisk_param; ventoy_chain_head *g_chain; ventoy_img_chunk *g_chunk; UINT32 g_img_chunk_num; @@ -353,6 +357,25 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector return EFI_SUCCESS; } +EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + //debug("### ventoy_block_io_ramdisk_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048); + + (VOID)This; + (VOID)MediaId; + + CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize); + + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI ventoy_block_io_read ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -497,6 +520,33 @@ EFI_STATUS EFIAPI ventoy_fill_device_path(VOID) return EFI_SUCCESS; } +EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID VarGuid = VENTOY_GUID; + + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_ramdisk_param), &(g_ramdisk_param)); + debug("set efi variable %r", Status); + + return Status; +} + +EFI_STATUS EFIAPI ventoy_del_ramdisk_param(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID VarGuid = VENTOY_GUID; + + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, NULL); + debug("delete efi variable %r", Status); + + return Status; +} + + EFI_STATUS EFIAPI ventoy_set_variable(VOID) { EFI_STATUS Status = EFI_SUCCESS; @@ -524,7 +574,7 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID) } -EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle) +EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize) { EFI_STATUS Status = EFI_SUCCESS; EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo); @@ -532,7 +582,7 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle) ventoy_fill_device_path(); gBlockData.Media.BlockSize = 2048; - gBlockData.Media.LastBlock = g_chain->virt_img_size_in_bytes / 2048 - 1; + gBlockData.Media.LastBlock = ImgSize / 2048 - 1; gBlockData.Media.ReadOnly = TRUE; gBlockData.Media.MediaPresent = 1; gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; @@ -540,7 +590,16 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle) pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; pBlockIo->Media = &(gBlockData.Media); pBlockIo->Reset = ventoy_block_io_reset; - pBlockIo->ReadBlocks = ventoy_block_io_read; + + if (gMemdiskMode) + { + pBlockIo->ReadBlocks = ventoy_block_io_ramdisk_read; + } + else + { + pBlockIo->ReadBlocks = ventoy_block_io_read; + } + pBlockIo->WriteBlocks = ventoy_block_io_write; pBlockIo->FlushBlocks = ventoy_block_io_flush; @@ -827,6 +886,7 @@ static int ventoy_update_image_location(ventoy_os_param *param) STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) { UINT32 i = 0; + UINTN size = 0; UINT8 chksum = 0; CHAR16 *pPos = NULL; CHAR16 *pCmdLine = NULL; @@ -866,32 +926,44 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); grub_env_get = pGrubParam->grub_env_get; - pPos = StrStr(pCmdLine, L"mem:"); g_chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); - g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset); - g_img_chunk_num = g_chain->img_chunk_num; - g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset); - g_override_chunk_num = g_chain->override_chunk_num; - g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset); - g_virt_chunk_num = g_chain->virt_chunk_num; + pPos = StrStr(pPos, L"size:"); + size = StrDecimalToUintn(pPos + 5); - for (i = 0; i < sizeof(ventoy_os_param); i++) - { - chksum += *((UINT8 *)(&(g_chain->os_param)) + i); - } + debug("memory addr:%p size:%lu", g_chain, size); - if (gDebugPrint) + if (StrStr(pCmdLine, L"memdisk")) { - debug("os param checksum: 0x%x %a", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); + g_iso_buf_size = size; + gMemdiskMode = TRUE; } + else + { + g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset); + g_img_chunk_num = g_chain->img_chunk_num; + g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset); + g_override_chunk_num = g_chain->override_chunk_num; + g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset); + g_virt_chunk_num = g_chain->virt_chunk_num; + + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((UINT8 *)(&(g_chain->os_param)) + i); + } - ventoy_update_image_location(&(g_chain->os_param)); + if (gDebugPrint) + { + debug("os param checksum: 0x%x %a", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); + } - if (gDebugPrint) - { - ventoy_dump_chain(g_chain); + ventoy_update_image_location(&(g_chain->os_param)); + + if (gDebugPrint) + { + ventoy_dump_chain(g_chain); + } } FreePool(pCmdLine); @@ -974,6 +1046,7 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) if (EFI_ERROR(Status)) { debug("Failed to start image %r", Status); + sleep(3); gBS->UnloadImage(Image); break; } @@ -1016,8 +1089,49 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID) return EFI_SUCCESS; } -EFI_STATUS EFIAPI VentoyEfiMain +EFI_STATUS EFIAPI ventoy_ramdisk_boot(IN EFI_HANDLE ImageHandle) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_RAM_DISK_PROTOCOL *RamDisk = NULL; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + + debug("RamDisk Boot ..."); + + Status = gBS->LocateProtocol(&gEfiRamDiskProtocolGuid, NULL, (VOID **)&RamDisk); + if (EFI_ERROR(Status)) + { + debug("Failed to locate ramdisk protocol %r", Status); + return Status; + } + debug("Locate RamDisk Protocol %r ...", Status); + + Status = RamDisk->Register((UINTN)g_chain, (UINT64)g_iso_buf_size, &gEfiVirtualCdGuid, NULL, &DevicePath); + if (EFI_ERROR(Status)) + { + debug("Failed to register ramdisk %r", Status); + return Status; + } + + debug("Register RamDisk %r ...", Status); + debug("RamDisk DevicePath:<%s> ...", ConvertDevicePathToText(DevicePath, FALSE, FALSE)); + + ventoy_debug_pause(); + + gBlockData.Path = DevicePath; + gBlockData.DevicePathCompareLen = GetDevicePathSize(DevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); + + Status = ventoy_boot(ImageHandle); + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(300); + } + + return EFI_SUCCESS; +} +EFI_STATUS EFIAPI VentoyEfiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -1037,36 +1151,56 @@ EFI_STATUS EFIAPI VentoyEfiMain ventoy_clear_input(); ventoy_parse_cmdline(ImageHandle); - ventoy_set_variable(); - ventoy_find_iso_disk(ImageHandle); - if (gLoadIsoEfi) + if (gMemdiskMode) { - ventoy_find_iso_disk_fs(ImageHandle); - ventoy_load_isoefi_driver(ImageHandle); + g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_chain; + g_ramdisk_param.DiskSize = (UINT64)g_iso_buf_size; + + ventoy_save_ramdisk_param(); + + ventoy_install_blockio(ImageHandle, g_iso_buf_size); + Status = ventoy_boot(ImageHandle); + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(300); + } + + ventoy_del_ramdisk_param(); } + else + { + ventoy_set_variable(); + ventoy_find_iso_disk(ImageHandle); - ventoy_debug_pause(); - - ventoy_install_blockio(ImageHandle); + if (gLoadIsoEfi) + { + ventoy_find_iso_disk_fs(ImageHandle); + ventoy_load_isoefi_driver(ImageHandle); + } - ventoy_debug_pause(); + ventoy_debug_pause(); + + ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes); - Status = ventoy_boot(ImageHandle); - if (EFI_NOT_FOUND == Status) - { - gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); - gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); - sleep(300); - } + ventoy_debug_pause(); - ventoy_clean_env(); + Status = ventoy_boot(ImageHandle); + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(300); + } + ventoy_clean_env(); + } + ventoy_clear_input(); gST->ConOut->ClearScreen(gST->ConOut); - - return EFI_SUCCESS; }