iPXE
elfboot.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26#include <string.h>
27#include <errno.h>
28#include <elf.h>
29#include <librm.h>
30#include <ipxe/image.h>
31#include <ipxe/elf.h>
32#include <ipxe/features.h>
33#include <ipxe/init.h>
34
35/**
36 * @file
37 *
38 * ELF bootable image
39 *
40 */
41
43
44/**
45 * Execute ELF image
46 *
47 * @v image ELF image
48 * @ret rc Return status code
49 */
50static int elfboot_exec ( struct image *image ) {
51 physaddr_t entry;
53 int rc;
54
55 /* Load the image using core ELF support */
56 if ( ( rc = elf_load ( image, &entry, &max ) ) != 0 ) {
57 DBGC ( image, "ELF %s could not load: %s\n",
58 image->name, strerror ( rc ) );
59 return rc;
60 }
61
62 /* An ELF image has no callback interface, so we need to shut
63 * down before invoking it.
64 */
66
67 /* Jump to OS with flat physical addressing */
68 DBGC ( image, "ELF %s starting execution at %lx\n",
69 image->name, entry );
70 __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */
71 "call *%%edi\n\t"
72 "popl %%ebp\n\t" /* gcc bug */ )
73 : : "D" ( entry )
74 : "eax", "ebx", "ecx", "edx", "esi", "memory" );
75
76 DBGC ( image, "ELF %s returned\n", image->name );
77
78 /* It isn't safe to continue after calling shutdown() */
79 while ( 1 ) {}
80
81 return -ECANCELED; /* -EIMPOSSIBLE, anyone? */
82}
83
84/**
85 * Check that ELF segment uses flat physical addressing
86 *
87 * @v image ELF file
88 * @v phdr ELF program header
89 * @v dest Destination address
90 * @ret rc Return status code
91 */
92static int elfboot_check_segment ( struct image *image, const Elf_Phdr *phdr,
94
95 /* Check that ELF segment uses flat physical addressing */
96 if ( phdr->p_vaddr != dest ) {
97 DBGC ( image, "ELF %s uses virtual addressing (phys %x, virt "
98 "%x)\n", image->name, phdr->p_paddr, phdr->p_vaddr );
99 return -ENOEXEC;
100 }
101
102 return 0;
103}
104
105/**
106 * Probe ELF image
107 *
108 * @v image ELF file
109 * @ret rc Return status code
110 */
111static int elfboot_probe ( struct image *image ) {
112 const Elf32_Ehdr *ehdr;
113 static const uint8_t e_ident[] = {
114 [EI_MAG0] = ELFMAG0,
115 [EI_MAG1] = ELFMAG1,
116 [EI_MAG2] = ELFMAG2,
117 [EI_MAG3] = ELFMAG3,
121 };
122 physaddr_t entry;
124 int rc;
125
126 /* Read ELF header */
127 if ( image->len < sizeof ( *ehdr ) ) {
128 DBGC ( image, "ELF %s too short for ELF header\n",
129 image->name );
130 return -ENOEXEC;
131 }
132 ehdr = image->data;
133 if ( memcmp ( ehdr->e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
134 DBGC ( image, "ELF %s invalid identifier\n", image->name );
135 return -ENOEXEC;
136 }
137
138 /* Check that this image uses flat physical addressing */
139 if ( ( rc = elf_segments ( image, ehdr, elfboot_check_segment,
140 &entry, &max ) ) != 0 ) {
141 DBGC ( image, "ELF %s is not loadable: %s\n",
142 image->name, strerror ( rc ) );
143 return rc;
144 }
145
146 return 0;
147}
148
149/** ELF image type */
150struct image_type elfboot_image_type __image_type ( PROBE_NORMAL ) = {
151 .name = "ELF",
152 .probe = elfboot_probe,
153 .exec = elfboot_exec,
154};
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
unsigned long physaddr_t
Definition stdint.h:20
unsigned char uint8_t
Definition stdint.h:10
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define max(x, y)
Definition ath.h:41
int elf_load(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF image into memory.
Definition elf.c:206
int elf_segments(struct image *image, const Elf_Ehdr *ehdr, int(*process)(struct image *image, const Elf_Phdr *phdr, physaddr_t dest), physaddr_t *entry, physaddr_t *max)
Process ELF segments.
Definition elf.c:157
ELF headers.
#define EI_MAG2
Definition elf.h:45
#define ELFMAG0
Definition elf.h:52
#define ELFMAG3
Definition elf.h:55
#define EI_MAG1
Definition elf.h:44
#define EI_CLASS
Definition elf.h:47
#define ELFCLASS32
Definition elf.h:58
#define ELFMAG1
Definition elf.h:53
#define EI_DATA
Definition elf.h:48
#define EV_CURRENT
Definition elf.h:64
#define ELFMAG2
Definition elf.h:54
#define EI_VERSION
Definition elf.h:49
#define EI_MAG0
Definition elf.h:43
#define EI_MAG3
Definition elf.h:46
#define ELFDATA2LSB
Definition elf.h:61
static int elfboot_exec(struct image *image)
Execute ELF image.
Definition elfboot.c:50
static int elfboot_check_segment(struct image *image, const Elf_Phdr *phdr, physaddr_t dest)
Check that ELF segment uses flat physical addressing.
Definition elfboot.c:92
static int elfboot_probe(struct image *image)
Probe ELF image.
Definition elfboot.c:111
Error codes.
#define DBGC(...)
Definition compiler.h:505
#define DHCP_EB_FEATURE_ELF
ELF format.
Definition features.h:51
#define FEATURE_IMAGE
Image formats.
Definition features.h:23
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOEXEC
Exec format error.
Definition errno.h:520
#define ECANCELED
Operation canceled.
Definition errno.h:344
Executable images.
#define PROBE_NORMAL
Normal image probe priority.
Definition image.h:156
#define __image_type(probe_order)
An executable image type.
Definition image.h:170
String functions.
static void shutdown_boot(void)
Shut down system for OS boot.
Definition init.h:78
ELF image format.
Elf32_Phdr Elf_Phdr
Definition elf.h:18
Feature list.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
Definition features.h:101
#define PHYS_CODE(asm_code_str)
Definition librm.h:167
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
ELF header.
Definition elf.h:25
unsigned char e_ident[EI_NIDENT]
Definition elf.h:26
Elf32_Addr p_vaddr
Definition elf.h:70
Elf32_Addr p_paddr
Definition elf.h:71
An executable image type.
Definition image.h:95
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:56