diff options
author | 2017-04-25 03:31:15 -0700 | |
---|---|---|
committer | 2017-05-22 06:48:08 +0000 | |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/ipxe/src/arch/i386/image | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/image')
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/bootsector.c | 141 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/bzimage.c | 669 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/com32.c | 292 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/comboot.c | 327 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/elfboot.c | 145 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/initrd.c | 304 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/multiboot.c | 492 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/nbi.c | 427 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/pxe_image.c | 171 | ||||
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/image/sdi.c | 140 |
10 files changed, 0 insertions, 3108 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/image/bootsector.c b/qemu/roms/ipxe/src/arch/i386/image/bootsector.c deleted file mode 100644 index dba87613c..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/bootsector.c +++ /dev/null @@ -1,141 +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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * x86 bootsector image format - * - */ - -#include <errno.h> -#include <realmode.h> -#include <biosint.h> -#include <bootsector.h> -#include <ipxe/console.h> - -/** Vector for storing original INT 18 handler - * - * We do not chain to this vector, so there is no need to place it in - * .text16. - */ -static struct segoff int18_vector; - -/** Vector for storing original INT 19 handler - * - * We do not chain to this vector, so there is no need to place it in - * .text16. - */ -static struct segoff int19_vector; - -/** Restart point for INT 18 or 19 */ -extern void bootsector_exec_fail ( void ); - -/** - * Jump to preloaded bootsector - * - * @v segment Real-mode segment - * @v offset Real-mode offset - * @v drive Drive number to pass to boot sector - * @ret rc Return status code - */ -int call_bootsector ( unsigned int segment, unsigned int offset, - unsigned int drive ) { - int discard_b, discard_D, discard_d; - - /* Reset console, since boot sector will probably use it */ - console_reset(); - - DBG ( "Booting from boot sector at %04x:%04x\n", segment, offset ); - - /* Hook INTs 18 and 19 to capture failure paths */ - hook_bios_interrupt ( 0x18, ( unsigned int ) bootsector_exec_fail, - &int18_vector ); - hook_bios_interrupt ( 0x19, ( unsigned int ) bootsector_exec_fail, - &int19_vector ); - - /* Boot the loaded sector - * - * We assume that the boot sector may completely destroy our - * real-mode stack, so we preserve everything we need in - * static storage. - */ - __asm__ __volatile__ ( REAL_CODE ( /* Save return address off-stack */ - "popw %%cs:saved_retaddr\n\t" - /* Save stack pointer */ - "movw %%ss, %%ax\n\t" - "movw %%ax, %%cs:saved_ss\n\t" - "movw %%sp, %%cs:saved_sp\n\t" - /* Save frame pointer (gcc bug) */ - "movl %%ebp, %%cs:saved_ebp\n\t" - /* Prepare jump to boot sector */ - "pushw %%bx\n\t" - "pushw %%di\n\t" - /* Clear all registers */ - "xorl %%eax, %%eax\n\t" - "xorl %%ebx, %%ebx\n\t" - "xorl %%ecx, %%ecx\n\t" - /* %edx contains drive number */ - "xorl %%esi, %%esi\n\t" - "xorl %%edi, %%edi\n\t" - "xorl %%ebp, %%ebp\n\t" - "movw %%ax, %%ds\n\t" - "movw %%ax, %%es\n\t" - "movw %%ax, %%fs\n\t" - "movw %%ax, %%gs\n\t" - /* Jump to boot sector */ - "sti\n\t" - "lret\n\t" - /* Preserved variables */ - "\nsaved_ebp: .long 0\n\t" - "\nsaved_ss: .word 0\n\t" - "\nsaved_sp: .word 0\n\t" - "\nsaved_retaddr: .word 0\n\t" - /* Boot failure return point */ - "\nbootsector_exec_fail:\n\t" - /* Restore frame pointer (gcc bug) */ - "movl %%cs:saved_ebp, %%ebp\n\t" - /* Restore stack pointer */ - "movw %%cs:saved_ss, %%ax\n\t" - "movw %%ax, %%ss\n\t" - "movw %%cs:saved_sp, %%sp\n\t" - /* Return via saved address */ - "jmp *%%cs:saved_retaddr\n\t" ) - : "=b" ( discard_b ), "=D" ( discard_D ), - "=d" ( discard_d ) - : "b" ( segment ), "D" ( offset ), - "d" ( drive ) - : "eax", "ecx", "esi" ); - - DBG ( "Booted disk returned via INT 18 or 19\n" ); - - /* Unhook INTs 18 and 19 */ - unhook_bios_interrupt ( 0x18, ( unsigned int ) bootsector_exec_fail, - &int18_vector ); - unhook_bios_interrupt ( 0x19, ( unsigned int ) bootsector_exec_fail, - &int19_vector ); - - return -ECANCELED; -} diff --git a/qemu/roms/ipxe/src/arch/i386/image/bzimage.c b/qemu/roms/ipxe/src/arch/i386/image/bzimage.c deleted file mode 100644 index a64206cd3..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/bzimage.c +++ /dev/null @@ -1,669 +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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * Linux bzImage image format - * - */ - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <bzimage.h> -#include <initrd.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/cpio.h> -#include <ipxe/features.h> - -FEATURE ( FEATURE_IMAGE, "bzImage", DHCP_EB_FEATURE_BZIMAGE, 1 ); - -/** - * bzImage context - */ -struct bzimage_context { - /** Boot protocol version */ - unsigned int version; - /** Real-mode kernel portion load segment address */ - unsigned int rm_kernel_seg; - /** Real-mode kernel portion load address */ - userptr_t rm_kernel; - /** Real-mode kernel portion file size */ - size_t rm_filesz; - /** Real-mode heap top (offset from rm_kernel) */ - size_t rm_heap; - /** Command line (offset from rm_kernel) */ - size_t rm_cmdline; - /** Command line maximum length */ - size_t cmdline_size; - /** Real-mode kernel portion total memory size */ - size_t rm_memsz; - /** Non-real-mode kernel portion load address */ - userptr_t pm_kernel; - /** Non-real-mode kernel portion file and memory size */ - size_t pm_sz; - /** Video mode */ - unsigned int vid_mode; - /** Memory limit */ - uint64_t mem_limit; - /** Initrd address */ - physaddr_t ramdisk_image; - /** Initrd size */ - physaddr_t ramdisk_size; - - /** Command line magic block */ - struct bzimage_cmdline cmdline_magic; - /** bzImage header */ - struct bzimage_header bzhdr; -}; - -/** - * Parse bzImage header - * - * @v image bzImage file - * @v bzimg bzImage context - * @v src bzImage to parse - * @ret rc Return status code - */ -static int bzimage_parse_header ( struct image *image, - struct bzimage_context *bzimg, - userptr_t src ) { - unsigned int syssize; - int is_bzimage; - - /* Sanity check */ - if ( image->len < ( BZI_HDR_OFFSET + sizeof ( bzimg->bzhdr ) ) ) { - DBGC ( image, "bzImage %p too short for kernel header\n", - image ); - return -ENOEXEC; - } - - /* Read in header structures */ - memset ( bzimg, 0, sizeof ( *bzimg ) ); - copy_from_user ( &bzimg->cmdline_magic, src, BZI_CMDLINE_OFFSET, - sizeof ( bzimg->cmdline_magic ) ); - copy_from_user ( &bzimg->bzhdr, src, BZI_HDR_OFFSET, - sizeof ( bzimg->bzhdr ) ); - - /* Calculate size of real-mode portion */ - bzimg->rm_filesz = ( ( ( bzimg->bzhdr.setup_sects ? - bzimg->bzhdr.setup_sects : 4 ) + 1 ) << 9 ); - if ( bzimg->rm_filesz > image->len ) { - DBGC ( image, "bzImage %p too short for %zd byte of setup\n", - image, bzimg->rm_filesz ); - return -ENOEXEC; - } - bzimg->rm_memsz = BZI_ASSUMED_RM_SIZE; - - /* Calculate size of protected-mode portion */ - bzimg->pm_sz = ( image->len - bzimg->rm_filesz ); - syssize = ( ( bzimg->pm_sz + 15 ) / 16 ); - - /* Check for signatures and determine version */ - if ( bzimg->bzhdr.boot_flag != BZI_BOOT_FLAG ) { - DBGC ( image, "bzImage %p missing 55AA signature\n", image ); - return -ENOEXEC; - } - if ( bzimg->bzhdr.header == BZI_SIGNATURE ) { - /* 2.00+ */ - bzimg->version = bzimg->bzhdr.version; - } else { - /* Pre-2.00. Check that the syssize field is correct, - * as a guard against accepting arbitrary binary data, - * since the 55AA check is pretty lax. Note that the - * syssize field is unreliable for protocols between - * 2.00 and 2.03 inclusive, so we should not always - * check this field. - */ - bzimg->version = 0x0100; - if ( bzimg->bzhdr.syssize != syssize ) { - DBGC ( image, "bzImage %p bad syssize %x (expected " - "%x)\n", image, bzimg->bzhdr.syssize, syssize ); - return -ENOEXEC; - } - } - - /* Determine image type */ - is_bzimage = ( ( bzimg->version >= 0x0200 ) ? - ( bzimg->bzhdr.loadflags & BZI_LOAD_HIGH ) : 0 ); - - /* Calculate load address of real-mode portion */ - bzimg->rm_kernel_seg = ( is_bzimage ? 0x1000 : 0x9000 ); - bzimg->rm_kernel = real_to_user ( bzimg->rm_kernel_seg, 0 ); - - /* Allow space for the stack and heap */ - bzimg->rm_memsz += BZI_STACK_SIZE; - bzimg->rm_heap = bzimg->rm_memsz; - - /* Allow space for the command line */ - bzimg->rm_cmdline = bzimg->rm_memsz; - bzimg->rm_memsz += BZI_CMDLINE_SIZE; - - /* Calculate load address of protected-mode portion */ - bzimg->pm_kernel = phys_to_user ( is_bzimage ? BZI_LOAD_HIGH_ADDR - : BZI_LOAD_LOW_ADDR ); - - /* Extract video mode */ - bzimg->vid_mode = bzimg->bzhdr.vid_mode; - - /* Extract memory limit */ - bzimg->mem_limit = ( ( bzimg->version >= 0x0203 ) ? - bzimg->bzhdr.initrd_addr_max : BZI_INITRD_MAX ); - - /* Extract command line size */ - bzimg->cmdline_size = ( ( bzimg->version >= 0x0206 ) ? - bzimg->bzhdr.cmdline_size : BZI_CMDLINE_SIZE ); - - DBGC ( image, "bzImage %p version %04x RM %#lx+%#zx PM %#lx+%#zx " - "cmdlen %zd\n", image, bzimg->version, - user_to_phys ( bzimg->rm_kernel, 0 ), bzimg->rm_filesz, - user_to_phys ( bzimg->pm_kernel, 0 ), bzimg->pm_sz, - bzimg->cmdline_size ); - - return 0; -} - -/** - * Update bzImage header in loaded kernel - * - * @v image bzImage file - * @v bzimg bzImage context - * @v dst bzImage to update - */ -static void bzimage_update_header ( struct image *image, - struct bzimage_context *bzimg, - userptr_t dst ) { - - /* Set loader type */ - if ( bzimg->version >= 0x0200 ) - bzimg->bzhdr.type_of_loader = BZI_LOADER_TYPE_IPXE; - - /* Set heap end pointer */ - if ( bzimg->version >= 0x0201 ) { - bzimg->bzhdr.heap_end_ptr = ( bzimg->rm_heap - 0x200 ); - bzimg->bzhdr.loadflags |= BZI_CAN_USE_HEAP; - } - - /* Set command line */ - if ( bzimg->version >= 0x0202 ) { - bzimg->bzhdr.cmd_line_ptr = user_to_phys ( bzimg->rm_kernel, - bzimg->rm_cmdline ); - } else { - bzimg->cmdline_magic.magic = BZI_CMDLINE_MAGIC; - bzimg->cmdline_magic.offset = bzimg->rm_cmdline; - if ( bzimg->version >= 0x0200 ) - bzimg->bzhdr.setup_move_size = bzimg->rm_memsz; - } - - /* Set video mode */ - bzimg->bzhdr.vid_mode = bzimg->vid_mode; - - /* Set initrd address */ - if ( bzimg->version >= 0x0200 ) { - bzimg->bzhdr.ramdisk_image = bzimg->ramdisk_image; - bzimg->bzhdr.ramdisk_size = bzimg->ramdisk_size; - } - - /* Write out header structures */ - copy_to_user ( dst, BZI_CMDLINE_OFFSET, &bzimg->cmdline_magic, - sizeof ( bzimg->cmdline_magic ) ); - copy_to_user ( dst, BZI_HDR_OFFSET, &bzimg->bzhdr, - sizeof ( bzimg->bzhdr ) ); - - DBGC ( image, "bzImage %p vidmode %d\n", image, bzimg->vid_mode ); -} - -/** - * Parse kernel command line for bootloader parameters - * - * @v image bzImage file - * @v bzimg bzImage context - * @v cmdline Kernel command line - * @ret rc Return status code - */ -static int bzimage_parse_cmdline ( struct image *image, - struct bzimage_context *bzimg, - const char *cmdline ) { - char *vga; - char *mem; - - /* Look for "vga=" */ - if ( ( vga = strstr ( cmdline, "vga=" ) ) ) { - vga += 4; - if ( strcmp ( vga, "normal" ) == 0 ) { - bzimg->vid_mode = BZI_VID_MODE_NORMAL; - } else if ( strcmp ( vga, "ext" ) == 0 ) { - bzimg->vid_mode = BZI_VID_MODE_EXT; - } else if ( strcmp ( vga, "ask" ) == 0 ) { - bzimg->vid_mode = BZI_VID_MODE_ASK; - } else { - bzimg->vid_mode = strtoul ( vga, &vga, 0 ); - if ( *vga && ( *vga != ' ' ) ) { - DBGC ( image, "bzImage %p strange \"vga=\"" - "terminator '%c'\n", image, *vga ); - } - } - } - - /* Look for "mem=" */ - if ( ( mem = strstr ( cmdline, "mem=" ) ) ) { - mem += 4; - bzimg->mem_limit = strtoul ( mem, &mem, 0 ); - switch ( *mem ) { - case 'G': - case 'g': - bzimg->mem_limit <<= 10; - case 'M': - case 'm': - bzimg->mem_limit <<= 10; - case 'K': - case 'k': - bzimg->mem_limit <<= 10; - break; - case '\0': - case ' ': - break; - default: - DBGC ( image, "bzImage %p strange \"mem=\" " - "terminator '%c'\n", image, *mem ); - break; - } - bzimg->mem_limit -= 1; - } - - return 0; -} - -/** - * Set command line - * - * @v image bzImage image - * @v bzimg bzImage context - * @v cmdline Kernel command line - */ -static void bzimage_set_cmdline ( struct image *image, - struct bzimage_context *bzimg, - const char *cmdline ) { - size_t cmdline_len; - - /* Copy command line down to real-mode portion */ - cmdline_len = ( strlen ( cmdline ) + 1 ); - if ( cmdline_len > bzimg->cmdline_size ) - cmdline_len = bzimg->cmdline_size; - copy_to_user ( bzimg->rm_kernel, bzimg->rm_cmdline, - cmdline, cmdline_len ); - DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline ); -} - -/** - * Parse standalone image command line for cpio parameters - * - * @v image bzImage file - * @v cpio CPIO header - * @v cmdline Command line - */ -static void bzimage_parse_cpio_cmdline ( struct image *image, - struct cpio_header *cpio, - const char *cmdline ) { - char *arg; - char *end; - unsigned int mode; - - /* Look for "mode=" */ - if ( ( arg = strstr ( cmdline, "mode=" ) ) ) { - arg += 5; - mode = strtoul ( arg, &end, 8 /* Octal for file mode */ ); - if ( *end && ( *end != ' ' ) ) { - DBGC ( image, "bzImage %p strange \"mode=\"" - "terminator '%c'\n", image, *end ); - } - cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) ); - } -} - -/** - * Align initrd length - * - * @v len Length - * @ret len Length rounded up to INITRD_ALIGN - */ -static inline size_t bzimage_align ( size_t len ) { - - return ( ( len + INITRD_ALIGN - 1 ) & ~( INITRD_ALIGN - 1 ) ); -} - -/** - * Load initrd - * - * @v image bzImage image - * @v initrd initrd image - * @v address Address at which to load, or UNULL - * @ret len Length of loaded image, excluding zero-padding - */ -static size_t bzimage_load_initrd ( struct image *image, - struct image *initrd, - userptr_t address ) { - char *filename = initrd->cmdline; - char *cmdline; - struct cpio_header cpio; - size_t offset; - size_t name_len; - size_t pad_len; - - /* Do not include kernel image itself as an initrd */ - if ( initrd == image ) - return 0; - - /* Create cpio header for non-prebuilt images */ - if ( filename && filename[0] ) { - cmdline = strchr ( filename, ' ' ); - name_len = ( ( cmdline ? ( ( size_t ) ( cmdline - filename ) ) - : strlen ( filename ) ) + 1 /* NUL */ ); - memset ( &cpio, '0', sizeof ( cpio ) ); - memcpy ( cpio.c_magic, CPIO_MAGIC, sizeof ( cpio.c_magic ) ); - cpio_set_field ( cpio.c_mode, 0100644 ); - cpio_set_field ( cpio.c_nlink, 1 ); - cpio_set_field ( cpio.c_filesize, initrd->len ); - cpio_set_field ( cpio.c_namesize, name_len ); - if ( cmdline ) { - bzimage_parse_cpio_cmdline ( image, &cpio, - ( cmdline + 1 /* ' ' */ )); - } - offset = ( ( sizeof ( cpio ) + name_len + 0x03 ) & ~0x03 ); - } else { - offset = 0; - name_len = 0; - } - - /* Copy in initrd image body (and cpio header if applicable) */ - if ( address ) { - memmove_user ( address, offset, initrd->data, 0, initrd->len ); - if ( offset ) { - memset_user ( address, 0, 0, offset ); - copy_to_user ( address, 0, &cpio, sizeof ( cpio ) ); - copy_to_user ( address, sizeof ( cpio ), filename, - ( name_len - 1 /* NUL (or space) */ ) ); - } - DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)" - "%s%s\n", image, initrd, user_to_phys ( address, 0 ), - user_to_phys ( address, offset ), - user_to_phys ( address, ( offset + initrd->len ) ), - ( filename ? " " : "" ), ( filename ? filename : "" ) ); - DBGC2_MD5A ( image, user_to_phys ( address, offset ), - user_to_virt ( address, offset ), initrd->len ); - } - offset += initrd->len; - - /* Zero-pad to next INITRD_ALIGN boundary */ - pad_len = ( ( -offset ) & ( INITRD_ALIGN - 1 ) ); - if ( address ) - memset_user ( address, offset, 0, pad_len ); - - return offset; -} - -/** - * Check that initrds can be loaded - * - * @v image bzImage image - * @v bzimg bzImage context - * @ret rc Return status code - */ -static int bzimage_check_initrds ( struct image *image, - struct bzimage_context *bzimg ) { - struct image *initrd; - userptr_t bottom; - size_t len = 0; - int rc; - - /* Calculate total loaded length of initrds */ - for_each_image ( initrd ) { - - /* Skip kernel */ - if ( initrd == image ) - continue; - - /* Calculate length */ - len += bzimage_load_initrd ( image, initrd, UNULL ); - len = bzimage_align ( len ); - - DBGC ( image, "bzImage %p initrd %p from [%#08lx,%#08lx)%s%s\n", - image, initrd, user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ), - ( initrd->cmdline ? " " : "" ), - ( initrd->cmdline ? initrd->cmdline : "" ) ); - DBGC2_MD5A ( image, user_to_phys ( initrd->data, 0 ), - user_to_virt ( initrd->data, 0 ), initrd->len ); - } - - /* Calculate lowest usable address */ - bottom = userptr_add ( bzimg->pm_kernel, bzimg->pm_sz ); - - /* Check that total length fits within space available for - * reshuffling. This is a conservative check, since CPIO - * headers are not present during reshuffling, but this - * doesn't hurt and keeps the code simple. - */ - if ( ( rc = initrd_reshuffle_check ( len, bottom ) ) != 0 ) { - DBGC ( image, "bzImage %p failed reshuffle check: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Check that total length fits within kernel's memory limit */ - if ( user_to_phys ( bottom, len ) > bzimg->mem_limit ) { - DBGC ( image, "bzImage %p not enough space for initrds\n", - image ); - return -ENOBUFS; - } - - return 0; -} - -/** - * Load initrds, if any - * - * @v image bzImage image - * @v bzimg bzImage context - */ -static void bzimage_load_initrds ( struct image *image, - struct bzimage_context *bzimg ) { - struct image *initrd; - struct image *highest = NULL; - struct image *other; - userptr_t top; - userptr_t dest; - size_t offset; - size_t len; - - /* Reshuffle initrds into desired order */ - initrd_reshuffle ( userptr_add ( bzimg->pm_kernel, bzimg->pm_sz ) ); - - /* Find highest initrd */ - for_each_image ( initrd ) { - if ( ( highest == NULL ) || - ( userptr_sub ( initrd->data, highest->data ) > 0 ) ) { - highest = initrd; - } - } - - /* Do nothing if there are no initrds */ - if ( ! highest ) - return; - - /* Find highest usable address */ - top = userptr_add ( highest->data, bzimage_align ( highest->len ) ); - if ( user_to_phys ( top, 0 ) > bzimg->mem_limit ) - top = phys_to_user ( bzimg->mem_limit ); - DBGC ( image, "bzImage %p loading initrds from %#08lx downwards\n", - image, user_to_phys ( top, 0 ) ); - - /* Load initrds in order */ - for_each_image ( initrd ) { - - /* Calculate cumulative length of following - * initrds (including padding). - */ - offset = 0; - for_each_image ( other ) { - if ( other == initrd ) - offset = 0; - offset += bzimage_load_initrd ( image, other, UNULL ); - offset = bzimage_align ( offset ); - } - - /* Load initrd at this address */ - dest = userptr_add ( top, -offset ); - len = bzimage_load_initrd ( image, initrd, dest ); - - /* Record initrd location */ - if ( ! bzimg->ramdisk_image ) - bzimg->ramdisk_image = user_to_phys ( dest, 0 ); - bzimg->ramdisk_size = ( user_to_phys ( dest, len ) - - bzimg->ramdisk_image ); - } - DBGC ( image, "bzImage %p initrds at [%#08lx,%#08lx)\n", - image, bzimg->ramdisk_image, - ( bzimg->ramdisk_image + bzimg->ramdisk_size ) ); -} - -/** - * Execute bzImage image - * - * @v image bzImage image - * @ret rc Return status code - */ -static int bzimage_exec ( struct image *image ) { - struct bzimage_context bzimg; - const char *cmdline = ( image->cmdline ? image->cmdline : "" ); - int rc; - - /* Read and parse header from image */ - if ( ( rc = bzimage_parse_header ( image, &bzimg, - image->data ) ) != 0 ) - return rc; - - /* Prepare segments */ - if ( ( rc = prep_segment ( bzimg.rm_kernel, bzimg.rm_filesz, - bzimg.rm_memsz ) ) != 0 ) { - DBGC ( image, "bzImage %p could not prepare RM segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - if ( ( rc = prep_segment ( bzimg.pm_kernel, bzimg.pm_sz, - bzimg.pm_sz ) ) != 0 ) { - DBGC ( image, "bzImage %p could not prepare PM segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Parse command line for bootloader parameters */ - if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0) - return rc; - - /* Check that initrds can be loaded */ - if ( ( rc = bzimage_check_initrds ( image, &bzimg ) ) != 0 ) - return rc; - - /* Remove kernel from image list (without invalidating image pointer) */ - unregister_image ( image_get ( image ) ); - - /* Load segments */ - memcpy_user ( bzimg.rm_kernel, 0, image->data, - 0, bzimg.rm_filesz ); - memcpy_user ( bzimg.pm_kernel, 0, image->data, - bzimg.rm_filesz, bzimg.pm_sz ); - - /* Store command line */ - bzimage_set_cmdline ( image, &bzimg, cmdline ); - - /* Prepare for exiting. Must do this before loading initrds, - * since loading the initrds will corrupt the external heap. - */ - shutdown_boot(); - - /* Load any initrds */ - bzimage_load_initrds ( image, &bzimg ); - - /* Update kernel header */ - bzimage_update_header ( image, &bzimg, bzimg.rm_kernel ); - - DBGC ( image, "bzImage %p jumping to RM kernel at %04x:0000 " - "(stack %04x:%04zx)\n", image, ( bzimg.rm_kernel_seg + 0x20 ), - bzimg.rm_kernel_seg, bzimg.rm_heap ); - - /* Jump to the kernel */ - __asm__ __volatile__ ( REAL_CODE ( "movw %w0, %%ds\n\t" - "movw %w0, %%es\n\t" - "movw %w0, %%fs\n\t" - "movw %w0, %%gs\n\t" - "movw %w0, %%ss\n\t" - "movw %w1, %%sp\n\t" - "pushw %w2\n\t" - "pushw $0\n\t" - "lret\n\t" ) - : : "r" ( bzimg.rm_kernel_seg ), - "r" ( bzimg.rm_heap ), - "r" ( bzimg.rm_kernel_seg + 0x20 ) ); - - /* There is no way for the image to return, since we provide - * no return address. - */ - assert ( 0 ); - - return -ECANCELED; /* -EIMPOSSIBLE */ -} - -/** - * Probe bzImage image - * - * @v image bzImage file - * @ret rc Return status code - */ -int bzimage_probe ( struct image *image ) { - struct bzimage_context bzimg; - int rc; - - /* Read and parse header from image */ - if ( ( rc = bzimage_parse_header ( image, &bzimg, - image->data ) ) != 0 ) - return rc; - - return 0; -} - -/** Linux bzImage image type */ -struct image_type bzimage_image_type __image_type ( PROBE_NORMAL ) = { - .name = "bzImage", - .probe = bzimage_probe, - .exec = bzimage_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/com32.c b/qemu/roms/ipxe/src/arch/i386/image/com32.c deleted file mode 100644 index c12ffb684..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/com32.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * @file - * - * SYSLINUX COM32 image format - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <basemem.h> -#include <comboot.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/io.h> - -/** - * Execute COMBOOT image - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_exec_loop ( struct image *image ) { - struct memory_map memmap; - unsigned int i; - int state; - uint32_t avail_mem_top; - - state = rmsetjmp ( comboot_return ); - - switch ( state ) { - case 0: /* First time through; invoke COM32 program */ - - /* Get memory map */ - get_memmap ( &memmap ); - - /* Find end of block covering COM32 image loading area */ - for ( i = 0, avail_mem_top = 0 ; i < memmap.count ; i++ ) { - if ( (memmap.regions[i].start <= COM32_START_PHYS) && - (memmap.regions[i].end > COM32_START_PHYS + image->len) ) { - avail_mem_top = memmap.regions[i].end; - break; - } - } - - DBGC ( image, "COM32 %p: available memory top = 0x%x\n", - image, avail_mem_top ); - - assert ( avail_mem_top != 0 ); - - com32_external_esp = phys_to_virt ( avail_mem_top ); - - /* Hook COMBOOT API interrupts */ - hook_comboot_interrupts(); - - /* Unregister image, so that a "boot" command doesn't - * throw us into an execution loop. We never - * reregister ourselves; COMBOOT images expect to be - * removed on exit. - */ - unregister_image ( image ); - - __asm__ __volatile__ ( - "movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */ - "movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */ - "call _virt_to_phys\n\t" /* Switch to flat physical address space */ - "sti\n\t" /* Enable interrupts */ - "pushl %0\n\t" /* Pointer to CDECL helper function */ - "pushl %1\n\t" /* Pointer to FAR call helper function */ - "pushl %2\n\t" /* Size of low memory bounce buffer */ - "pushl %3\n\t" /* Pointer to low memory bounce buffer */ - "pushl %4\n\t" /* Pointer to INT call helper function */ - "pushl %5\n\t" /* Pointer to the command line arguments */ - "pushl $6\n\t" /* Number of additional arguments */ - "call *%6\n\t" /* Execute image */ - "cli\n\t" /* Disable interrupts */ - "call _phys_to_virt\n\t" /* Switch back to internal virtual address space */ - "movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */ - : - : - /* %0 */ "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ), - /* %1 */ "r" ( virt_to_phys ( com32_farcall_wrapper ) ), - /* %2 */ "r" ( get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4) ), - /* %3 */ "i" ( COM32_BOUNCE_SEG << 4 ), - /* %4 */ "r" ( virt_to_phys ( com32_intcall_wrapper ) ), - /* %5 */ "r" ( virt_to_phys ( image->cmdline ? - image->cmdline : "" ) ), - /* %6 */ "r" ( COM32_START_PHYS ) - : - "memory" ); - DBGC ( image, "COM32 %p: returned\n", image ); - break; - - case COMBOOT_EXIT: - DBGC ( image, "COM32 %p: exited\n", image ); - break; - - case COMBOOT_EXIT_RUN_KERNEL: - assert ( image->replacement ); - DBGC ( image, "COM32 %p: exited to run kernel %s\n", - image, image->replacement->name ); - break; - - case COMBOOT_EXIT_COMMAND: - DBGC ( image, "COM32 %p: exited after executing command\n", - image ); - break; - - default: - assert ( 0 ); - break; - } - - unhook_comboot_interrupts(); - comboot_force_text_mode(); - - return 0; -} - -/** - * Check image name extension - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_identify ( struct image *image ) { - const char *ext; - static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 }; - uint8_t buf[5]; - - if ( image->len >= 5 ) { - /* Check for magic number - * mov eax,21cd4cffh - * B8 FF 4C CD 21 - */ - copy_from_user ( buf, image->data, 0, sizeof(buf) ); - if ( ! memcmp ( buf, magic, sizeof(buf) ) ) { - DBGC ( image, "COM32 %p: found magic number\n", - image ); - return 0; - } - } - - /* Magic number not found; check filename extension */ - - ext = strrchr( image->name, '.' ); - - if ( ! ext ) { - DBGC ( image, "COM32 %p: no extension\n", - image ); - return -ENOEXEC; - } - - ++ext; - - if ( strcasecmp( ext, "c32" ) ) { - DBGC ( image, "COM32 %p: unrecognized extension %s\n", - image, ext ); - return -ENOEXEC; - } - - return 0; -} - - -/** - * Load COM32 image into memory - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_load_image ( struct image *image ) { - size_t filesz, memsz; - userptr_t buffer; - int rc; - - filesz = image->len; - memsz = filesz; - buffer = phys_to_user ( COM32_START_PHYS ); - if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { - DBGC ( image, "COM32 %p: could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Copy image to segment */ - memcpy_user ( buffer, 0, image->data, 0, filesz ); - - return 0; -} - -/** - * Prepare COM32 low memory bounce buffer - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_prepare_bounce_buffer ( struct image * image ) { - unsigned int seg; - userptr_t seg_userptr; - size_t filesz, memsz; - int rc; - - seg = COM32_BOUNCE_SEG; - seg_userptr = real_to_user ( seg, 0 ); - - /* Ensure the entire 64k segment is free */ - memsz = 0xFFFF; - filesz = 0; - - /* Prepare, verify, and load the real-mode segment */ - if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) { - DBGC ( image, "COM32 %p: could not prepare bounce buffer segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Probe COM32 image - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_probe ( struct image *image ) { - int rc; - - DBGC ( image, "COM32 %p: name '%s'\n", image, image->name ); - - /* Check if this is a COMBOOT image */ - if ( ( rc = com32_identify ( image ) ) != 0 ) { - return rc; - } - - return 0; -} - -/** - * Execute COMBOOT image - * - * @v image COM32 image - * @ret rc Return status code - */ -static int com32_exec ( struct image *image ) { - int rc; - - /* Load image */ - if ( ( rc = com32_load_image ( image ) ) != 0 ) { - return rc; - } - - /* Prepare bounce buffer segment */ - if ( ( rc = com32_prepare_bounce_buffer ( image ) ) != 0 ) { - return rc; - } - - return com32_exec_loop ( image ); -} - -/** SYSLINUX COM32 image type */ -struct image_type com32_image_type __image_type ( PROBE_NORMAL ) = { - .name = "COM32", - .probe = com32_probe, - .exec = com32_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/comboot.c b/qemu/roms/ipxe/src/arch/i386/image/comboot.c deleted file mode 100644 index 1ec02331d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/comboot.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * @file - * - * SYSLINUX COMBOOT (16-bit) image format - * - */ - -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <basemem.h> -#include <comboot.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/features.h> - -FEATURE ( FEATURE_IMAGE, "COMBOOT", DHCP_EB_FEATURE_COMBOOT, 1 ); - -/** - * COMBOOT PSP, copied to offset 0 of code segment - */ -struct comboot_psp { - /** INT 20 instruction, executed if COMBOOT image returns with RET */ - uint16_t int20; - /** Segment of first non-free paragraph of memory */ - uint16_t first_non_free_para; -}; - -/** Offset in PSP of command line */ -#define COMBOOT_PSP_CMDLINE_OFFSET 0x81 - -/** Maximum length of command line in PSP - * (127 bytes minus space and CR) */ -#define COMBOOT_MAX_CMDLINE_LEN 125 - - -/** - * Copy command line to PSP - * - * @v image COMBOOT image - */ -static void comboot_copy_cmdline ( struct image * image, userptr_t seg_userptr ) { - const char *cmdline = ( image->cmdline ? image->cmdline : "" ); - int cmdline_len = strlen ( cmdline ); - if( cmdline_len > COMBOOT_MAX_CMDLINE_LEN ) - cmdline_len = COMBOOT_MAX_CMDLINE_LEN; - uint8_t len_byte = cmdline_len; - char spc = ' ', cr = '\r'; - - /* Copy length to byte before command line */ - copy_to_user ( seg_userptr, COMBOOT_PSP_CMDLINE_OFFSET - 1, - &len_byte, 1 ); - - /* Command line starts with space */ - copy_to_user ( seg_userptr, - COMBOOT_PSP_CMDLINE_OFFSET, - &spc, 1 ); - - /* Copy command line */ - copy_to_user ( seg_userptr, - COMBOOT_PSP_CMDLINE_OFFSET + 1, - cmdline, cmdline_len ); - - /* Command line ends with CR */ - copy_to_user ( seg_userptr, - COMBOOT_PSP_CMDLINE_OFFSET + cmdline_len + 1, - &cr, 1 ); -} - -/** - * Initialize PSP - * - * @v image COMBOOT image - * @v seg_userptr segment to initialize - */ -static void comboot_init_psp ( struct image * image, userptr_t seg_userptr ) { - struct comboot_psp psp; - - /* Fill PSP */ - - /* INT 20h instruction, byte order reversed */ - psp.int20 = 0x20CD; - - /* get_fbms() returns BIOS free base memory counter, which is in - * kilobytes; x * 1024 / 16 == x * 64 == x << 6 */ - psp.first_non_free_para = get_fbms() << 6; - - DBGC ( image, "COMBOOT %p: first non-free paragraph = 0x%x\n", - image, psp.first_non_free_para ); - - /* Copy the PSP to offset 0 of segment. - * The rest of the PSP was already zeroed by - * comboot_prepare_segment. */ - copy_to_user ( seg_userptr, 0, &psp, sizeof( psp ) ); - - /* Copy the command line to the PSP */ - comboot_copy_cmdline ( image, seg_userptr ); -} - -/** - * Execute COMBOOT image - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_exec_loop ( struct image *image ) { - userptr_t seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); - int state; - - state = rmsetjmp ( comboot_return ); - - switch ( state ) { - case 0: /* First time through; invoke COMBOOT program */ - - /* Initialize PSP */ - comboot_init_psp ( image, seg_userptr ); - - /* Hook COMBOOT API interrupts */ - hook_comboot_interrupts(); - - DBGC ( image, "executing 16-bit COMBOOT image at %4x:0100\n", - COMBOOT_PSP_SEG ); - - /* Unregister image, so that a "boot" command doesn't - * throw us into an execution loop. We never - * reregister ourselves; COMBOOT images expect to be - * removed on exit. - */ - unregister_image ( image ); - - /* Store stack segment at 0x38 and stack pointer at 0x3A - * in the PSP and jump to the image */ - __asm__ __volatile__ ( - REAL_CODE ( /* Save return address with segment on old stack */ - "popw %%ax\n\t" - "pushw %%cs\n\t" - "pushw %%ax\n\t" - /* Set DS=ES=segment with image */ - "movw %w0, %%ds\n\t" - "movw %w0, %%es\n\t" - /* Set SS:SP to new stack (end of image segment) */ - "movw %w0, %%ss\n\t" - "xor %%sp, %%sp\n\t" - "pushw $0\n\t" - "pushw %w0\n\t" - "pushw $0x100\n\t" - /* Zero registers (some COM files assume GP regs are 0) */ - "xorw %%ax, %%ax\n\t" - "xorw %%bx, %%bx\n\t" - "xorw %%cx, %%cx\n\t" - "xorw %%dx, %%dx\n\t" - "xorw %%si, %%si\n\t" - "xorw %%di, %%di\n\t" - "xorw %%bp, %%bp\n\t" - "lret\n\t" ) - : : "r" ( COMBOOT_PSP_SEG ) : "eax" ); - DBGC ( image, "COMBOOT %p: returned\n", image ); - break; - - case COMBOOT_EXIT: - DBGC ( image, "COMBOOT %p: exited\n", image ); - break; - - case COMBOOT_EXIT_RUN_KERNEL: - assert ( image->replacement ); - DBGC ( image, "COMBOOT %p: exited to run kernel %s\n", - image, image->replacement->name ); - break; - - case COMBOOT_EXIT_COMMAND: - DBGC ( image, "COMBOOT %p: exited after executing command\n", - image ); - break; - - default: - assert ( 0 ); - break; - } - - unhook_comboot_interrupts(); - comboot_force_text_mode(); - - return 0; -} - -/** - * Check image name extension - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_identify ( struct image *image ) { - const char *ext; - - ext = strrchr( image->name, '.' ); - - if ( ! ext ) { - DBGC ( image, "COMBOOT %p: no extension\n", - image ); - return -ENOEXEC; - } - - ++ext; - - if ( strcasecmp( ext, "cbt" ) ) { - DBGC ( image, "COMBOOT %p: unrecognized extension %s\n", - image, ext ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Load COMBOOT image into memory, preparing a segment and returning it - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_prepare_segment ( struct image *image ) -{ - userptr_t seg_userptr; - size_t filesz, memsz; - int rc; - - /* Load image in segment */ - seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); - - /* Allow etra 0x100 bytes before image for PSP */ - filesz = image->len + 0x100; - - /* Ensure the entire 64k segment is free */ - memsz = 0xFFFF; - - /* Prepare, verify, and load the real-mode segment */ - if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) { - DBGC ( image, "COMBOOT %p: could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Zero PSP */ - memset_user ( seg_userptr, 0, 0, 0x100 ); - - /* Copy image to segment:0100 */ - memcpy_user ( seg_userptr, 0x100, image->data, 0, image->len ); - - return 0; -} - -/** - * Probe COMBOOT image - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_probe ( struct image *image ) { - int rc; - - DBGC ( image, "COMBOOT %p: name '%s'\n", - image, image->name ); - - /* Check if this is a COMBOOT image */ - if ( ( rc = comboot_identify ( image ) ) != 0 ) { - - return rc; - } - - return 0; -} - -/** - * Execute COMBOOT image - * - * @v image COMBOOT image - * @ret rc Return status code - */ -static int comboot_exec ( struct image *image ) { - int rc; - - /* Sanity check for filesize */ - if( image->len >= 0xFF00 ) { - DBGC( image, "COMBOOT %p: image too large\n", - image ); - return -ENOEXEC; - } - - /* Prepare segment and load image */ - if ( ( rc = comboot_prepare_segment ( image ) ) != 0 ) { - return rc; - } - - return comboot_exec_loop ( image ); -} - -/** SYSLINUX COMBOOT (16-bit) image type */ -struct image_type comboot_image_type __image_type ( PROBE_NORMAL ) = { - .name = "COMBOOT", - .probe = comboot_probe, - .exec = comboot_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/elfboot.c b/qemu/roms/ipxe/src/arch/i386/image/elfboot.c deleted file mode 100644 index dc3568929..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/elfboot.c +++ /dev/null @@ -1,145 +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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <elf.h> -#include <ipxe/image.h> -#include <ipxe/elf.h> -#include <ipxe/features.h> -#include <ipxe/init.h> - -/** - * @file - * - * ELF bootable image - * - */ - -FEATURE ( FEATURE_IMAGE, "ELF", DHCP_EB_FEATURE_ELF, 1 ); - -/** - * Execute ELF image - * - * @v image ELF image - * @ret rc Return status code - */ -static int elfboot_exec ( struct image *image ) { - 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? */ -} - -/** - * Check that ELF segment uses flat physical addressing - * - * @v image ELF file - * @v phdr ELF program header - * @v dest Destination address - * @ret rc Return status code - */ -static int elfboot_check_segment ( struct image *image, Elf_Phdr *phdr, - physaddr_t dest ) { - - /* 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; -} - -/** - * Probe ELF image - * - * @v image ELF file - * @ret rc Return status code - */ -static int elfboot_probe ( struct image *image ) { - 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; -} - -/** ELF image type */ -struct image_type elfboot_image_type __image_type ( PROBE_NORMAL ) = { - .name = "ELF", - .probe = elfboot_probe, - .exec = elfboot_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/initrd.c b/qemu/roms/ipxe/src/arch/i386/image/initrd.c deleted file mode 100644 index 80c197417..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/initrd.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2012 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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <errno.h> -#include <initrd.h> -#include <ipxe/image.h> -#include <ipxe/uaccess.h> -#include <ipxe/init.h> -#include <ipxe/memblock.h> - -/** @file - * - * Initial ramdisk (initrd) reshuffling - * - */ - -/** Maximum address available for initrd */ -userptr_t initrd_top; - -/** Minimum address available for initrd */ -userptr_t initrd_bottom; - -/** - * Squash initrds as high as possible in memory - * - * @v top Highest possible address - * @ret used Lowest address used by initrds - */ -static userptr_t initrd_squash_high ( userptr_t top ) { - userptr_t current = top; - struct image *initrd; - struct image *highest; - size_t len; - - /* Squash up any initrds already within or below the region */ - while ( 1 ) { - - /* Find the highest image not yet in its final position */ - highest = NULL; - for_each_image ( initrd ) { - if ( ( userptr_sub ( initrd->data, current ) < 0 ) && - ( ( highest == NULL ) || - ( userptr_sub ( initrd->data, - highest->data ) > 0 ) ) ) { - highest = initrd; - } - } - if ( ! highest ) - break; - - /* Move this image to its final position */ - len = ( ( highest->len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - current = userptr_sub ( current, len ); - DBGC ( &images, "INITRD squashing %s [%#08lx,%#08lx)->" - "[%#08lx,%#08lx)\n", highest->name, - user_to_phys ( highest->data, 0 ), - user_to_phys ( highest->data, highest->len ), - user_to_phys ( current, 0 ), - user_to_phys ( current, highest->len ) ); - memmove_user ( current, 0, highest->data, 0, highest->len ); - highest->data = current; - } - - /* Copy any remaining initrds (e.g. embedded images) to the region */ - for_each_image ( initrd ) { - if ( userptr_sub ( initrd->data, top ) >= 0 ) { - len = ( ( initrd->len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - current = userptr_sub ( current, len ); - DBGC ( &images, "INITRD copying %s [%#08lx,%#08lx)->" - "[%#08lx,%#08lx)\n", initrd->name, - user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ), - user_to_phys ( current, 0 ), - user_to_phys ( current, initrd->len ) ); - memcpy_user ( current, 0, initrd->data, 0, - initrd->len ); - initrd->data = current; - } - } - - return current; -} - -/** - * Swap position of two adjacent initrds - * - * @v low Lower initrd - * @v high Higher initrd - * @v free Free space - * @v free_len Length of free space - */ -static void initrd_swap ( struct image *low, struct image *high, - userptr_t free, size_t free_len ) { - size_t len = 0; - size_t frag_len; - size_t new_len; - - DBGC ( &images, "INITRD swapping %s [%#08lx,%#08lx)<->[%#08lx,%#08lx) " - "%s\n", low->name, user_to_phys ( low->data, 0 ), - user_to_phys ( low->data, low->len ), - user_to_phys ( high->data, 0 ), - user_to_phys ( high->data, high->len ), high->name ); - - /* Round down length of free space */ - free_len &= ~( INITRD_ALIGN - 1 ); - assert ( free_len > 0 ); - - /* Swap image data */ - while ( len < high->len ) { - - /* Calculate maximum fragment length */ - frag_len = ( high->len - len ); - if ( frag_len > free_len ) - frag_len = free_len; - new_len = ( ( len + frag_len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - - /* Swap fragments */ - memcpy_user ( free, 0, high->data, len, frag_len ); - memmove_user ( low->data, new_len, low->data, len, low->len ); - memcpy_user ( low->data, len, free, 0, frag_len ); - len = new_len; - } - - /* Adjust data pointers */ - high->data = low->data; - low->data = userptr_add ( low->data, len ); -} - -/** - * Swap position of any two adjacent initrds not currently in the correct order - * - * @v free Free space - * @v free_len Length of free space - * @ret swapped A pair of initrds was swapped - */ -static int initrd_swap_any ( userptr_t free, size_t free_len ) { - struct image *low; - struct image *high; - size_t padded_len; - userptr_t adjacent; - - /* Find any pair of initrds that can be swapped */ - for_each_image ( low ) { - - /* Calculate location of adjacent image (if any) */ - padded_len = ( ( low->len + INITRD_ALIGN - 1 ) & - ~( INITRD_ALIGN - 1 ) ); - adjacent = userptr_add ( low->data, padded_len ); - - /* Search for adjacent image */ - for_each_image ( high ) { - - /* If we have found the adjacent image, swap and exit */ - if ( high->data == adjacent ) { - initrd_swap ( low, high, free, free_len ); - return 1; - } - - /* Stop search if all remaining potential - * adjacent images are already in the correct - * order. - */ - if ( high == low ) - break; - } - } - - /* Nothing swapped */ - return 0; -} - -/** - * Dump initrd locations (for debug) - * - */ -static void initrd_dump ( void ) { - struct image *initrd; - - /* Do nothing unless debugging is enabled */ - if ( ! DBG_LOG ) - return; - - /* Dump initrd locations */ - for_each_image ( initrd ) { - DBGC ( &images, "INITRD %s at [%#08lx,%#08lx)\n", - initrd->name, user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ) ); - DBGC2_MD5A ( &images, user_to_phys ( initrd->data, 0 ), - user_to_virt ( initrd->data, 0 ), initrd->len ); - } -} - -/** - * Reshuffle initrds into desired order at top of memory - * - * @v bottom Lowest address available for initrds - * - * After this function returns, the initrds have been rearranged in - * memory and the external heap structures will have been corrupted. - * Reshuffling must therefore take place immediately prior to jumping - * to the loaded OS kernel; no further execution within iPXE is - * permitted. - */ -void initrd_reshuffle ( userptr_t bottom ) { - userptr_t top; - userptr_t used; - userptr_t free; - size_t free_len; - - /* Calculate limits of available space for initrds */ - top = initrd_top; - if ( userptr_sub ( initrd_bottom, bottom ) > 0 ) - bottom = initrd_bottom; - - /* Debug */ - DBGC ( &images, "INITRD region [%#08lx,%#08lx)\n", - user_to_phys ( bottom, 0 ), user_to_phys ( top, 0 ) ); - initrd_dump(); - - /* Squash initrds as high as possible in memory */ - used = initrd_squash_high ( top ); - - /* Calculate available free space */ - free = bottom; - free_len = userptr_sub ( used, free ); - - /* Bubble-sort initrds into desired order */ - while ( initrd_swap_any ( free, free_len ) ) {} - - /* Debug */ - initrd_dump(); -} - -/** - * Check that there is enough space to reshuffle initrds - * - * @v len Total length of initrds (including padding) - * @v bottom Lowest address available for initrds - * @ret rc Return status code - */ -int initrd_reshuffle_check ( size_t len, userptr_t bottom ) { - userptr_t top; - size_t available; - - /* Calculate limits of available space for initrds */ - top = initrd_top; - if ( userptr_sub ( initrd_bottom, bottom ) > 0 ) - bottom = initrd_bottom; - available = userptr_sub ( top, bottom ); - - /* Allow for a sensible minimum amount of free space */ - len += INITRD_MIN_FREE_LEN; - - /* Check for available space */ - return ( ( len < available ) ? 0 : -ENOBUFS ); -} - -/** - * initrd startup function - * - */ -static void initrd_startup ( void ) { - size_t len; - - /* Record largest memory block available. Do this after any - * allocations made during driver startup (e.g. large host - * memory blocks for Infiniband devices, which may still be in - * use at the time of rearranging if a SAN device is hooked) - * but before any allocations for downloaded images (which we - * can safely reuse when rearranging). - */ - len = largest_memblock ( &initrd_bottom ); - initrd_top = userptr_add ( initrd_bottom, len ); -} - -/** initrd startup function */ -struct startup_fn startup_initrd __startup_fn ( STARTUP_LATE ) = { - .startup = initrd_startup, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/multiboot.c b/qemu/roms/ipxe/src/arch/i386/image/multiboot.c deleted file mode 100644 index 0c85df708..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/multiboot.c +++ /dev/null @@ -1,492 +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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * Multiboot image format - * - */ - -#include <stdio.h> -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <multiboot.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/io.h> -#include <ipxe/elf.h> -#include <ipxe/init.h> -#include <ipxe/features.h> -#include <ipxe/uri.h> -#include <ipxe/version.h> - -FEATURE ( FEATURE_IMAGE, "MBOOT", DHCP_EB_FEATURE_MULTIBOOT, 1 ); - -/** - * Maximum number of modules we will allow for - * - * If this has bitten you: sorry. I did have a perfect scheme with a - * dynamically allocated list of modules on the protected-mode stack, - * but it was incompatible with some broken OSes that can only access - * low memory at boot time (even though we kindly set up 4GB flat - * physical addressing as per the multiboot specification. - * - */ -#define MAX_MODULES 8 - -/** - * Maximum combined length of command lines - * - * Again; sorry. Some broken OSes zero out any non-base memory that - * isn't part of the loaded module set, so we can't just use - * virt_to_phys(cmdline) to point to the command lines, even though - * this would comply with the Multiboot spec. - */ -#define MB_MAX_CMDLINE 512 - -/** Multiboot flags that we support */ -#define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \ - MB_FLAG_VIDMODE | MB_FLAG_RAW ) - -/** Compulsory feature multiboot flags */ -#define MB_COMPULSORY_FLAGS 0x0000ffff - -/** Optional feature multiboot flags */ -#define MB_OPTIONAL_FLAGS 0xffff0000 - -/** - * Multiboot flags that we don't support - * - * We only care about the compulsory feature flags (bits 0-15); we are - * allowed to ignore the optional feature flags. - */ -#define MB_UNSUPPORTED_FLAGS ( MB_COMPULSORY_FLAGS & ~MB_SUPPORTED_FLAGS ) - -/** A multiboot header descriptor */ -struct multiboot_header_info { - /** The actual multiboot header */ - struct multiboot_header mb; - /** Offset of header within the multiboot image */ - size_t offset; -}; - -/** Multiboot module command lines */ -static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] ); -#define mb_cmdlines __use_data16 ( mb_cmdlines ) - -/** Offset within module command lines */ -static unsigned int mb_cmdline_offset; - -/** - * Build multiboot memory map - * - * @v image Multiboot image - * @v mbinfo Multiboot information structure - * @v mbmemmap Multiboot memory map - * @v limit Maxmimum number of memory map entries - */ -static void multiboot_build_memmap ( struct image *image, - struct multiboot_info *mbinfo, - struct multiboot_memory_map *mbmemmap, - unsigned int limit ) { - struct memory_map memmap; - unsigned int i; - - /* Get memory map */ - get_memmap ( &memmap ); - - /* Translate into multiboot format */ - memset ( mbmemmap, 0, sizeof ( *mbmemmap ) ); - for ( i = 0 ; i < memmap.count ; i++ ) { - if ( i >= limit ) { - DBGC ( image, "MULTIBOOT %p limit of %d memmap " - "entries reached\n", image, limit ); - break; - } - mbmemmap[i].size = ( sizeof ( mbmemmap[i] ) - - sizeof ( mbmemmap[i].size ) ); - mbmemmap[i].base_addr = memmap.regions[i].start; - mbmemmap[i].length = ( memmap.regions[i].end - - memmap.regions[i].start ); - mbmemmap[i].type = MBMEM_RAM; - mbinfo->mmap_length += sizeof ( mbmemmap[i] ); - if ( memmap.regions[i].start == 0 ) - mbinfo->mem_lower = ( memmap.regions[i].end / 1024 ); - if ( memmap.regions[i].start == 0x100000 ) - mbinfo->mem_upper = ( ( memmap.regions[i].end - - 0x100000 ) / 1024 ); - } -} - -/** - * Add command line in base memory - * - * @v image Image - * @ret physaddr Physical address of command line - */ -static physaddr_t multiboot_add_cmdline ( struct image *image ) { - char *mb_cmdline = ( mb_cmdlines + mb_cmdline_offset ); - size_t remaining = ( sizeof ( mb_cmdlines ) - mb_cmdline_offset ); - char *buf = mb_cmdline; - size_t len; - - /* Copy image URI to base memory buffer as start of command line */ - len = ( format_uri ( image->uri, buf, remaining ) + 1 /* NUL */ ); - if ( len > remaining ) - len = remaining; - mb_cmdline_offset += len; - buf += len; - remaining -= len; - - /* Copy command line to base memory buffer, if present */ - if ( image->cmdline ) { - mb_cmdline_offset--; /* Strip NUL */ - buf--; - remaining++; - len = ( snprintf ( buf, remaining, " %s", - image->cmdline ) + 1 /* NUL */ ); - if ( len > remaining ) - len = remaining; - mb_cmdline_offset += len; - } - - return virt_to_phys ( mb_cmdline ); -} - -/** - * Add multiboot modules - * - * @v image Multiboot image - * @v start Start address for modules - * @v mbinfo Multiboot information structure - * @v modules Multiboot module list - * @ret rc Return status code - */ -static int multiboot_add_modules ( struct image *image, physaddr_t start, - struct multiboot_info *mbinfo, - struct multiboot_module *modules, - unsigned int limit ) { - struct image *module_image; - struct multiboot_module *module; - int rc; - - /* Add each image as a multiboot module */ - for_each_image ( module_image ) { - - if ( mbinfo->mods_count >= limit ) { - DBGC ( image, "MULTIBOOT %p limit of %d modules " - "reached\n", image, limit ); - break; - } - - /* Do not include kernel image itself as a module */ - if ( module_image == image ) - continue; - - /* Page-align the module */ - start = ( ( start + 0xfff ) & ~0xfff ); - - /* Prepare segment */ - if ( ( rc = prep_segment ( phys_to_user ( start ), - module_image->len, - module_image->len ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p could not prepare module " - "%s: %s\n", image, module_image->name, - strerror ( rc ) ); - return rc; - } - - /* Copy module */ - memcpy_user ( phys_to_user ( start ), 0, - module_image->data, 0, module_image->len ); - - /* Add module to list */ - module = &modules[mbinfo->mods_count++]; - module->mod_start = start; - module->mod_end = ( start + module_image->len ); - module->string = multiboot_add_cmdline ( module_image ); - module->reserved = 0; - DBGC ( image, "MULTIBOOT %p module %s is [%x,%x)\n", - image, module_image->name, module->mod_start, - module->mod_end ); - start += module_image->len; - } - - return 0; -} - -/** - * The multiboot information structure - * - * Kept in base memory because some OSes won't find it elsewhere, - * along with the other structures belonging to the Multiboot - * information table. - */ -static struct multiboot_info __bss16 ( mbinfo ); -#define mbinfo __use_data16 ( mbinfo ) - -/** The multiboot bootloader name */ -static char __bss16_array ( mb_bootloader_name, [32] ); -#define mb_bootloader_name __use_data16 ( mb_bootloader_name ) - -/** The multiboot memory map */ -static struct multiboot_memory_map - __bss16_array ( mbmemmap, [MAX_MEMORY_REGIONS] ); -#define mbmemmap __use_data16 ( mbmemmap ) - -/** The multiboot module list */ -static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] ); -#define mbmodules __use_data16 ( mbmodules ) - -/** - * Find multiboot header - * - * @v image Multiboot file - * @v hdr Multiboot header descriptor to fill in - * @ret rc Return status code - */ -static int multiboot_find_header ( struct image *image, - struct multiboot_header_info *hdr ) { - uint32_t buf[64]; - size_t offset; - unsigned int buf_idx; - uint32_t checksum; - - /* Scan through first 8kB of image file 256 bytes at a time. - * (Use the buffering to avoid the overhead of a - * copy_from_user() for every dword.) - */ - for ( offset = 0 ; offset < 8192 ; offset += sizeof ( buf[0] ) ) { - /* Check for end of image */ - if ( offset > image->len ) - break; - /* Refill buffer if applicable */ - buf_idx = ( ( offset % sizeof ( buf ) ) / sizeof ( buf[0] ) ); - if ( buf_idx == 0 ) { - copy_from_user ( buf, image->data, offset, - sizeof ( buf ) ); - } - /* Check signature */ - if ( buf[buf_idx] != MULTIBOOT_HEADER_MAGIC ) - continue; - /* Copy header and verify checksum */ - copy_from_user ( &hdr->mb, image->data, offset, - sizeof ( hdr->mb ) ); - checksum = ( hdr->mb.magic + hdr->mb.flags + - hdr->mb.checksum ); - if ( checksum != 0 ) - continue; - /* Record offset of multiboot header and return */ - hdr->offset = offset; - return 0; - } - - /* No multiboot header found */ - return -ENOEXEC; -} - -/** - * Load raw multiboot image into memory - * - * @v image Multiboot file - * @v hdr Multiboot header descriptor - * @ret entry Entry point - * @ret max Maximum used address - * @ret rc Return status code - */ -static int multiboot_load_raw ( struct image *image, - struct multiboot_header_info *hdr, - physaddr_t *entry, physaddr_t *max ) { - size_t offset; - size_t filesz; - size_t memsz; - userptr_t buffer; - int rc; - - /* Sanity check */ - if ( ! ( hdr->mb.flags & MB_FLAG_RAW ) ) { - DBGC ( image, "MULTIBOOT %p is not flagged as a raw image\n", - image ); - return -EINVAL; - } - - /* Verify and prepare segment */ - offset = ( hdr->offset - hdr->mb.header_addr + hdr->mb.load_addr ); - filesz = ( hdr->mb.load_end_addr ? - ( hdr->mb.load_end_addr - hdr->mb.load_addr ) : - ( image->len - offset ) ); - memsz = ( hdr->mb.bss_end_addr ? - ( hdr->mb.bss_end_addr - hdr->mb.load_addr ) : filesz ); - buffer = phys_to_user ( hdr->mb.load_addr ); - if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Copy image to segment */ - memcpy_user ( buffer, 0, image->data, offset, filesz ); - - /* Record execution entry point and maximum used address */ - *entry = hdr->mb.entry_addr; - *max = ( hdr->mb.load_addr + memsz ); - - return 0; -} - -/** - * Load ELF multiboot image into memory - * - * @v image Multiboot file - * @ret entry Entry point - * @ret max Maximum used address - * @ret rc Return status code - */ -static int multiboot_load_elf ( struct image *image, physaddr_t *entry, - physaddr_t *max ) { - int rc; - - /* Load ELF image*/ - if ( ( rc = elf_load ( image, entry, max ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p ELF image failed to load: %s\n", - image, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Execute multiboot image - * - * @v image Multiboot image - * @ret rc Return status code - */ -static int multiboot_exec ( struct image *image ) { - struct multiboot_header_info hdr; - physaddr_t entry; - physaddr_t max; - int rc; - - /* Locate multiboot header, if present */ - if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p has no multiboot header\n", - image ); - return rc; - } - - /* Abort if we detect flags that we cannot support */ - if ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) { - DBGC ( image, "MULTIBOOT %p flags %08x not supported\n", - image, ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) ); - return -ENOTSUP; - } - - /* There is technically a bit MB_FLAG_RAW to indicate whether - * this is an ELF or a raw image. In practice, grub will use - * the ELF header if present, and Solaris relies on this - * behaviour. - */ - if ( ( ( rc = multiboot_load_elf ( image, &entry, &max ) ) != 0 ) && - ( ( rc = multiboot_load_raw ( image, &hdr, &entry, &max ) ) != 0 )) - return rc; - - /* Populate multiboot information structure */ - memset ( &mbinfo, 0, sizeof ( mbinfo ) ); - mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP | - MBI_FLAG_CMDLINE | MBI_FLAG_MODS ); - mb_cmdline_offset = 0; - mbinfo.cmdline = multiboot_add_cmdline ( image ); - mbinfo.mods_addr = virt_to_phys ( mbmodules ); - mbinfo.mmap_addr = virt_to_phys ( mbmemmap ); - snprintf ( mb_bootloader_name, sizeof ( mb_bootloader_name ), - "iPXE %s", product_version ); - mbinfo.boot_loader_name = virt_to_phys ( mb_bootloader_name ); - if ( ( rc = multiboot_add_modules ( image, max, &mbinfo, mbmodules, - ( sizeof ( mbmodules ) / - sizeof ( mbmodules[0] ) ) ) ) !=0) - return rc; - - /* Multiboot images may not return and have no callback - * interface, so shut everything down prior to booting the OS. - */ - shutdown_boot(); - - /* Build memory map after unhiding bootloader memory regions as part of - * shutting everything down. - */ - multiboot_build_memmap ( image, &mbinfo, mbmemmap, - ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) ); - - /* Jump to OS with flat physical addressing */ - DBGC ( image, "MULTIBOOT %p starting execution at %lx\n", - image, entry ); - __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t" - "call *%%edi\n\t" - "popl %%ebp\n\t" ) - : : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ), - "b" ( virt_to_phys ( &mbinfo ) ), - "D" ( entry ) - : "ecx", "edx", "esi", "memory" ); - - DBGC ( image, "MULTIBOOT %p returned\n", image ); - - /* It isn't safe to continue after calling shutdown() */ - while ( 1 ) {} - - return -ECANCELED; /* -EIMPOSSIBLE, anyone? */ -} - -/** - * Probe multiboot image - * - * @v image Multiboot file - * @ret rc Return status code - */ -static int multiboot_probe ( struct image *image ) { - struct multiboot_header_info hdr; - int rc; - - /* Locate multiboot header, if present */ - if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) { - DBGC ( image, "MULTIBOOT %p has no multiboot header\n", - image ); - return rc; - } - DBGC ( image, "MULTIBOOT %p found header with flags %08x\n", - image, hdr.mb.flags ); - - return 0; -} - -/** Multiboot image type */ -struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT ) = { - .name = "Multiboot", - .probe = multiboot_probe, - .exec = multiboot_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/nbi.c b/qemu/roms/ipxe/src/arch/i386/image/nbi.c deleted file mode 100644 index 99046144d..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/nbi.c +++ /dev/null @@ -1,427 +0,0 @@ -#include <errno.h> -#include <assert.h> -#include <realmode.h> -#include <memsizes.h> -#include <basemem_packet.h> -#include <ipxe/uaccess.h> -#include <ipxe/segment.h> -#include <ipxe/init.h> -#include <ipxe/netdevice.h> -#include <ipxe/fakedhcp.h> -#include <ipxe/image.h> -#include <ipxe/features.h> -#include <ipxe/version.h> - -/** @file - * - * NBI image format. - * - * The Net Boot Image format is defined by the "Draft Net Boot Image - * Proposal 0.3" by Jamie Honan, Gero Kuhlmann and Ken Yap. It is now - * considered to be a legacy format, but it still included because a - * large amount of software (e.g. nymph, LTSP) makes use of NBI files. - * - * Etherboot does not implement the INT 78 callback interface - * described by the NBI specification. For a callback interface on - * x86 architecture, use PXE. - * - */ - -FEATURE ( FEATURE_IMAGE, "NBI", DHCP_EB_FEATURE_NBI, 1 ); - -/** - * An NBI image header - * - * Note that the length field uses a peculiar encoding; use the - * NBI_LENGTH() macro to decode the actual header length. - * - */ -struct imgheader { - unsigned long magic; /**< Magic number (NBI_MAGIC) */ - union { - unsigned char length; /**< Nibble-coded header length */ - unsigned long flags; /**< Image flags */ - }; - segoff_t location; /**< 16-bit seg:off header location */ - union { - segoff_t segoff; /**< 16-bit seg:off entry point */ - unsigned long linear; /**< 32-bit entry point */ - } execaddr; -} __attribute__ (( packed )); - -/** NBI magic number */ -#define NBI_MAGIC 0x1B031336UL - -/* Interpretation of the "length" fields */ -#define NBI_NONVENDOR_LENGTH(len) ( ( (len) & 0x0f ) << 2 ) -#define NBI_VENDOR_LENGTH(len) ( ( (len) & 0xf0 ) >> 2 ) -#define NBI_LENGTH(len) ( NBI_NONVENDOR_LENGTH(len) + NBI_VENDOR_LENGTH(len) ) - -/* Interpretation of the "flags" fields */ -#define NBI_PROGRAM_RETURNS(flags) ( (flags) & ( 1 << 8 ) ) -#define NBI_LINEAR_EXEC_ADDR(flags) ( (flags) & ( 1 << 31 ) ) - -/** NBI header length */ -#define NBI_HEADER_LENGTH 512 - -/** - * An NBI segment header - * - * Note that the length field uses a peculiar encoding; use the - * NBI_LENGTH() macro to decode the actual header length. - * - */ -struct segheader { - unsigned char length; /**< Nibble-coded header length */ - unsigned char vendortag; /**< Vendor-defined private tag */ - unsigned char reserved; - unsigned char flags; /**< Segment flags */ - unsigned long loadaddr; /**< Load address */ - unsigned long imglength; /**< Segment length in NBI file */ - unsigned long memlength; /**< Segment length in memory */ -}; - -/* Interpretation of the "flags" fields */ -#define NBI_LOADADDR_FLAGS(flags) ( (flags) & 0x03 ) -#define NBI_LOADADDR_ABS 0x00 -#define NBI_LOADADDR_AFTER 0x01 -#define NBI_LOADADDR_END 0x02 -#define NBI_LOADADDR_BEFORE 0x03 -#define NBI_LAST_SEGHEADER(flags) ( (flags) & ( 1 << 2 ) ) - -/* Define a type for passing info to a loaded program */ -struct ebinfo { - uint8_t major, minor; /* Version */ - uint16_t flags; /* Bit flags */ -}; - -/** - * Prepare a segment for an NBI image - * - * @v image NBI image - * @v offset Offset within NBI image - * @v filesz Length of initialised-data portion of the segment - * @v memsz Total length of the segment - * @v src Source for initialised data - * @ret rc Return status code - */ -static int nbi_prepare_segment ( struct image *image, size_t offset __unused, - userptr_t dest, size_t filesz, size_t memsz ){ - int rc; - - if ( ( rc = prep_segment ( dest, filesz, memsz ) ) != 0 ) { - DBGC ( image, "NBI %p could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - return 0; -} - -/** - * Load a segment for an NBI image - * - * @v image NBI image - * @v offset Offset within NBI image - * @v filesz Length of initialised-data portion of the segment - * @v memsz Total length of the segment - * @v src Source for initialised data - * @ret rc Return status code - */ -static int nbi_load_segment ( struct image *image, size_t offset, - userptr_t dest, size_t filesz, - size_t memsz __unused ) { - memcpy_user ( dest, 0, image->data, offset, filesz ); - return 0; -} - -/** - * Process segments of an NBI image - * - * @v image NBI image - * @v imgheader Image header information - * @v process Function to call for each segment - * @ret rc Return status code - */ -static int nbi_process_segments ( struct image *image, - struct imgheader *imgheader, - int ( * process ) ( struct image *image, - size_t offset, - userptr_t dest, - size_t filesz, - size_t memsz ) ) { - struct segheader sh; - size_t offset = 0; - size_t sh_off; - userptr_t dest; - size_t filesz; - size_t memsz; - int rc; - - /* Copy image header to target location */ - dest = real_to_user ( imgheader->location.segment, - imgheader->location.offset ); - filesz = memsz = NBI_HEADER_LENGTH; - if ( ( rc = process ( image, offset, dest, filesz, memsz ) ) != 0 ) - return rc; - offset += filesz; - - /* Process segments in turn */ - sh_off = NBI_LENGTH ( imgheader->length ); - do { - /* Read segment header */ - copy_from_user ( &sh, image->data, sh_off, sizeof ( sh ) ); - if ( sh.length == 0 ) { - /* Avoid infinite loop? */ - DBGC ( image, "NBI %p invalid segheader length 0\n", - image ); - return -ENOEXEC; - } - - /* Calculate segment load address */ - switch ( NBI_LOADADDR_FLAGS ( sh.flags ) ) { - case NBI_LOADADDR_ABS: - dest = phys_to_user ( sh.loadaddr ); - break; - case NBI_LOADADDR_AFTER: - dest = userptr_add ( dest, memsz + sh.loadaddr ); - break; - case NBI_LOADADDR_BEFORE: - dest = userptr_add ( dest, -sh.loadaddr ); - break; - case NBI_LOADADDR_END: - /* Not correct according to the spec, but - * maintains backwards compatibility with - * previous versions of Etherboot. - */ - dest = phys_to_user ( ( extmemsize() + 1024 ) * 1024 - - sh.loadaddr ); - break; - default: - /* Cannot be reached */ - assert ( 0 ); - } - - /* Process this segment */ - filesz = sh.imglength; - memsz = sh.memlength; - if ( ( offset + filesz ) > image->len ) { - DBGC ( image, "NBI %p segment outside file\n", image ); - return -ENOEXEC; - } - if ( ( rc = process ( image, offset, dest, - filesz, memsz ) ) != 0 ) { - return rc; - } - offset += filesz; - - /* Next segheader */ - sh_off += NBI_LENGTH ( sh.length ); - if ( sh_off >= NBI_HEADER_LENGTH ) { - DBGC ( image, "NBI %p header overflow\n", image ); - return -ENOEXEC; - } - - } while ( ! NBI_LAST_SEGHEADER ( sh.flags ) ); - - if ( offset != image->len ) { - DBGC ( image, "NBI %p length wrong (file %zd, metadata %zd)\n", - image, image->len, offset ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Boot a 16-bit NBI image - * - * @v imgheader Image header information - * @ret rc Return status code, if image returns - */ -static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) { - int discard_D, discard_S, discard_b; - int rc; - - DBGC ( image, "NBI %p executing 16-bit image at %04x:%04x\n", image, - imgheader->execaddr.segoff.segment, - imgheader->execaddr.segoff.offset ); - - __asm__ __volatile__ ( - REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "pushw %%ds\n\t" /* far pointer to bootp data */ - "pushw %%bx\n\t" - "pushl %%esi\n\t" /* location */ - "pushw %%cs\n\t" /* lcall execaddr */ - "call 1f\n\t" - "jmp 2f\n\t" - "\n1:\n\t" - "pushl %%edi\n\t" - "lret\n\t" - "\n2:\n\t" - "addw $8,%%sp\n\t" /* clean up stack */ - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ), - "=b" ( discard_b ) - : "D" ( imgheader->execaddr.segoff ), - "S" ( imgheader->location ), - "b" ( __from_data16 ( basemem_packet ) ) - : "ecx", "edx" ); - - return rc; -} - -/** - * Boot a 32-bit NBI image - * - * @v imgheader Image header information - * @ret rc Return status code, if image returns - */ -static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) { - struct ebinfo loaderinfo = { - product_major_version, product_minor_version, - 0 - }; - int discard_D, discard_S, discard_b; - int rc; - - DBGC ( image, "NBI %p executing 32-bit image at %lx\n", - image, imgheader->execaddr.linear ); - - /* Jump to OS with flat physical addressing */ - __asm__ __volatile__ ( - PHYS_CODE ( "pushl %%ebp\n\t" /* gcc bug */ - "pushl %%ebx\n\t" /* bootp data */ - "pushl %%esi\n\t" /* imgheader */ - "pushl %%eax\n\t" /* loaderinfo */ - "call *%%edi\n\t" - "addl $12, %%esp\n\t" /* clean up stack */ - "popl %%ebp\n\t" /* gcc bug */ ) - : "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ), - "=b" ( discard_b ) - : "D" ( imgheader->execaddr.linear ), - "S" ( ( imgheader->location.segment << 4 ) + - imgheader->location.offset ), - "b" ( virt_to_phys ( basemem_packet ) ), - "a" ( virt_to_phys ( &loaderinfo ) ) - : "ecx", "edx", "memory" ); - - return rc; -} - -/** - * Prepare DHCP parameter block for NBI image - * - * @v image NBI image - * @ret rc Return status code - */ -static int nbi_prepare_dhcp ( struct image *image ) { - struct net_device *boot_netdev; - int rc; - - boot_netdev = last_opened_netdev(); - if ( ! boot_netdev ) { - DBGC ( image, "NBI %p could not identify a network device\n", - image ); - return -ENODEV; - } - - if ( ( rc = create_fakedhcpack ( boot_netdev, basemem_packet, - sizeof ( basemem_packet ) ) ) != 0 ) { - DBGC ( image, "NBI %p failed to build DHCP packet\n", image ); - return rc; - } - - return 0; -} - -/** - * Execute a loaded NBI image - * - * @v image NBI image - * @ret rc Return status code - */ -static int nbi_exec ( struct image *image ) { - struct imgheader imgheader; - int may_return; - int rc; - - /* Retrieve image header */ - copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) ); - - DBGC ( image, "NBI %p placing header at %hx:%hx\n", image, - imgheader.location.segment, imgheader.location.offset ); - - /* NBI files can have overlaps between segments; the bss of - * one segment may overlap the initialised data of another. I - * assume this is a design flaw, but there are images out - * there that we need to work with. We therefore do two - * passes: first to initialise the segments, then to copy the - * data. This avoids zeroing out already-copied data. - */ - if ( ( rc = nbi_process_segments ( image, &imgheader, - nbi_prepare_segment ) ) != 0 ) - return rc; - if ( ( rc = nbi_process_segments ( image, &imgheader, - nbi_load_segment ) ) != 0 ) - return rc; - - /* Prepare DHCP option block */ - if ( ( rc = nbi_prepare_dhcp ( image ) ) != 0 ) - return rc; - - /* Shut down now if NBI image will not return */ - may_return = NBI_PROGRAM_RETURNS ( imgheader.flags ); - if ( ! may_return ) - shutdown_boot(); - - /* Execute NBI image */ - if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) { - rc = nbi_boot32 ( image, &imgheader ); - } else { - rc = nbi_boot16 ( image, &imgheader ); - } - - if ( ! may_return ) { - /* Cannot continue after shutdown() called */ - DBGC ( image, "NBI %p returned %d from non-returnable image\n", - image, rc ); - while ( 1 ) {} - } - - DBGC ( image, "NBI %p returned %d\n", image, rc ); - - return rc; -} - -/** - * Probe NBI image - * - * @v image NBI image - * @ret rc Return status code - */ -static int nbi_probe ( struct image *image ) { - struct imgheader imgheader; - - /* If we don't have enough data give up */ - if ( image->len < NBI_HEADER_LENGTH ) { - DBGC ( image, "NBI %p too short for an NBI image\n", image ); - return -ENOEXEC; - } - - /* Check image header */ - copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) ); - if ( imgheader.magic != NBI_MAGIC ) { - DBGC ( image, "NBI %p has no NBI signature\n", image ); - return -ENOEXEC; - } - - return 0; -} - -/** NBI image type */ -struct image_type nbi_image_type __image_type ( PROBE_NORMAL ) = { - .name = "NBI", - .probe = nbi_probe, - .exec = nbi_exec, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/pxe_image.c b/qemu/roms/ipxe/src/arch/i386/image/pxe_image.c deleted file mode 100644 index 5b0f6eb89..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/pxe_image.c +++ /dev/null @@ -1,171 +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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * PXE image format - * - */ - -#include <pxe.h> -#include <pxe_call.h> -#include <ipxe/uaccess.h> -#include <ipxe/image.h> -#include <ipxe/segment.h> -#include <ipxe/netdevice.h> -#include <ipxe/features.h> -#include <ipxe/console.h> -#include <ipxe/efi/efi.h> -#include <ipxe/efi/IndustryStandard/PeImage.h> - -FEATURE ( FEATURE_IMAGE, "PXE", DHCP_EB_FEATURE_PXE, 1 ); - -/** PXE command line */ -const char *pxe_cmdline; - -/** - * Execute PXE image - * - * @v image PXE image - * @ret rc Return status code - */ -static int pxe_exec ( struct image *image ) { - userptr_t buffer = real_to_user ( 0, 0x7c00 ); - struct net_device *netdev; - int rc; - - /* Verify and prepare segment */ - if ( ( rc = prep_segment ( buffer, image->len, image->len ) ) != 0 ) { - DBGC ( image, "IMAGE %p could not prepare segment: %s\n", - image, strerror ( rc ) ); - return rc; - } - - /* Copy image to segment */ - memcpy_user ( buffer, 0, image->data, 0, image->len ); - - /* Arbitrarily pick the most recently opened network device */ - if ( ( netdev = last_opened_netdev() ) == NULL ) { - DBGC ( image, "IMAGE %p could not locate PXE net device\n", - image ); - return -ENODEV; - } - netdev_get ( netdev ); - - /* Activate PXE */ - pxe_activate ( netdev ); - - /* Set PXE command line */ - pxe_cmdline = image->cmdline; - - /* Reset console since PXE NBP will probably use it */ - console_reset(); - - /* Start PXE NBP */ - rc = pxe_start_nbp(); - - /* Clear PXE command line */ - pxe_cmdline = NULL; - - /* Deactivate PXE */ - pxe_deactivate(); - - /* Try to reopen network device. Ignore errors, since the NBP - * may have called PXENV_STOP_UNDI. - */ - netdev_open ( netdev ); - netdev_put ( netdev ); - - return rc; -} - -/** - * Probe PXE image - * - * @v image PXE file - * @ret rc Return status code - */ -int pxe_probe ( struct image *image ) { - - /* Images too large to fit in base memory cannot be PXE - * images. We include this check to help prevent unrecognised - * images from being marked as PXE images, since PXE images - * have no signature we can check against. - */ - if ( image->len > ( 0xa0000 - 0x7c00 ) ) - return -ENOEXEC; - - /* Rejecting zero-length images is also useful, since these - * end up looking to the user like bugs in iPXE. - */ - if ( ! image->len ) - return -ENOEXEC; - - return 0; -} - -/** - * Probe PXE image (with rejection of potential EFI images) - * - * @v image PXE file - * @ret rc Return status code - */ -int pxe_probe_no_mz ( struct image *image ) { - uint16_t magic; - int rc; - - /* Probe PXE image */ - if ( ( rc = pxe_probe ( image ) ) != 0 ) - return rc; - - /* Reject image with an "MZ" signature which may indicate an - * EFI image incorrectly handed out to a BIOS system. - */ - if ( image->len >= sizeof ( magic ) ) { - copy_from_user ( &magic, image->data, 0, sizeof ( magic ) ); - if ( magic == cpu_to_le16 ( EFI_IMAGE_DOS_SIGNATURE ) ) { - DBGC ( image, "IMAGE %p may be an EFI image\n", - image ); - return -ENOTTY; - } - } - - return 0; -} - -/** PXE image type */ -struct image_type pxe_image_type[] __image_type ( PROBE_PXE ) = { - { - .name = "PXE-NBP", - .probe = pxe_probe_no_mz, - .exec = pxe_exec, - }, - { - .name = "PXE-NBP (may be EFI?)", - .probe = pxe_probe, - .exec = pxe_exec, - }, -}; diff --git a/qemu/roms/ipxe/src/arch/i386/image/sdi.c b/qemu/roms/ipxe/src/arch/i386/image/sdi.c deleted file mode 100644 index fa2d0b73f..000000000 --- a/qemu/roms/ipxe/src/arch/i386/image/sdi.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2012 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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <errno.h> -#include <realmode.h> -#include <sdi.h> -#include <ipxe/image.h> -#include <ipxe/features.h> - -/** @file - * - * System Deployment Image (SDI) - * - * Based on the MSDN article "RAM boot using SDI in Windows XP - * Embedded with Service Pack 1", available at the time of writing - * from: - * - * http://msdn.microsoft.com/en-us/library/ms838543.aspx - */ - -FEATURE ( FEATURE_IMAGE, "SDI", DHCP_EB_FEATURE_SDI, 1 ); - -/** - * Parse SDI image header - * - * @v image SDI file - * @v sdi SDI header to fill in - * @ret rc Return status code - */ -static int sdi_parse_header ( struct image *image, struct sdi_header *sdi ) { - - /* Sanity check */ - if ( image->len < sizeof ( *sdi ) ) { - DBGC ( image, "SDI %p too short for SDI header\n", image ); - return -ENOEXEC; - } - - /* Read in header */ - copy_from_user ( sdi, image->data, 0, sizeof ( *sdi ) ); - - /* Check signature */ - if ( sdi->magic != SDI_MAGIC ) { - DBGC ( image, "SDI %p is not an SDI image\n", image ); - return -ENOEXEC; - } - - return 0; -} - -/** - * Execute SDI image - * - * @v image SDI file - * @ret rc Return status code - */ -static int sdi_exec ( struct image *image ) { - struct sdi_header sdi; - uint32_t sdiptr; - int rc; - - /* Parse image header */ - if ( ( rc = sdi_parse_header ( image, &sdi ) ) != 0 ) - return rc; - - /* Check that image is bootable */ - if ( sdi.boot_size == 0 ) { - DBGC ( image, "SDI %p is not bootable\n", image ); - return -ENOTTY; - } - DBGC ( image, "SDI %p image at %08lx+%08zx\n", - image, user_to_phys ( image->data, 0 ), image->len ); - DBGC ( image, "SDI %p boot code at %08lx+%llx\n", image, - user_to_phys ( image->data, sdi.boot_offset ), sdi.boot_size ); - - /* Copy boot code */ - memcpy_user ( real_to_user ( SDI_BOOT_SEG, SDI_BOOT_OFF ), 0, - image->data, sdi.boot_offset, sdi.boot_size ); - - /* Jump to boot code */ - sdiptr = ( user_to_phys ( image->data, 0 ) | SDI_WTF ); - __asm__ __volatile__ ( REAL_CODE ( "ljmp %0, %1\n\t" ) - : : "i" ( SDI_BOOT_SEG ), - "i" ( SDI_BOOT_OFF ), - "d" ( sdiptr ) ); - - /* There is no way for the image to return, since we provide - * no return address. - */ - assert ( 0 ); - - return -ECANCELED; /* -EIMPOSSIBLE */ -} - -/** - * Probe SDI image - * - * @v image SDI file - * @ret rc Return status code - */ -static int sdi_probe ( struct image *image ) { - struct sdi_header sdi; - int rc; - - /* Parse image */ - if ( ( rc = sdi_parse_header ( image, &sdi ) ) != 0 ) - return rc; - - return 0; -} - -/** SDI image type */ -struct image_type sdi_image_type __image_type ( PROBE_NORMAL ) = { - .name = "SDI", - .probe = sdi_probe, - .exec = sdi_exec, -}; |