1. change some directory structure for the build script

2. add build script and document
   see DOC/BuildVentoyFromSource.txt for detail
This commit is contained in:
longpanda
2020-05-20 22:36:27 +08:00
parent 965417970b
commit 2aae096c2a
97 changed files with 6298 additions and 67 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
/******************************************************************************
* Ventoy.h
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __VENTOY_H__
#define __VENTOY_H__
#define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1]
#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }}
#pragma pack(1)
typedef struct ventoy_guid
{
UINT32 data1;
UINT16 data2;
UINT16 data3;
UINT8 data4[8];
}ventoy_guid;
typedef struct ventoy_image_disk_region
{
UINT32 image_sector_count; /* image sectors contained in this region */
UINT32 image_start_sector; /* image sector start */
UINT64 disk_start_sector; /* disk sector start */
}ventoy_image_disk_region;
typedef struct ventoy_image_location
{
ventoy_guid guid;
/* image sector size, currently this value is always 2048 */
UINT32 image_sector_size;
/* disk sector size, normally the value is 512 */
UINT32 disk_sector_size;
UINT32 region_count;
/*
* disk region data
* If the image file has more than one fragments in disk,
* there will be more than one region data here.
*
*/
ventoy_image_disk_region regions[1];
/* ventoy_image_disk_region regions[2~region_count-1] */
}ventoy_image_location;
typedef struct ventoy_os_param
{
ventoy_guid guid; // VENTOY_GUID
UINT8 chksum; // checksum
UINT8 vtoy_disk_guid[16];
UINT64 vtoy_disk_size; // disk size in bytes
UINT16 vtoy_disk_part_id; // begin with 1
UINT16 vtoy_disk_part_type; // 0:exfat 1:ntfs other: reserved
char vtoy_img_path[384]; // It seems to be enough, utf-8 format
UINT64 vtoy_img_size; // image file size in bytes
/*
* Ventoy will write a copy of ventoy_image_location data into runtime memory
* this is the physically address and length of that memory.
* Address 0 means no such data exist.
* Address will be aligned by 4KB.
*
*/
UINT64 vtoy_img_location_addr;
UINT32 vtoy_img_location_len;
UINT64 vtoy_reserved[4]; // Internal use by ventoy
UINT8 reserved[31];
}ventoy_os_param;
#pragma pack()
// compile assert to check that size of ventoy_os_param must be 512
COMPILE_ASSERT(sizeof(ventoy_os_param) == 512);
#pragma pack(4)
typedef struct ventoy_chain_head
{
ventoy_os_param os_param;
UINT32 disk_drive;
UINT32 drive_map;
UINT32 disk_sector_size;
UINT64 real_img_size_in_bytes;
UINT64 virt_img_size_in_bytes;
UINT32 boot_catalog;
UINT8 boot_catalog_sector[2048];
UINT32 img_chunk_offset;
UINT32 img_chunk_num;
UINT32 override_chunk_offset;
UINT32 override_chunk_num;
UINT32 virt_chunk_offset;
UINT32 virt_chunk_num;
}ventoy_chain_head;
typedef struct ventoy_img_chunk
{
UINT32 img_start_sector; //2KB
UINT32 img_end_sector;
UINT64 disk_start_sector; // in disk_sector_size
UINT64 disk_end_sector;
}ventoy_img_chunk;
typedef struct ventoy_override_chunk
{
UINT64 img_offset;
UINT32 override_size;
UINT8 override_data[512];
}ventoy_override_chunk;
typedef struct ventoy_virt_chunk
{
UINT32 mem_sector_start;
UINT32 mem_sector_end;
UINT32 mem_sector_offset;
UINT32 remap_sector_start;
UINT32 remap_sector_end;
UINT32 org_sector_start;
}ventoy_virt_chunk;
#pragma pack()
#define VTOY_BLOCK_DEVICE_PATH_GUID \
{ 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }}
#define VTOY_BLOCK_DEVICE_PATH_NAME L"ventoy"
#if defined (MDE_CPU_IA32)
#define VENTOY_UEFI_DESC L"IA32 UEFI"
#elif defined (MDE_CPU_X64)
#define VENTOY_UEFI_DESC L"X64 UEFI"
#elif defined (MDE_CPU_EBC)
#elif defined (MDE_CPU_ARM)
#define VENTOY_UEFI_DESC L"ARM UEFI"
#elif defined (MDE_CPU_AARCH64)
#define VENTOY_UEFI_DESC L"ARM64 UEFI"
#else
#error Unknown Processor Type
#endif
typedef struct ventoy_sector_flag
{
UINT8 flag; // 0:init 1:mem 2:remap
UINT64 remap_lba;
}ventoy_sector_flag;
typedef struct vtoy_block_data
{
EFI_HANDLE Handle;
EFI_BLOCK_IO_MEDIA Media; /* Media descriptor */
EFI_BLOCK_IO_PROTOCOL BlockIo; /* Block I/O protocol */
UINTN DevicePathCompareLen;
EFI_DEVICE_PATH_PROTOCOL *Path; /* Device path protocol */
EFI_HANDLE RawBlockIoHandle;
EFI_BLOCK_IO_PROTOCOL *pRawBlockIo;
EFI_DEVICE_PATH_PROTOCOL *pDiskDevPath;
/* ventoy disk part2 ESP */
EFI_HANDLE DiskFsHandle;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs;
EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath;
EFI_HANDLE IsoDriverImage;
}vtoy_block_data;
#define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi"
#define debug(expr, ...) if (gDebugPrint) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
#define trace(expr, ...) VtoyDebug("[VTOY] "expr"\r\n", ##__VA_ARGS__)
#define sleep(sec) gBS->Stall(1000000 * (sec))
#define ventoy_debug_pause() \
if (gDebugPrint) \
{ \
UINTN __Index = 0; \
gST->ConOut->OutputString(gST->ConOut, L"[VTOY] ###### Press Enter to continue... ######\r\n");\
gST->ConIn->Reset(gST->ConIn, FALSE); \
gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\
}
typedef const char * (*grub_env_get_pf)(const char *name);
#pragma pack(1)
#define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF
typedef struct ventoy_efi_file_replace
{
UINT64 BlockIoSectorStart;
UINT64 CurPos;
UINT64 FileSizeBytes;
EFI_FILE_PROTOCOL WrapperHandle;
}ventoy_efi_file_replace;
typedef struct ventoy_grub_param_file_replace
{
UINT32 magic;
char old_file_name[4][256];
UINT32 old_file_cnt;
UINT32 new_file_virtual_id;
}ventoy_grub_param_file_replace;
typedef struct ventoy_grub_param
{
grub_env_get_pf grub_env_get;
ventoy_grub_param_file_replace file_replace;
}ventoy_grub_param;
typedef struct ventoy_ram_disk
{
UINT64 PhyAddr;
UINT64 DiskSize;
}ventoy_ram_disk;
#pragma pack()
typedef struct well_known_guid
{
EFI_GUID *guid;
const char *name;
}well_known_guid;
typedef struct ventoy_system_wrapper
{
EFI_LOCATE_PROTOCOL NewLocateProtocol;
EFI_LOCATE_PROTOCOL OriLocateProtocol;
EFI_HANDLE_PROTOCOL NewHandleProtocol;
EFI_HANDLE_PROTOCOL OriHandleProtocol;
EFI_OPEN_PROTOCOL NewOpenProtocol;
EFI_OPEN_PROTOCOL OriOpenProtocol;
} ventoy_system_wrapper;
#define ventoy_wrapper(bs, wrapper, func, newfunc) \
{\
wrapper.Ori##func = bs->func;\
wrapper.New##func = newfunc;\
bs->func = wrapper.New##func;\
}
extern ventoy_efi_file_replace g_efi_file_replace;
extern BOOLEAN gDebugPrint;
VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...);
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID);
EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File);
EFI_STATUS EFIAPI ventoy_block_io_read
(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
#endif

View File

@@ -0,0 +1,80 @@
#************************************************************************************
# Copyright (c) 2020, longpanda <admin@ventoy.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
#************************************************************************************
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = Ventoy
FILE_GUID = 1c3a0915-09dc-49c2-873d-0aaaa7733299
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = VentoyEfiMain
[Sources]
Ventoy.h
Ventoy.c
VentoyDebug.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ShellPkg/ShellPkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
DebugLib
[Guids]
gShellVariableGuid
gEfiVirtualCdGuid
gEfiFileInfoGuid
[Protocols]
gEfiLoadedImageProtocolGuid
gEfiBlockIoProtocolGuid
gEfiDevicePathProtocolGuid
gEfiSimpleFileSystemProtocolGuid
gEfiRamDiskProtocolGuid
gEfiAbsolutePointerProtocolGuid
gEfiAcpiTableProtocolGuid
gEfiBlockIo2ProtocolGuid
gEfiBusSpecificDriverOverrideProtocolGuid
gEfiComponentNameProtocolGuid
gEfiComponentName2ProtocolGuid
gEfiDriverBindingProtocolGuid
gEfiDiskIoProtocolGuid
gEfiDiskIo2ProtocolGuid
gEfiGraphicsOutputProtocolGuid
gEfiHiiConfigAccessProtocolGuid
gEfiHiiFontProtocolGuid
gEfiLoadFileProtocolGuid
gEfiLoadFile2ProtocolGuid
gEfiLoadedImageProtocolGuid
gEfiLoadedImageDevicePathProtocolGuid
gEfiPciIoProtocolGuid
gEfiSerialIoProtocolGuid
gEfiSimpleTextInProtocolGuid
gEfiSimpleTextInputExProtocolGuid
gEfiSimpleTextOutProtocolGuid

View File

@@ -0,0 +1,325 @@
/******************************************************************************
* Ventoy.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Protocol/LoadedImage.h>
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Protocol/BlockIo.h>
#include <Protocol/RamDisk.h>
#include <Protocol/SimpleFileSystem.h>
#include <Ventoy.h>
STATIC ventoy_system_wrapper g_system_wrapper;
static struct well_known_guid g_efi_well_known_guids[] =
{
{ &gEfiAbsolutePointerProtocolGuid, "AbsolutePointer" },
{ &gEfiAcpiTableProtocolGuid, "AcpiTable" },
{ &gEfiBlockIoProtocolGuid, "BlockIo" },
{ &gEfiBlockIo2ProtocolGuid, "BlockIo2" },
{ &gEfiBusSpecificDriverOverrideProtocolGuid, "BusSpecificDriverOverride" },
{ &gEfiComponentNameProtocolGuid, "ComponentName" },
{ &gEfiComponentName2ProtocolGuid, "ComponentName2" },
{ &gEfiDevicePathProtocolGuid, "DevicePath" },
{ &gEfiDriverBindingProtocolGuid, "DriverBinding" },
{ &gEfiDiskIoProtocolGuid, "DiskIo" },
{ &gEfiDiskIo2ProtocolGuid, "DiskIo2" },
{ &gEfiGraphicsOutputProtocolGuid, "GraphicsOutput" },
{ &gEfiHiiConfigAccessProtocolGuid, "HiiConfigAccess" },
{ &gEfiHiiFontProtocolGuid, "HiiFont" },
{ &gEfiLoadFileProtocolGuid, "LoadFile" },
{ &gEfiLoadFile2ProtocolGuid, "LoadFile2" },
{ &gEfiLoadedImageProtocolGuid, "LoadedImage" },
{ &gEfiLoadedImageDevicePathProtocolGuid, "LoadedImageDevicePath"},
{ &gEfiPciIoProtocolGuid, "PciIo" },
{ &gEfiSerialIoProtocolGuid, "SerialIo" },
{ &gEfiSimpleFileSystemProtocolGuid, "SimpleFileSystem" },
{ &gEfiSimpleTextInProtocolGuid, "SimpleTextInput" },
{ &gEfiSimpleTextInputExProtocolGuid, "SimpleTextInputEx" },
{ &gEfiSimpleTextOutProtocolGuid, "SimpleTextOutput" },
};
STATIC CHAR8 gEfiGuidName[128];
static const char * ventoy_get_guid_name(EFI_GUID *guid)
{
UINTN i;
for (i = 0; i < ARRAY_SIZE(g_efi_well_known_guids); i++)
{
if (CompareGuid(g_efi_well_known_guids[i].guid, guid))
{
return g_efi_well_known_guids[i].name;
}
}
AsciiSPrint(gEfiGuidName, sizeof(gEfiGuidName), "%g", guid);
return gEfiGuidName;
}
EFI_STATUS EFIAPI
ventoy_wrapper_fs_open(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes)
{
(VOID)This;
(VOID)New;
(VOID)Name;
(VOID)Mode;
(VOID)Attributes;
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_open_ex(EFI_FILE_HANDLE This, EFI_FILE_HANDLE *New, CHAR16 *Name, UINT64 Mode, UINT64 Attributes, EFI_FILE_IO_TOKEN *Token)
{
return ventoy_wrapper_fs_open(This, New, Name, Mode, Attributes);
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_delete(EFI_FILE_HANDLE This)
{
(VOID)This;
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_set_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN Len, VOID *Data)
{
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_flush(EFI_FILE_HANDLE This)
{
(VOID)This;
return EFI_SUCCESS;
}
/* Ex version */
EFI_STATUS EFIAPI
ventoy_wrapper_file_flush_ex(EFI_FILE_HANDLE This, EFI_FILE_IO_TOKEN *Token)
{
(VOID)This;
(VOID)Token;
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_write(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
{
(VOID)This;
(VOID)Len;
(VOID)Data;
return EFI_WRITE_PROTECTED;
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_write_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token)
{
return ventoy_wrapper_file_write(This, &(Token->BufferSize), Token->Buffer);
}
static EFI_STATUS EFIAPI
ventoy_wrapper_file_close(EFI_FILE_HANDLE This)
{
(VOID)This;
return EFI_SUCCESS;
}
static EFI_STATUS EFIAPI
ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position)
{
(VOID)This;
g_efi_file_replace.CurPos = Position;
return EFI_SUCCESS;
}
static EFI_STATUS EFIAPI
ventoy_wrapper_file_get_pos(EFI_FILE_HANDLE This, UINT64 *Position)
{
(VOID)This;
*Position = g_efi_file_replace.CurPos;
return EFI_SUCCESS;
}
static EFI_STATUS EFIAPI
ventoy_wrapper_file_get_info(EFI_FILE_HANDLE This, EFI_GUID *Type, UINTN *Len, VOID *Data)
{
EFI_FILE_INFO *Info = (EFI_FILE_INFO *) Data;
debug("ventoy_wrapper_file_get_info ... %u", *Len);
if (!CompareGuid(Type, &gEfiFileInfoGuid))
{
return EFI_INVALID_PARAMETER;
}
if (*Len == 0)
{
*Len = 384;
return EFI_BUFFER_TOO_SMALL;
}
ZeroMem(Data, sizeof(EFI_FILE_INFO));
Info->Size = sizeof(EFI_FILE_INFO);
Info->FileSize = g_efi_file_replace.FileSizeBytes;
Info->PhysicalSize = g_efi_file_replace.FileSizeBytes;
Info->Attribute = EFI_FILE_READ_ONLY;
//Info->FileName = EFI_FILE_READ_ONLY;
*Len = Info->Size;
return EFI_SUCCESS;
}
static EFI_STATUS EFIAPI
ventoy_wrapper_file_read(EFI_FILE_HANDLE This, UINTN *Len, VOID *Data)
{
EFI_LBA Lba;
UINTN ReadLen = *Len;
(VOID)This;
debug("ventoy_wrapper_file_read ... %u", *Len);
if (g_efi_file_replace.CurPos + ReadLen > g_efi_file_replace.FileSizeBytes)
{
ReadLen = g_efi_file_replace.FileSizeBytes - g_efi_file_replace.CurPos;
}
Lba = g_efi_file_replace.CurPos / 2048 + g_efi_file_replace.BlockIoSectorStart;
ventoy_block_io_read(NULL, 0, Lba, ReadLen, Data);
*Len = ReadLen;
g_efi_file_replace.CurPos += ReadLen;
return EFI_SUCCESS;
}
EFI_STATUS EFIAPI
ventoy_wrapper_file_read_ex(IN EFI_FILE_PROTOCOL *This, IN OUT EFI_FILE_IO_TOKEN *Token)
{
return ventoy_wrapper_file_read(This, &(Token->BufferSize), Token->Buffer);
}
EFI_STATUS EFIAPI ventoy_wrapper_file_procotol(EFI_FILE_PROTOCOL *File)
{
File->Revision = EFI_FILE_PROTOCOL_REVISION2;
File->Open = ventoy_wrapper_fs_open;
File->Close = ventoy_wrapper_file_close;
File->Delete = ventoy_wrapper_file_delete;
File->Read = ventoy_wrapper_file_read;
File->Write = ventoy_wrapper_file_write;
File->GetPosition = ventoy_wrapper_file_get_pos;
File->SetPosition = ventoy_wrapper_file_set_pos;
File->GetInfo = ventoy_wrapper_file_get_info;
File->SetInfo = ventoy_wrapper_file_set_info;
File->Flush = ventoy_wrapper_file_flush;
File->OpenEx = ventoy_wrapper_file_open_ex;
File->ReadEx = ventoy_wrapper_file_read_ex;
File->WriteEx = ventoy_wrapper_file_write_ex;
File->FlushEx = ventoy_wrapper_file_flush_ex;
return EFI_SUCCESS;
}
STATIC EFI_STATUS EFIAPI ventoy_handle_protocol
(
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT VOID **Interface
)
{
EFI_STATUS Status = EFI_SUCCESS;
debug("ventoy_handle_protocol:%a", ventoy_get_guid_name(Protocol));
Status = g_system_wrapper.OriHandleProtocol(Handle, Protocol, Interface);
if (CompareGuid(Protocol, &gEfiSimpleFileSystemProtocolGuid))
{
EFI_FILE_PROTOCOL *FileProtocol = NULL;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = *((EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **)(Interface));
pFile->OpenVolume(pFile, &FileProtocol);
debug("Handle FS Protocol: %p OpenVolume:%p, FileProtocol:%p, Open:%p",
pFile, pFile->OpenVolume, FileProtocol, FileProtocol->Open);
sleep(3);
}
return Status;
}
STATIC EFI_STATUS EFIAPI ventoy_open_protocol
(
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol,
OUT VOID **Interface, OPTIONAL
IN EFI_HANDLE AgentHandle,
IN EFI_HANDLE ControllerHandle,
IN UINT32 Attributes
)
{
debug("ventoy_open_protocol:%a", ventoy_get_guid_name(Protocol));
return g_system_wrapper.OriOpenProtocol(Handle, Protocol, Interface, AgentHandle, ControllerHandle, Attributes);
}
STATIC EFI_STATUS EFIAPI ventoy_locate_protocol
(
IN EFI_GUID *Protocol,
IN VOID *Registration, OPTIONAL
OUT VOID **Interface
)
{
debug("ventoy_locate_protocol:%a", ventoy_get_guid_name(Protocol));
return g_system_wrapper.OriLocateProtocol(Protocol, Registration, Interface);
}
EFI_STATUS EFIAPI ventoy_wrapper_system(VOID)
{
ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol);
ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol);
ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol);
return EFI_SUCCESS;
}