|
|
1.1 root 1: /*
2: * Copyright (C) 2008 Michael Brown <[email protected]>.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: FILE_LICENCE ( GPL2_OR_LATER );
20:
21: #include <errno.h>
22: #include <elf.h>
23: #include <ipxe/image.h>
24: #include <ipxe/elf.h>
25: #include <ipxe/features.h>
26: #include <ipxe/init.h>
27:
28: /**
29: * @file
30: *
31: * ELF bootable image
32: *
33: */
34:
35: FEATURE ( FEATURE_IMAGE, "ELF", DHCP_EB_FEATURE_ELF, 1 );
36:
37: /**
38: * Execute ELF image
39: *
40: * @v image ELF image
41: * @ret rc Return status code
42: */
43: static int elfboot_exec ( struct image *image ) {
44: physaddr_t entry;
45: int rc;
46:
47: /* Load the image using core ELF support */
48: if ( ( rc = elf_load ( image, &entry ) ) != 0 ) {
49: DBGC ( image, "ELF %p could not load: %s\n",
50: image, strerror ( rc ) );
51: return rc;
52: }
53:
54: /* An ELF image has no callback interface, so we need to shut
55: * down before invoking it.
56: */
57: shutdown_boot();
58:
59: /* Jump to OS with flat physical addressing */
60: DBGC ( image, "ELF %p starting execution at %lx\n", image, entry );
61: __asm__ __volatile__ ( PHYS_CODE ( "call *%%edi\n\t" )
62: : : "D" ( entry )
63: : "eax", "ebx", "ecx", "edx", "esi", "ebp",
64: "memory" );
65:
66: DBGC ( image, "ELF %p returned\n", image );
67:
68: /* It isn't safe to continue after calling shutdown() */
69: while ( 1 ) {}
70:
71: return -ECANCELED; /* -EIMPOSSIBLE, anyone? */
72: }
73:
74: /**
75: * Probe ELF image
76: *
77: * @v image ELF file
78: * @ret rc Return status code
79: */
80: static int elfboot_probe ( struct image *image ) {
81: Elf32_Ehdr ehdr;
82: static const uint8_t e_ident[] = {
83: [EI_MAG0] = ELFMAG0,
84: [EI_MAG1] = ELFMAG1,
85: [EI_MAG2] = ELFMAG2,
86: [EI_MAG3] = ELFMAG3,
87: [EI_CLASS] = ELFCLASS32,
88: [EI_DATA] = ELFDATA2LSB,
89: [EI_VERSION] = EV_CURRENT,
90: };
91:
92: /* Read ELF header */
93: copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) );
94: if ( memcmp ( ehdr.e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
95: DBG ( "Invalid ELF identifier\n" );
96: return -ENOEXEC;
97: }
98:
99: return 0;
100: }
101:
102: /** ELF image type */
103: struct image_type elfboot_image_type __image_type ( PROBE_NORMAL ) = {
104: .name = "ELF",
105: .probe = elfboot_probe,
106: .exec = elfboot_exec,
107: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.