From patchwork Mon Jan 29 20:43:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatol Pomozov X-Patchwork-Id: 867287 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="tGwoB11k"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zVhMd1stSz9s75 for ; Tue, 30 Jan 2018 07:44:44 +1100 (AEDT) Received: from localhost ([::1]:37762 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGID-0002Oz-Jr for incoming@patchwork.ozlabs.org; Mon, 29 Jan 2018 15:44:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39551) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGHZ-0002OK-Qx for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egGHX-00017F-35 for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:01 -0500 Received: from mail-pg0-x244.google.com ([2607:f8b0:400e:c05::244]:34459) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1egGHW-00016C-MD for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:43:59 -0500 Received: by mail-pg0-x244.google.com with SMTP id r19so5398580pgn.1 for ; Mon, 29 Jan 2018 12:43:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=DO8q+SVAFO6lsowvfO9pn8z+iKp3nXEh1lPTEWVXa/I=; b=tGwoB11kw2/6dD2SNPoql9rhYJuWLC1WPyyJCT/sYVA3zz3PK/ux8lCz3bvu87AOBq CNDhBx8nzyqhXrwAhRZ8id1rF4zoI47mtTfSBNtpXaFxfvOyr+n3ncbu7NJyhh3ypIjk PbXblgcuicvksRRDyfmg3qr3cvPBNtQeGosz02jbObn0EfJtSvgFAmsGMX2Ap1FUEWM0 99uRS8oIWxbEU5eQMRCKT55RmAxuKB93++8rgfmPm8Qac2K9U8juS1POlPQSOiRHBIvR eRqrX1/stVpCKe/OzClI8WzqaOrQ0tXJi4P0mGT56RYCARpWa6d8yfTKuw7kIFoTo2Jt wdtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=DO8q+SVAFO6lsowvfO9pn8z+iKp3nXEh1lPTEWVXa/I=; b=gTVdXl+Mk7nCF6KM1HjIZncndRKxQVSTB4zwapjgT9q3IUXyVNnLcEkQOlf13ehQSv ZUZA1KUe0deAYTNvOayVv0S4jgEgcIWTWPtlaK6t89DBjScVt7XIWplllM5+thEZ+4eG jpqJ688CmK7qAncOrp9/6WNdlb+4z3/q2uO5n533PE1310OywseBuJBjBxwBl97UsjW7 1odZhMhBtWuYQf9x+KYp6VjfpLyA3MUOTRWDYgM8xAi2XWISnIKupiCy46A90Rl3o5Zc vtMP3ODgDmctQlpYVtwi0C1SMK96kROXqO4zJSXagU6vQnfG+EyDBn+b7/rv1sA78jpf e+jA== X-Gm-Message-State: AKwxyteH5mc6E7s42m8foVJNzG5cY7oLETHhnEOKY2K/Rydi2QeopYHf Z9trxdUdp6ZEL/7ffLr5pijatieaCS0= X-Google-Smtp-Source: AH8x226YOdjYUG5+qvKH1/PHrCEh75VEr1gM4ag7A4rznqxQtPmZG6jB1aRNIul4eYLJNbxsyeaxow== X-Received: by 10.99.182.75 with SMTP id v11mr17321209pgt.158.1517258636773; Mon, 29 Jan 2018 12:43:56 -0800 (PST) Received: from anatol.mtv.corp.google.com ([2620:15c:202:1:a4ef:a3cf:87b8:ef77]) by smtp.gmail.com with ESMTPSA id t1sm37436140pfj.21.2018.01.29.12.43.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 12:43:55 -0800 (PST) From: Anatol Pomozov To: qemu-devel@nongnu.org Date: Mon, 29 Jan 2018 12:43:41 -0800 Message-Id: <20180129204344.196196-1-anatol.pomozov@gmail.com> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::244 Subject: [Qemu-devel] [PATCH 1/4] multiboot: Change multiboot_info from array of bytes to a C struct X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, Anatol Pomozov , jack.schwartz@oracle.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Using C structs makes the code more readable and prevents type conversion errors. Borrow multiboot1 header from GRUB project. Signed-off-by: Anatol Pomozov --- hw/i386/multiboot.c | 124 +++++++++------------ hw/i386/multiboot_header.h | 254 ++++++++++++++++++++++++++++++++++++++++++++ tests/multiboot/mmap.c | 14 +-- tests/multiboot/mmap.out | 10 ++ tests/multiboot/modules.c | 12 ++- tests/multiboot/modules.out | 10 ++ tests/multiboot/multiboot.h | 66 ------------ 7 files changed, 339 insertions(+), 151 deletions(-) create mode 100644 hw/i386/multiboot_header.h delete mode 100644 tests/multiboot/multiboot.h diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index c7b70c91d5..c6d05ca46b 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -28,6 +28,7 @@ #include "hw/hw.h" #include "hw/nvram/fw_cfg.h" #include "multiboot.h" +#include "multiboot_header.h" #include "hw/loader.h" #include "elf.h" #include "sysemu/sysemu.h" @@ -47,39 +48,9 @@ #error multiboot struct needs to fit in 16 bit real mode #endif -enum { - /* Multiboot info */ - MBI_FLAGS = 0, - MBI_MEM_LOWER = 4, - MBI_MEM_UPPER = 8, - MBI_BOOT_DEVICE = 12, - MBI_CMDLINE = 16, - MBI_MODS_COUNT = 20, - MBI_MODS_ADDR = 24, - MBI_MMAP_ADDR = 48, - MBI_BOOTLOADER = 64, - - MBI_SIZE = 88, - - /* Multiboot modules */ - MB_MOD_START = 0, - MB_MOD_END = 4, - MB_MOD_CMDLINE = 8, - - MB_MOD_SIZE = 16, - - /* Region offsets */ - ADDR_E820_MAP = MULTIBOOT_STRUCT_ADDR + 0, - ADDR_MBI = ADDR_E820_MAP + 0x500, - - /* Multiboot flags */ - MULTIBOOT_FLAGS_MEMORY = 1 << 0, - MULTIBOOT_FLAGS_BOOT_DEVICE = 1 << 1, - MULTIBOOT_FLAGS_CMDLINE = 1 << 2, - MULTIBOOT_FLAGS_MODULES = 1 << 3, - MULTIBOOT_FLAGS_MMAP = 1 << 6, - MULTIBOOT_FLAGS_BOOTLOADER = 1 << 9, -}; +/* Region offsets */ +#define ADDR_E820_MAP MULTIBOOT_STRUCT_ADDR +#define ADDR_MBI (ADDR_E820_MAP + 0x500) typedef struct { /* buffer holding kernel, cmdlines and mb_infos */ @@ -128,14 +99,15 @@ static void mb_add_mod(MultibootState *s, hwaddr start, hwaddr end, hwaddr cmdline_phys) { - char *p; + multiboot_module_t *mod; assert(s->mb_mods_count < s->mb_mods_avail); - p = (char *)s->mb_buf + s->offset_mbinfo + MB_MOD_SIZE * s->mb_mods_count; + mod = s->mb_buf + s->offset_mbinfo + + sizeof(multiboot_module_t) * s->mb_mods_count; - stl_p(p + MB_MOD_START, start); - stl_p(p + MB_MOD_END, end); - stl_p(p + MB_MOD_CMDLINE, cmdline_phys); + stl_p(&mod->mod_start, start); + stl_p(&mod->mod_end, end); + stl_p(&mod->cmdline, cmdline_phys); mb_debug("mod%02d: "TARGET_FMT_plx" - "TARGET_FMT_plx"\n", s->mb_mods_count, start, end); @@ -151,26 +123,29 @@ int load_multiboot(FWCfgState *fw_cfg, int kernel_file_size, uint8_t *header) { - int i, is_multiboot = 0; + int i; + bool is_multiboot = false; uint32_t flags = 0; uint32_t mh_entry_addr; uint32_t mh_load_addr; uint32_t mb_kernel_size; MultibootState mbs; - uint8_t bootinfo[MBI_SIZE]; + multiboot_info_t bootinfo; uint8_t *mb_bootinfo_data; uint32_t cmdline_len; + struct multiboot_header *multiboot_header; /* Ok, let's see if it is a multiboot image. The header is 12x32bit long, so the latest entry may be 8192 - 48. */ for (i = 0; i < (8192 - 48); i += 4) { - if (ldl_p(header+i) == 0x1BADB002) { - uint32_t checksum = ldl_p(header+i+8); - flags = ldl_p(header+i+4); + multiboot_header = (struct multiboot_header *)(header + i); + if (ldl_p(&multiboot_header->magic) == MULTIBOOT_HEADER_MAGIC) { + uint32_t checksum = ldl_p(&multiboot_header->checksum); + flags = ldl_p(&multiboot_header->flags); checksum += flags; - checksum += (uint32_t)0x1BADB002; + checksum += (uint32_t)MULTIBOOT_HEADER_MAGIC; if (!checksum) { - is_multiboot = 1; + is_multiboot = true; break; } } @@ -180,13 +155,13 @@ int load_multiboot(FWCfgState *fw_cfg, return 0; /* no multiboot */ mb_debug("qemu: I believe we found a multiboot image!\n"); - memset(bootinfo, 0, sizeof(bootinfo)); + memset(&bootinfo, 0, sizeof(bootinfo)); memset(&mbs, 0, sizeof(mbs)); - if (flags & 0x00000004) { /* MULTIBOOT_HEADER_HAS_VBE */ + if (flags & MULTIBOOT_VIDEO_MODE) { fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n"); } - if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */ + if (!(flags & MULTIBOOT_AOUT_KLUDGE)) { uint64_t elf_entry; uint64_t elf_low, elf_high; int kernel_size; @@ -217,12 +192,12 @@ int load_multiboot(FWCfgState *fw_cfg, mb_debug("qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n", mb_kernel_size, (size_t)mh_entry_addr); } else { - /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */ - uint32_t mh_header_addr = ldl_p(header+i+12); - uint32_t mh_load_end_addr = ldl_p(header+i+20); - uint32_t mh_bss_end_addr = ldl_p(header+i+24); + /* Valid if mh_flags sets MULTIBOOT_AOUT_KLUDGE. */ + uint32_t mh_header_addr = ldl_p(&multiboot_header->header_addr); + uint32_t mh_load_end_addr = ldl_p(&multiboot_header->load_end_addr); + uint32_t mh_bss_end_addr = ldl_p(&multiboot_header->bss_end_addr); + mh_load_addr = ldl_p(&multiboot_header->load_addr); - mh_load_addr = ldl_p(header+i+16); if (mh_header_addr < mh_load_addr) { fprintf(stderr, "invalid mh_load_addr address\n"); exit(1); @@ -230,7 +205,7 @@ int load_multiboot(FWCfgState *fw_cfg, uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr); uint32_t mb_load_size = 0; - mh_entry_addr = ldl_p(header+i+28); + mh_entry_addr = ldl_p(&multiboot_header->entry_addr); if (mh_load_end_addr) { if (mh_bss_end_addr < mh_load_addr) { @@ -253,11 +228,11 @@ int load_multiboot(FWCfgState *fw_cfg, mb_load_size = mb_kernel_size; } - /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. - uint32_t mh_mode_type = ldl_p(header+i+32); - uint32_t mh_width = ldl_p(header+i+36); - uint32_t mh_height = ldl_p(header+i+40); - uint32_t mh_depth = ldl_p(header+i+44); */ + /* Valid if mh_flags sets MULTIBOOT_VIDEO_MODE. + uint32_t mh_mode_type = ldl_p(&multiboot_header->mode_type); + uint32_t mh_width = ldl_p(&multiboot_header->width); + uint32_t mh_height = ldl_p(&multiboot_header->height); + uint32_t mh_depth = ldl_p(&multiboot_header->depth); */ mb_debug("multiboot: mh_header_addr = %#x\n", mh_header_addr); mb_debug("multiboot: mh_load_addr = %#x\n", mh_load_addr); @@ -295,14 +270,15 @@ int load_multiboot(FWCfgState *fw_cfg, } mbs.mb_buf_size += cmdline_len; - mbs.mb_buf_size += MB_MOD_SIZE * mbs.mb_mods_avail; + mbs.mb_buf_size += sizeof(multiboot_module_t) * mbs.mb_mods_avail; mbs.mb_buf_size += strlen(bootloader_name) + 1; mbs.mb_buf_size = TARGET_PAGE_ALIGN(mbs.mb_buf_size); /* enlarge mb_buf to hold cmdlines, bootloader, mb-info structs */ mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size); - mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE; + mbs.offset_cmdlines = mbs.offset_mbinfo + + mbs.mb_mods_avail * sizeof(multiboot_module_t); mbs.offset_bootloader = mbs.offset_cmdlines + cmdline_len; if (initrd_filename) { @@ -348,22 +324,22 @@ int load_multiboot(FWCfgState *fw_cfg, char kcmdline[strlen(kernel_filename) + strlen(kernel_cmdline) + 2]; snprintf(kcmdline, sizeof(kcmdline), "%s %s", kernel_filename, kernel_cmdline); - stl_p(bootinfo + MBI_CMDLINE, mb_add_cmdline(&mbs, kcmdline)); + stl_p(&bootinfo.cmdline, mb_add_cmdline(&mbs, kcmdline)); - stl_p(bootinfo + MBI_BOOTLOADER, mb_add_bootloader(&mbs, bootloader_name)); + stl_p(&bootinfo.boot_loader_name, mb_add_bootloader(&mbs, bootloader_name)); - stl_p(bootinfo + MBI_MODS_ADDR, mbs.mb_buf_phys + mbs.offset_mbinfo); - stl_p(bootinfo + MBI_MODS_COUNT, mbs.mb_mods_count); /* mods_count */ + stl_p(&bootinfo.mods_addr, mbs.mb_buf_phys + mbs.offset_mbinfo); + stl_p(&bootinfo.mods_count, mbs.mb_mods_count); /* mods_count */ /* the kernel is where we want it to be now */ - stl_p(bootinfo + MBI_FLAGS, MULTIBOOT_FLAGS_MEMORY - | MULTIBOOT_FLAGS_BOOT_DEVICE - | MULTIBOOT_FLAGS_CMDLINE - | MULTIBOOT_FLAGS_MODULES - | MULTIBOOT_FLAGS_MMAP - | MULTIBOOT_FLAGS_BOOTLOADER); - stl_p(bootinfo + MBI_BOOT_DEVICE, 0x8000ffff); /* XXX: use the -boot switch? */ - stl_p(bootinfo + MBI_MMAP_ADDR, ADDR_E820_MAP); + stl_p(&bootinfo.flags, MULTIBOOT_INFO_MEMORY + | MULTIBOOT_INFO_BOOTDEV + | MULTIBOOT_INFO_CMDLINE + | MULTIBOOT_INFO_MODS + | MULTIBOOT_INFO_MEM_MAP + | MULTIBOOT_INFO_BOOT_LOADER_NAME); + stl_p(&bootinfo.boot_device, 0x8000ffff); /* XXX: use the -boot switch? */ + stl_p(&bootinfo.mmap_addr, ADDR_E820_MAP); mb_debug("multiboot: mh_entry_addr = %#x\n", mh_entry_addr); mb_debug(" mb_buf_phys = "TARGET_FMT_plx"\n", mbs.mb_buf_phys); @@ -371,7 +347,7 @@ int load_multiboot(FWCfgState *fw_cfg, mb_debug(" mb_mods_count = %d\n", mbs.mb_mods_count); /* save bootinfo off the stack */ - mb_bootinfo_data = g_memdup(bootinfo, sizeof(bootinfo)); + mb_bootinfo_data = g_memdup(&bootinfo, sizeof(bootinfo)); /* Pass variables to option rom */ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ENTRY, mh_entry_addr); diff --git a/hw/i386/multiboot_header.h b/hw/i386/multiboot_header.h new file mode 100644 index 0000000000..563014698c --- /dev/null +++ b/hw/i386/multiboot_header.h @@ -0,0 +1,254 @@ +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the 'flags' member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the 'flags' member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +struct multiboot_header { + /* Must be MULTIBOOT_MAGIC - see above. */ + uint32_t magic; + + /* Feature flags. */ + uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + uint32_t header_addr; + uint32_t load_addr; + uint32_t load_end_addr; + uint32_t bss_end_addr; + uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + uint32_t mode_type; + uint32_t width; + uint32_t height; + uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table { + uint32_t tabsize; + uint32_t strsize; + uint32_t addr; + uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table { + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table + multiboot_elf_section_header_table_t; + +struct multiboot_info { + /* Multiboot info version number */ + uint32_t flags; + + /* Available memory from BIOS */ + uint32_t mem_lower; + uint32_t mem_upper; + + /* "root" partition */ + uint32_t boot_device; + + /* Kernel command line */ + uint32_t cmdline; + + /* Boot-Module list */ + uint32_t mods_count; + uint32_t mods_addr; + + union { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + uint32_t mmap_length; + uint32_t mmap_addr; + + /* Drive Info buffer */ + uint32_t drives_length; + uint32_t drives_addr; + + /* ROM configuration table */ + uint32_t config_table; + + /* Boot Loader Name */ + uint32_t boot_loader_name; + + /* APM table */ + uint32_t apm_table; + + /* Video */ + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + uint8_t framebuffer_type; + union { + struct { + uint32_t framebuffer_palette_addr; + uint16_t framebuffer_palette_num_colors; + }; + struct { + uint8_t framebuffer_red_field_position; + uint8_t framebuffer_red_mask_size; + uint8_t framebuffer_green_field_position; + uint8_t framebuffer_green_mask_size; + uint8_t framebuffer_blue_field_position; + uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color { + uint8_t red; + uint8_t green; + uint8_t blue; +}; + +struct multiboot_mmap_entry { + uint32_t size; + uint64_t addr; + uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + uint32_t type; +} __attribute__ ((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list { + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + uint32_t mod_start; + uint32_t mod_end; + + /* Module command line */ + uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info { + uint16_t version; + uint16_t cseg; + uint32_t offset; + uint16_t cseg_16; + uint16_t dseg; + uint16_t flags; + uint16_t cseg_len; + uint16_t cseg_16_len; + uint16_t dseg_len; +}; + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/tests/multiboot/mmap.c b/tests/multiboot/mmap.c index 766b003f38..9cba8b07e0 100644 --- a/tests/multiboot/mmap.c +++ b/tests/multiboot/mmap.c @@ -21,15 +21,17 @@ */ #include "libc.h" -#include "multiboot.h" +#include "../../hw/i386/multiboot_header.h" -int test_main(uint32_t magic, struct mb_info *mbi) +int test_main(uint32_t magic, struct multiboot_info *mbi) { uintptr_t entry_addr; - struct mb_mmap_entry *entry; + struct multiboot_mmap_entry *entry; (void) magic; + printf("Multiboot header at %x\n\n", mbi); + printf("Lower memory: %dk\n", mbi->mem_lower); printf("Upper memory: %dk\n", mbi->mem_upper); @@ -39,11 +41,11 @@ int test_main(uint32_t magic, struct mb_info *mbi) entry_addr < mbi->mmap_addr + mbi->mmap_length; entry_addr += entry->size + 4) { - entry = (struct mb_mmap_entry*) entry_addr; + entry = (struct multiboot_mmap_entry*) entry_addr; printf("%#llx - %#llx: type %d [entry size: %d]\n", - entry->base_addr, - entry->base_addr + entry->length, + entry->addr, + entry->addr + entry->len, entry->type, entry->size); } diff --git a/tests/multiboot/mmap.out b/tests/multiboot/mmap.out index 003e109b4c..e3a28237ab 100644 --- a/tests/multiboot/mmap.out +++ b/tests/multiboot/mmap.out @@ -3,6 +3,8 @@ === Running test case: mmap.elf === +Multiboot header at 9500 + Lower memory: 639k Upper memory: 129920k @@ -21,6 +23,8 @@ real mmap end: 0x9090 === Running test case: mmap.elf -m 1.1M === +Multiboot header at 9500 + Lower memory: 639k Upper memory: 104k @@ -38,6 +42,8 @@ real mmap end: 0x9078 === Running test case: mmap.elf -m 2G === +Multiboot header at 9500 + Lower memory: 639k Upper memory: 2096000k @@ -56,6 +62,8 @@ real mmap end: 0x9090 === Running test case: mmap.elf -m 4G === +Multiboot header at 9500 + Lower memory: 639k Upper memory: 3144576k @@ -75,6 +83,8 @@ real mmap end: 0x90a8 === Running test case: mmap.elf -m 8G === +Multiboot header at 9500 + Lower memory: 639k Upper memory: 3144576k diff --git a/tests/multiboot/modules.c b/tests/multiboot/modules.c index 531601fb30..a1da0ded44 100644 --- a/tests/multiboot/modules.c +++ b/tests/multiboot/modules.c @@ -21,19 +21,21 @@ */ #include "libc.h" -#include "multiboot.h" +#include "../../hw/i386/multiboot_header.h" -int test_main(uint32_t magic, struct mb_info *mbi) +int test_main(uint32_t magic, struct multiboot_info *mbi) { - struct mb_module *mod; + struct multiboot_mod_list *mod; unsigned int i; (void) magic; + printf("Multiboot header at %x\n\n", mbi); + printf("Module list with %d entries at %x\n", mbi->mods_count, mbi->mods_addr); - for (i = 0, mod = (struct mb_module*) mbi->mods_addr; + for (i = 0, mod = (struct multiboot_mod_list*) mbi->mods_addr; i < mbi->mods_count; i++, mod++) { @@ -41,7 +43,7 @@ int test_main(uint32_t magic, struct mb_info *mbi) unsigned int size = mod->mod_end - mod->mod_start; printf("[%p] Module: %x - %x (%d bytes) '%s'\n", - mod, mod->mod_start, mod->mod_end, size, mod->string); + mod, mod->mod_start, mod->mod_end, size, mod->cmdline); /* Print test file, but remove the newline at the end */ if (size < sizeof(buf)) { diff --git a/tests/multiboot/modules.out b/tests/multiboot/modules.out index 1636708035..0da7b39374 100644 --- a/tests/multiboot/modules.out +++ b/tests/multiboot/modules.out @@ -3,11 +3,15 @@ === Running test case: modules.elf === +Multiboot header at 9500 + Module list with 0 entries at 102000 === Running test case: modules.elf -initrd module.txt === +Multiboot header at 9500 + Module list with 1 entries at 102000 [102000] Module: 103000 - 103038 (56 bytes) 'module.txt' Content: 'This is a test file that is used as a multiboot module.' @@ -15,6 +19,8 @@ Module list with 1 entries at 102000 === Running test case: modules.elf -initrd module.txt argument === +Multiboot header at 9500 + Module list with 1 entries at 102000 [102000] Module: 103000 - 103038 (56 bytes) 'module.txt argument' Content: 'This is a test file that is used as a multiboot module.' @@ -22,6 +28,8 @@ Module list with 1 entries at 102000 === Running test case: modules.elf -initrd module.txt argument,,with,,commas === +Multiboot header at 9500 + Module list with 1 entries at 102000 [102000] Module: 103000 - 103038 (56 bytes) 'module.txt argument,with,commas' Content: 'This is a test file that is used as a multiboot module.' @@ -29,6 +37,8 @@ Module list with 1 entries at 102000 === Running test case: modules.elf -initrd module.txt,module.txt argument,module.txt === +Multiboot header at 9500 + Module list with 3 entries at 102000 [102000] Module: 103000 - 103038 (56 bytes) 'module.txt' Content: 'This is a test file that is used as a multiboot module.' diff --git a/tests/multiboot/multiboot.h b/tests/multiboot/multiboot.h deleted file mode 100644 index 4eb1fbe5d4..0000000000 --- a/tests/multiboot/multiboot.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013 Kevin Wolf - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MULTIBOOT_H -#define MULTIBOOT_H - -#include "libc.h" - -struct mb_info { - uint32_t flags; - uint32_t mem_lower; - uint32_t mem_upper; - uint32_t boot_device; - uint32_t cmdline; - uint32_t mods_count; - uint32_t mods_addr; - char syms[16]; - uint32_t mmap_length; - uint32_t mmap_addr; - uint32_t drives_length; - uint32_t drives_addr; - uint32_t config_table; - uint32_t boot_loader_name; - uint32_t apm_table; - uint32_t vbe_control_info; - uint32_t vbe_mode_info; - uint16_t vbe_mode; - uint16_t vbe_interface_seg; - uint16_t vbe_interface_off; - uint16_t vbe_interface_len; -} __attribute__((packed)); - -struct mb_module { - uint32_t mod_start; - uint32_t mod_end; - uint32_t string; - uint32_t reserved; -} __attribute__((packed)); - -struct mb_mmap_entry { - uint32_t size; - uint64_t base_addr; - uint64_t length; - uint32_t type; -} __attribute__((packed)); - -#endif From patchwork Mon Jan 29 20:43:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatol Pomozov X-Patchwork-Id: 867288 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="s/38x/Aq"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zVhMl3KRWz9s75 for ; Tue, 30 Jan 2018 07:44:51 +1100 (AEDT) Received: from localhost ([::1]:37765 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGIL-0002Ri-GZ for incoming@patchwork.ozlabs.org; Mon, 29 Jan 2018 15:44:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39564) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGHe-0002Oy-O8 for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egGHc-0001AR-B5 for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:06 -0500 Received: from mail-pf0-x244.google.com ([2607:f8b0:400e:c00::244]:38341) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1egGHc-00019q-0d for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:04 -0500 Received: by mail-pf0-x244.google.com with SMTP id k19so6464017pfj.5 for ; Mon, 29 Jan 2018 12:44:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7EGHMrXrKZokEOhnN7dME1XwqHjhMffkD76Xp6Fp8ZA=; b=s/38x/AqQt3a40AIqVLW8r4BLWOdjRI8DaGU2jnK+iogp4P/Nlv11SnmroVNAyb+uD Bx2BehjqWpfiZ+yjTx9/aUBsP7vEvSLt+6oW+6qngs0vJ1KM/VMg+wxMhdUqU4BcouXZ EoNPux66S2Jo2ODpbXjFzlSWrC1Yi2LMaRPy/qIFAdSZ/yNGokWwQJo2fQTmMwXJDr54 ocGfNRQKT7HFQqp5IwNzTY5db7OG+77pcWO92Xb4jcU4To8SsMrZLWcU4kZqXXW6v2mI 2Y36WW4XlWSG+Ry9kJtpATIltx5A5PCoGsHxhOCmvtAhY4DhNKtaKJpmNudBRqSTjskb 5VKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7EGHMrXrKZokEOhnN7dME1XwqHjhMffkD76Xp6Fp8ZA=; b=Or0hqwX2k4U685bBfJXSh01euXV3c7s6C7UnuVSkxzXFc9FQegGoZMFHcwr1LNRBeX BaOwgGw1Zz5M6VYLDvvpwvNorQSPhV3pzxyvDW380OUt9UBF6kjbUDsgmXnR1zWyYU5e hpxJVWbNUY7NP14Nshybjup0MZTPWTDUzPRFY9K4kzBNjT/jeAXnnQHZHIn9XTjs4+qO Y5edodq1WinlKXuvb/Z41iNhRsDQfWk3l/AdKqbpSMvmEpDgQbyuHbClsRz729f4Deiz YmpuR90Bal4JJsDnMHv/7yIJvJAFrxJDmh+D65BwjbH/F7DI50d0loidlhgukwTIKsGk Ed9w== X-Gm-Message-State: AKwxyteGYRGEB1DIabe/FQOI8N7FzKMswKC+A0FoMjBxfNy/BpPi4gCw cwaCaQpqsYWwvJUggwQuTa9RyWcBG1M= X-Google-Smtp-Source: AH8x226o2vWNiOWZGU4HV28NmlGmOlf8V2Od+3j7JZh28czDpoK4GVPteMLe7cJIPKnIVfOmgExJsA== X-Received: by 10.98.223.196 with SMTP id d65mr28485637pfl.176.1517258642316; Mon, 29 Jan 2018 12:44:02 -0800 (PST) Received: from anatol.mtv.corp.google.com ([2620:15c:202:1:a4ef:a3cf:87b8:ef77]) by smtp.gmail.com with ESMTPSA id t1sm37436140pfj.21.2018.01.29.12.44.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 12:44:01 -0800 (PST) From: Anatol Pomozov To: qemu-devel@nongnu.org Date: Mon, 29 Jan 2018 12:43:42 -0800 Message-Id: <20180129204344.196196-2-anatol.pomozov@gmail.com> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180129204344.196196-1-anatol.pomozov@gmail.com> References: <20180129204344.196196-1-anatol.pomozov@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::244 Subject: [Qemu-devel] [PATCH 2/4] multiboot: load elf sections and section headers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, Anatol Pomozov , jack.schwartz@oracle.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Multiboot may load section headers and all sections (even those that are not part of any segment) to target memory. Tested with an ELF application that uses data from strings table section. Signed-off-by: Anatol Pomozov --- hw/core/loader.c | 8 +-- hw/i386/multiboot.c | 17 +++-- hw/s390x/ipl.c | 2 +- include/hw/elf_ops.h | 110 +++++++++++++++++++++++++++++-- include/hw/loader.h | 11 +++- tests/multiboot/Makefile | 8 ++- tests/multiboot/generate_sections_out.py | 33 ++++++++++ tests/multiboot/modules.out | 22 +++---- tests/multiboot/run_test.sh | 6 +- tests/multiboot/sections.c | 57 ++++++++++++++++ tests/multiboot/start.S | 2 +- 11 files changed, 248 insertions(+), 28 deletions(-) create mode 100755 tests/multiboot/generate_sections_out.py create mode 100644 tests/multiboot/sections.c diff --git a/hw/core/loader.c b/hw/core/loader.c index 91669d65aa..3f0412eeef 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -439,7 +439,7 @@ int load_elf_as(const char *filename, { return load_elf_ram(filename, translate_fn, translate_opaque, pentry, lowaddr, highaddr, big_endian, elf_machine, - clear_lsb, data_swab, as, true); + clear_lsb, data_swab, as, true, NULL); } /* return < 0 if error, otherwise the number of bytes loaded in memory */ @@ -448,7 +448,7 @@ int load_elf_ram(const char *filename, void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as, - bool load_rom) + bool load_rom, SectionsData *sections) { int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED; uint8_t e_ident[EI_NIDENT]; @@ -488,11 +488,11 @@ int load_elf_ram(const char *filename, if (e_ident[EI_CLASS] == ELFCLASS64) { ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, - data_swab, as, load_rom); + data_swab, as, load_rom, sections); } else { ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, - data_swab, as, load_rom); + data_swab, as, load_rom, sections); } fail: diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index c6d05ca46b..79b89e4fee 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -125,7 +125,7 @@ int load_multiboot(FWCfgState *fw_cfg, { int i; bool is_multiboot = false; - uint32_t flags = 0; + uint32_t flags = 0, bootinfo_flags = 0; uint32_t mh_entry_addr; uint32_t mh_load_addr; uint32_t mb_kernel_size; @@ -134,6 +134,7 @@ int load_multiboot(FWCfgState *fw_cfg, uint8_t *mb_bootinfo_data; uint32_t cmdline_len; struct multiboot_header *multiboot_header; + SectionsData sections; /* Ok, let's see if it is a multiboot image. The header is 12x32bit long, so the latest entry may be 8192 - 48. */ @@ -172,9 +173,9 @@ int load_multiboot(FWCfgState *fw_cfg, exit(1); } - kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size = load_elf_ram(kernel_filename, NULL, NULL, &elf_entry, &elf_low, &elf_high, 0, I386_ELF_MACHINE, - 0, 0); + 0, 0, NULL, true, §ions); if (kernel_size < 0) { fprintf(stderr, "Error while loading elf kernel\n"); exit(1); @@ -191,6 +192,13 @@ int load_multiboot(FWCfgState *fw_cfg, mb_debug("qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n", mb_kernel_size, (size_t)mh_entry_addr); + + stl_p(&bootinfo.u.elf_sec.num, sections.num); + stl_p(&bootinfo.u.elf_sec.size, sections.size); + stl_p(&bootinfo.u.elf_sec.addr, sections.addr); + stl_p(&bootinfo.u.elf_sec.shndx, sections.shndx); + + bootinfo_flags |= MULTIBOOT_INFO_ELF_SHDR; } else { /* Valid if mh_flags sets MULTIBOOT_AOUT_KLUDGE. */ uint32_t mh_header_addr = ldl_p(&multiboot_header->header_addr); @@ -332,7 +340,8 @@ int load_multiboot(FWCfgState *fw_cfg, stl_p(&bootinfo.mods_count, mbs.mb_mods_count); /* mods_count */ /* the kernel is where we want it to be now */ - stl_p(&bootinfo.flags, MULTIBOOT_INFO_MEMORY + stl_p(&bootinfo.flags, bootinfo_flags + | MULTIBOOT_INFO_MEMORY | MULTIBOOT_INFO_BOOTDEV | MULTIBOOT_INFO_CMDLINE | MULTIBOOT_INFO_MODS diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 0d06fc12b6..4d9cc6261a 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -327,7 +327,7 @@ static int load_netboot_image(Error **errp) } img_size = load_elf_ram(netboot_filename, NULL, NULL, &ipl->start_addr, - NULL, NULL, 1, EM_S390, 0, 0, NULL, false); + NULL, NULL, 1, EM_S390, 0, 0, NULL, false, NULL); if (img_size < 0) { img_size = load_image_size(netboot_filename, ram_ptr, ram_size); diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index d192e7e2a3..8e41300525 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -264,12 +264,13 @@ static int glue(load_elf, SZ)(const char *name, int fd, int must_swab, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int elf_machine, int clear_lsb, int data_swab, - AddressSpace *as, bool load_rom) + AddressSpace *as, bool load_rom, + SectionsData *sections) { struct elfhdr ehdr; struct elf_phdr *phdr = NULL, *ph; int size, i, total_size; - elf_word mem_size, file_size; + elf_word mem_size, file_size, sec_size; uint64_t addr, low = (uint64_t)-1, high = 0; uint8_t *data = NULL; char label[128]; @@ -336,8 +337,6 @@ static int glue(load_elf, SZ)(const char *name, int fd, goto fail; } phdr = g_malloc0(size); - if (!phdr) - goto fail; if (read(fd, phdr, size) != size) goto fail; if (must_swab) { @@ -481,6 +480,109 @@ static int glue(load_elf, SZ)(const char *name, int fd, } } g_free(phdr); + + if (sections) { + struct elf_shdr *shdr = NULL, *sh; + int shsize; + + /* user requested loading all ELF sections */ + shsize = ehdr.e_shnum * sizeof(shdr[0]); + if (lseek(fd, ehdr.e_shoff, SEEK_SET) != ehdr.e_shoff) { + goto fail; + } + shdr = g_malloc0(shsize); + if (read(fd, shdr, shsize) != shsize) { + goto fail; + } + if (must_swab) { + for (i = 0; i < ehdr.e_shnum; i++) { + sh = &shdr[i]; + glue(bswap_shdr, SZ)(sh); + } + } + + for (i = 0; i < ehdr.e_shnum; i++) { + sh = &shdr[i]; + if (sh->sh_type == SHT_NULL) { + continue; + } + /* if section has address then it loaded already, + * no need to load it again */ + if (sh->sh_addr) { + continue; + } + + /* append section data at the end of the loaded segments */ + addr = ROUND_UP(high, sh->sh_addralign); + sh->sh_addr = addr; + + sec_size = sh->sh_size; /* Size of the section data */ + data = g_malloc0(sec_size); + if (sec_size > 0) { + if (lseek(fd, sh->sh_offset, SEEK_SET) < 0) { + goto fail; + } + if (read(fd, data, sec_size) != sec_size) { + goto fail; + } + } + + /* As these sections are not loadable no need to perform reloaction + * using translate_fn() */ + if (data_swab) { + int j; + for (j = 0; j < sec_size; j += (1 << data_swab)) { + uint8_t *dp = data + j; + switch (data_swab) { + case 1: + *(uint16_t *)dp = bswap16(*(uint16_t *)dp); + break; + case 2: + *(uint32_t *)dp = bswap32(*(uint32_t *)dp); + break; + case 3: + *(uint64_t *)dp = bswap64(*(uint64_t *)dp); + break; + default: + g_assert_not_reached(); + } + } + } + + if (load_rom) { + snprintf(label, sizeof(label), "shdr #%d: %s", i, name); + + /* rom_add_elf_program() seize the ownership of 'data' */ + rom_add_elf_program(label, data, sec_size, sec_size, addr, as); + } else { + cpu_physical_memory_write(addr, data, sec_size); + g_free(data); + } + + total_size += sec_size; + high = addr + sec_size; + + data = NULL; + } + + sections->num = ehdr.e_shnum; + sections->size = ehdr.e_shentsize; + sections->addr = high; /* Address where we load the sections header */ + sections->shndx = ehdr.e_shstrndx; + + /* Append section headers at the end of loaded segments/sections */ + if (load_rom) { + snprintf(label, sizeof(label), "shdrs"); + + /* rom_add_elf_program() seize the ownership of 'shdr' */ + rom_add_elf_program(label, shdr, shsize, shsize, high, as); + } else { + cpu_physical_memory_write(high, shdr, shsize); + g_free(shdr); + } + high += shsize; + } + if (lowaddr) *lowaddr = (uint64_t)(elf_sword)low; if (highaddr) diff --git a/include/hw/loader.h b/include/hw/loader.h index 355fe0f5a2..3cf2d6da0f 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -65,6 +65,13 @@ int load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz); #define ELF_LOAD_WRONG_ENDIAN -4 const char *load_elf_strerror(int error); +typedef struct { + uint32_t num; // number of loaded sections + uint32_t size; // size of entry in sections header list + uint32_t addr; // address of loaded sections header + uint32_t shndx; // number of section that contains string table +} SectionsData; + /** load_elf_ram: * @filename: Path of ELF file * @translate_fn: optional function to translate load addresses @@ -82,6 +89,8 @@ const char *load_elf_strerror(int error); * @as: The AddressSpace to load the ELF to. The value of address_space_memory * is used if nothing is supplied here. * @load_rom : Load ELF binary as ROM + * @sections: If parameter is non-NULL then all ELF sections loaded into memory + * and this structure is populated. * * Load an ELF file's contents to the emulated system's address space. * Clients may optionally specify a callback to perform address @@ -99,7 +108,7 @@ int load_elf_ram(const char *filename, void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as, - bool load_rom); + bool load_rom, SectionsData *sections); /** load_elf_as: * Same as load_elf_ram(), but always loads the elf as ROM diff --git a/tests/multiboot/Makefile b/tests/multiboot/Makefile index 36f01dc647..b6a5056347 100644 --- a/tests/multiboot/Makefile +++ b/tests/multiboot/Makefile @@ -6,7 +6,7 @@ LD=ld LDFLAGS=-melf_i386 -T link.ld LIBS=$(shell $(CC) $(CCFLAGS) -print-libgcc-file-name) -all: mmap.elf modules.elf +all: mmap.elf modules.elf sections.elf sections.out mmap.elf: start.o mmap.o libc.o $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) @@ -14,6 +14,12 @@ mmap.elf: start.o mmap.o libc.o modules.elf: start.o modules.o libc.o $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) +sections.elf: start.o sections.o libc.o + $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) + +sections.out: sections.elf generate_sections_out.py + python2 generate_sections_out.py $^ > $@ + %.o: %.c $(CC) $(CCFLAGS) -c -o $@ $^ diff --git a/tests/multiboot/generate_sections_out.py b/tests/multiboot/generate_sections_out.py new file mode 100755 index 0000000000..8077856823 --- /dev/null +++ b/tests/multiboot/generate_sections_out.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python2 + +import sys + +from elftools.elf.elffile import ELFFile + +def roundup(num, align): + return (num + align - 1) / align * align + +def main(filename): + print "\n\n\n=== Running test case: sections.elf ===\n" + print "Multiboot header at 9500, ELF section headers present\n" + + with open(filename, 'rb') as f: + elf = ELFFile(f) + header = elf.header + load_addr = 0x100000 # we load image starting from 1M + sections = "" + for s in elf.iter_sections(): + align = s.header.sh_addralign + addr = 0 + if s.header.sh_type != 'SHT_NULL': + addr = s.header.sh_addr + if addr == 0: + addr = roundup(load_addr, s.header.sh_addralign) + load_addr = addr + s.header.sh_size + sections += "Elf section name=%s addr=%x size=%d\n" % (s.name, addr, s.header.sh_size) + + print "Sections list with %d entries of size %d at %x, string index %d" % (header.e_shnum, header.e_shentsize, load_addr, header.e_shstrndx) + print sections, + +if __name__ == '__main__': + main(sys.argv[1]) diff --git a/tests/multiboot/modules.out b/tests/multiboot/modules.out index 0da7b39374..b6c1a01be1 100644 --- a/tests/multiboot/modules.out +++ b/tests/multiboot/modules.out @@ -5,15 +5,15 @@ Multiboot header at 9500 -Module list with 0 entries at 102000 +Module list with 0 entries at 104000 === Running test case: modules.elf -initrd module.txt === Multiboot header at 9500 -Module list with 1 entries at 102000 -[102000] Module: 103000 - 103038 (56 bytes) 'module.txt' +Module list with 1 entries at 104000 +[104000] Module: 105000 - 105038 (56 bytes) 'module.txt' Content: 'This is a test file that is used as a multiboot module.' @@ -21,8 +21,8 @@ Module list with 1 entries at 102000 Multiboot header at 9500 -Module list with 1 entries at 102000 -[102000] Module: 103000 - 103038 (56 bytes) 'module.txt argument' +Module list with 1 entries at 104000 +[104000] Module: 105000 - 105038 (56 bytes) 'module.txt argument' Content: 'This is a test file that is used as a multiboot module.' @@ -30,8 +30,8 @@ Module list with 1 entries at 102000 Multiboot header at 9500 -Module list with 1 entries at 102000 -[102000] Module: 103000 - 103038 (56 bytes) 'module.txt argument,with,commas' +Module list with 1 entries at 104000 +[104000] Module: 105000 - 105038 (56 bytes) 'module.txt argument,with,commas' Content: 'This is a test file that is used as a multiboot module.' @@ -39,10 +39,10 @@ Module list with 1 entries at 102000 Multiboot header at 9500 -Module list with 3 entries at 102000 -[102000] Module: 103000 - 103038 (56 bytes) 'module.txt' +Module list with 3 entries at 104000 +[104000] Module: 105000 - 105038 (56 bytes) 'module.txt' Content: 'This is a test file that is used as a multiboot module.' -[102010] Module: 104000 - 104038 (56 bytes) 'module.txt argument' +[104010] Module: 106000 - 106038 (56 bytes) 'module.txt argument' Content: 'This is a test file that is used as a multiboot module.' -[102020] Module: 105000 - 105038 (56 bytes) 'module.txt' +[104020] Module: 107000 - 107038 (56 bytes) 'module.txt' Content: 'This is a test file that is used as a multiboot module.' diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh index 0278148b43..f04e35cbf0 100755 --- a/tests/multiboot/run_test.sh +++ b/tests/multiboot/run_test.sh @@ -56,9 +56,13 @@ modules() { run_qemu modules.elf -initrd "module.txt,module.txt argument,module.txt" } +sections() { + run_qemu sections.elf +} + make all -for t in mmap modules; do +for t in mmap modules sections; do echo > test.log $t diff --git a/tests/multiboot/sections.c b/tests/multiboot/sections.c new file mode 100644 index 0000000000..64060510ce --- /dev/null +++ b/tests/multiboot/sections.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017 Anatol Pomozov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "libc.h" +#include "../../hw/i386/multiboot_header.h" +#include "../../include/elf.h" + +int test_main(uint32_t magic, struct multiboot_info *mbi) +{ + void *p; + unsigned int i; + + (void) magic; + multiboot_elf_section_header_table_t shdr; + + printf("Multiboot header at %x, ELF section headers %s\n\n", mbi, + mbi->flags & MULTIBOOT_INFO_ELF_SHDR ? "present" : "doesn't present"); + + shdr = mbi->u.elf_sec; + printf("Sections list with %d entries of size %d at %x, string index %d\n", + shdr.num, shdr.size, shdr.addr, shdr.shndx); + + const char *string_table = (char *)((Elf32_Shdr *)(uintptr_t)(shdr.addr + + shdr.shndx * shdr.size))->sh_addr; + + for (i = 0, p = (void *)shdr.addr; + i < shdr.num; + i++, p += shdr.size) + { + Elf32_Shdr *sec; + + sec = (Elf32_Shdr *)p; + printf("Elf section name=%s addr=%lx size=%ld\n", + string_table + sec->sh_name, sec->sh_addr, sec->sh_size); + } + + return 0; +} diff --git a/tests/multiboot/start.S b/tests/multiboot/start.S index 7d33959650..bd404100c2 100644 --- a/tests/multiboot/start.S +++ b/tests/multiboot/start.S @@ -23,7 +23,7 @@ .section multiboot #define MB_MAGIC 0x1badb002 -#define MB_FLAGS 0x0 +#define MB_FLAGS 0x2 #define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS) .align 4 From patchwork Mon Jan 29 20:43:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatol Pomozov X-Patchwork-Id: 867290 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HKDiNSxc"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zVhQQ0Qbjz9sCZ for ; Tue, 30 Jan 2018 07:47:09 +1100 (AEDT) Received: from localhost ([::1]:37852 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGKZ-0004Lg-MN for incoming@patchwork.ozlabs.org; Mon, 29 Jan 2018 15:47:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39571) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGHg-0002QA-Rk for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egGHf-0001Ck-Oc for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:08 -0500 Received: from mail-pg0-x244.google.com ([2607:f8b0:400e:c05::244]:46420) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1egGHf-0001CF-Ip for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:07 -0500 Received: by mail-pg0-x244.google.com with SMTP id s9so5379888pgq.13 for ; Mon, 29 Jan 2018 12:44:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Feii58VQGKY1gVfV2UWXGJ1ITKww6WhN2pizUIWjLyA=; b=HKDiNSxcofYEnoZBdMRI1XrkLWwc3z+iVhbJHbzohMqhKsE9koMN5x0D8eF4kUBYBU 3363/D/G7YJwrbpULgGTUPi3nTXlcPZDRViFraavJiIjOWAqelxXJZc7Wk7cOaofbHCJ 3pc+1pjdQWso2RTSWGSy+K81+c6BVAHyIeTgf/R5xvRzTwsmWFnUUWh/bqHmkFBOxY+Q y++JlnhFKw9KXuNdl3EjdNxil1SefaRttfvainqBb7VGzGX2YfpfnPJgXB0bCAM/3/5M dJGbe7FzS1O0HjzJGvLS7dManJyHFNmucqeeFJYIWcdo91IkJ/nf+O11bc/a0DdlB6ZF tu8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Feii58VQGKY1gVfV2UWXGJ1ITKww6WhN2pizUIWjLyA=; b=LsWmlfcLXUfBLN30p112XVnh6aG3GK8AYh7XHKHbq4lfvWTSrNL1w++8tlFyrOUZkP djexmSbgRAxjbYzW0qcqg7aYH3F0FDoNO6CnxH+nTPNqXZVXAl79al4HTB34tI3eNzLI REFQjpideET5eCsUn2O4EGkaI+gLaKJfljt3Y10J2kiXXJfHXWebXqxmtzchOV5V0Q1i UO31D7z4v6DY2HGlIbYJAfNtiQyGxGx8dcZTes9OZsvbT0o+vzwdmS0Tz9RS3czu/c3d 90hwvzPw82EGeOPg1DhCkIHfm1yiWO4r5yNFuRYLU7i7t/m9PI5G3d2OIJ/0N1zvB8aI PUew== X-Gm-Message-State: AKwxytfmC9oniEMuXuI68khzRI2ilWPzk59j4tLUy0XupLpiw5AG/EoJ 15Bzf2V/0hjF8ZPNJm9OhaiCOGx55Fw= X-Google-Smtp-Source: AH8x226AY3S+T/Cg3f2zqJN1YQKiejddtuHjCqAAHN1yYRsMmBkS7yWnfCLXq5D5uZUFz40+YYVyMQ== X-Received: by 10.98.15.195 with SMTP id 64mr23737063pfp.225.1517258646090; Mon, 29 Jan 2018 12:44:06 -0800 (PST) Received: from anatol.mtv.corp.google.com ([2620:15c:202:1:a4ef:a3cf:87b8:ef77]) by smtp.gmail.com with ESMTPSA id t1sm37436140pfj.21.2018.01.29.12.44.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 12:44:05 -0800 (PST) From: Anatol Pomozov To: qemu-devel@nongnu.org Date: Mon, 29 Jan 2018 12:43:43 -0800 Message-Id: <20180129204344.196196-3-anatol.pomozov@gmail.com> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180129204344.196196-1-anatol.pomozov@gmail.com> References: <20180129204344.196196-1-anatol.pomozov@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::244 Subject: [Qemu-devel] [PATCH 3/4] multiboot: make tests work with clang X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, Anatol Pomozov , jack.schwartz@oracle.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" * clang 3.8 enables SSE even for 32bit code. Generate code for pentium CPU to make sure no new instructions are used. * add memset() implementation. Clang implements array zeroing in print_num() via memset() function call. Signed-off-by: Anatol Pomozov --- tests/multiboot/Makefile | 2 +- tests/multiboot/libc.c | 9 +++++++++ tests/multiboot/libc.h | 2 ++ tests/multiboot/run_test.sh | 1 + 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/multiboot/Makefile b/tests/multiboot/Makefile index b6a5056347..79dfe85afc 100644 --- a/tests/multiboot/Makefile +++ b/tests/multiboot/Makefile @@ -1,5 +1,5 @@ CC=gcc -CCFLAGS=-m32 -Wall -Wextra -Werror -fno-stack-protector -nostdinc -fno-builtin +CCFLAGS=-m32 -Wall -Wextra -Werror -fno-stack-protector -nostdinc -fno-builtin -march=pentium ASFLAGS=-m32 LD=ld diff --git a/tests/multiboot/libc.c b/tests/multiboot/libc.c index 6df9bda96d..512fccd7fa 100644 --- a/tests/multiboot/libc.c +++ b/tests/multiboot/libc.c @@ -33,6 +33,15 @@ void* memcpy(void *dest, const void *src, int n) return dest; } +void *memset(void *s, int c, size_t n) +{ + size_t i; + char *d = s; + for (i = 0; i < n; i++) { + *d++ = c; + } + return s; +} static void print_char(char c) { diff --git a/tests/multiboot/libc.h b/tests/multiboot/libc.h index 04c9922c27..bdf7c34287 100644 --- a/tests/multiboot/libc.h +++ b/tests/multiboot/libc.h @@ -36,6 +36,7 @@ typedef signed short int16_t; typedef signed char int8_t; typedef uint32_t uintptr_t; +typedef uint32_t size_t; /* stdarg.h */ @@ -58,5 +59,6 @@ static inline void outb(uint16_t port, uint8_t data) void printf(const char *fmt, ...); void* memcpy(void *dest, const void *src, int n); +void* memset(void *s, int c, size_t n); #endif diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh index f04e35cbf0..38dcfef42c 100755 --- a/tests/multiboot/run_test.sh +++ b/tests/multiboot/run_test.sh @@ -29,6 +29,7 @@ run_qemu() { printf %b "\n\n=== Running test case: $kernel $* ===\n\n" >> test.log $QEMU \ + -cpu pentium \ -kernel $kernel \ -display none \ -device isa-debugcon,chardev=stdio \ From patchwork Mon Jan 29 20:43:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatol Pomozov X-Patchwork-Id: 867289 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="M+3zuN7O"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zVhMt5xfRz9s75 for ; Tue, 30 Jan 2018 07:44:58 +1100 (AEDT) Received: from localhost ([::1]:37767 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGIS-0002Wn-RY for incoming@patchwork.ozlabs.org; Mon, 29 Jan 2018 15:44:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39587) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egGHm-0002Un-BT for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egGHl-0001EA-Jy for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:14 -0500 Received: from mail-pg0-x243.google.com ([2607:f8b0:400e:c05::243]:46420) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1egGHl-0001E2-Dt for qemu-devel@nongnu.org; Mon, 29 Jan 2018 15:44:13 -0500 Received: by mail-pg0-x243.google.com with SMTP id s9so5380035pgq.13 for ; Mon, 29 Jan 2018 12:44:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LgTuK9VZqjSJoMWM/37e8/fe1fwxbo+4tb9VMHSta7Q=; b=M+3zuN7OaziOVOFm4wR4JADjNwsdswlUDgY9zXxI0W8OuyaQGSQ296MOABkadZH98j dRCWp5N09VvDfA/MxojtbI/LojVQU/aDijfWoeEWZISTpkXR4+P6ZNKaX+nYalhU8oAz 7v3iIMESP38d2K9/uAQOB9JiiZtPhLzKyWLjZfNFsSTPzDTyNUIV7XlgGaJWg83HD6Ip 7Y9PwDYIXyp3IQahGNSAglnmWt9fSzsBSi92nd0KLw9VHS/3AlNDzKFV+smKrmXvTy3K 9m7muc8A1G1VSwePwhpVod+zBBBFsnWBGa+zOHJ1rittMLmqomrWOMFGjZKhqwOqkw8M oS2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LgTuK9VZqjSJoMWM/37e8/fe1fwxbo+4tb9VMHSta7Q=; b=hv4miqUsKgzgiHPyYlonQX+oRHzl5tukPmWWiXpu8q9fRmwWud2zJ3a8pxZfQJOCBB f84ibekNFIbTP+W1wkrR8lp1CuGkwrz9DF7mSoEZjH1N9a0UG+XZH9VRYZzeMA3G4ooX yWEQfG1BxRmToCj0BFGIqVUfRllcNdaW5LuZjFU/vh5JOv+TUgKEu6dBGb/svQUY0CxK t29QkfabrLodvAEet1dmVyIE82bI/d8vtZZPCAai76zfyKX2BdXs5gvPjRkV3J2502mW 7EHz15qokI/0nytsdBq4Al2BHdzPlhmWbf6/jiRbsmkfT1hPgUqKrNIZCCEPJbrAmWPh nwSQ== X-Gm-Message-State: AKwxytezxPu7/58YetiqTGzD0uw3KlONRWOzwLLRu7KYgVMI8Lvebgov R5zrhqVPS+K1J8SGp71wk+/12cOgnJA= X-Google-Smtp-Source: AH8x225K8t8sjK5MpfgDBLooryYpE+nJ3p7EZfLIc+hyN/1hG25/Xjts+EprCfJ/t29zFnaGUq+npA== X-Received: by 2002:a17:902:68cb:: with SMTP id x11-v6mr22834870plm.198.1517258651915; Mon, 29 Jan 2018 12:44:11 -0800 (PST) Received: from anatol.mtv.corp.google.com ([2620:15c:202:1:a4ef:a3cf:87b8:ef77]) by smtp.gmail.com with ESMTPSA id t1sm37436140pfj.21.2018.01.29.12.44.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 12:44:11 -0800 (PST) From: Anatol Pomozov To: qemu-devel@nongnu.org Date: Mon, 29 Jan 2018 12:43:44 -0800 Message-Id: <20180129204344.196196-4-anatol.pomozov@gmail.com> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180129204344.196196-1-anatol.pomozov@gmail.com> References: <20180129204344.196196-1-anatol.pomozov@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::243 Subject: [Qemu-devel] [PATCH 4/4] multiboot: Make elf64 loading functionality compatible with GRUB X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, Anatol Pomozov , jack.schwartz@oracle.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" GRUB is a reference multiboot implementation and supports loading elf64 binaries. Make QEMU to work similar was as GRUB. --- hw/i386/multiboot.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 79b89e4fee..676ac7c48d 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -168,11 +168,6 @@ int load_multiboot(FWCfgState *fw_cfg, int kernel_size; fclose(f); - if (((struct elf64_hdr*)header)->e_machine == EM_X86_64) { - fprintf(stderr, "Cannot load x86-64 image, give a 32bit one.\n"); - exit(1); - } - kernel_size = load_elf_ram(kernel_filename, NULL, NULL, &elf_entry, &elf_low, &elf_high, 0, I386_ELF_MACHINE, 0, 0, NULL, true, §ions);