iPXE
Functions
elfboot.c File Reference

ELF bootable image. More...

#include <errno.h>
#include <elf.h>
#include <ipxe/image.h>
#include <ipxe/elf.h>
#include <ipxe/features.h>
#include <ipxe/init.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FEATURE (FEATURE_IMAGE,"ELF", DHCP_EB_FEATURE_ELF, 1)
static int elfboot_exec (struct image *image)
 Execute ELF image.
static int elfboot_check_segment (struct image *image, Elf_Phdr *phdr, physaddr_t dest)
 Check that ELF segment uses flat physical addressing.
static int elfboot_probe (struct image *image)
 Probe ELF image.
struct image_type
elfboot_image_type 
__image_type (PROBE_NORMAL)
 ELF image type.

Detailed Description

ELF bootable image.

Definition in file elfboot.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
FEATURE ( FEATURE_IMAGE  ,
"ELF"  ,
DHCP_EB_FEATURE_ELF  ,
 
)
static int elfboot_exec ( struct image image) [static]

Execute ELF image.

Parameters:
imageELF image
Return values:
rcReturn status code

Definition at line 48 of file elfboot.c.

References __asm__(), DBGC, ECANCELED, elf_load(), entry, max, PHYS_CODE, rc, shutdown_boot(), and strerror().

                                                {
        physaddr_t entry;
        physaddr_t max;
        int rc;

        /* Load the image using core ELF support */
        if ( ( rc = elf_load ( image, &entry, &max ) ) != 0 ) {
                DBGC ( image, "ELF %p could not load: %s\n",
                       image, strerror ( rc ) );
                return rc;
        }

        /* An ELF image has no callback interface, so we need to shut
         * down before invoking it.
         */
        shutdown_boot();

        /* Jump to OS with flat physical addressing */
        DBGC ( image, "ELF %p starting execution at %lx\n", image, entry );
        __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */
                                           "call *%%edi\n\t"
                                           "popl %%ebp\n\t" /* gcc bug */ )
                               : : "D" ( entry )
                               : "eax", "ebx", "ecx", "edx", "esi", "memory" );

        DBGC ( image, "ELF %p returned\n", image );

        /* It isn't safe to continue after calling shutdown() */
        while ( 1 ) {}

        return -ECANCELED;  /* -EIMPOSSIBLE, anyone? */
}
static int elfboot_check_segment ( struct image image,
Elf_Phdr phdr,
physaddr_t  dest 
) [static]

Check that ELF segment uses flat physical addressing.

Parameters:
imageELF file
phdrELF program header
destDestination address
Return values:
rcReturn status code

Definition at line 89 of file elfboot.c.

References DBGC, ENOEXEC, Elf32_Phdr::p_paddr, and Elf32_Phdr::p_vaddr.

Referenced by elfboot_probe().

                                                     {

        /* Check that ELF segment uses flat physical addressing */
        if ( phdr->p_vaddr != dest ) {
                DBGC ( image, "ELF %p uses virtual addressing (phys %x, "
                       "virt %x)\n", image, phdr->p_paddr, phdr->p_vaddr );
                return -ENOEXEC;
        }

        return 0;
}
static int elfboot_probe ( struct image image) [static]

Probe ELF image.

Parameters:
imageELF file
Return values:
rcReturn status code

Definition at line 108 of file elfboot.c.

References copy_from_user(), image::data, DBGC, Elf32_Ehdr::e_ident, EI_CLASS, EI_DATA, EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3, EI_VERSION, elf_segments(), elfboot_check_segment(), ELFCLASS32, ELFDATA2LSB, ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ENOEXEC, entry, EV_CURRENT, max, memcmp(), and rc.

                                                 {
        Elf32_Ehdr ehdr;
        static const uint8_t e_ident[] = {
                [EI_MAG0]       = ELFMAG0,
                [EI_MAG1]       = ELFMAG1,
                [EI_MAG2]       = ELFMAG2,
                [EI_MAG3]       = ELFMAG3,
                [EI_CLASS]      = ELFCLASS32,
                [EI_DATA]       = ELFDATA2LSB,
                [EI_VERSION]    = EV_CURRENT,
        };
        physaddr_t entry;
        physaddr_t max;
        int rc;

        /* Read ELF header */
        copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) );
        if ( memcmp ( ehdr.e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
                DBGC ( image, "Invalid ELF identifier\n" );
                return -ENOEXEC;
        }

        /* Check that this image uses flat physical addressing */
        if ( ( rc = elf_segments ( image, &ehdr, elfboot_check_segment,
                                   &entry, &max ) ) != 0 ) {
                DBGC ( image, "Unloadable ELF image\n" );
                return rc;
        }

        return 0;
}
struct image_type elfboot_image_type __image_type ( PROBE_NORMAL  ) [read]

ELF image type.