/
niceSOFT
/
systemd
Обзор
Документация
Войти
/
niceSOFT
/
systemd
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
v260
src/boot/initrd.c
135 строк
5 KB
Mike Yuan
boot/initrd: fix typo
15 янв 2026, 13:36
Не верифицирован
15 янв 2026, 13:36
1d69e36
Код
Авторство
О чём код?
/* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "initrd.h" #include "iovec-util-fundamental.h" #include "proto/device-path.h" #include "proto/load-file.h" #include "util.h" #define LINUX_INITRD_MEDIA_GUID \ GUID_DEF(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68) /* extend LoadFileProtocol */ struct initrd_loader { EFI_LOAD_FILE_PROTOCOL load_file; struct iovec data; }; /* static structure for LINUX_INITRD_MEDIA device path see https://github.com/torvalds/linux/blob/v5.13/drivers/firmware/efi/libstub/efi-stub-helper.c */ static const struct { VENDOR_DEVICE_PATH vendor; EFI_DEVICE_PATH end; } _packed_ efi_initrd_device_path = { .vendor = { .Header = { .Type = MEDIA_DEVICE_PATH, .SubType = MEDIA_VENDOR_DP, .Length = sizeof(efi_initrd_device_path.vendor), }, .Guid = LINUX_INITRD_MEDIA_GUID }, .end = { .Type = END_DEVICE_PATH_TYPE, .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE, .Length = sizeof(efi_initrd_device_path.end), } }; static EFIAPI EFI_STATUS initrd_load_file( EFI_LOAD_FILE_PROTOCOL *this, EFI_DEVICE_PATH *file_path, bool boot_policy, size_t *buffer_size, void *buffer) { struct initrd_loader *loader; if (!this || !buffer_size || !file_path) return EFI_INVALID_PARAMETER; if (boot_policy) return EFI_UNSUPPORTED; loader = (struct initrd_loader *) this; if (!iovec_is_set(&loader->data)) return EFI_NOT_FOUND; if (!buffer || *buffer_size < loader->data.iov_len) { *buffer_size = loader->data.iov_len; return EFI_BUFFER_TOO_SMALL; } memcpy(buffer, loader->data.iov_base, loader->data.iov_len); *buffer_size = loader->data.iov_len; return EFI_SUCCESS; } EFI_STATUS initrd_register( const struct iovec *initrd, EFI_HANDLE *ret_initrd_handle) { EFI_STATUS err; EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) &efi_initrd_device_path; EFI_HANDLE handle; struct initrd_loader *loader; assert(ret_initrd_handle); /* If no initrd is specified we'll not install any. This avoids registration of the protocol for that * case, leaving it open for something else. */ if (!iovec_is_set(initrd)) return EFI_SUCCESS; /* check if a LINUX_INITRD_MEDIA_GUID DevicePath is already registered. LocateDevicePath checks for the "closest DevicePath" and returns its handle, where as InstallMultipleProtocolInterfaces only matches identical DevicePaths. */ err = BS->LocateDevicePath(MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), &dp, &handle); if (err != EFI_NOT_FOUND) /* InitrdMedia is already registered */ return EFI_ALREADY_STARTED; loader = xnew(struct initrd_loader, 1); *loader = (struct initrd_loader) { .load_file.LoadFile = initrd_load_file, .data = *initrd, }; /* create a new handle and register the LoadFile2 protocol with the InitrdMediaPath on it */ err = BS->InstallMultipleProtocolInterfaces( ret_initrd_handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), &efi_initrd_device_path, MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), loader, NULL); if (err != EFI_SUCCESS) free(loader); return err; } EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle) { EFI_STATUS err; struct initrd_loader *loader; if (!initrd_handle) return EFI_SUCCESS; /* get the LoadFile2 protocol that we allocated earlier */ err = BS->HandleProtocol(initrd_handle, MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), (void **) &loader); if (err != EFI_SUCCESS) return err; /* uninstall all protocols thus destroying the handle */ err = BS->UninstallMultipleProtocolInterfaces( initrd_handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), &efi_initrd_device_path, MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), loader, NULL); if (err != EFI_SUCCESS) return err; initrd_handle = NULL; free(loader); return EFI_SUCCESS; }