All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
@ 2009-06-17 16:41 Alexander Graf
  2009-06-17 16:41 ` [Qemu-devel] [PATCH 1/4] Change bochs bios init order Alexander Graf
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Alexander Graf @ 2009-06-17 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, rene

This patch implements support for Multiboot on x86 for -kernel.
Multiboot is a "new" approach to get rid of different bootloaders, providing
a unified interface for the kernel. It supports command line options and
kernel modules.

The two probably best known projects using multiboot are Xen and GNU Hurd.

This implementation should be mostly feature-complete. It is missing VBE
extensions, but as no system uses them currently it does not really hurt.

To use multiboot, specify the kernel as -kernel option. Modules should be given
as -initrd options, seperated by a comma (,). -append also works.

Please bear in mind that grub also does gzip decompression, which qemu does
not do yet. To run existing images, please ungzip them first.

The guest multiboot loader code is implemented as option rom using int 19.
Parts of the work are based on efforts by Rene Rebe, who originally ported
my code to int 19.

Also, Kevin Wolf helped a lot whenever I had a new version of this patch
around.

v2 addresses the fw_cfg comments from Blue Swirl

Alexander Graf (4):
  Change bochs bios init order
  Expose fw_cfg
  Multiboot support
  Multiboot build system

 hw/pc.c                       |  243 ++++++++++++++++++++++++++++++++++++++---
 pc-bios/multiboot/Makefile    |   41 +++++++
 pc-bios/multiboot/multiboot.S |  229 ++++++++++++++++++++++++++++++++++++++
 pc-bios/multiboot/signrom.c   |   79 +++++++++++++
 4 files changed, 577 insertions(+), 15 deletions(-)
 create mode 100644 pc-bios/multiboot/Makefile
 create mode 100644 pc-bios/multiboot/multiboot.S
 create mode 100644 pc-bios/multiboot/signrom.c

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 1/4] Change bochs bios init order
  2009-06-17 16:41 [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 Alexander Graf
@ 2009-06-17 16:41 ` Alexander Graf
  2009-06-17 16:41   ` [Qemu-devel] [PATCH 2/4] Expose fw_cfg v2 Alexander Graf
  2009-06-17 17:10 ` [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 François Revol
  2009-06-18 11:15 ` Gleb Natapov
  2 siblings, 1 reply; 22+ messages in thread
From: Alexander Graf @ 2009-06-17 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, rene

For multiboot support, we need bochs_bios_init to happen before
load_linux, so we get the fw_cfg device.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/pc.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 143b697..f0df669 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -970,6 +970,12 @@ static void pc_init1(ram_addr_t ram_size,
     if (oprom_area_size < 0x8000)
         oprom_area_size = 0x8000;
 
+    /* map all the bios at the top of memory */
+    cpu_register_physical_memory((uint32_t)(-bios_size),
+                                 bios_size, bios_offset | IO_MEM_ROM);
+
+    bochs_bios_init();
+
     if (linux_boot) {
         load_linux(0xc0000 + oprom_area_size,
                    kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
@@ -981,12 +987,6 @@ static void pc_init1(ram_addr_t ram_size,
                                            0xc0000 + oprom_area_size, 0xe0000);
     }
 
-    /* map all the bios at the top of memory */
-    cpu_register_physical_memory((uint32_t)(-bios_size),
-                                 bios_size, bios_offset | IO_MEM_ROM);
-
-    bochs_bios_init();
-
     cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
     i8259 = i8259_init(cpu_irq[0]);
     ferr_irq = i8259[13];
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 2/4] Expose fw_cfg v2
  2009-06-17 16:41 ` [Qemu-devel] [PATCH 1/4] Change bochs bios init order Alexander Graf
@ 2009-06-17 16:41   ` Alexander Graf
  2009-06-17 16:41     ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Alexander Graf
  0 siblings, 1 reply; 22+ messages in thread
From: Alexander Graf @ 2009-06-17 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, rene

Multiboot passes options to the option rom using the fw_cfg device.
Right now, that device is local to the bochs_bios_init function.

Let's change that and expose it, so everyone may put data in there.

Signed-off-by: Alexander Graf <agraf@suse.de>

---

v2 leaves env alone and just returns fw_cfg
---
 hw/pc.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index f0df669..debde9d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -448,7 +448,7 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
 
 extern uint64_t node_cpumask[MAX_NODES];
 
-static void bochs_bios_init(void)
+static void *bochs_bios_init(void)
 {
     void *fw_cfg;
     uint8_t *smbios_table;
@@ -497,6 +498,8 @@ static void bochs_bios_init(void)
     }
     fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg,
                      (1 + smp_cpus + nb_numa_nodes) * 8);
+
+    return fw_cfg;
 }
 
 /* Generate an initial boot sector which sets state and jump to
@@ -856,6 +859,7 @@ static void pc_init1(ram_addr_t ram_size,
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
     int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
+    void *fw_cfg;
 
     if (ram_size >= 0xe0000000 ) {
         above_4g_mem_size = ram_size - 0xe0000000;
@@ -974,7 +978,7 @@ static void pc_init1(ram_addr_t ram_size,
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
 
-    bochs_bios_init();
+    fw_cfg = bochs_bios_init();
 
     if (linux_boot) {
         load_linux(0xc0000 + oprom_area_size,
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 3/4] Multiboot support v2
  2009-06-17 16:41   ` [Qemu-devel] [PATCH 2/4] Expose fw_cfg v2 Alexander Graf
@ 2009-06-17 16:41     ` Alexander Graf
  2009-06-17 16:41       ` [Qemu-devel] [PATCH 4/4] Multiboot build system Alexander Graf
  2009-06-18  9:56       ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Avi Kivity
  0 siblings, 2 replies; 22+ messages in thread
From: Alexander Graf @ 2009-06-17 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, rene

This patch implements support for Multiboot on x86 for -kernel.
Multiboot is a "new" approach to get rid of different bootloaders, providing
a unified interface for the kernel. It supports command line options and
kernel modules.

The two probably best known projects using multiboot are Xen and GNU Hurd.

This implementation should be mostly feature-complete. It is missing VBE
extensions, but as no system uses them currently it does not really hurt.

To use multiboot, specify the kernel as -kernel option. Modules should be given
as -initrd options, seperated by a comma (,). -append also works.

Please bear in mind that grub also does gzip decompression, which qemu does
not do yet. To run existing images, please ungzip them first.

The guest multiboot loader code is implemented as option rom using int 19.
Parts of the work are based on efforts by Rene Rebe, who originally ported
my code to int 19.

Signed-off-by: Alexander Graf <agraf@suse.de>

---

v2 uses fw_cfg directly instead of env->fw_cfg
---
 hw/pc.c                       |  225 ++++++++++++++++++++++++++++++++++++++--
 pc-bios/multiboot/multiboot.S |  229 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 446 insertions(+), 8 deletions(-)
 create mode 100644 pc-bios/multiboot/multiboot.S

diff --git a/hw/pc.c b/hw/pc.c
index debde9d..487060c 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -40,6 +40,9 @@
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
 
+/* Show multiboot debug output */
+//#define DEBUG_MULTIBOOT
+
 #define BIOS_FILENAME "bios.bin"
 #define VGABIOS_FILENAME "vgabios.bin"
 #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
@@ -596,7 +599,197 @@ static long get_file_size(FILE *f)
     return size;
 }
 
