summaryrefslogtreecommitdiffstats
path: root/src/image
diff options
context:
space:
mode:
authorMichael Brown2011-03-07 01:37:50 +0100
committerMichael Brown2011-03-07 01:37:50 +0100
commit34b6ecb2f1d7940a0065cbabd6f9dcd439b4c841 (patch)
treeea583bf6fde26b2ed12ee3c6b117055e555555d9 /src/image
parent[spi] Reset device on each access (diff)
downloadipxe-34b6ecb2f1d7940a0065cbabd6f9dcd439b4c841.tar.gz
ipxe-34b6ecb2f1d7940a0065cbabd6f9dcd439b4c841.tar.xz
ipxe-34b6ecb2f1d7940a0065cbabd6f9dcd439b4c841.zip
[image] Simplify image management
Refactor the {load,exec} image operations as {probe,exec}. This makes the probe mechanism cleaner, eliminates some forward declarations, avoids holding magic state in image->priv, eliminates the possibility of screwing up between the "load" and "exec" stages, and makes the documentation simpler since the concept of "loading" (as distinct from "executing") no longer needs to be explained. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/image')
-rw-r--r--src/image/efi_image.c12
-rw-r--r--src/image/elf.c29
-rw-r--r--src/image/embedded.c6
-rw-r--r--src/image/script.c15
4 files changed, 24 insertions, 38 deletions
diff --git a/src/image/efi_image.c b/src/image/efi_image.c
index bf2e6f4a..ac54fdf6 100644
--- a/src/image/efi_image.c
+++ b/src/image/efi_image.c
@@ -26,8 +26,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
FEATURE ( FEATURE_IMAGE, "EFI", DHCP_EB_FEATURE_EFI, 1 );
-struct image_type efi_image_type __image_type ( PROBE_NORMAL );
-
/** Event used to signal shutdown */
static EFI_EVENT efi_shutdown_event;
@@ -99,12 +97,12 @@ done:
}
/**
- * Load EFI image into memory
+ * Probe EFI image
*
* @v image EFI file
* @ret rc Return status code
*/
-static int efi_image_load ( struct image *image ) {
+static int efi_image_probe ( struct image *image ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_HANDLE handle;
EFI_STATUS efirc;
@@ -119,10 +117,6 @@ static int efi_image_load ( struct image *image ) {
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.
*/
@@ -134,6 +128,6 @@ static int efi_image_load ( struct image *image ) {
/** EFI image type */
struct image_type efi_image_type __image_type ( PROBE_NORMAL ) = {
.name = "EFI",
- .load = efi_image_load,
+ .probe = efi_image_probe,
.exec = efi_image_exec,
};
diff --git a/src/image/elf.c b/src/image/elf.c
index 740fd3ac..406a8d47 100644
--- a/src/image/elf.c
+++ b/src/image/elf.c
@@ -45,10 +45,11 @@ typedef Elf32_Off Elf_Off;
* @v image ELF file
* @v phdr ELF program header
* @v ehdr ELF executable header
+ * @ret entry Entry point, if found
* @ret rc Return status code
*/
static int elf_load_segment ( struct image *image, Elf_Phdr *phdr,
- Elf_Ehdr *ehdr ) {
+ Elf_Ehdr *ehdr, physaddr_t *entry ) {
physaddr_t dest;
userptr_t buffer;
unsigned long e_offset;
@@ -96,15 +97,15 @@ static int elf_load_segment ( struct image *image, Elf_Phdr *phdr,
/* 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;
+ *entry = ehdr->e_entry;
DBGC ( image, "ELF %p found physical entry point at %lx\n",
- image, image->priv.phys );
+ image, *entry );
} else if ( ( e_offset = ( ehdr->e_entry - phdr->p_vaddr ) )
< phdr->p_filesz ) {
- if ( ! image->priv.phys ) {
- image->priv.phys = ( dest + e_offset );
+ if ( ! *entry ) {
+ *entry = ( dest + e_offset );
DBGC ( image, "ELF %p found virtual entry point at %lx"
- " (virt %lx)\n", image, image->priv.phys,
+ " (virt %lx)\n", image, *entry,
( ( unsigned long ) ehdr->e_entry ) );
}
}
@@ -116,18 +117,16 @@ static int elf_load_segment ( struct image *image, Elf_Phdr *phdr,
* Load ELF image into memory
*
* @v image ELF file
+ * @ret entry Entry point
* @ret rc Return status code
*/
-int elf_load ( struct image *image ) {
+int elf_load ( struct image *image, physaddr_t *entry ) {
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 ) {
@@ -135,8 +134,8 @@ int elf_load ( struct image *image ) {
return -ENOEXEC;
}
- /* Invalidate execution address */
- image->priv.phys = 0;
+ /* Invalidate entry point */
+ *entry = 0;
/* Read ELF program headers */
for ( phoff = ehdr.e_phoff , phnum = ehdr.e_phnum ; phnum ;
@@ -147,12 +146,14 @@ int elf_load ( struct image *image ) {
return -ENOEXEC;
}
copy_from_user ( &phdr, image->data, phoff, sizeof ( phdr ) );
- if ( ( rc = elf_load_segment ( image, &phdr, &ehdr ) ) != 0 )
+ if ( ( rc = elf_load_segment ( image, &phdr, &ehdr,
+ entry ) ) != 0 ) {
return rc;
+ }
}
/* Check for a valid execution address */
- if ( ! image->priv.phys ) {
+ if ( ! *entry ) {
DBGC ( image, "ELF %p entry point %lx outside image\n",
image, ( ( unsigned long ) ehdr.e_entry ) );
return -ENOEXEC;
diff --git a/src/image/embedded.c b/src/image/embedded.c
index 53d601a6..2ddccfed 100644
--- a/src/image/embedded.c
+++ b/src/image/embedded.c
@@ -76,10 +76,10 @@ static void embedded_init ( void ) {
}
}
- /* Load the first image */
+ /* Select the first image */
image = &embedded_images[0];
- if ( ( rc = image_autoload ( image ) ) != 0 ) {
- DBG ( "Could not load embedded image \"%s\": %s\n",
+ if ( ( rc = image_select ( image ) ) != 0 ) {
+ DBG ( "Could not select embedded image \"%s\": %s\n",
image->name, strerror ( rc ) );
return;
}
diff --git a/src/image/script.c b/src/image/script.c
index b05abf94..3344c679 100644
--- a/src/image/script.c
+++ b/src/image/script.c
@@ -36,8 +36,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/image.h>
#include <ipxe/shell.h>
-struct image_type script_image_type __image_type ( PROBE_NORMAL );
-
/** Currently running script
*
* This is a global in order to allow goto_exec() to update the
@@ -165,12 +163,12 @@ static int script_exec ( struct image *image ) {
}
/**
- * Load script into memory
+ * Probe script image
*
* @v image Script
* @ret rc Return status code
*/
-static int script_load ( struct image *image ) {
+static int script_probe ( struct image *image ) {
static const char ipxe_magic[] = "#!ipxe";
static const char gpxe_magic[] = "#!gpxe";
linker_assert ( sizeof ( ipxe_magic ) == sizeof ( gpxe_magic ),
@@ -193,20 +191,13 @@ static int script_load ( struct image *image ) {
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,
+ .probe = script_probe,
.exec = script_exec,
};