summaryrefslogtreecommitdiff
path: root/gpxe/src/image
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/image')
-rw-r--r--gpxe/src/image/efi_image.c108
-rw-r--r--gpxe/src/image/elf.c162
-rw-r--r--gpxe/src/image/embedded.c101
-rw-r--r--gpxe/src/image/script.c126
-rw-r--r--gpxe/src/image/segment.c87
5 files changed, 0 insertions, 584 deletions
diff --git a/gpxe/src/image/efi_image.c b/gpxe/src/image/efi_image.c
deleted file mode 100644
index 60d150a9..00000000
--- a/gpxe/src/image/efi_image.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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 2 of the
- * License, or 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <errno.h>
-#include <gpxe/efi/efi.h>
-#include <gpxe/image.h>
-#include <gpxe/features.h>
-
-FEATURE ( FEATURE_IMAGE, "EFI", DHCP_EB_FEATURE_EFI, 1 );
-
-struct image_type efi_image_type __image_type ( PROBE_NORMAL );
-
-/**
- * Execute EFI image
- *
- * @v image EFI image
- * @ret rc Return status code
- */
-static int efi_image_exec ( struct image *image ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE handle;
- UINTN exit_data_size;
- CHAR16 *exit_data;
- EFI_STATUS efirc;
-
- /* Attempt loading image */
- if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, NULL,
- user_to_virt ( image->data, 0 ),
- image->len, &handle ) ) != 0 ) {
- /* Not an EFI image */
- DBGC ( image, "EFIIMAGE %p could not load: %s\n",
- image, efi_strerror ( efirc ) );
- return -ENOEXEC;
- }
-
- /* Start the image */
- if ( ( efirc = bs->StartImage ( handle, &exit_data_size,
- &exit_data ) ) != 0 ) {
- DBGC ( image, "EFIIMAGE %p returned with status %s\n",
- image, efi_strerror ( efirc ) );
- goto done;
- }
-
- done:
- /* Unload the image. We can't leave it loaded, because we
- * have no "unload" operation.
- */
- bs->UnloadImage ( handle );
-
- return EFIRC_TO_RC ( efirc );
-}
-
-/**
- * Load EFI image into memory
- *
- * @v image EFI file
- * @ret rc Return status code
- */
-static int efi_image_load ( struct image *image ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE handle;
- EFI_STATUS efirc;
-
- /* Attempt loading image */
- if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, NULL,
- user_to_virt ( image->data, 0 ),
- image->len, &handle ) ) != 0 ) {
- /* Not an EFI image */
- DBGC ( image, "EFIIMAGE %p could not load: %s\n",
- image, efi_strerror ( efirc ) );
- return -ENOEXEC;
- }
-
- /* This is an EFI image */
- if ( ! image->type )
- image->type = &efi_image_type;
-
- /* Unload the image. We can't leave it loaded, because we
- * have no "unload" operation.
- */
- bs->UnloadImage ( handle );
-
- return 0;
-}
-
-/** EFI image type */
-struct image_type efi_image_type __image_type ( PROBE_NORMAL ) = {
- .name = "EFI",
- .load = efi_image_load,
- .exec = efi_image_exec,
-};
diff --git a/gpxe/src/image/elf.c b/gpxe/src/image/elf.c
deleted file mode 100644
index a0ec065e..00000000
--- a/gpxe/src/image/elf.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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 2 of the
- * License, or 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-/**
- * @file
- *
- * ELF image format
- *
- * A "pure" ELF image is not a bootable image. There are various
- * bootable formats based upon ELF (e.g. Multiboot), which share
- * common ELF-related functionality.
- */
-
-#include <errno.h>
-#include <elf.h>
-#include <gpxe/uaccess.h>
-#include <gpxe/segment.h>
-#include <gpxe/image.h>
-#include <gpxe/elf.h>
-
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Phdr Elf_Phdr;
-typedef Elf32_Off Elf_Off;
-
-/**
- * Load ELF segment into memory
- *
- * @v image ELF file
- * @v phdr ELF program header
- * @v ehdr ELF executable header
- * @ret rc Return status code
- */
-static int elf_load_segment ( struct image *image, Elf_Phdr *phdr,
- Elf_Ehdr *ehdr ) {
- physaddr_t dest;
- userptr_t buffer;
- unsigned long e_offset;
- int rc;
-
- /* Do nothing for non-PT_LOAD segments */
- if ( phdr->p_type != PT_LOAD )
- return 0;
-
- /* Check segment lies within image */
- if ( ( phdr->p_offset + phdr->p_filesz ) > image->len ) {
- DBGC ( image, "ELF %p segment outside image\n", image );
- return -ENOEXEC;
- }
-
- /* Find start address: use physical address for preference,
- * fall back to virtual address if no physical address
- * supplied.
- */
- dest = phdr->p_paddr;
- if ( ! dest )
- dest = phdr->p_vaddr;
- if ( ! dest ) {
- DBGC ( image, "ELF %p segment loads to physical address 0\n",
- image );
- return -ENOEXEC;
- }
- buffer = phys_to_user ( dest );
-
- DBGC ( image, "ELF %p loading segment [%x,%x) to [%x,%x,%x)\n", image,
- phdr->p_offset, ( phdr->p_offset + phdr->p_filesz ),
- phdr->p_paddr, ( phdr->p_paddr + phdr->p_filesz ),
- ( phdr->p_paddr + phdr->p_memsz ) );
-
- /* Verify and prepare segment */
- if ( ( rc = prep_segment ( buffer, phdr->p_filesz,
- phdr->p_memsz ) ) != 0 ) {
- DBGC ( image, "ELF %p could not prepare segment: %s\n",
- image, strerror ( rc ) );
- return rc;
- }
-
- /* Copy image to segment */
- memcpy_user ( buffer, 0, image->data, phdr->p_offset, phdr->p_filesz );
-
- /* Set execution address, if it lies within this segment */
- if ( ( e_offset = ( ehdr->e_entry - dest ) ) < phdr->p_filesz ) {
- image->priv.phys = ehdr->e_entry;
- DBGC ( image, "ELF %p found physical entry point at %lx\n",
- image, image->priv.phys );
- } else if ( ( e_offset = ( ehdr->e_entry - phdr->p_vaddr ) )
- < phdr->p_filesz ) {
- if ( ! image->priv.phys ) {
- image->priv.phys = ( dest + e_offset );
- DBGC ( image, "ELF %p found virtual entry point at %lx"
- " (virt %lx)\n", image, image->priv.phys,
- ( ( unsigned long ) ehdr->e_entry ) );
- }
- }
-
- return 0;
-}
-
-/**
- * Load ELF image into memory
- *
- * @v image ELF file
- * @ret rc Return status code
- */
-int elf_load ( struct image *image ) {
- Elf_Ehdr ehdr;
- Elf_Phdr phdr;
- Elf_Off phoff;
- unsigned int phnum;
- int rc;
-
- /* Image type must already have been set by caller */
- assert ( image->type != NULL );
-
- /* Read ELF header */
- copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) );
- if ( memcmp ( &ehdr.e_ident[EI_MAG0], ELFMAG, SELFMAG ) != 0 ) {
- DBGC ( image, "ELF %p has invalid signature\n", image );
- return -ENOEXEC;
- }
-
- /* Invalidate execution address */
- image->priv.phys = 0;
-
- /* Read ELF program headers */
- for ( phoff = ehdr.e_phoff , phnum = ehdr.e_phnum ; phnum ;
- phoff += ehdr.e_phentsize, phnum-- ) {
- if ( phoff > image->len ) {
- DBGC ( image, "ELF %p program header %d outside "
- "image\n", image, phnum );
- return -ENOEXEC;
- }
- copy_from_user ( &phdr, image->data, phoff, sizeof ( phdr ) );
- if ( ( rc = elf_load_segment ( image, &phdr, &ehdr ) ) != 0 )
- return rc;
- }
-
- /* Check for a valid execution address */
- if ( ! image->priv.phys ) {
- DBGC ( image, "ELF %p entry point %lx outside image\n",
- image, ( ( unsigned long ) ehdr.e_entry ) );
- return -ENOEXEC;
- }
-
- return 0;
-}
diff --git a/gpxe/src/image/embedded.c b/gpxe/src/image/embedded.c
deleted file mode 100644
index 58a14ea4..00000000
--- a/gpxe/src/image/embedded.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/** @file
- *
- * Embedded image support
- *
- * Embedded images are images built into the gPXE binary and do not require
- * fetching over the network.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <string.h>
-#include <gpxe/image.h>
-#include <gpxe/uaccess.h>
-#include <gpxe/init.h>
-
-/**
- * Free embedded image
- *
- * @v refcnt Reference counter
- */
-static void __attribute__ (( unused ))
-embedded_image_free ( struct refcnt *refcnt __unused ) {
- /* Do nothing */
-}
-
-/* Raw image data for all embedded images */
-#undef EMBED
-#define EMBED( _index, _path, _name ) \
- extern char embedded_image_ ## _index ## _data[]; \
- extern char embedded_image_ ## _index ## _len[]; \
- __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t" \
- "\nembedded_image_" #_index "_data:\n\t" \
- ".incbin \"" _path "\"\n\t" \
- "\nembedded_image_" #_index "_end:\n\t" \
- ".equ embedded_image_" #_index "_len, " \
- "( embedded_image_" #_index "_end - " \
- " embedded_image_" #_index "_data )\n\t" \
- ".previous\n\t" );
-EMBED_ALL
-
-/* Image structures for all embedded images */
-#undef EMBED
-#define EMBED( _index, _path, _name ) { \
- .refcnt = { .free = embedded_image_free, }, \
- .name = _name, \
- .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ), \
- .len = ( size_t ) embedded_image_ ## _index ## _len, \
-},
-static struct image embedded_images[] = {
- EMBED_ALL
-};
-
-/**
- * Register all embedded images
- */
-static void embedded_init ( void ) {
- int i;
- struct image *image;
- void *data;
- int rc;
-
- /* Skip if we have no embedded images */
- if ( ! sizeof ( embedded_images ) )
- return;
-
- /* Fix up data pointers and register images */
- for ( i = 0 ; i < ( int ) ( sizeof ( embedded_images ) /
- sizeof ( embedded_images[0] ) ) ; i++ ) {
- image = &embedded_images[i];
-
- /* virt_to_user() cannot be used in a static
- * initialiser, so we cast the pointer to a userptr_t
- * in the initialiser and fix it up here. (This will
- * actually be a no-op on most platforms.)
- */
- data = ( ( void * ) image->data );
- image->data = virt_to_user ( data );
-
- DBG ( "Embedded image \"%s\": %zd bytes at %p\n",
- image->name, image->len, data );
-
- if ( ( rc = register_image ( image ) ) != 0 ) {
- DBG ( "Could not register embedded image \"%s\": "
- "%s\n", image->name, strerror ( rc ) );
- return;
- }
- }
-
- /* Load the first image */
- image = &embedded_images[0];
- if ( ( rc = image_autoload ( image ) ) != 0 ) {
- DBG ( "Could not load embedded image \"%s\": %s\n",
- image->name, strerror ( rc ) );
- return;
- }
-}
-
-/** Embedded image initialisation function */
-struct init_fn embedded_init_fn __init_fn ( INIT_NORMAL ) = {
- .initialise = embedded_init,
-};
diff --git a/gpxe/src/image/script.c b/gpxe/src/image/script.c
deleted file mode 100644
index 0835ecb5..00000000
--- a/gpxe/src/image/script.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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 2 of the
- * License, or 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-/**
- * @file
- *
- * gPXE scripts
- *
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <gpxe/image.h>
-
-struct image_type script_image_type __image_type ( PROBE_NORMAL );
-
-/**
- * Execute script
- *
- * @v image Script
- * @ret rc Return status code
- */
-static int script_exec ( struct image *image ) {
- size_t offset = 0;
- off_t eol;
- size_t len;
- int rc;
-
- /* Temporarily de-register image, so that a "boot" command
- * doesn't throw us into an execution loop.
- */
- unregister_image ( image );
-
- while ( offset < image->len ) {
-
- /* Find length of next line, excluding any terminating '\n' */
- eol = memchr_user ( image->data, offset, '\n',
- ( image->len - offset ) );
- if ( eol < 0 )
- eol = image->len;
- len = ( eol - offset );
-
- /* Copy line, terminate with NUL, and execute command */
- {
- char cmdbuf[ len + 1 ];
-
- copy_from_user ( cmdbuf, image->data, offset, len );
- cmdbuf[len] = '\0';
- DBG ( "$ %s\n", cmdbuf );
- if ( ( rc = system ( cmdbuf ) ) != 0 ) {
- DBG ( "Command \"%s\" failed: %s\n",
- cmdbuf, strerror ( rc ) );
- goto done;
- }
- }
-
- /* Move to next line */
- offset += ( len + 1 );
- }
-
- rc = 0;
- done:
- /* Re-register image and return */
- register_image ( image );
- return rc;
-}
-
-/**
- * Load script into memory
- *
- * @v image Script
- * @ret rc Return status code
- */
-static int script_load ( struct image *image ) {
- static const char magic[] = "#!gpxe";
- char test[ sizeof ( magic ) - 1 /* NUL */ + 1 /* terminating space */];
-
- /* Sanity check */
- if ( image->len < sizeof ( test ) ) {
- DBG ( "Too short to be a script\n" );
- return -ENOEXEC;
- }
-
- /* Check for magic signature */
- copy_from_user ( test, image->data, 0, sizeof ( test ) );
- if ( ( memcmp ( test, magic, ( sizeof ( test ) - 1 ) ) != 0 ) ||
- ! isspace ( test[ sizeof ( test ) - 1 ] ) ) {
- DBG ( "Invalid magic signature\n" );
- return -ENOEXEC;
- }
-
- /* This is a script */
- image->type = &script_image_type;
-
- /* We don't actually load it anywhere; we will pick the lines
- * out of the image as we need them.
- */
-
- return 0;
-}
-
-/** Script image type */
-struct image_type script_image_type __image_type ( PROBE_NORMAL ) = {
- .name = "script",
- .load = script_load,
- .exec = script_exec,
-};
diff --git a/gpxe/src/image/segment.c b/gpxe/src/image/segment.c
deleted file mode 100644
index e2474536..00000000
--- a/gpxe/src/image/segment.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * 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 2 of the
- * License, or 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-/**
- * @file
- *
- * Executable image segments
- *
- */
-
-#include <errno.h>
-#include <gpxe/uaccess.h>
-#include <gpxe/memmap.h>
-#include <gpxe/errortab.h>
-#include <gpxe/segment.h>
-
-/**
- * Prepare segment for loading
- *
- * @v segment Segment start
- * @v filesz Size of the "allocated bytes" portion of the segment
- * @v memsz Size of the segment
- * @ret rc Return status code
- */
-int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ) {
- struct memory_map memmap;
- physaddr_t start = user_to_phys ( segment, 0 );
- physaddr_t mid = user_to_phys ( segment, filesz );
- physaddr_t end = user_to_phys ( segment, memsz );
- unsigned int i;
-
- DBG ( "Preparing segment [%lx,%lx,%lx)\n", start, mid, end );
-
- /* Sanity check */
- if ( filesz > memsz ) {
- DBG ( "Insane segment [%lx,%lx,%lx)\n", start, mid, end );
- return -EINVAL;
- }
-
- /* Get a fresh memory map. This allows us to automatically
- * avoid treading on any regions that Etherboot is currently
- * editing out of the memory map.
- */
- get_memmap ( &memmap );
-
- /* Look for a suitable memory region */
- for ( i = 0 ; i < memmap.count ; i++ ) {
- if ( ( start >= memmap.regions[i].start ) &&
- ( end <= memmap.regions[i].end ) ) {
- /* Found valid region: zero bss and return */
- memset_user ( segment, filesz, 0, ( memsz - filesz ) );
- return 0;
- }
- }
-
- /* No suitable memory region found */
- DBG ( "Segment [%lx,%lx,%lx) does not fit into available memory\n",
- start, mid, end );
- return -ERANGE;
-}
-
-/**
- * Segment-specific error messages
- *
- * This error happens sufficiently often to merit a user-friendly
- * description.
- */
-struct errortab segment_errors[] __errortab = {
- { ERANGE, "Requested memory not available" },
-};