-static void load_linux(target_phys_addr_t option_rom,
+static int load_multiboot(void *fw_cfg,
+                          FILE *f,
+                          const char *kernel_filename,
+                          const char *initrd_filename,
+                          const char *kernel_cmdline,
+                          uint8_t *header)
+{
+    int i, is_multiboot = 0;
+    uint32_t flags = 0;
+    uint32_t mh_entry_addr;
+    uint32_t mh_load_addr;
+    uint32_t mb_kernel_size;
+    uint32_t mb_bootinfo = 0x90500;
+    uint32_t mmap_addr = 0x90000;
+
+    /* 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);
+            checksum += flags;
+            checksum += (uint32_t)0x1BADB002;
+            if(!checksum) {
+                is_multiboot = 1;
+                break;
+            }
+        }
+    }
+
+    if(!is_multiboot)
+        return 0; /* no multiboot */
+
+#ifdef DEBUG_MULTIBOOT
+    fprintf(stderr, "qemu: I believe we found a multiboot image!\n");
+#endif
+
+    if(flags & 0x00000004) { /* MULTIBOOT_HEADER_HAS_VBE */
+        fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");
+    }
+    if(!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */
+        uint64_t elf_entry;
+        int kernel_size;
+        fclose(f);
+        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
+        if(kernel_size < 0) {
+            fprintf(stderr, "Error while loading elf kernel\n");
+            exit(1);
+        }
+        mh_load_addr = mh_entry_addr = elf_entry;
+        mb_kernel_size = kernel_size;
+
+#ifdef DEBUG_MULTIBOOT
+        fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n",
+                mb_kernel_size, (size_t)mh_entry_addr);
+#endif
+    } else {
+        /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */
+        uint32_t mh_header_addr = ldl_p(header+i+12);
+        mh_load_addr = ldl_p(header+i+16);
+#ifdef DEBUG_MULTIBOOT
+        uint32_t mh_load_end_addr = ldl_p(header+i+20);
+        uint32_t mh_bss_end_addr = ldl_p(header+i+24);
+#endif
+        uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
+
+        mh_entry_addr = ldl_p(header+i+28);
+        mb_kernel_size = get_file_size(f) - mb_kernel_text_offset;
+
+        /* 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); */
+
+#ifdef DEBUG_MULTIBOOT
+        fprintf(stderr, "multiboot: mh_header_addr = %#x\n", mh_header_addr);
+        fprintf(stderr, "multiboot: mh_load_addr = %#x\n", mh_load_addr);
+        fprintf(stderr, "multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr);
+        fprintf(stderr, "multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr);
+#endif
+
+        fseek(f, mb_kernel_text_offset, SEEK_SET);
+
+#ifdef DEBUG_MULTIBOOT
+        fprintf(stderr, "qemu: loading multiboot kernel (%#x bytes) at %#x\n",
+                mb_kernel_size, mh_load_addr);
+#endif
+
+        if (!fread_targphys_ok(mh_load_addr, mb_kernel_size, f)) {
+            fprintf(stderr, "qemu: read error on multiboot kernel '%s' (%#x)\n",
+                    kernel_filename, mb_kernel_size);
+            exit(1);
+        }
+        fclose(f);
+    }
+
+
+    /* load modules */
+    stl_phys(mb_bootinfo + 20, 0x0); /* mods_count */
+    if(initrd_filename) {
+        uint32_t mb_mod_info = mb_bootinfo + 0x100;
+        uint32_t mb_mod_cmdline = mb_bootinfo + 0x300;
+        uint32_t mb_mod_start = mh_load_addr;
+        uint32_t mb_mod_length = mb_kernel_size;
+        char *next_initrd;
+        char *next_space;
+        int mb_mod_count = 0;
+
+        do {
+            next_initrd = strchr(initrd_filename, ',');
+            if(next_initrd)
+                *next_initrd = '\0';
+            /* if a space comes after the module filename, treat everything
+               after that as parameters */
+            cpu_physical_memory_write(mb_mod_cmdline, (uint8_t*)initrd_filename,
+                                      strlen(initrd_filename) + 1);
+            stl_phys(mb_mod_info + 8, mb_mod_cmdline); /* string */
+            mb_mod_cmdline += strlen(initrd_filename) + 1;
+            if((next_space = strchr(initrd_filename, ' ')))
+                *next_space = '\0';
+#ifdef DEBUG_MULTIBOOT
+	     printf("multiboot loading module: %s\n", initrd_filename);
+#endif
+            f = fopen(initrd_filename, "rb");
+            if(f) {
+                mb_mod_start = (mb_mod_start + mb_mod_length + (TARGET_PAGE_SIZE - 1))
+                             & (TARGET_PAGE_MASK);
+                mb_mod_length = get_file_size(f);
+
+                if (!fread_targphys_ok(mb_mod_start, mb_mod_length, f)) {
+                    fprintf(stderr, "qemu: read error on multiboot module '%s' (%#x)\n",
+                            initrd_filename, mb_mod_length);
+                    exit(1);
+                }
+
+                mb_mod_count++;
+                stl_phys(mb_mod_info + 0, mb_mod_start);
+                stl_phys(mb_mod_info + 4, mb_mod_start + mb_mod_length);
+#ifdef DEBUG_MULTIBOOT
+                printf("mod_start: %#x\nmod_end:   %#x\n", mb_mod_start,
+                       mb_mod_start + mb_mod_length);
+#endif
+                stl_phys(mb_mod_info + 12, 0x0); /* reserved */
+            }
+            initrd_filename = next_initrd+1;
+            mb_mod_info += 16;
+        } while(next_initrd);
+        stl_phys(mb_bootinfo + 20, mb_mod_count); /* mods_count */
+        stl_phys(mb_bootinfo + 24, mb_bootinfo + 0x100); /* mods_addr */
+    }
+
+    /* Commandline support */
+    stl_phys(mb_bootinfo + 16, mb_bootinfo + 0x200);
+    cpu_physical_memory_write(mb_bootinfo + 0x200, (uint8_t*)kernel_cmdline,
+                              strlen(kernel_cmdline) + 1);
+
+    /* the kernel is where we want it to be now */
+
+#define MULTIBOOT_FLAGS_MEMORY (1 << 0)
+#define MULTIBOOT_FLAGS_BOOT_DEVICE (1 << 1)
+#define MULTIBOOT_FLAGS_CMDLINE (1 << 2)
+#define MULTIBOOT_FLAGS_MODULES (1 << 3)
+#define MULTIBOOT_FLAGS_MMAP (1 << 6)
+    stl_phys(mb_bootinfo, MULTIBOOT_FLAGS_MEMORY
+                        | MULTIBOOT_FLAGS_BOOT_DEVICE
+                        | MULTIBOOT_FLAGS_CMDLINE
+                        | MULTIBOOT_FLAGS_MODULES
+                        | MULTIBOOT_FLAGS_MMAP);
+    stl_phys(mb_bootinfo + 4, 640); /* mem_lower */
+    stl_phys(mb_bootinfo + 8, ram_size / 1024); /* mem_upper */
+    stl_phys(mb_bootinfo + 12, 0x8001ffff); /* XXX: use the -boot switch? */
+    stl_phys(mb_bootinfo + 48, mmap_addr); /* mmap_addr */
+
+#ifdef DEBUG_MULTIBOOT
+    fprintf(stderr, "multiboot: mh_entry_addr = %#x\n", mh_entry_addr);
+#endif
+
+    /* Pass variables to option rom */
+    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_entry_addr);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, mb_bootinfo);
+    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, mmap_addr);
+
+    option_rom[nb_option_roms] = "multiboot.bin";
+    nb_option_roms++;
+
+    return 1; /* yes, we are multiboot */
+}
+
+static void load_linux(void *fw_cfg,
+                       target_phys_addr_t option_rom,
                        const char *kernel_filename,
 		       const char *initrd_filename,
 		       const char *kernel_cmdline,
@@ -608,7 +801,7 @@ static void load_linux(target_phys_addr_t option_rom,
     uint16_t real_seg;
     int setup_size, kernel_size, initrd_size = 0, cmdline_size;
     uint32_t initrd_max;
-    uint8_t header[1024];
+    uint8_t header[8192];
     target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
     FILE *f, *fi;
 
@@ -618,7 +811,8 @@ static void load_linux(target_phys_addr_t option_rom,
     /* load the kernel header */
     f = fopen(kernel_filename, "rb");
     if (!f || !(kernel_size = get_file_size(f)) ||
-	fread(header, 1, 1024, f) != 1024) {
+	fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) !=
+	MIN(ARRAY_SIZE(header), kernel_size)) {
 	fprintf(stderr, "qemu: could not load kernel '%s'\n",
 		kernel_filename);
 	exit(1);
@@ -630,8 +824,14 @@ static void load_linux(target_phys_addr_t option_rom,
 #endif
     if (ldl_p(header+0x202) == 0x53726448)
 	protocol = lduw_p(header+0x206);
-    else
+    else {
+	/* This looks like a multiboot kernel. If it is, let's stop
+	   treating it like a Linux kernel. */
+	if (load_multiboot(fw_cfg, f, kernel_filename,
+                           initrd_filename, kernel_cmdline, header))
+	   return;
 	protocol = 0;
+    }
 
     if (protocol < 0x200 || !(header[0x211] & 0x01)) {
 	/* Low kernel */
@@ -721,16 +921,25 @@ static void load_linux(target_phys_addr_t option_rom,
     }
 
     /* store the finalized header and load the rest of the kernel */
-    cpu_physical_memory_write(real_addr, header, 1024);
+    cpu_physical_memory_write(real_addr, header, ARRAY_SIZE(header));
 
     setup_size = header[0x1f1];
     if (setup_size == 0)
 	setup_size = 4;
 
     setup_size = (setup_size+1)*512;
-    kernel_size -= setup_size;	/* Size of protected-mode code */
+    /* Size of protected-mode code */
+    kernel_size -= (setup_size > ARRAY_SIZE(header)) ? setup_size : ARRAY_SIZE(header);
+
+    /* In case we have read too much already, copy that over */
+    if (setup_size < ARRAY_SIZE(header)) {
+        cpu_physical_memory_write(prot_addr, header + setup_size, ARRAY_SIZE(header) - setup_size);
+        prot_addr += (ARRAY_SIZE(header) - setup_size);
+        setup_size = ARRAY_SIZE(header);
+    }
 
-    if (!fread_targphys_ok(real_addr+1024, setup_size-1024, f) ||
+    if (!fread_targphys_ok(real_addr + ARRAY_SIZE(header),
+                           setup_size - ARRAY_SIZE(header), f) ||
 	!fread_targphys_ok(prot_addr, kernel_size, f)) {
 	fprintf(stderr, "qemu: read error on kernel '%s'\n",
 		kernel_filename);
@@ -981,7 +1190,7 @@ static void pc_init1(ram_addr_t ram_size,
     fw_cfg = bochs_bios_init();
 
     if (linux_boot) {
-        load_linux(0xc0000 + oprom_area_size,
+        load_linux(fw_cfg, 0xc0000 + oprom_area_size,
                    kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
         oprom_area_size += 2048;
     }
diff --git a/pc-bios/multiboot/multiboot.S b/pc-bios/multiboot/multiboot.S
new file mode 100644
index 0000000..5a2acba
--- /dev/null
+++ b/pc-bios/multiboot/multiboot.S
@@ -0,0 +1,229 @@
+/*
+ * Multiboot Option ROM
+ *
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright Novell Inc, 2009
+ *   Authors: Alexander Graf <agraf@suse.de>
+ */
+
+#define NO_QEMU_PROTOS
+#include "../../hw/fw_cfg.h"
+
+#define BIOS_CFG_IOPORT_CFG	0x510
+#define BIOS_CFG_IOPORT_DATA	0x511
+
+#define MULTIBOOT_MAGIC		0x2badb002
+
+/* Read a variable from the fw_cfg device.
+   Clobbers:	%edx
+   Out:		%eax */
+.macro read_fw VAR
+	mov		$\VAR, %ax
+	mov		$BIOS_CFG_IOPORT_CFG, %dx
+	outw		%ax, (%dx)
+	mov		$BIOS_CFG_IOPORT_DATA, %dx
+	inb		(%dx), %al
+	shl		$8, %eax
+	inb		(%dx), %al
+	shl		$8, %eax
+	inb		(%dx), %al
+	shl		$8, %eax
+	inb		(%dx), %al
+	bswap		%eax
+.endm
+
+.code16
+.text
+	.global 	_start
+_start:
+	.short		0xaa55
+	.byte		(_end - _start) / 512
+	push		%eax
+	push		%ds
+
+	/* setup ds so we can access the IVT */
+	xor		%ax, %ax
+	mov		%ax, %ds
+
+	/* save old int 19 */
+	mov		(0x19*4), %eax
+	mov		%eax, %cs:old_int19
+
+	/* install our int 19 handler */
+	movw		$int19_handler, (0x19*4)
+	mov		%cs, (0x19*4+2)
+
+	pop		%ds
+	pop		%eax
+	lret
+
+int19_handler:
+	/* DS = CS */
+	movw		%cs, %ax
+	movw		%ax, %ds
+
+	/* fall through */
+
+run_multiboot:
+
+	cli
+	cld
+
+	mov		%cs, %eax
+	shl		$0x4, %eax
+
+	/* fix the gdt descriptor to be PC relative */
+	mov		(gdt_desc+2), %ebx
+	add		%eax, %ebx
+	mov		%ebx, (gdt_desc+2)
+
+	/* fix the lgdt instruction to be PC relative */
+	mov		(lgdt + 5), %ebx
+	add		%eax, %ebx
+	mov		%ebx, (lgdt + 5)
+
+	/* fix the ljmp instructions to be PC relative */
+	mov		(ljmp + 4), %ebx
+	add		%eax, %ebx
+	mov		%ebx, (ljmp + 4)
+	mov		%ebx, (ljmp2 + 2)
+
+	/* get the indirect jump to prot mode PC relative */
+	mov		(prot_jump), %ebx
+	add		%eax, %ebx
+	mov		%ebx, (prot_jump)
+
+	/* fix mov to prot_jump in protected mode */
+	mov		(mov_pj + 1), %ebx
+	add		%eax, %ebx
+	mov		%ebx, (mov_pj + 1)
+
+	/* FS = bootinfo_struct */
+	read_fw		FW_CFG_INITRD_ADDR
+	shr		$4, %eax
+	mov		%ax, %fs
+
+	/* ES = mmap_addr */
+	read_fw		FW_CFG_INITRD_SIZE
+	shr		$4, %eax
+	mov		%ax, %es
+
+	/* Initialize multiboot mmap structs using int 0x15(e820) */
+	xor		%ebx, %ebx
+	/* mmap start after first size */
+	movl		$4, %edi
+
+mmap_loop:
+	/* entry size (mmap struct) & max buffer size (int15) */
+	movl		$20, %ecx
+	/* store entry size */
+	movl		%ecx, %es:-4(%edi)
+	/* e820 */
+	movl		$0x0000e820, %eax
+	/* 'SMAP' magic */
+	movl		$0x534d4150, %edx
+	int		$0x15
+
+mmap_check_entry:
+	/* last entry? then we're done */
+	jb		mmap_done
+	and		%bx, %bx
+	jz		mmap_done
+	/* valid entry, so let's loop on */
+
+mmap_store_entry:
+	/* %ax = entry_number * 24 */
+	mov		$24, %ax
+	mul		%bx
+	mov		%ax, %di
+	movw		%di, %fs:0x2c
+	/* %di = 4 + (entry_number * 24) */
+	add		$4, %di
+	jmp		mmap_loop
+
+mmap_done:
+real_to_prot:
+	/* get us to protected mode now */
+	movl		$1, %eax
+	movl		%eax, %cr0
+
+	/* Load the GDT before going into protected mode */
+	xor		%bx, %bx
+	mov		%bx, %ds
+lgdt:
+	addr32 data32 lgdt	(gdt_desc)
+
+	/* the LJMP sets CS for us and gets us to 32-bit */
+ljmp:
+	addr32 data32 ljmp	*(prot_jump)
+
+prot_mode:
+.code32
+
+	/* initialize all other segments */
+	movl		$0x10, %eax
+	movl		%eax, %ss
+	movl		%eax, %ds
+	movl		%eax, %es
+	movl		%eax, %fs
+	movl		%eax, %gs
+
+	/* Jump off to the kernel */
+	read_fw		FW_CFG_KERNEL_ADDR
+mov_pj:
+	mov		%eax, (prot_jump)
+
+	/* EBX contains a pointer to the bootinfo struct */
+	read_fw		FW_CFG_INITRD_ADDR
+	movl		%eax, %ebx
+
+	/* EAX has to contain the magic */
+	movl		$MULTIBOOT_MAGIC, %eax
+ljmp2:
+	ljmp		*(prot_jump)
+
+/* Variables */
+.align 4, 0
+old_int19:	.long 0
+
+.align 4, 0
+gdt:
+	/* 0x00 */
+.byte	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+	/* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
+.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
+
+	/* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
+.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
+
+	/* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */
+.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
+
+	/* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */
+.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
+
+gdt_desc:
+.short	(5 * 8) - 1
+.long	gdt
+
+prot_jump:
+.long	prot_mode
+.short	0x8
+
+.align 512, 0
+_end:
+
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH 4/4] Multiboot build system
  2009-06-17 16:41     ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Alexander Graf
@ 2009-06-17 16:41       ` Alexander Graf
  2009-06-18  9:56       ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Avi Kivity
  1 sibling, 0 replies; 22+ messages in thread
From: Alexander Graf @ 2009-06-17 16:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, rene

In order to build the multiboot option rom, we need a Makefile and a tool
to sign the rom with.

Both are provided by this patch and mostly taken from the extboot source,
written by Anthony Liguori.

Once built, please copy the multiboot.bin file to your pc-bios directory
to actually be able to use the option rom.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 pc-bios/multiboot/Makefile  |   41 ++++++++++++++++++++++
 pc-bios/multiboot/signrom.c |   79 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 0 deletions(-)
 create mode 100644 pc-bios/multiboot/Makefile
 create mode 100644 pc-bios/multiboot/signrom.c

diff --git a/pc-bios/multiboot/Makefile b/pc-bios/multiboot/Makefile
new file mode 100644
index 0000000..0e7a764
--- /dev/null
+++ b/pc-bios/multiboot/Makefile
@@ -0,0 +1,41 @@
+OBJCOPY=objcopy
+
+# from kernel sources - scripts/Kbuild.include
+# try-run
+# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
+# Exit code chooses option. "$$TMP" is can be used as temporary file and
+# is automatically cleaned up.
+try-run = $(shell set -e;		\
+	TMP="$(TMPOUT).$$$$.tmp";	\
+	if ($(1)) >/dev/null 2>&1;	\
+	then echo "$(2)";		\
+	else echo "$(3)";		\
+	fi;				\
+	rm -f "$$TMP")
+
+# cc-option-yn
+# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
+cc-option-yn = $(call try-run,\
+	$(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",y,n)
+
+CFLAGS = -Wall -Wstrict-prototypes -Werror -fomit-frame-pointer -fno-builtin
+ifeq ($(call cc-option-yn,-fno-stack-protector),y)
+CFLAGS += -fno-stack-protector
+endif
+
+all: multiboot.bin
+
+%.o: %.S
+	$(CC) $(CFLAGS) -o $@ -c $<
+
+multiboot.img: multiboot.o
+	$(LD) --oformat binary -Ttext 0 -o $@ $<
+
+multiboot.bin: multiboot.img signrom
+	./signrom multiboot.img multiboot.bin
+
+signrom: signrom.c
+	$(CC) -o $@ -g -Wall $^
+
+clean:
+	$(RM) *.o *.img *.bin signrom *~
diff --git a/pc-bios/multiboot/signrom.c b/pc-bios/multiboot/signrom.c
new file mode 100644
index 0000000..fe8d677
--- /dev/null
+++ b/pc-bios/multiboot/signrom.c
@@ -0,0 +1,79 @@
+/*
+ * Extended Boot Option ROM
+ *
+ * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corporation, 2007
+ *   Authors: Anthony Liguori <aliguori@us.ibm.com>
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+	FILE *fin, *fout;
+	char buffer[512], oldbuffer[512];
+	int i, size, lag = 0;
+	uint8_t sum = 0;
+
+	if (argc != 3) {
+		printf("Usage: %s ROM OUTPUT\n", argv[0]);
+		return 1;
+	}
+
+	fin = fopen(argv[1], "rb");
+	fout = fopen(argv[2], "wb");
+
+	if (fin == NULL || fout == NULL) {
+		fprintf(stderr, "Could not open input/output files\n");
+		return 1;
+	}
+
+	do {
+		size = fread(buffer, 512, 1, fin);
+		if (size == 1) {
+			for (i = 0; i < 512; i++)
+				sum += buffer[i];
+
+			if (lag) {
+				if (fwrite(oldbuffer, 512, 1, fout) != 1) {
+					fprintf(stderr, "Write failed\n");
+					return 1;
+				}
+			}
+			lag = 1;
+			memcpy(oldbuffer, buffer, 512);
+		}
+	} while (size == 1);
+
+	if (size != 0) {
+		fprintf(stderr, "Failed to read from input file\n");
+		return 1;
+	}
+
+	oldbuffer[511] = -sum;
+
+	if (fwrite(oldbuffer, 512, 1, fout) != 1) {
+		fprintf(stderr, "Failed to write to output file\n");
+		return 1;
+	}
+
+	fclose(fin);
+	fclose(fout);
+
+	return 0;
+}
-- 
1.6.0.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-17 16:41 [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 Alexander Graf
  2009-06-17 16:41 ` [Qemu-devel] [PATCH 1/4] Change bochs bios init order Alexander Graf
@ 2009-06-17 17:10 ` François Revol
  2009-06-17 17:59   ` Anthony Liguori
  2009-06-18 11:15 ` Gleb Natapov
  2 siblings, 1 reply; 22+ messages in thread
From: François Revol @ 2009-06-17 17:10 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kwolf, rene, qemu-devel

> This patch implements support for Multiboot on x86 for -kernel.
> Multiboot is a "new" approach to get rid of different bootloaders,
> providing
> a unified interface for the kernel. It supports command line options
> and
> kernel modules.
>
> The two probably best known projects using multiboot are Xen and GNU
> Hurd.

While Haiku doesn't use it (yet, but it will probably never be able to
load without a BIOS except with the gzipped kernel trick used on a
floppy image for CD booting), it'd be nice to have the -append option
args forwarded by the BIOS so one could still use -append regardless
the boot method used to pass options to the OS, in which case I'd add
support for them in the Haiku loader.

François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-17 17:10 ` [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 François Revol
@ 2009-06-17 17:59   ` Anthony Liguori
  2009-06-18  8:25     ` François Revol
  0 siblings, 1 reply; 22+ messages in thread
From: Anthony Liguori @ 2009-06-17 17:59 UTC (permalink / raw)
  To: François Revol; +Cc: kwolf, rene, Alexander Graf, qemu-devel

François Revol wrote:
>> This patch implements support for Multiboot on x86 for -kernel.
>> Multiboot is a "new" approach to get rid of different bootloaders, 
>> providing
>> a unified interface for the kernel. It supports command line options 
>> and
>> kernel modules.
>>
>> The two probably best known projects using multiboot are Xen and GNU 
>> Hurd.
>>     
>
> While Haiku doesn't use it (yet, but it will probably never be able to 
> load without a BIOS except with the gzipped kernel trick used on a 
> floppy image for CD booting), it'd be nice to have the -append option 
> args forwarded by the BIOS so one could still use -append regardless 
> the boot method used to pass options to the OS, in which case I'd add 
> support for them in the Haiku loader.
>   

How can the BIOS pass such information?

The BIOS boot specification doesn't have any notion of command line AFAIK.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-17 17:59   ` Anthony Liguori
@ 2009-06-18  8:25     ` François Revol
  2009-06-18  9:09       ` Kevin Wolf
  0 siblings, 1 reply; 22+ messages in thread
From: François Revol @ 2009-06-18  8:25 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: kwolf, rene, agraf, qemu-devel

> François Revol wrote:
> >> This patch implements support for Multiboot on x86 for -kernel.
> >> Multiboot is a "new" approach to get rid of different bootloaders,
> >> providing
> >> a unified interface for the kernel. It supports command line
> > > options
> >> and
> >> kernel modules.
> >>
> >> The two probably best known projects using multiboot are Xen and
> > > GNU
> >> Hurd.
> >>
> >
> > While Haiku doesn't use it (yet, but it will probably never be able
> > to
> > load without a BIOS except with the gzipped kernel trick used on a
> > floppy image for CD booting), it'd be nice to have the -append
> > option
> > args forwarded by the BIOS so one could still use -append
> > regardless
> > the boot method used to pass options to the OS, in which case I'd
> > add
> > support for them in the Haiku loader.
> >
>
> How can the BIOS pass such information?
>
> The BIOS boot specification doesn't have any notion of command line
> AFAIK.

Indeed, at least not the PC BIOS.
OF has the concept OTH... and QEMU does pass it through IIRC, and Haiku
should be able to get it AFAIR.

The idea would be to have it pass it anyway through a multiboot frame.
It would them behave just as if the OS was booted by grub and args had
been typed at boot time, as well as select the boot resolution.
It would be useful for the free live OS Zoo or
http://dev.haiku-os.org/browser/haiku/trunk/3rdparty/mmu_man/onlinedemo/haiku.php
for ex.

This would allow passing boot args to OSes to automate yet not having
to fake a vmlinuz to load them with -kernel.

François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18  8:25     ` François Revol
@ 2009-06-18  9:09       ` Kevin Wolf
  2009-06-18 11:44         ` François Revol
  0 siblings, 1 reply; 22+ messages in thread
From: Kevin Wolf @ 2009-06-18  9:09 UTC (permalink / raw)
  To: François Revol; +Cc: rene, agraf, qemu-devel

François Revol schrieb:
>> François Revol wrote:
>>>> This patch implements support for Multiboot on x86 for -kernel.
>>>> Multiboot is a "new" approach to get rid of different bootloaders, 
>>>> providing
>>>> a unified interface for the kernel. It supports command line 
>>>> options 
>>>> and
>>>> kernel modules.
>>>>
>>>> The two probably best known projects using multiboot are Xen and 
>>>> GNU 
>>>> Hurd.
>>>>     
>>> While Haiku doesn't use it (yet, but it will probably never be able 
>>> to 
>>> load without a BIOS except with the gzipped kernel trick used on a 
>>> floppy image for CD booting), it'd be nice to have the -append 
>>> option 
>>> args forwarded by the BIOS so one could still use -append 
>>> regardless 
>>> the boot method used to pass options to the OS, in which case I'd 
>>> add 
>>> support for them in the Haiku loader.
>>>   
>> How can the BIOS pass such information?
>>
>> The BIOS boot specification doesn't have any notion of command line 
>> AFAIK.
> 
> Indeed, at least not the PC BIOS.
> OF has the concept OTH... and QEMU does pass it through IIRC, and Haiku 
> should be able to get it AFAIR.
> 
> The idea would be to have it pass it anyway through a multiboot frame.
> It would them behave just as if the OS was booted by grub and args had 
> been typed at boot time, as well as select the boot resolution.

Why would an OS want to parse multiboot structures but not implement
proper multiboot support? I mean, this really isn't anything
complicated. When you have enabled it to understand multiboot structures
you are only missing a handful of bytes for the multiboot header.

What is it that you need to do differently for Haiku?

Kevin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] Multiboot support v2
  2009-06-17 16:41     ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Alexander Graf
  2009-06-17 16:41       ` [Qemu-devel] [PATCH 4/4] Multiboot build system Alexander Graf
@ 2009-06-18  9:56       ` Avi Kivity
  2009-06-18 10:22         ` Alexander Graf
  1 sibling, 1 reply; 22+ messages in thread
From: Avi Kivity @ 2009-06-18  9:56 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kwolf, rene, qemu-devel

On 06/17/2009 07:41 PM, Alexander Graf wrote:
> This patch implements support for Multiboot on x86 for -kernel.
> Multiboot is a "new" approach to get rid of different bootloaders, providing
> a unified interface for the kernel. It supports command line options and
> kernel modules.
>
> The two probably best known projects using multiboot are Xen and GNU Hurd.
>
> This implementation should be mostly feature-complete. It is missing VBE
> extensions, but as no system uses them currently it does not really hurt.
>
> To use multiboot, specify the kernel as -kernel option. Modules should be given
> as -initrd options, seperated by a comma (,). -append also works.
>
> Please bear in mind that grub also does gzip decompression, which qemu does
> not do yet. To run existing images, please ungzip them first.
>
> The guest multiboot loader code is implemented as option rom using int 19.
> Parts of the work are based on efforts by Rene Rebe, who originally ported
> my code to int 19.
>    

This will be very useful for running test cases.

> +    /* 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) {
>    

Here (and in many other places in the patch) you have a control flow 
keyword followed immediately by a parentheses, so it looks like a 
function call.  Really reduced readability IMO.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] Multiboot support v2
  2009-06-18  9:56       ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Avi Kivity
@ 2009-06-18 10:22         ` Alexander Graf
  2009-06-18 11:19           ` Avi Kivity
  0 siblings, 1 reply; 22+ messages in thread
From: Alexander Graf @ 2009-06-18 10:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kwolf, rene, qemu-devel


On 18.06.2009, at 11:56, Avi Kivity wrote:

> On 06/17/2009 07:41 PM, Alexander Graf wrote:
>> This patch implements support for Multiboot on x86 for -kernel.
>> Multiboot is a "new" approach to get rid of different bootloaders,  
>> providing
>> a unified interface for the kernel. It supports command line  
>> options and
>> kernel modules.
>>
>> The two probably best known projects using multiboot are Xen and  
>> GNU Hurd.
>>
>> This implementation should be mostly feature-complete. It is  
>> missing VBE
>> extensions, but as no system uses them currently it does not really  
>> hurt.
>>
>> To use multiboot, specify the kernel as -kernel option. Modules  
>> should be given
>> as -initrd options, seperated by a comma (,). -append also works.
>>
>> Please bear in mind that grub also does gzip decompression, which  
>> qemu does
>> not do yet. To run existing images, please ungzip them first.
>>
>> The guest multiboot loader code is implemented as option rom using  
>> int 19.
>> Parts of the work are based on efforts by Rene Rebe, who originally  
>> ported
>> my code to int 19.
>>
>
> This will be very useful for running test cases.
>
>> +    /* 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) {
>>
>
> Here (and in many other places in the patch) you have a control flow  
> keyword followed immediately by a parentheses, so it looks like a  
> function call.  Really reduced readability IMO.

Looking through pc.c I found for mostly without space, but if with  
immediate space after it.

Wouldn't it be more useful to write some automatic formatting script  
git would run on patches that go in? Maybe people using tabs in the  
wrong areas of the code would be able to submit patches by then too ;-).

IMHO there is no real "qemu coding style" atm anyway - each maintainer  
has his own and uses that for its subtree. It'd be a lot more helpful  
to start addressing things at the root of the problems.

Alex

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-17 16:41 [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 Alexander Graf
  2009-06-17 16:41 ` [Qemu-devel] [PATCH 1/4] Change bochs bios init order Alexander Graf
  2009-06-17 17:10 ` [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 François Revol
@ 2009-06-18 11:15 ` Gleb Natapov
  2 siblings, 0 replies; 22+ messages in thread
From: Gleb Natapov @ 2009-06-18 11:15 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kwolf, rene, qemu-devel

On Wed, Jun 17, 2009 at 06:41:09PM +0200, Alexander Graf wrote:
> This patch implements support for Multiboot on x86 for -kernel.
> Multiboot is a "new" approach to get rid of different bootloaders, providing
> a unified interface for the kernel. It supports command line options and
> kernel modules.
> 
> The two probably best known projects using multiboot are Xen and GNU Hurd.
> 
> This implementation should be mostly feature-complete. It is missing VBE
> extensions, but as no system uses them currently it does not really hurt.
> 
> To use multiboot, specify the kernel as -kernel option. Modules should be given
> as -initrd options, seperated by a comma (,). -append also works.
> 
> Please bear in mind that grub also does gzip decompression, which qemu does
> not do yet. To run existing images, please ungzip them first.
> 
> The guest multiboot loader code is implemented as option rom using int 19.
> Parts of the work are based on efforts by Rene Rebe, who originally ported
> my code to int 19.
> 
> Also, Kevin Wolf helped a lot whenever I had a new version of this patch
> around.
> 
With this small patch it also works for me in KVM


diff --git a/pc-bios/multiboot/multiboot.S b/pc-bios/multiboot/multiboot.S
index 5a2acba..943c381 100644
--- a/pc-bios/multiboot/multiboot.S
+++ b/pc-bios/multiboot/multiboot.S
@@ -156,9 +156,6 @@ mmap_store_entry:
 
 mmap_done:
 real_to_prot:
-	/* get us to protected mode now */
-	movl		$1, %eax
-	movl		%eax, %cr0
 
 	/* Load the GDT before going into protected mode */
 	xor		%bx, %bx
@@ -166,12 +163,9 @@ real_to_prot:
 lgdt:
 	addr32 data32 lgdt	(gdt_desc)
 
-	/* the LJMP sets CS for us and gets us to 32-bit */
-ljmp:
-	addr32 data32 ljmp	*(prot_jump)
-
-prot_mode:
-.code32
+	/* get us to protected mode now */
+	movl		$1, %eax
+	movl		%eax, %cr0
 
 	/* initialize all other segments */
 	movl		$0x10, %eax
@@ -181,6 +175,12 @@ prot_mode:
 	movl		%eax, %fs
 	movl		%eax, %gs
 
+	/* the LJMP sets CS for us and gets us to 32-bit */
+ljmp:
+	addr32 data32 ljmp	*(prot_jump)
+
+prot_mode:
+.code32
 	/* Jump off to the kernel */
 	read_fw		FW_CFG_KERNEL_ADDR
 mov_pj:
--
			Gleb.

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] Multiboot support v2
  2009-06-18 10:22         ` Alexander Graf
@ 2009-06-18 11:19           ` Avi Kivity
  0 siblings, 0 replies; 22+ messages in thread
From: Avi Kivity @ 2009-06-18 11:19 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kwolf, rene, qemu-devel

On 06/18/2009 01:22 PM, Alexander Graf wrote:
> Looking through pc.c I found for mostly without space, but if with 
> immediate space after it.
>

pc.c:

    [avi@cleopatra qemu-kvm (master)]$ grep -c -F 'if (' hw/pc.c
    99
    [avi@cleopatra qemu-kvm (master)]$ grep -c -F 'if(' hw/pc.c
    0
    [avi@cleopatra qemu-kvm (master)]$ grep -c -F 'for (' hw/pc.c
    13
    [avi@cleopatra qemu-kvm (master)]$ grep -c -F 'for(' hw/pc.c
    8


the entire tree:

    [avi@cleopatra qemu-kvm (1b443f4...)]$ git ls-files | xargs cat |
    grep -c -F 'if ('
    25831
    [avi@cleopatra qemu-kvm (1b443f4...)]$ git ls-files | xargs cat |
    grep -c -F 'if('
    711
    [avi@cleopatra qemu-kvm (1b443f4...)]$ git ls-files | xargs cat |
    grep -c -F 'for ('
    2085
    [avi@cleopatra qemu-kvm (1b443f4...)]$ git ls-files | xargs cat |
    grep -c -F 'for('
    906


The spaces win.

> Wouldn't it be more useful to write some automatic formatting script 
> git would run on patches that go in? Maybe people using tabs in the 
> wrong areas of the code would be able to submit patches by then too ;-).
>
> IMHO there is no real "qemu coding style" atm anyway - each maintainer 
> has his own and uses that for its subtree. It'd be a lot more helpful 
> to start addressing things at the root of the problems.
>

There's CODING_STYLE (which doesn't address this bit, but is a start).


-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18  9:09       ` Kevin Wolf
@ 2009-06-18 11:44         ` François Revol
  2009-06-18 11:55           ` Alexander Graf
  2009-06-18 12:01           ` Kevin Wolf
  0 siblings, 2 replies; 22+ messages in thread
From: François Revol @ 2009-06-18 11:44 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: rene, agraf, qemu-devel

> >> The BIOS boot specification doesn't have any notion of command
> > > line
> >> AFAIK.
> >
> > Indeed, at least not the PC BIOS.
> > OF has the concept OTH... and QEMU does pass it through IIRC, and
> > Haiku
> > should be able to get it AFAIR.
> >
> > The idea would be to have it pass it anyway through a multiboot
> > frame.
> > It would them behave just as if the OS was booted by grub and args
> > had
> > been typed at boot time, as well as select the boot resolution.
>
> Why would an OS want to parse multiboot structures but not implement
> proper multiboot support? I mean, this really isn't anything
> complicated. When you have enabled it to understand multiboot
> structures
> you are only missing a handful of bytes for the multiboot header.
>
> What is it that you need to do differently for Haiku?

Because Haiku has its own second stage loader, which requires the BIOS
to locate the kernel and module in a BFS partition which grub doesn't
implement btw. It also handles PM switching by itself.
Haiku might also use the BIOS for other stuff, like VESA mode
switching, so I'd need to make sure all calls aren't strictly required.

IIRC someone proposed a patch to support multiboot in Haiku, but it
didn't get much interest.

The only way we could use multiboot without BIOS is with the tgz trick
(a tgz of kernel and modules located after the loader on the floppy
image, that is used for CD boot too, and for PXE, or by reading them
from a non BFS partition first.
But those ways require extra stuff besides the plain BFS partition, so
it complicates things for users.

I suppose I could still support it for special uses like the os zoo...
Then I could map -kernel to haiku_loader or an ELF version, and use -
initrd to pass the kernel tgz...

I started looking at adding BFS support to GRUB2, but of course until
it propagates to the existing installed base...

François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 11:44         ` François Revol
@ 2009-06-18 11:55           ` Alexander Graf
  2009-06-18 12:13             ` François Revol
  2009-06-18 12:01           ` Kevin Wolf
  1 sibling, 1 reply; 22+ messages in thread
From: Alexander Graf @ 2009-06-18 11:55 UTC (permalink / raw)
  To: "François Revol"; +Cc: Kevin Wolf, rene, qemu-devel


On 18.06.2009, at 13:44, François Revol wrote:

>>>> The BIOS boot specification doesn't have any notion of command
>>>> line
>>>> AFAIK.
>>>
>>> Indeed, at least not the PC BIOS.
>>> OF has the concept OTH... and QEMU does pass it through IIRC, and
>>> Haiku
>>> should be able to get it AFAIR.
>>>
>>> The idea would be to have it pass it anyway through a multiboot
>>> frame.
>>> It would them behave just as if the OS was booted by grub and args
>>> had
>>> been typed at boot time, as well as select the boot resolution.
>>
>> Why would an OS want to parse multiboot structures but not implement
>> proper multiboot support? I mean, this really isn't anything
>> complicated. When you have enabled it to understand multiboot
>> structures
>> you are only missing a handful of bytes for the multiboot header.
>>
>> What is it that you need to do differently for Haiku?
>
> Because Haiku has its own second stage loader, which requires the BIOS
> to locate the kernel and module in a BFS partition which grub doesn't
> implement btw. It also handles PM switching by itself.
> Haiku might also use the BIOS for other stuff, like VESA mode
> switching, so I'd need to make sure all calls aren't strictly  
> required.
>
> IIRC someone proposed a patch to support multiboot in Haiku, but it
> didn't get much interest.
>
> The only way we could use multiboot without BIOS is with the tgz trick
> (a tgz of kernel and modules located after the loader on the floppy
> image, that is used for CD boot too, and for PXE, or by reading them
> from a non BFS partition first.
> But those ways require extra stuff besides the plain BFS partition, so
> it complicates things for users.
>
> I suppose I could still support it for special uses like the os zoo...
> Then I could map -kernel to haiku_loader or an ELF version, and use -
> initrd to pass the kernel tgz...

That roughly what Xen does. The dom0 kernel is passed as -initrd.
Also, the original reason I implemented multiboot support for -kernel  
was the Mac OS X bootloader. Basically only the stage2 loader is  
loaded using -kernel and that again contains an HFS reader that reads  
the actual kernel from the disk.

I don't see why you couldn't do the same with your stage2 loader.

But then again - the question is of course what you're trying to  
achieve :-). I merely wanted to replace the EFI stage2 loader with a  
BIOS stage2 loader.


Alex

>
> I started looking at adding BFS support to GRUB2, but of course until
> it propagates to the existing installed base...
>
> François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 11:44         ` François Revol
  2009-06-18 11:55           ` Alexander Graf
@ 2009-06-18 12:01           ` Kevin Wolf
  2009-06-18 12:17             ` François Revol
  1 sibling, 1 reply; 22+ messages in thread
From: Kevin Wolf @ 2009-06-18 12:01 UTC (permalink / raw)
  To: François Revol; +Cc: rene, agraf, qemu-devel

François Revol schrieb:
>> Why would an OS want to parse multiboot structures but not implement
>> proper multiboot support? I mean, this really isn't anything
>> complicated. When you have enabled it to understand multiboot 
>> structures
>> you are only missing a handful of bytes for the multiboot header.
>>
>> What is it that you need to do differently for Haiku?
> 
> Because Haiku has its own second stage loader, which requires the BIOS 
> to locate the kernel and module in a BFS partition which grub doesn't 
> implement btw.

That makes sense on real hardware, of course. But for -kernel you don't
need a file system to read the kernel from.

I'm not talking about replacing the existing loader, but just about
adding support for multiboot as an additional option. Don't know how the
Haiku boot process works though, so maybe I'm completely wrong.

> It also handles PM switching by itself.
> Haiku might also use the BIOS for other stuff, like VESA mode 
> switching, so I'd need to make sure all calls aren't strictly required.

In theory you could switch back to Real Mode when starting through
multiboot and then continue as with a normal boot. Admittedly, doesn't
sound exactly nice, but should be doable...

Kevin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 11:55           ` Alexander Graf
@ 2009-06-18 12:13             ` François Revol
  0 siblings, 0 replies; 22+ messages in thread
From: François Revol @ 2009-06-18 12:13 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kwolf, rene, qemu-devel

> > I suppose I could still support it for special uses like the os
> > zoo...
> > Then I could map -kernel to haiku_loader or an ELF version, and use
> > -
> > initrd to pass the kernel tgz...
>
> That roughly what Xen does. The dom0 kernel is passed as -initrd.
> Also, the original reason I implemented multiboot support for -kernel
> was the Mac OS X bootloader. Basically only the stage2 loader is
> loaded using -kernel and that again contains an HFS reader that reads
> the actual kernel from the disk.

Yeah that'd be the idea, with s/HFS/BFS/ :)

> I don't see why you couldn't do the same with your stage2 loader.

It's just that it wouldn't be useful for the general "user" case,
because the other way is simpler.


>
> But then again - the question is of course what you're trying to
> achieve :-). I merely wanted to replace the EFI stage2 loader with a
> BIOS stage2 loader.

Well the idea for now was just to allow passing args from command line
to implement options like setting boot resolution or other stuff to
allow configurable demos.

But probably it could be useful also for other configurations.


François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 12:01           ` Kevin Wolf
@ 2009-06-18 12:17             ` François Revol
  2009-06-18 12:23               ` Alexander Graf
  2009-06-18 12:29               ` Kevin Wolf
  0 siblings, 2 replies; 22+ messages in thread
From: François Revol @ 2009-06-18 12:17 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: rene, agraf, qemu-devel

> François Revol schrieb:
> >> Why would an OS want to parse multiboot structures but not
> > > implement
> >> proper multiboot support? I mean, this really isn't anything
> >> complicated. When you have enabled it to understand multiboot
> >> structures
> >> you are only missing a handful of bytes for the multiboot header.
> >>
> >> What is it that you need to do differently for Haiku?
> >
> > Because Haiku has its own second stage loader, which requires the
> > BIOS
> > to locate the kernel and module in a BFS partition which grub
> > doesn't
> > implement btw.
>
> That makes sense on real hardware, of course. But for -kernel you
> don't
> need a file system to read the kernel from.

Except that wouldn't be the actual kernel passed but the 2nd stage.
And having to pass the kernel in a tgz outside the BFS image makes it
more complex to set up.

> I'm not talking about replacing the existing loader, but just about
> adding support for multiboot as an additional option. Don't know how
> the
> Haiku boot process works though, so maybe I'm completely wrong.

Yes that's possible, we already support OF for PPC, and we'll implement
U-Boot support for ARM anyway.
It's just that I "just" needed to pass args for this usage.

> > It also handles PM switching by itself.
> > Haiku might also use the BIOS for other stuff, like VESA mode
> > switching, so I'd need to make sure all calls aren't strictly
> > required.
>
> In theory you could switch back to Real Mode when starting through
> multiboot and then continue as with a normal boot. Admittedly,
> doesn't
> sound exactly nice, but should be doable...

The loader can likey detect it anyway. If multiboot is used it should't
need to call the BIOS to read the kernel anyway. It's just a different
code path.
PPC boot starts with paging enabled IIRC.

François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 12:17             ` François Revol
@ 2009-06-18 12:23               ` Alexander Graf
  2009-06-18 12:34                 ` François Revol
  2009-06-18 12:29               ` Kevin Wolf
  1 sibling, 1 reply; 22+ messages in thread
From: Alexander Graf @ 2009-06-18 12:23 UTC (permalink / raw)
  To: François Revol; +Cc: Kevin Wolf, rene, qemu-devel


On 18.06.2009, at 14:17, François Revol wrote:

>> François Revol schrieb:
>>>> Why would an OS want to parse multiboot structures but not
>>>> implement
>>>> proper multiboot support? I mean, this really isn't anything
>>>> complicated. When you have enabled it to understand multiboot
>>>> structures
>>>> you are only missing a handful of bytes for the multiboot header.
>>>>
>>>> What is it that you need to do differently for Haiku?
>>>
>>> Because Haiku has its own second stage loader, which requires the
>>> BIOS
>>> to locate the kernel and module in a BFS partition which grub
>>> doesn't
>>> implement btw.
>>
>> That makes sense on real hardware, of course. But for -kernel you
>> don't
>> need a file system to read the kernel from.
>
> Except that wouldn't be the actual kernel passed but the 2nd stage.
> And having to pass the kernel in a tgz outside the BFS image makes it
> more complex to set up.

I don't see why you need a tgz file. Multiboot can pass multiple  
modules. Just use -initrd foo,bar,xxx

Alex

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 12:17             ` François Revol
  2009-06-18 12:23               ` Alexander Graf
@ 2009-06-18 12:29               ` Kevin Wolf
  2009-06-18 12:35                 ` François Revol
  1 sibling, 1 reply; 22+ messages in thread
From: Kevin Wolf @ 2009-06-18 12:29 UTC (permalink / raw)
  To: François Revol; +Cc: rene, agraf, qemu-devel

François Revol schrieb:
>> François Revol schrieb:
>>>> Why would an OS want to parse multiboot structures but not 
>>>> implement
>>>> proper multiboot support? I mean, this really isn't anything
>>>> complicated. When you have enabled it to understand multiboot 
>>>> structures
>>>> you are only missing a handful of bytes for the multiboot header.
>>>>
>>>> What is it that you need to do differently for Haiku?
>>> Because Haiku has its own second stage loader, which requires the 
>>> BIOS 
>>> to locate the kernel and module in a BFS partition which grub 
>>> doesn't 
>>> implement btw.
>> That makes sense on real hardware, of course. But for -kernel you 
>> don't
>> need a file system to read the kernel from.
> 
> Except that wouldn't be the actual kernel passed but the 2nd stage.
> And having to pass the kernel in a tgz outside the BFS image makes it 
> more complex to set up.

As Alex said, you don't need the tgz. Multiboot supports passing modules
to the kernel (or 2nd stage loader), i.e. files that are loaded into
memory by the bootloader (qemu in this case).

>>> It also handles PM switching by itself.
>>> Haiku might also use the BIOS for other stuff, like VESA mode 
>>> switching, so I'd need to make sure all calls aren't strictly 
>>> required.
>> In theory you could switch back to Real Mode when starting through
>> multiboot and then continue as with a normal boot. Admittedly, 
>> doesn't
>> sound exactly nice, but should be doable...
> 
> The loader can likey detect it anyway. If multiboot is used it should't 
> need to call the BIOS to read the kernel anyway. It's just a different 
> code path. 

Detecting shouldn't be problem, you have the multiboot magic in eax. I
thought you would need the BIOS anyway (e.g. for VESA, as you mentioned
yourself). If you don't or you can use VM86 instead, it's going to be
much simpler, of course.

Kevin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 12:23               ` Alexander Graf
@ 2009-06-18 12:34                 ` François Revol
  0 siblings, 0 replies; 22+ messages in thread
From: François Revol @ 2009-06-18 12:34 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kwolf, rene, qemu-devel

> >> That makes sense on real hardware, of course. But for -kernel you
> >> don't
> >> need a file system to read the kernel from.
> >
> > Except that wouldn't be the actual kernel passed but the 2nd stage.
> > And having to pass the kernel in a tgz outside the BFS image makes
> > it
> > more complex to set up.
>
> I don't see why you need a tgz file. Multiboot can pass multiple
> modules. Just use -initrd foo,bar,xxx

Sure you'll pass 30 names there ;)
Plus, does it handle folders and symlinks, as that's required ?

There is no need to make it even harder anyway, the build process does
generate the tgz for CD/floppy boot anyway.

François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2
  2009-06-18 12:29               ` Kevin Wolf
@ 2009-06-18 12:35                 ` François Revol
  0 siblings, 0 replies; 22+ messages in thread
From: François Revol @ 2009-06-18 12:35 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: rene, agraf, qemu-devel

> > The loader can likey detect it anyway. If multiboot is used it
> > should't
> > need to call the BIOS to read the kernel anyway. It's just a
> > different
> > code path.
>
> Detecting shouldn't be problem, you have the multiboot magic in eax.
> I
> thought you would need the BIOS anyway (e.g. for VESA, as you
> mentioned
> yourself). If you don't or you can use VM86 instead, it's going to be
> much simpler, of course.

Not from the bootloader IIRC, but well, I've other pending stuff first.

François.

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2009-06-18 12:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-17 16:41 [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 Alexander Graf
2009-06-17 16:41 ` [Qemu-devel] [PATCH 1/4] Change bochs bios init order Alexander Graf
2009-06-17 16:41   ` [Qemu-devel] [PATCH 2/4] Expose fw_cfg v2 Alexander Graf
2009-06-17 16:41     ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Alexander Graf
2009-06-17 16:41       ` [Qemu-devel] [PATCH 4/4] Multiboot build system Alexander Graf
2009-06-18  9:56       ` [Qemu-devel] [PATCH 3/4] Multiboot support v2 Avi Kivity
2009-06-18 10:22         ` Alexander Graf
2009-06-18 11:19           ` Avi Kivity
2009-06-17 17:10 ` [Qemu-devel] [PATCH 0/4] Add multiboot support (x86) v2 François Revol
2009-06-17 17:59   ` Anthony Liguori
2009-06-18  8:25     ` François Revol
2009-06-18  9:09       ` Kevin Wolf
2009-06-18 11:44         ` François Revol
2009-06-18 11:55           ` Alexander Graf
2009-06-18 12:13             ` François Revol
2009-06-18 12:01           ` Kevin Wolf
2009-06-18 12:17             ` François Revol
2009-06-18 12:23               ` Alexander Graf
2009-06-18 12:34                 ` François Revol
2009-06-18 12:29               ` Kevin Wolf
2009-06-18 12:35                 ` François Revol
2009-06-18 11:15 ` Gleb Natapov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.