mirror of https://github.com/ipxe/ipxe.git
[efi] Provide an "initrd.magic" file for use by UEFI kernels
Provide a file "initrd.magic" via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL that contains the initrd file as constructed for BIOS bzImage kernels (including injected files with CPIO headers constructed by iPXE). This allows BIOS and UEFI kernels to obtain the exact same initramfs image, by adding "initrd=initrd.magic" to the kernel command line. For example: #!ipxe kernel boot/vmlinuz initrd=initrd.magic initrd boot/initrd.img initrd boot/modules/e1000.ko /lib/modules/e1000.ko initrd boot/modules/af_packet.ko /lib/modules/af_packet.ko boot Do not include the "initrd.magic" file within the root directory listing, since doing so would break software such as wimboot that processes all files within the root directory. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/373/head
parent
ef9953b712
commit
e5f0255173
|
@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <errno.h>
|
||||
#include <wchar.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/cpio.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
|
||||
#include <ipxe/efi/Protocol/BlockIo.h>
|
||||
|
@ -84,6 +85,7 @@ struct efi_file {
|
|||
};
|
||||
|
||||
static struct efi_file efi_file_root;
|
||||
static struct efi_file efi_file_initrd;
|
||||
|
||||
/**
|
||||
* Free EFI file
|
||||
|
@ -209,6 +211,67 @@ static size_t efi_file_read_image ( struct efi_file_reader *reader ) {
|
|||
return efi_file_read_chunk ( reader, image->data, image->len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from magic initrd file
|
||||
*
|
||||
* @v reader EFI file reader
|
||||
* @ret len Length read
|
||||
*/
|
||||
static size_t efi_file_read_initrd ( struct efi_file_reader *reader ) {
|
||||
struct efi_file *file = reader->file;
|
||||
struct cpio_header cpio;
|
||||
struct image *image;
|
||||
const char *name;
|
||||
size_t pad_len;
|
||||
size_t cpio_len;
|
||||
size_t name_len;
|
||||
size_t len;
|
||||
|
||||
/* Read from file */
|
||||
len = 0;
|
||||
for_each_image ( image ) {
|
||||
|
||||
/* Ignore currently executing image */
|
||||
if ( image == current_image )
|
||||
continue;
|
||||
|
||||
/* Pad to alignment boundary */
|
||||
pad_len = ( ( -reader->pos ) & ( INITRD_ALIGN - 1 ) );
|
||||
if ( pad_len ) {
|
||||
DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) pad\n",
|
||||
efi_file_name ( file ), reader->pos,
|
||||
( reader->pos + pad_len ) );
|
||||
}
|
||||
len += efi_file_read_chunk ( reader, UNULL, pad_len );
|
||||
|
||||
/* Read CPIO header, if applicable */
|
||||
cpio_len = cpio_header ( image, &cpio );
|
||||
if ( cpio_len ) {
|
||||
name = cpio_name ( image );
|
||||
name_len = cpio_name_len ( image );
|
||||
pad_len = ( cpio_len - sizeof ( cpio ) - name_len );
|
||||
DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s header\n",
|
||||
efi_file_name ( file ), reader->pos,
|
||||
( reader->pos + cpio_len ), image->name );
|
||||
len += efi_file_read_chunk ( reader,
|
||||
virt_to_user ( &cpio ),
|
||||
sizeof ( cpio ) );
|
||||
len += efi_file_read_chunk ( reader,
|
||||
virt_to_user ( name ),
|
||||
name_len );
|
||||
len += efi_file_read_chunk ( reader, UNULL, pad_len );
|
||||
}
|
||||
|
||||
/* Read file data */
|
||||
DBGC ( file, "EFIFILE %s [%#08zx,%#08zx) %s\n",
|
||||
efi_file_name ( file ), reader->pos,
|
||||
( reader->pos + image->len ), image->name );
|
||||
len += efi_file_read_chunk ( reader, image->data, image->len );
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open fixed file
|
||||
*
|
||||
|
@ -289,6 +352,10 @@ efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
|
|||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
/* Allow magic initrd to be opened */
|
||||
if ( strcasecmp ( name, efi_file_initrd.name ) == 0 )
|
||||
return efi_file_open_fixed ( &efi_file_initrd, new );
|
||||
|
||||
/* Identify image */
|
||||
image = efi_file_find ( name );
|
||||
if ( ! image ) {
|
||||
|
@ -637,6 +704,27 @@ static struct efi_file efi_file_root = {
|
|||
.name = "",
|
||||
};
|
||||
|
||||
/** Magic initrd file */
|
||||
static struct efi_file efi_file_initrd = {
|
||||
.refcnt = REF_INIT ( ref_no_free ),
|
||||
.file = {
|
||||
.Revision = EFI_FILE_PROTOCOL_REVISION,
|
||||
.Open = efi_file_open,
|
||||
.Close = efi_file_close,
|
||||
.Delete = efi_file_delete,
|
||||
.Read = efi_file_read,
|
||||
.Write = efi_file_write,
|
||||
.GetPosition = efi_file_get_position,
|
||||
.SetPosition = efi_file_set_position,
|
||||
.GetInfo = efi_file_get_info,
|
||||
.SetInfo = efi_file_set_info,
|
||||
.Flush = efi_file_flush,
|
||||
},
|
||||
.image = NULL,
|
||||
.name = "initrd.magic",
|
||||
.read = efi_file_read_initrd,
|
||||
};
|
||||
|
||||
/**
|
||||
* Open root directory
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue