* [Qemu-devel] [RFC] linuxboot Option ROM for Linux kernel booting
@ 2008-04-21 3:32 Nguyen Anh Quynh
2008-04-21 3:33 ` [Qemu-devel] " Nguyen Anh Quynh
2008-04-22 13:50 ` Anthony Liguori
0 siblings, 2 replies; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-21 3:32 UTC (permalink / raw)
To: kvm-devel, qemu-devel; +Cc: Anthony Liguori, H. Peter Anvin
[-- Attachment #1: Type: text/plain, Size: 1357 bytes --]
Hi,
This should be submitted to upstream (but not to kvm-devel list), but
this is only the test code that I want to quickly send out for
comments. In case it looks OK, I will send it to upstream later.
Inspired by extboot and conversations with Anthony and HPA, this
linuxboot option ROM is a simple option ROM that intercepts int19 in
order to execute linux setup code. This approach eliminates the need
to manipulate the boot sector for this purpose.
To test it, just load linux kernel with your KVM/QEMU image using
-kernel option in normal way.
I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
Ubuntu 8.04.
Thanks,
Quynh
# diffstat linuxboot1.diff
Makefile | 13 ++++-
linuxboot/Makefile | 40 +++++++++++++++
linuxboot/boot.S | 54 +++++++++++++++++++++
linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
linuxboot/signrom |binary
linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
linuxboot/util.h | 69 +++++++++++++++++++++++++++
qemu/Makefile | 3 -
qemu/Makefile.target | 2
qemu/hw/linuxboot.c | 39 +++++++++++++++
qemu/hw/pc.c | 22 +++++++-
qemu/hw/pc.h | 5 +
13 files changed, 600 insertions(+), 9 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: linuxboot1.diff --]
[-- Type: text/x-diff; name=linuxboot1.diff, Size: 24174 bytes --]
commit f4f1178898c8a4bbbc0a432354dbcc56353099c3
Author: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Mon Apr 21 12:27:47 2008 +0900
Linuxboot Option ROM support.
Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
diff --git a/Makefile b/Makefile
index 76c149a..fdd9388 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ DESTDIR=
rpmrelease = devel
-.PHONY: kernel user libkvm qemu bios vgabios extboot clean libfdt
+.PHONY: kernel user libkvm qemu bios vgabios extboot linuxboot clean libfdt
all: libkvm qemu
ifneq '$(filter $(ARCH), x86_64 i386 ia64)' ''
@@ -19,7 +19,7 @@ qemu kernel user libkvm:
qemu: libkvm
ifneq '$(filter $(ARCH), i386 x86_64)' ''
- qemu: extboot
+ qemu: extboot linuxboot
endif
ifneq '$(filter $(ARCH), powerpc)' ''
qemu: libfdt
@@ -41,6 +41,14 @@ extboot:
|| ! cmp -s qemu/pc-bios/extboot.bin extboot/extboot.bin; then \
cp extboot/extboot.bin qemu/pc-bios/extboot.bin; \
fi
+
+linuxboot:
+ $(MAKE) -C $@
+ if ! [ -f qemu/pc-bios/linuxboot.bin ] \
+ || ! cmp -s qemu/pc-bios/linuxboot.bin linuxboot/linuxboot.bin; then \
+ cp linuxboot/linuxboot.bin qemu/pc-bios/linuxboot.bin; \
+ fi
+
libfdt:
$(MAKE) -C $@
@@ -88,6 +96,7 @@ srpm:
tar czf $(RPMTOPDIR)/SOURCES/kernel.tar.gz kernel
tar czf $(RPMTOPDIR)/SOURCES/scripts.tar.gz scripts
tar czf $(RPMTOPDIR)/SOURCES/extboot.tar.gz extboot
+ tar czf $(RPMTOPDIR)/SOURCES/linuxboot.tar.gz linuxboot
cp Makefile configure kvm_stat $(RPMTOPDIR)/SOURCES
rpmbuild --define="_topdir $(RPMTOPDIR)" -bs $(tmpspec)
$(RM) $(tmpspec)
diff --git a/linuxboot/Makefile b/linuxboot/Makefile
new file mode 100644
index 0000000..3bc88a6
--- /dev/null
+++ b/linuxboot/Makefile
@@ -0,0 +1,40 @@
+# Makefile for linuxboot Option ROM
+# Nguyen Anh Quynh <aquynh@gmail.com>
+
+CC = gcc
+CCFLAGS = -g -Wall -Werror -nostdlib -fno-builtin -fomit-frame-pointer -Os
+
+cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
+ /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
+CCFLAGS += $(call cc-option,$(CC),-nopie,)
+CCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
+CCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
+
+INSTALLDIR = /usr/share/qemu
+
+.PHONY: all
+all: clean linuxboot.bin
+
+.PHONY: install
+install: linuxboot.bin
+ cp linuxboot.bin $(INSTALLDIR)
+
+.PHONY: clean
+clean:
+ $(RM) *.o *.img *.bin signrom *~
+
+linuxboot.img: boot.o rom.o
+ $(LD) --oformat binary -Ttext 0 $^ -o $@
+
+linuxboot.bin: linuxboot.img signrom
+ ./signrom linuxboot.img linuxboot.bin
+
+signrom: signrom.c
+ $(CC) -o $@ -g -Wall $^
+
+%.o: %.c
+ $(CC) $(CCFLAGS) -c $<
+
+%.o: %.S
+ $(CC) $(CCFLAGS) -c $<
+
diff --git a/linuxboot/boot.S b/linuxboot/boot.S
new file mode 100644
index 0000000..a9461d6
--- /dev/null
+++ b/linuxboot/boot.S
@@ -0,0 +1,54 @@
+/*
+ * boot.S
+ * Linux Boot Option ROM for QEMU.
+
+ * Copyright (C) by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * 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.
+ */
+
+ .text
+ .code16gcc
+ .globl _start
+ .extern setup
+_start:
+ .short 0xAA55 /* ROM signature */
+ .byte 0 /* ROM size - to be patched at built-time */
+ /* ROM entry: initializing */
+ pushal
+ /* %es is clobbered, so save it */
+ pushw %es
+ /* just in case */
+ pushw %ds
+ cld
+ call setup /* call C code */
+ popw %ds
+ popw %es
+ popal
+ lretw
+
+ /* interrupt 19 handler */
+ .globl int19_handler
+ .extern int19_handler_C
+ .extern linux_boot
+ int19_handler:
+ /* we never execute the original int19, so no need to care
+ * about clobbered registers :-) */
+ /* Set %ds = %ss */
+ movw %ss, %ax
+ movw %ax, %ds
+ cld
+ call int19_handler_C /* call C code */
+ /* we actually jump to linux kernel setup, so never reach here */
diff --git a/linuxboot/farvar.h b/linuxboot/farvar.h
new file mode 100644
index 0000000..7876186
--- /dev/null
+++ b/linuxboot/farvar.h
@@ -0,0 +1,130 @@
+/*
+ * farvar.h
+ * Code to access multiple segments within gcc.
+ *
+ * Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+ *
+ * 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.
+ */
+
+#ifndef __FARVAR_H
+#define __FARVAR_H
+
+#include <stdint.h>
+
+// Dummy definitions used to make sure gcc understands dependencies
+// between SET_SEG and GET/READ/WRITE_SEG macros.
+extern uint16_t __segment_CS, __segment_DS, __segment_ES, __segment_SS;
+extern uint16_t __segment_GS, __segment_FS;
+
+// Low level macros for reading/writing memory via a segment selector.
+#define __READ8_SEG(SEG, var) ({ \
+ typeof(var) __value; \
+ __asm__("movb %%" #SEG ":%1, %b0" : "=Qi"(__value) \
+ : "m"(var), "m"(__segment_ ## SEG)); \
+ __value; })
+#define __READ16_SEG(SEG, var) ({ \
+ typeof(var) __value; \
+ __asm__("movw %%" #SEG ":%1, %w0" : "=ri"(__value) \
+ : "m"(var), "m"(__segment_ ## SEG)); \
+ __value; })
+#define __READ32_SEG(SEG, var) ({ \
+ typeof(var) __value; \
+ __asm__("movl %%" #SEG ":%1, %0" : "=ri"(__value) \
+ : "m"(var), "m"(__segment_ ## SEG)); \
+ __value; })
+
+#define __WRITE8_SEG(SEG, var, value) \
+ __asm__("movb %b1, %%" #SEG ":%0" : "=m"(var) \
+ : "Q"(value), "m"(__segment_ ## SEG))
+#define __WRITE16_SEG(SEG, var, value) \
+ __asm__("movw %w1, %%" #SEG ":%0" : "=m"(var) \
+ : "r"(value), "m"(__segment_ ## SEG))
+#define __WRITE32_SEG(SEG, var, value) \
+ __asm__("movl %1, %%" #SEG ":%0" : "=m"(var) \
+ : "r"(value), "m"(__segment_ ## SEG))
+
+// Low level macros for getting/setting a segment register.
+#define __SET_SEG(SEG, value) \
+ __asm__("movw %w1, %%" #SEG : "=m"(__segment_ ## SEG) \
+ : "r"(value))
+#define __GET_SEG(SEG) ({ \
+ uint16_t __seg; \
+ __asm__("movw %%" #SEG ", %w0" : "=r"(__seg) \
+ : "m"(__segment_ ## SEG)); \
+ __seg;})
+
+// Macros for automatically choosing the appropriate memory size
+// access method.
+extern void __force_link_error__unknown_type();
+
+#define __GET_VAR(seg, var) ({ \
+ typeof(var) __val; \
+ if (__builtin_types_compatible_p(typeof(__val), uint8_t) \
+ || __builtin_types_compatible_p(typeof(__val), int8_t)) \
+ __val = __READ8_SEG(seg, var); \
+ else if (__builtin_types_compatible_p(typeof(__val), uint16_t) \
+ || __builtin_types_compatible_p(typeof(__val), int16_t)) \
+ __val = __READ16_SEG(seg, var); \
+ else if (__builtin_types_compatible_p(typeof(__val), uint32_t) \
+ || __builtin_types_compatible_p(typeof(__val), int32_t)) \
+ __val = __READ32_SEG(seg, var); \
+ else \
+ __force_link_error__unknown_type(); \
+ __val; })
+
+#define __SET_VAR(seg, var, val) do { \
+ if (__builtin_types_compatible_p(typeof(var), uint8_t) \
+ || __builtin_types_compatible_p(typeof(var), int8_t)) \
+ __WRITE8_SEG(seg, var, (val)); \
+ else if (__builtin_types_compatible_p(typeof(var), uint16_t) \
+ || __builtin_types_compatible_p(typeof(var), int16_t)) \
+ __WRITE16_SEG(seg, var, (val)); \
+ else if (__builtin_types_compatible_p(typeof(var), uint32_t) \
+ || __builtin_types_compatible_p(typeof(var), int32_t)) \
+ __WRITE32_SEG(seg, var, (val)); \
+ else \
+ __force_link_error__unknown_type(); \
+} while (0)
+
+// Macros for converting to/from 32bit style pointers to their
+// equivalent 16bit segment/offset values.
+#define FARPTR_TO_SEG(p) (((u32)(p)) >> 4)
+#define FARPTR_TO_OFFSET(p) (((u32)(p)) & 0xf)
+#define MAKE_FARPTR(seg,off) ((void*)(((seg)<<4)+(off)))
+
+// Macros for accessing a variable in another segment. (They
+// automatically update the %es segment and then make the appropriate
+// access.)
+#define __GET_FARVAR(seg, var) ({ \
+ SET_SEG(ES, (seg)); \
+ GET_VAR(ES, (var)); })
+
+#define __SET_FARVAR(seg, var, val) do { \
+ typeof(var) __sfv_val = (val); \
+ SET_SEG(ES, (seg)); \
+ SET_VAR(ES, (var), __sfv_val); \
+} while (0)
+
+#define GET_FARVAR(seg, var) __GET_FARVAR((seg), (var))
+#define SET_FARVAR(seg, var, val) __SET_FARVAR((seg), (var), (val))
+
+#define GET_VAR(seg, var) __GET_VAR(seg, (var))
+#define SET_VAR(seg, var, val) __SET_VAR(seg, (var), (val))
+
+#define SET_SEG(SEG, value) __SET_SEG(SEG, (value))
+#define GET_SEG(SEG) __GET_SEG(SEG)
+
+#endif
diff --git a/linuxboot/rom.c b/linuxboot/rom.c
new file mode 100644
index 0000000..4cd600d
--- /dev/null
+++ b/linuxboot/rom.c
@@ -0,0 +1,104 @@
+/*
+ * rom.c
+ * Linux Boot Option ROM for QEMU.
+ *
+ * Copyright (C) by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * 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.
+ */
+
+#include "util.h"
+#include "farvar.h"
+
+asm (".code16gcc");
+
+struct linuxboot_info {
+ uint16_t cs; /* CS segment */
+ uint16_t ds; /* DS segment */
+ uint16_t sp; /* SP reg */
+};
+
+#define LINUXBOOT_PORT 0x407
+
+struct ivector {
+ uint16_t offset;
+ uint16_t segment;
+};
+/* manipulate interrupt vector entry */
+#define GET_IVT_ENTRY(index,var) \
+ GET_FARVAR(0, ((struct ivector *)(index*sizeof(struct ivector)))->var)
+#define SET_IVT_ENTRY(index,var,value) \
+ SET_FARVAR(0, ((struct ivector *)(index*sizeof(struct ivector)))->var, value)
+
+/* called from ASM code in boot.S */
+void setup()
+{
+ /* install our INT 19 handler */
+ extern void int19_handler;
+ SET_IVT_ENTRY(0x19, segment, GET_SEG(CS));
+ SET_IVT_ENTRY(0x19, offset, (uint16_t)&int19_handler);
+}
+
+/* send command to QEMU via a dedicated IO port */
+static void get_linuxboot_info(struct linuxboot_info *info)
+{
+ uint16_t seg;
+ char tmp[16 + sizeof(*info)], *p;
+
+ /* align to 16 */
+ p = (char *)(((uint32_t)tmp + 0xF) & ~0xF);
+ memcpy(p, info, sizeof(*info));
+
+ /* send segment contained info to QEMU */
+ seg = ((uint32_t)p >> 4) + GET_SEG(SS);
+ outw(seg, LINUXBOOT_PORT);
+
+ /* now copy back the result to info */
+ memcpy(info, p, sizeof(*info));
+}
+
+/* boot linux by jmp to its kernel setup code */
+static void boot_linux(uint16_t cs, uint16_t ds, uint16_t sp)
+{
+ asm volatile (
+ "cli \n"
+ "cld \n"
+ /* setup registers for kernel setup */
+ "movw %0, %%ds \n"
+ "movw %0, %%es \n"
+ "movw %0, %%fs \n"
+ "movw %0, %%gs \n"
+ "movw %0, %%ss \n"
+ "movw %2, %%sp \n"
+ /* push CS:IP */
+ "pushw %1 \n"
+ "pushw $0 \n"
+ /* now (implicitly) jump to CS:IP */
+ "lretw \n"
+ :
+ : "rm" (ds), "rm" (cs), "rm" (sp)
+ );
+}
+
+/* hook INT 13 */
+/* called from ASM code in boot.S */
+void int19_handler_C()
+{
+ struct linuxboot_info info;
+
+ get_linuxboot_info(&info);
+
+ boot_linux(info.cs, info.ds, info.sp);
+}
diff --git a/linuxboot/signrom b/linuxboot/signrom
new file mode 100755
index 0000000..cdc39a9
Binary files /dev/null and b/linuxboot/signrom differ
diff --git a/linuxboot/signrom.c b/linuxboot/signrom.c
new file mode 100644
index 0000000..2f2a734
--- /dev/null
+++ b/linuxboot/signrom.c
@@ -0,0 +1,128 @@
+/*
+ * 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>
+ *
+ * Copyright by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define BLOCK 512
+
+static long get_file_size(FILE *f)
+{
+ long where, size;
+
+ where = ftell(f);
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fseek(f, where, SEEK_SET);
+
+ return size;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *fin, *fout;
+ char buffer[BLOCK];
+ int i, j, size;
+ long rom_size;
+
+ 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;
+ }
+
+ rom_size = get_file_size(fin);
+ if (rom_size == 0) {
+ fprintf(stderr, "Error: ROM size = 0?\n");
+ return 1;
+ }
+
+ /* set rom_size to blocks of 512 bytes */
+ rom_size = (rom_size/512) + 1;
+
+ /* read all data in ROM image, except the last block */
+ for (i = 0; i < rom_size - 1; i ++) {
+ memset(buffer, 0, sizeof(buffer));
+
+ size = fread(buffer, BLOCK, 1, fin);
+ if (size == 1) {
+ if (i == 0) {
+ /* first block, lets set ROM size */
+ buffer[2] = (uint8_t)rom_size;
+ }
+
+ for (j = 0; j < BLOCK; j++)
+ sum += buffer[j];
+
+ if (fwrite(buffer, BLOCK, 1, fout) != 1) {
+ fprintf(stderr, "Write failed\n");
+ return 1;
+ }
+ }
+ else {
+ fprintf(stderr, "Failed to read from input file\n");
+ return 1;
+ }
+ }
+
+ /* now read last block of ROM image */
+ memset(buffer, 0, sizeof(buffer));
+ size = fread(buffer, 1, BLOCK, fin);
+ if (ferror(fin)) {
+ fprintf(stderr, "Failed to read from input file\n");
+ return 1;
+ }
+
+ if (rom_size == 1)
+ /* set ROM size */
+ buffer[2] = (uint8_t)rom_size;
+
+ for (i = 0; i < size; i++)
+ sum += buffer[i];
+
+ /* set checksum in final byte */
+ buffer[BLOCK - 1] = -sum;
+
+ if (fwrite(buffer, BLOCK, 1, fout) != 1) {
+ fprintf(stderr, "Failed to write to output file\n");
+ return 1;
+ }
+
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
diff --git a/linuxboot/util.h b/linuxboot/util.h
new file mode 100644
index 0000000..7f859d8
--- /dev/null
+++ b/linuxboot/util.h
@@ -0,0 +1,69 @@
+/*
+ * util.h
+ *
+ * Copyright (C) 2008, Nguyen Anh Quynh <aquynh@gmail.com>
+ *
+ * Some code is lifted from the legacybios project by Kevin O'Connor (http://www.linuxtogo.org/~kevin/)
+ *
+ * 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.
+ */
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include <stdint.h>
+
+static inline void outw(uint16_t value, uint16_t port)
+{
+ asm volatile("outw %w0, %w1" : : "a"(value), "Nd"(port));
+}
+
+#define UREG(ER, R, RH, RL) union { uint32_t ER; \
+ struct { uint16_t R; uint16_t R ## _hi; }; \
+ struct { \
+ uint8_t RL; \
+ uint8_t RH; \
+ uint8_t R ## _hilo; \
+ uint8_t R ## _hihi; \
+ }; \
+}
+
+/* Set of registers passed to INT 13 handler.
+ * These registers can be modified on return. */
+struct iregs {
+ uint16_t ds;
+ uint16_t es;
+ UREG(edi, di, di_hi, di_lo);
+ UREG(esi, si, si_hi, si_lo);
+ UREG(ebx, bx, bh, bl);
+ UREG(edx, dx, dh, dl);
+ UREG(ecx, cx, ch, cl);
+ UREG(eax, ax, ah, al);
+ uint16_t ip;
+ uint16_t cs;
+ uint16_t flags;
+} __attribute__((packed));
+
+static inline void *memcpy(void * dest, void *src, unsigned int count)
+{
+ char *tmp = (char *)dest, *s = (char *)src;
+
+ while (count--)
+ *tmp++ = *s++;
+
+ return dest;
+}
+
+#endif
diff --git a/qemu/Makefile b/qemu/Makefile
index a3054b4..3722b5e 100644
--- a/qemu/Makefile
+++ b/qemu/Makefile
@@ -195,7 +195,7 @@ endif
mkdir -p "$(DESTDIR)$(datadir)"
set -e; for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
video.x openbios-sparc32 pxe-ne2k_pci.bin \
- pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin extboot.bin \
+ pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin extboot.bin linuxboot.bin \
bamboo.dtb; \
do \
$(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
@@ -302,6 +302,7 @@ tarbin:
$(datadir)/pxe-rtl8139.bin \
$(datadir)/pxe-pcnet.bin \
$(datadir)/extboot.bin \
+ $(datadir)/linuxboot.bin \
$(docdir)/qemu-doc.html \
$(docdir)/qemu-tech.html \
$(mandir)/man1/qemu.1 $(mandir)/man1/qemu-img.1
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index 2fc2988..6a6d21b 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -591,7 +591,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o linuxboot.o
ifeq ($(USE_KVM_PIT), 1)
OBJS+= i8254-kvm.o
endif
diff --git a/qemu/hw/linuxboot.c b/qemu/hw/linuxboot.c
new file mode 100644
index 0000000..e6b7e4f
--- /dev/null
+++ b/qemu/hw/linuxboot.c
@@ -0,0 +1,39 @@
+/*
+ * linuxboot.c
+ * Linux Boot Option ROM.
+ *
+ * Copyright (C) Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * This code is released under the GNU GPL license version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw.h"
+#include "pc.h"
+
+/* Extended Boot ROM suport */
+
+struct linuxboot_info {
+ /* uint16_t request; */
+ uint16_t cs; /* CS segment */
+ uint16_t ds; /* DS segment */
+ uint16_t sp; /* SP reg */
+};
+
+#define LINUXBOOT_PORT 0x407
+
+static void linuxboot_write(void *opaque, uint32_t addr, uint32_t value)
+{
+ struct linuxboot_info *info = (void *)(phys_ram_base + ((value & 0xFFFF) << 4));
+
+ info->cs = kernel_setup_cs;
+ info->ds = kernel_setup_ds;
+ info->sp = kernel_setup_sp;
+
+ cpu_physical_memory_set_dirty((value & 0xFFFF) << 4);
+}
+
+void linuxboot_init()
+{
+ register_ioport_write(LINUXBOOT_PORT, 1, 2, linuxboot_write, NULL);
+}
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index ae87ab9..fdde4cd 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -41,6 +41,7 @@
#define VGABIOS_FILENAME "vgabios.bin"
#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
#define EXTBOOT_FILENAME "extboot.bin"
+#define LINUXBOOT_FILENAME "linuxboot.bin"
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
#define ACPI_DATA_SIZE 0x10000
@@ -492,6 +493,8 @@ static long get_file_size(FILE *f)
return size;
}
+uint16_t kernel_setup_cs, kernel_setup_ds, kernel_setup_sp;
+
static void load_linux(const char *kernel_filename,
const char *initrd_filename,
const char *kernel_cmdline)
@@ -638,11 +641,12 @@ static void load_linux(const char *kernel_filename,
/* generate bootsector to set up the initial register state */
real_seg = (real_addr-phys_ram_base) >> 4;
seg[0] = seg[2] = seg[3] = seg[4] = seg[4] = real_seg;
- seg[1] = real_seg+0x20; /* CS */
+ kernel_setup_ds = real_seg;
+ kernel_setup_cs = seg[1] = real_seg+0x20; /* CS */
memset(gpr, 0, sizeof gpr);
- gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
+ kernel_setup_sp = gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
- generate_bootsect(gpr, seg, 0);
+ //generate_bootsect(gpr, seg, 0);
}
static void main_cpu_reset(void *opaque)
@@ -903,6 +907,14 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
for (i = 0; i < nb_option_roms; i++)
opt_rom_offset += load_option_rom(option_rom[i], opt_rom_offset);
+ /* linuxboot option ROM also intercepts int19, but never call original int19,
+ * so it must be loaded before extboot! */
+ if (linux_boot) {
+ snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUXBOOT_FILENAME);
+ opt_rom_offset += load_option_rom(buf, opt_rom_offset);
+ fprintf(stderr, "linuxboot ROM loaded at 0x%x\n", opt_rom_offset);
+ }
+
if (extboot_drive != -1) {
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, EXTBOOT_FILENAME);
opt_rom_offset += load_option_rom(buf, opt_rom_offset);
@@ -931,8 +943,10 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
bochs_bios_init();
- if (linux_boot)
+ if (linux_boot) {
load_linux(kernel_filename, initrd_filename, kernel_cmdline);
+ linuxboot_init();
+ }
cpu_irq = qemu_allocate_irqs(pic_irq_request, first_cpu, 1);
i8259 = i8259_init(cpu_irq[0]);
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index f26fcb6..d86ecfd 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -158,7 +158,10 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
BlockDriverState *bs);
/* extboot.c */
-
void extboot_init(BlockDriverState *bs, int cmd);
+/* linux_boot */
+uint16_t kernel_setup_cs, kernel_setup_ds, kernel_setup_sp;
+void linuxboot_init(void);
+
#endif
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-21 3:32 [Qemu-devel] [RFC] linuxboot Option ROM for Linux kernel booting Nguyen Anh Quynh
@ 2008-04-21 3:33 ` Nguyen Anh Quynh
2008-04-21 3:36 ` Nguyen Anh Quynh
2008-04-22 13:50 ` Anthony Liguori
1 sibling, 1 reply; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-21 3:33 UTC (permalink / raw)
To: kvm-devel, qemu-devel; +Cc: Anthony Liguori, H. Peter Anvin
Forget to say that this patch is against kvm-66.
Thanks,
Q
On Mon, Apr 21, 2008 at 12:32 PM, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> Hi,
>
> This should be submitted to upstream (but not to kvm-devel list), but
> this is only the test code that I want to quickly send out for
> comments. In case it looks OK, I will send it to upstream later.
>
> Inspired by extboot and conversations with Anthony and HPA, this
> linuxboot option ROM is a simple option ROM that intercepts int19 in
> order to execute linux setup code. This approach eliminates the need
> to manipulate the boot sector for this purpose.
>
> To test it, just load linux kernel with your KVM/QEMU image using
> -kernel option in normal way.
>
> I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
> Ubuntu 8.04.
>
> Thanks,
> Quynh
>
>
> # diffstat linuxboot1.diff
> Makefile | 13 ++++-
> linuxboot/Makefile | 40 +++++++++++++++
> linuxboot/boot.S | 54 +++++++++++++++++++++
> linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
> linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
> linuxboot/signrom |binary
> linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
> linuxboot/util.h | 69 +++++++++++++++++++++++++++
> qemu/Makefile | 3 -
> qemu/Makefile.target | 2
> qemu/hw/linuxboot.c | 39 +++++++++++++++
> qemu/hw/pc.c | 22 +++++++-
> qemu/hw/pc.h | 5 +
> 13 files changed, 600 insertions(+), 9 deletions(-)
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-21 3:33 ` [Qemu-devel] " Nguyen Anh Quynh
@ 2008-04-21 3:36 ` Nguyen Anh Quynh
2008-04-22 9:07 ` Nguyen Anh Quynh
0 siblings, 1 reply; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-21 3:36 UTC (permalink / raw)
To: kvm-devel, qemu-devel; +Cc: Anthony Liguori, H. Peter Anvin
[-- Attachment #1: Type: text/plain, Size: 2561 bytes --]
Hmm, the last patch includes a binary. So please take this patch instead.
Thanks,
Q
# diffstat linuxboot1.diff
Makefile | 13 ++++-
linuxboot/Makefile | 40 +++++++++++++++
linuxboot/boot.S | 54 +++++++++++++++++++++
linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
linuxboot/util.h | 69 +++++++++++++++++++++++++++
qemu/Makefile | 3 -
qemu/Makefile.target | 2
qemu/hw/linuxboot.c | 39 +++++++++++++++
qemu/hw/pc.c | 22 +++++++-
qemu/hw/pc.h | 5 +
12 files changed, 600 insertions(+), 9 deletions(-)
On Mon, Apr 21, 2008 at 12:33 PM, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> Forget to say that this patch is against kvm-66.
>
> Thanks,
> Q
>
>
>
> On Mon, Apr 21, 2008 at 12:32 PM, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> > Hi,
> >
> > This should be submitted to upstream (but not to kvm-devel list), but
> > this is only the test code that I want to quickly send out for
> > comments. In case it looks OK, I will send it to upstream later.
> >
> > Inspired by extboot and conversations with Anthony and HPA, this
> > linuxboot option ROM is a simple option ROM that intercepts int19 in
> > order to execute linux setup code. This approach eliminates the need
> > to manipulate the boot sector for this purpose.
> >
> > To test it, just load linux kernel with your KVM/QEMU image using
> > -kernel option in normal way.
> >
> > I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
> > Ubuntu 8.04.
> >
> > Thanks,
> > Quynh
> >
> >
> > # diffstat linuxboot1.diff
> > Makefile | 13 ++++-
> > linuxboot/Makefile | 40 +++++++++++++++
> > linuxboot/boot.S | 54 +++++++++++++++++++++
> > linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
> > linuxboot/signrom |binary
> > linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > linuxboot/util.h | 69 +++++++++++++++++++++++++++
> > qemu/Makefile | 3 -
> > qemu/Makefile.target | 2
> > qemu/hw/linuxboot.c | 39 +++++++++++++++
> > qemu/hw/pc.c | 22 +++++++-
> > qemu/hw/pc.h | 5 +
> > 13 files changed, 600 insertions(+), 9 deletions(-)
> >
>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: linuxboot1.1.diff --]
[-- Type: text/x-diff; name=linuxboot1.1.diff, Size: 24025 bytes --]
commit f4f1178898c8a4bbbc0a432354dbcc56353099c3
Author: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Mon Apr 21 12:27:47 2008 +0900
Linuxboot Option ROM support.
Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
diff --git a/Makefile b/Makefile
index 76c149a..fdd9388 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ DESTDIR=
rpmrelease = devel
-.PHONY: kernel user libkvm qemu bios vgabios extboot clean libfdt
+.PHONY: kernel user libkvm qemu bios vgabios extboot linuxboot clean libfdt
all: libkvm qemu
ifneq '$(filter $(ARCH), x86_64 i386 ia64)' ''
@@ -19,7 +19,7 @@ qemu kernel user libkvm:
qemu: libkvm
ifneq '$(filter $(ARCH), i386 x86_64)' ''
- qemu: extboot
+ qemu: extboot linuxboot
endif
ifneq '$(filter $(ARCH), powerpc)' ''
qemu: libfdt
@@ -41,6 +41,14 @@ extboot:
|| ! cmp -s qemu/pc-bios/extboot.bin extboot/extboot.bin; then \
cp extboot/extboot.bin qemu/pc-bios/extboot.bin; \
fi
+
+linuxboot:
+ $(MAKE) -C $@
+ if ! [ -f qemu/pc-bios/linuxboot.bin ] \
+ || ! cmp -s qemu/pc-bios/linuxboot.bin linuxboot/linuxboot.bin; then \
+ cp linuxboot/linuxboot.bin qemu/pc-bios/linuxboot.bin; \
+ fi
+
libfdt:
$(MAKE) -C $@
@@ -88,6 +96,7 @@ srpm:
tar czf $(RPMTOPDIR)/SOURCES/kernel.tar.gz kernel
tar czf $(RPMTOPDIR)/SOURCES/scripts.tar.gz scripts
tar czf $(RPMTOPDIR)/SOURCES/extboot.tar.gz extboot
+ tar czf $(RPMTOPDIR)/SOURCES/linuxboot.tar.gz linuxboot
cp Makefile configure kvm_stat $(RPMTOPDIR)/SOURCES
rpmbuild --define="_topdir $(RPMTOPDIR)" -bs $(tmpspec)
$(RM) $(tmpspec)
diff --git a/linuxboot/Makefile b/linuxboot/Makefile
new file mode 100644
index 0000000..3bc88a6
--- /dev/null
+++ b/linuxboot/Makefile
@@ -0,0 +1,40 @@
+# Makefile for linuxboot Option ROM
+# Nguyen Anh Quynh <aquynh@gmail.com>
+
+CC = gcc
+CCFLAGS = -g -Wall -Werror -nostdlib -fno-builtin -fomit-frame-pointer -Os
+
+cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
+ /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
+CCFLAGS += $(call cc-option,$(CC),-nopie,)
+CCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
+CCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
+
+INSTALLDIR = /usr/share/qemu
+
+.PHONY: all
+all: clean linuxboot.bin
+
+.PHONY: install
+install: linuxboot.bin
+ cp linuxboot.bin $(INSTALLDIR)
+
+.PHONY: clean
+clean:
+ $(RM) *.o *.img *.bin signrom *~
+
+linuxboot.img: boot.o rom.o
+ $(LD) --oformat binary -Ttext 0 $^ -o $@
+
+linuxboot.bin: linuxboot.img signrom
+ ./signrom linuxboot.img linuxboot.bin
+
+signrom: signrom.c
+ $(CC) -o $@ -g -Wall $^
+
+%.o: %.c
+ $(CC) $(CCFLAGS) -c $<
+
+%.o: %.S
+ $(CC) $(CCFLAGS) -c $<
+
diff --git a/linuxboot/boot.S b/linuxboot/boot.S
new file mode 100644
index 0000000..a9461d6
--- /dev/null
+++ b/linuxboot/boot.S
@@ -0,0 +1,54 @@
+/*
+ * boot.S
+ * Linux Boot Option ROM for QEMU.
+
+ * Copyright (C) by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * 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.
+ */
+
+ .text
+ .code16gcc
+ .globl _start
+ .extern setup
+_start:
+ .short 0xAA55 /* ROM signature */
+ .byte 0 /* ROM size - to be patched at built-time */
+ /* ROM entry: initializing */
+ pushal
+ /* %es is clobbered, so save it */
+ pushw %es
+ /* just in case */
+ pushw %ds
+ cld
+ call setup /* call C code */
+ popw %ds
+ popw %es
+ popal
+ lretw
+
+ /* interrupt 19 handler */
+ .globl int19_handler
+ .extern int19_handler_C
+ .extern linux_boot
+ int19_handler:
+ /* we never execute the original int19, so no need to care
+ * about clobbered registers :-) */
+ /* Set %ds = %ss */
+ movw %ss, %ax
+ movw %ax, %ds
+ cld
+ call int19_handler_C /* call C code */
+ /* we actually jump to linux kernel setup, so never reach here */
diff --git a/linuxboot/farvar.h b/linuxboot/farvar.h
new file mode 100644
index 0000000..7876186
--- /dev/null
+++ b/linuxboot/farvar.h
@@ -0,0 +1,130 @@
+/*
+ * farvar.h
+ * Code to access multiple segments within gcc.
+ *
+ * Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+ *
+ * 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.
+ */
+
+#ifndef __FARVAR_H
+#define __FARVAR_H
+
+#include <stdint.h>
+
+// Dummy definitions used to make sure gcc understands dependencies
+// between SET_SEG and GET/READ/WRITE_SEG macros.
+extern uint16_t __segment_CS, __segment_DS, __segment_ES, __segment_SS;
+extern uint16_t __segment_GS, __segment_FS;
+
+// Low level macros for reading/writing memory via a segment selector.
+#define __READ8_SEG(SEG, var) ({ \
+ typeof(var) __value; \
+ __asm__("movb %%" #SEG ":%1, %b0" : "=Qi"(__value) \
+ : "m"(var), "m"(__segment_ ## SEG)); \
+ __value; })
+#define __READ16_SEG(SEG, var) ({ \
+ typeof(var) __value; \
+ __asm__("movw %%" #SEG ":%1, %w0" : "=ri"(__value) \
+ : "m"(var), "m"(__segment_ ## SEG)); \
+ __value; })
+#define __READ32_SEG(SEG, var) ({ \
+ typeof(var) __value; \
+ __asm__("movl %%" #SEG ":%1, %0" : "=ri"(__value) \
+ : "m"(var), "m"(__segment_ ## SEG)); \
+ __value; })
+
+#define __WRITE8_SEG(SEG, var, value) \
+ __asm__("movb %b1, %%" #SEG ":%0" : "=m"(var) \
+ : "Q"(value), "m"(__segment_ ## SEG))
+#define __WRITE16_SEG(SEG, var, value) \
+ __asm__("movw %w1, %%" #SEG ":%0" : "=m"(var) \
+ : "r"(value), "m"(__segment_ ## SEG))
+#define __WRITE32_SEG(SEG, var, value) \
+ __asm__("movl %1, %%" #SEG ":%0" : "=m"(var) \
+ : "r"(value), "m"(__segment_ ## SEG))
+
+// Low level macros for getting/setting a segment register.
+#define __SET_SEG(SEG, value) \
+ __asm__("movw %w1, %%" #SEG : "=m"(__segment_ ## SEG) \
+ : "r"(value))
+#define __GET_SEG(SEG) ({ \
+ uint16_t __seg; \
+ __asm__("movw %%" #SEG ", %w0" : "=r"(__seg) \
+ : "m"(__segment_ ## SEG)); \
+ __seg;})
+
+// Macros for automatically choosing the appropriate memory size
+// access method.
+extern void __force_link_error__unknown_type();
+
+#define __GET_VAR(seg, var) ({ \
+ typeof(var) __val; \
+ if (__builtin_types_compatible_p(typeof(__val), uint8_t) \
+ || __builtin_types_compatible_p(typeof(__val), int8_t)) \
+ __val = __READ8_SEG(seg, var); \
+ else if (__builtin_types_compatible_p(typeof(__val), uint16_t) \
+ || __builtin_types_compatible_p(typeof(__val), int16_t)) \
+ __val = __READ16_SEG(seg, var); \
+ else if (__builtin_types_compatible_p(typeof(__val), uint32_t) \
+ || __builtin_types_compatible_p(typeof(__val), int32_t)) \
+ __val = __READ32_SEG(seg, var); \
+ else \
+ __force_link_error__unknown_type(); \
+ __val; })
+
+#define __SET_VAR(seg, var, val) do { \
+ if (__builtin_types_compatible_p(typeof(var), uint8_t) \
+ || __builtin_types_compatible_p(typeof(var), int8_t)) \
+ __WRITE8_SEG(seg, var, (val)); \
+ else if (__builtin_types_compatible_p(typeof(var), uint16_t) \
+ || __builtin_types_compatible_p(typeof(var), int16_t)) \
+ __WRITE16_SEG(seg, var, (val)); \
+ else if (__builtin_types_compatible_p(typeof(var), uint32_t) \
+ || __builtin_types_compatible_p(typeof(var), int32_t)) \
+ __WRITE32_SEG(seg, var, (val)); \
+ else \
+ __force_link_error__unknown_type(); \
+} while (0)
+
+// Macros for converting to/from 32bit style pointers to their
+// equivalent 16bit segment/offset values.
+#define FARPTR_TO_SEG(p) (((u32)(p)) >> 4)
+#define FARPTR_TO_OFFSET(p) (((u32)(p)) & 0xf)
+#define MAKE_FARPTR(seg,off) ((void*)(((seg)<<4)+(off)))
+
+// Macros for accessing a variable in another segment. (They
+// automatically update the %es segment and then make the appropriate
+// access.)
+#define __GET_FARVAR(seg, var) ({ \
+ SET_SEG(ES, (seg)); \
+ GET_VAR(ES, (var)); })
+
+#define __SET_FARVAR(seg, var, val) do { \
+ typeof(var) __sfv_val = (val); \
+ SET_SEG(ES, (seg)); \
+ SET_VAR(ES, (var), __sfv_val); \
+} while (0)
+
+#define GET_FARVAR(seg, var) __GET_FARVAR((seg), (var))
+#define SET_FARVAR(seg, var, val) __SET_FARVAR((seg), (var), (val))
+
+#define GET_VAR(seg, var) __GET_VAR(seg, (var))
+#define SET_VAR(seg, var, val) __SET_VAR(seg, (var), (val))
+
+#define SET_SEG(SEG, value) __SET_SEG(SEG, (value))
+#define GET_SEG(SEG) __GET_SEG(SEG)
+
+#endif
diff --git a/linuxboot/rom.c b/linuxboot/rom.c
new file mode 100644
index 0000000..4cd600d
--- /dev/null
+++ b/linuxboot/rom.c
@@ -0,0 +1,104 @@
+/*
+ * rom.c
+ * Linux Boot Option ROM for QEMU.
+ *
+ * Copyright (C) by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * 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.
+ */
+
+#include "util.h"
+#include "farvar.h"
+
+asm (".code16gcc");
+
+struct linuxboot_info {
+ uint16_t cs; /* CS segment */
+ uint16_t ds; /* DS segment */
+ uint16_t sp; /* SP reg */
+};
+
+#define LINUXBOOT_PORT 0x407
+
+struct ivector {
+ uint16_t offset;
+ uint16_t segment;
+};
+/* manipulate interrupt vector entry */
+#define GET_IVT_ENTRY(index,var) \
+ GET_FARVAR(0, ((struct ivector *)(index*sizeof(struct ivector)))->var)
+#define SET_IVT_ENTRY(index,var,value) \
+ SET_FARVAR(0, ((struct ivector *)(index*sizeof(struct ivector)))->var, value)
+
+/* called from ASM code in boot.S */
+void setup()
+{
+ /* install our INT 19 handler */
+ extern void int19_handler;
+ SET_IVT_ENTRY(0x19, segment, GET_SEG(CS));
+ SET_IVT_ENTRY(0x19, offset, (uint16_t)&int19_handler);
+}
+
+/* send command to QEMU via a dedicated IO port */
+static void get_linuxboot_info(struct linuxboot_info *info)
+{
+ uint16_t seg;
+ char tmp[16 + sizeof(*info)], *p;
+
+ /* align to 16 */
+ p = (char *)(((uint32_t)tmp + 0xF) & ~0xF);
+ memcpy(p, info, sizeof(*info));
+
+ /* send segment contained info to QEMU */
+ seg = ((uint32_t)p >> 4) + GET_SEG(SS);
+ outw(seg, LINUXBOOT_PORT);
+
+ /* now copy back the result to info */
+ memcpy(info, p, sizeof(*info));
+}
+
+/* boot linux by jmp to its kernel setup code */
+static void boot_linux(uint16_t cs, uint16_t ds, uint16_t sp)
+{
+ asm volatile (
+ "cli \n"
+ "cld \n"
+ /* setup registers for kernel setup */
+ "movw %0, %%ds \n"
+ "movw %0, %%es \n"
+ "movw %0, %%fs \n"
+ "movw %0, %%gs \n"
+ "movw %0, %%ss \n"
+ "movw %2, %%sp \n"
+ /* push CS:IP */
+ "pushw %1 \n"
+ "pushw $0 \n"
+ /* now (implicitly) jump to CS:IP */
+ "lretw \n"
+ :
+ : "rm" (ds), "rm" (cs), "rm" (sp)
+ );
+}
+
+/* hook INT 13 */
+/* called from ASM code in boot.S */
+void int19_handler_C()
+{
+ struct linuxboot_info info;
+
+ get_linuxboot_info(&info);
+
+ boot_linux(info.cs, info.ds, info.sp);
+}
diff --git a/linuxboot/signrom.c b/linuxboot/signrom.c
new file mode 100644
index 0000000..2f2a734
--- /dev/null
+++ b/linuxboot/signrom.c
@@ -0,0 +1,128 @@
+/*
+ * 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>
+ *
+ * Copyright by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define BLOCK 512
+
+static long get_file_size(FILE *f)
+{
+ long where, size;
+
+ where = ftell(f);
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fseek(f, where, SEEK_SET);
+
+ return size;
+}
+
+int main(int argc, char **argv)
+{
+ FILE *fin, *fout;
+ char buffer[BLOCK];
+ int i, j, size;
+ long rom_size;
+
+ 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;
+ }
+
+ rom_size = get_file_size(fin);
+ if (rom_size == 0) {
+ fprintf(stderr, "Error: ROM size = 0?\n");
+ return 1;
+ }
+
+ /* set rom_size to blocks of 512 bytes */
+ rom_size = (rom_size/512) + 1;
+
+ /* read all data in ROM image, except the last block */
+ for (i = 0; i < rom_size - 1; i ++) {
+ memset(buffer, 0, sizeof(buffer));
+
+ size = fread(buffer, BLOCK, 1, fin);
+ if (size == 1) {
+ if (i == 0) {
+ /* first block, lets set ROM size */
+ buffer[2] = (uint8_t)rom_size;
+ }
+
+ for (j = 0; j < BLOCK; j++)
+ sum += buffer[j];
+
+ if (fwrite(buffer, BLOCK, 1, fout) != 1) {
+ fprintf(stderr, "Write failed\n");
+ return 1;
+ }
+ }
+ else {
+ fprintf(stderr, "Failed to read from input file\n");
+ return 1;
+ }
+ }
+
+ /* now read last block of ROM image */
+ memset(buffer, 0, sizeof(buffer));
+ size = fread(buffer, 1, BLOCK, fin);
+ if (ferror(fin)) {
+ fprintf(stderr, "Failed to read from input file\n");
+ return 1;
+ }
+
+ if (rom_size == 1)
+ /* set ROM size */
+ buffer[2] = (uint8_t)rom_size;
+
+ for (i = 0; i < size; i++)
+ sum += buffer[i];
+
+ /* set checksum in final byte */
+ buffer[BLOCK - 1] = -sum;
+
+ if (fwrite(buffer, BLOCK, 1, fout) != 1) {
+ fprintf(stderr, "Failed to write to output file\n");
+ return 1;
+ }
+
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
diff --git a/linuxboot/util.h b/linuxboot/util.h
new file mode 100644
index 0000000..7f859d8
--- /dev/null
+++ b/linuxboot/util.h
@@ -0,0 +1,69 @@
+/*
+ * util.h
+ *
+ * Copyright (C) 2008, Nguyen Anh Quynh <aquynh@gmail.com>
+ *
+ * Some code is lifted from the legacybios project by Kevin O'Connor (http://www.linuxtogo.org/~kevin/)
+ *
+ * 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.
+ */
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include <stdint.h>
+
+static inline void outw(uint16_t value, uint16_t port)
+{
+ asm volatile("outw %w0, %w1" : : "a"(value), "Nd"(port));
+}
+
+#define UREG(ER, R, RH, RL) union { uint32_t ER; \
+ struct { uint16_t R; uint16_t R ## _hi; }; \
+ struct { \
+ uint8_t RL; \
+ uint8_t RH; \
+ uint8_t R ## _hilo; \
+ uint8_t R ## _hihi; \
+ }; \
+}
+
+/* Set of registers passed to INT 13 handler.
+ * These registers can be modified on return. */
+struct iregs {
+ uint16_t ds;
+ uint16_t es;
+ UREG(edi, di, di_hi, di_lo);
+ UREG(esi, si, si_hi, si_lo);
+ UREG(ebx, bx, bh, bl);
+ UREG(edx, dx, dh, dl);
+ UREG(ecx, cx, ch, cl);
+ UREG(eax, ax, ah, al);
+ uint16_t ip;
+ uint16_t cs;
+ uint16_t flags;
+} __attribute__((packed));
+
+static inline void *memcpy(void * dest, void *src, unsigned int count)
+{
+ char *tmp = (char *)dest, *s = (char *)src;
+
+ while (count--)
+ *tmp++ = *s++;
+
+ return dest;
+}
+
+#endif
diff --git a/qemu/Makefile b/qemu/Makefile
index a3054b4..3722b5e 100644
--- a/qemu/Makefile
+++ b/qemu/Makefile
@@ -195,7 +195,7 @@ endif
mkdir -p "$(DESTDIR)$(datadir)"
set -e; for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
video.x openbios-sparc32 pxe-ne2k_pci.bin \
- pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin extboot.bin \
+ pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin extboot.bin linuxboot.bin \
bamboo.dtb; \
do \
$(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \
@@ -302,6 +302,7 @@ tarbin:
$(datadir)/pxe-rtl8139.bin \
$(datadir)/pxe-pcnet.bin \
$(datadir)/extboot.bin \
+ $(datadir)/linuxboot.bin \
$(docdir)/qemu-doc.html \
$(docdir)/qemu-tech.html \
$(mandir)/man1/qemu.1 $(mandir)/man1/qemu-img.1
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index 2fc2988..6a6d21b 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -591,7 +591,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o
+OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o linuxboot.o
ifeq ($(USE_KVM_PIT), 1)
OBJS+= i8254-kvm.o
endif
diff --git a/qemu/hw/linuxboot.c b/qemu/hw/linuxboot.c
new file mode 100644
index 0000000..e6b7e4f
--- /dev/null
+++ b/qemu/hw/linuxboot.c
@@ -0,0 +1,39 @@
+/*
+ * linuxboot.c
+ * Linux Boot Option ROM.
+ *
+ * Copyright (C) Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * This code is released under the GNU GPL license version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw.h"
+#include "pc.h"
+
+/* Extended Boot ROM suport */
+
+struct linuxboot_info {
+ /* uint16_t request; */
+ uint16_t cs; /* CS segment */
+ uint16_t ds; /* DS segment */
+ uint16_t sp; /* SP reg */
+};
+
+#define LINUXBOOT_PORT 0x407
+
+static void linuxboot_write(void *opaque, uint32_t addr, uint32_t value)
+{
+ struct linuxboot_info *info = (void *)(phys_ram_base + ((value & 0xFFFF) << 4));
+
+ info->cs = kernel_setup_cs;
+ info->ds = kernel_setup_ds;
+ info->sp = kernel_setup_sp;
+
+ cpu_physical_memory_set_dirty((value & 0xFFFF) << 4);
+}
+
+void linuxboot_init()
+{
+ register_ioport_write(LINUXBOOT_PORT, 1, 2, linuxboot_write, NULL);
+}
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index ae87ab9..fdde4cd 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -41,6 +41,7 @@
#define VGABIOS_FILENAME "vgabios.bin"
#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
#define EXTBOOT_FILENAME "extboot.bin"
+#define LINUXBOOT_FILENAME "linuxboot.bin"
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
#define ACPI_DATA_SIZE 0x10000
@@ -492,6 +493,8 @@ static long get_file_size(FILE *f)
return size;
}
+uint16_t kernel_setup_cs, kernel_setup_ds, kernel_setup_sp;
+
static void load_linux(const char *kernel_filename,
const char *initrd_filename,
const char *kernel_cmdline)
@@ -638,11 +641,12 @@ static void load_linux(const char *kernel_filename,
/* generate bootsector to set up the initial register state */
real_seg = (real_addr-phys_ram_base) >> 4;
seg[0] = seg[2] = seg[3] = seg[4] = seg[4] = real_seg;
- seg[1] = real_seg+0x20; /* CS */
+ kernel_setup_ds = real_seg;
+ kernel_setup_cs = seg[1] = real_seg+0x20; /* CS */
memset(gpr, 0, sizeof gpr);
- gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
+ kernel_setup_sp = gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
- generate_bootsect(gpr, seg, 0);
+ //generate_bootsect(gpr, seg, 0);
}
static void main_cpu_reset(void *opaque)
@@ -903,6 +907,14 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
for (i = 0; i < nb_option_roms; i++)
opt_rom_offset += load_option_rom(option_rom[i], opt_rom_offset);
+ /* linuxboot option ROM also intercepts int19, but never call original int19,
+ * so it must be loaded before extboot! */
+ if (linux_boot) {
+ snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUXBOOT_FILENAME);
+ opt_rom_offset += load_option_rom(buf, opt_rom_offset);
+ fprintf(stderr, "linuxboot ROM loaded at 0x%x\n", opt_rom_offset);
+ }
+
if (extboot_drive != -1) {
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, EXTBOOT_FILENAME);
opt_rom_offset += load_option_rom(buf, opt_rom_offset);
@@ -931,8 +943,10 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
bochs_bios_init();
- if (linux_boot)
+ if (linux_boot) {
load_linux(kernel_filename, initrd_filename, kernel_cmdline);
+ linuxboot_init();
+ }
cpu_irq = qemu_allocate_irqs(pic_irq_request, first_cpu, 1);
i8259 = i8259_init(cpu_irq[0]);
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index f26fcb6..d86ecfd 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -158,7 +158,10 @@ void *virtio_blk_init(PCIBus *bus, uint16_t vendor, uint16_t device,
BlockDriverState *bs);
/* extboot.c */
-
void extboot_init(BlockDriverState *bs, int cmd);
+/* linux_boot */
+uint16_t kernel_setup_cs, kernel_setup_ds, kernel_setup_sp;
+void linuxboot_init(void);
+
#endif
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-21 3:36 ` Nguyen Anh Quynh
@ 2008-04-22 9:07 ` Nguyen Anh Quynh
2008-04-22 10:35 ` Alexander Graf
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-22 9:07 UTC (permalink / raw)
To: kvm-devel, qemu-devel; +Cc: Anthony Liguori, H. Peter Anvin
Hi,
I am thinking about comibing this ROM with the extboot. Both two ROM
are about "booting", so I think that is reasonable. So we will have
only 1 ROM that supports both external boot and Linux boot.
Is that desirable or not?
Thanks,
Quynh
On 4/21/08, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> Hmm, the last patch includes a binary. So please take this patch instead.
>
> Thanks,
>
> Q
>
> # diffstat linuxboot1.diff
> Makefile | 13 ++++-
> linuxboot/Makefile | 40 +++++++++++++++
> linuxboot/boot.S | 54 +++++++++++++++++++++
> linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
> linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
>
> linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
> linuxboot/util.h | 69 +++++++++++++++++++++++++++
> qemu/Makefile | 3 -
> qemu/Makefile.target | 2
> qemu/hw/linuxboot.c | 39 +++++++++++++++
> qemu/hw/pc.c | 22 +++++++-
> qemu/hw/pc.h | 5 +
>
> 12 files changed, 600 insertions(+), 9 deletions(-)
>
>
>
>
>
>
> On Mon, Apr 21, 2008 at 12:33 PM, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> > Forget to say that this patch is against kvm-66.
> >
> > Thanks,
> > Q
> >
> >
> >
> > On Mon, Apr 21, 2008 at 12:32 PM, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> > > Hi,
> > >
> > > This should be submitted to upstream (but not to kvm-devel list), but
> > > this is only the test code that I want to quickly send out for
> > > comments. In case it looks OK, I will send it to upstream later.
> > >
> > > Inspired by extboot and conversations with Anthony and HPA, this
> > > linuxboot option ROM is a simple option ROM that intercepts int19 in
> > > order to execute linux setup code. This approach eliminates the need
> > > to manipulate the boot sector for this purpose.
> > >
> > > To test it, just load linux kernel with your KVM/QEMU image using
> > > -kernel option in normal way.
> > >
> > > I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
> > > Ubuntu 8.04.
> > >
> > > Thanks,
> > > Quynh
> > >
> > >
> > > # diffstat linuxboot1.diff
> > > Makefile | 13 ++++-
> > > linuxboot/Makefile | 40 +++++++++++++++
> > > linuxboot/boot.S | 54 +++++++++++++++++++++
> > > linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
> > > linuxboot/signrom |binary
> > > linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > linuxboot/util.h | 69 +++++++++++++++++++++++++++
> > > qemu/Makefile | 3 -
> > > qemu/Makefile.target | 2
> > > qemu/hw/linuxboot.c | 39 +++++++++++++++
> > > qemu/hw/pc.c | 22 +++++++-
> > > qemu/hw/pc.h | 5 +
> > > 13 files changed, 600 insertions(+), 9 deletions(-)
> > >
> >
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 9:07 ` Nguyen Anh Quynh
@ 2008-04-22 10:35 ` Alexander Graf
2008-04-23 13:40 ` Nguyen Anh Quynh
2008-04-22 13:45 ` Anthony Liguori
2008-04-22 16:23 ` H. Peter Anvin
2 siblings, 1 reply; 12+ messages in thread
From: Alexander Graf @ 2008-04-22 10:35 UTC (permalink / raw)
To: qemu-devel; +Cc: kvm-devel, Anthony Liguori, H. Peter Anvin
I believe that's the way to go. If you have spare time on your hands,
feel free to integrate my multiboot patches as well.
Alex
On Apr 22, 2008, at 11:07 AM, Nguyen Anh Quynh wrote:
> Hi,
>
> I am thinking about comibing this ROM with the extboot. Both two ROM
> are about "booting", so I think that is reasonable. So we will have
> only 1 ROM that supports both external boot and Linux boot.
>
> Is that desirable or not?
>
> Thanks,
> Quynh
>
> On 4/21/08, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
>> Hmm, the last patch includes a binary. So please take this patch
>> instead.
>>
>> Thanks,
>>
>> Q
>>
>> # diffstat linuxboot1.diff
>> Makefile | 13 ++++-
>> linuxboot/Makefile | 40 +++++++++++++++
>> linuxboot/boot.S | 54 +++++++++++++++++++++
>> linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++
>> ++++++++++++
>> linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
>>
>> linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++
>> ++++++++++
>> linuxboot/util.h | 69 +++++++++++++++++++++++++++
>> qemu/Makefile | 3 -
>> qemu/Makefile.target | 2
>> qemu/hw/linuxboot.c | 39 +++++++++++++++
>> qemu/hw/pc.c | 22 +++++++-
>> qemu/hw/pc.h | 5 +
>>
>> 12 files changed, 600 insertions(+), 9 deletions(-)
>>
>>
>>
>>
>>
>>
>> On Mon, Apr 21, 2008 at 12:33 PM, Nguyen Anh Quynh
>> <aquynh@gmail.com> wrote:
>>> Forget to say that this patch is against kvm-66.
>>>
>>> Thanks,
>>> Q
>>>
>>>
>>>
>>> On Mon, Apr 21, 2008 at 12:32 PM, Nguyen Anh Quynh
>>> <aquynh@gmail.com> wrote:
>>>> Hi,
>>>>
>>>> This should be submitted to upstream (but not to kvm-devel list),
>>>> but
>>>> this is only the test code that I want to quickly send out for
>>>> comments. In case it looks OK, I will send it to upstream later.
>>>>
>>>> Inspired by extboot and conversations with Anthony and HPA, this
>>>> linuxboot option ROM is a simple option ROM that intercepts int19
>>>> in
>>>> order to execute linux setup code. This approach eliminates the
>>>> need
>>>> to manipulate the boot sector for this purpose.
>>>>
>>>> To test it, just load linux kernel with your KVM/QEMU image using
>>>> -kernel option in normal way.
>>>>
>>>> I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10,
>>>> guest
>>>> Ubuntu 8.04.
>>>>
>>>> Thanks,
>>>> Quynh
>>>>
>>>>
>>>> # diffstat linuxboot1.diff
>>>> Makefile | 13 ++++-
>>>> linuxboot/Makefile | 40 +++++++++++++++
>>>> linuxboot/boot.S | 54 +++++++++++++++++++++
>>>> linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++
>>>> ++++++++++++++
>>>> linuxboot/rom.c | 104 +++++++++++++++++++++++++++++++++++++
>>>> +++
>>>> linuxboot/signrom |binary
>>>> linuxboot/signrom.c | 128 +++++++++++++++++++++++++++++++++++++
>>>> +++++++++++++
>>>> linuxboot/util.h | 69 +++++++++++++++++++++++++++
>>>> qemu/Makefile | 3 -
>>>> qemu/Makefile.target | 2
>>>> qemu/hw/linuxboot.c | 39 +++++++++++++++
>>>> qemu/hw/pc.c | 22 +++++++-
>>>> qemu/hw/pc.h | 5 +
>>>> 13 files changed, 600 insertions(+), 9 deletions(-)
>>>>
>>>
>>
>>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 9:07 ` Nguyen Anh Quynh
2008-04-22 10:35 ` Alexander Graf
@ 2008-04-22 13:45 ` Anthony Liguori
2008-04-22 16:23 ` H. Peter Anvin
2 siblings, 0 replies; 12+ messages in thread
From: Anthony Liguori @ 2008-04-22 13:45 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel, qemu-devel, H. Peter Anvin
Nguyen Anh Quynh wrote:
> Hi,
>
> I am thinking about comibing this ROM with the extboot. Both two ROM
> are about "booting", so I think that is reasonable. So we will have
> only 1 ROM that supports both external boot and Linux boot.
>
> Is that desirable or not?
>
I think so.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-21 3:32 [Qemu-devel] [RFC] linuxboot Option ROM for Linux kernel booting Nguyen Anh Quynh
2008-04-21 3:33 ` [Qemu-devel] " Nguyen Anh Quynh
@ 2008-04-22 13:50 ` Anthony Liguori
2008-04-22 15:02 ` Laurent Vivier
2008-04-23 13:41 ` Nguyen Anh Quynh
1 sibling, 2 replies; 12+ messages in thread
From: Anthony Liguori @ 2008-04-22 13:50 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel, Paul Brook, qemu-devel, H. Peter Anvin
Nguyen Anh Quynh wrote:
> Hi,
>
> This should be submitted to upstream (but not to kvm-devel list), but
> this is only the test code that I want to quickly send out for
> comments. In case it looks OK, I will send it to upstream later.
>
> Inspired by extboot and conversations with Anthony and HPA, this
> linuxboot option ROM is a simple option ROM that intercepts int19 in
> order to execute linux setup code. This approach eliminates the need
> to manipulate the boot sector for this purpose.
>
> To test it, just load linux kernel with your KVM/QEMU image using
> -kernel option in normal way.
>
> I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
> Ubuntu 8.04.
>
For the next rounds, could you actually rebase against upstream QEMU and
submit to qemu-devel? One of Paul Brook's objections to extboot had
historically been that it wasn't not easily sharable with other
architectures. With a C version, it seems more reasonable now to do that.
Make sure you remove all the old linux boot code too within QEMU along
with the -hda checks.
Regards,
Anthony Liguori
> Thanks,
> Quynh
>
>
> # diffstat linuxboot1.diff
> Makefile | 13 ++++-
> linuxboot/Makefile | 40 +++++++++++++++
> linuxboot/boot.S | 54 +++++++++++++++++++++
> linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
> linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
> linuxboot/signrom |binary
> linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
> linuxboot/util.h | 69 +++++++++++++++++++++++++++
> qemu/Makefile | 3 -
> qemu/Makefile.target | 2
> qemu/hw/linuxboot.c | 39 +++++++++++++++
> qemu/hw/pc.c | 22 +++++++-
> qemu/hw/pc.h | 5 +
> 13 files changed, 600 insertions(+), 9 deletions(-)
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 13:50 ` Anthony Liguori
@ 2008-04-22 15:02 ` Laurent Vivier
2008-04-23 13:41 ` Nguyen Anh Quynh
1 sibling, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2008-04-22 15:02 UTC (permalink / raw)
To: qemu-devel; +Cc: kvm-devel, Paul Brook, H. Peter Anvin
Le mardi 22 avril 2008 à 08:50 -0500, Anthony Liguori a écrit :
> Nguyen Anh Quynh wrote:
> > Hi,
> >
> > This should be submitted to upstream (but not to kvm-devel list), but
> > this is only the test code that I want to quickly send out for
> > comments. In case it looks OK, I will send it to upstream later.
> >
> > Inspired by extboot and conversations with Anthony and HPA, this
> > linuxboot option ROM is a simple option ROM that intercepts int19 in
> > order to execute linux setup code. This approach eliminates the need
> > to manipulate the boot sector for this purpose.
> >
> > To test it, just load linux kernel with your KVM/QEMU image using
> > -kernel option in normal way.
> >
> > I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
> > Ubuntu 8.04.
> >
>
> For the next rounds, could you actually rebase against upstream QEMU and
> submit to qemu-devel? One of Paul Brook's objections to extboot had
> historically been that it wasn't not easily sharable with other
> architectures. With a C version, it seems more reasonable now to do that.
Moreover add a binary version of the ROM in the pc-bios directory: it
avoids to have a cross-compiler to build ROM on non-x86 architecture.
Regards,
Laurent
> Make sure you remove all the old linux boot code too within QEMU along
> with the -hda checks.
>
> Regards,
>
> Anthony Liguori
>
> > Thanks,
> > Quynh
> >
> >
> > # diffstat linuxboot1.diff
> > Makefile | 13 ++++-
> > linuxboot/Makefile | 40 +++++++++++++++
> > linuxboot/boot.S | 54 +++++++++++++++++++++
> > linuxboot/farvar.h | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > linuxboot/rom.c | 104 ++++++++++++++++++++++++++++++++++++++++
> > linuxboot/signrom |binary
> > linuxboot/signrom.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > linuxboot/util.h | 69 +++++++++++++++++++++++++++
> > qemu/Makefile | 3 -
> > qemu/Makefile.target | 2
> > qemu/hw/linuxboot.c | 39 +++++++++++++++
> > qemu/hw/pc.c | 22 +++++++-
> > qemu/hw/pc.h | 5 +
> > 13 files changed, 600 insertions(+), 9 deletions(-)
> >
>
>
>
>
--
------------- Laurent.Vivier@bull.net ---------------
"The best way to predict the future is to invent it."
- Alan Kay
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 9:07 ` Nguyen Anh Quynh
2008-04-22 10:35 ` Alexander Graf
2008-04-22 13:45 ` Anthony Liguori
@ 2008-04-22 16:23 ` H. Peter Anvin
2008-04-23 13:49 ` Nguyen Anh Quynh
2 siblings, 1 reply; 12+ messages in thread
From: H. Peter Anvin @ 2008-04-22 16:23 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel, Anthony Liguori, qemu-devel
Nguyen Anh Quynh wrote:
> Hi,
>
> I am thinking about comibing this ROM with the extboot. Both two ROM
> are about "booting", so I think that is reasonable. So we will have
> only 1 ROM that supports both external boot and Linux boot.
>
> Is that desirable or not?
>
Does it make the code simpler and easier to understand? If not, then I
would say no.
-hpa
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 10:35 ` Alexander Graf
@ 2008-04-23 13:40 ` Nguyen Anh Quynh
0 siblings, 0 replies; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-23 13:40 UTC (permalink / raw)
To: Alexander Graf; +Cc: kvm-devel, qemu-devel
On 4/22/08, Alexander Graf <alex@csgraf.de> wrote:
> I believe that's the way to go. If you have spare time on your hands, feel
> free to integrate my multiboot patches as well.
>
OK, that looks straightforward enough.
Thanks,
Q
>
> On Apr 22, 2008, at 11:07 AM, Nguyen Anh Quynh wrote:
>
>
> > Hi,
> >
> > I am thinking about comibing this ROM with the extboot. Both two ROM
> > are about "booting", so I think that is reasonable. So we will have
> > only 1 ROM that supports both external boot and Linux boot.
> >
> > Is that desirable or not?
> >
> > Thanks,
> > Quynh
> >
> > On 4/21/08, Nguyen Anh Quynh <aquynh@gmail.com> wrote:
> >
> > > Hmm, the last patch includes a binary. So please take this patch
> instead.
> > >
> > > Thanks,
> > >
> > > Q
> > >
> > > # diffstat linuxboot1.diff
> > > Makefile | 13 ++++-
> > > linuxboot/Makefile | 40 +++++++++++++++
> > > linuxboot/boot.S | 54 +++++++++++++++++++++
> > > linuxboot/farvar.h | 130
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > linuxboot/rom.c | 104
> ++++++++++++++++++++++++++++++++++++++++
> > >
> > > linuxboot/signrom.c | 128
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > linuxboot/util.h | 69 +++++++++++++++++++++++++++
> > > qemu/Makefile | 3 -
> > > qemu/Makefile.target | 2
> > > qemu/hw/linuxboot.c | 39 +++++++++++++++
> > > qemu/hw/pc.c | 22 +++++++-
> > > qemu/hw/pc.h | 5 +
> > >
> > > 12 files changed, 600 insertions(+), 9 deletions(-)
> > >
> > >
> > >
> > >
> > >
> > >
> > > On Mon, Apr 21, 2008 at 12:33 PM, Nguyen Anh Quynh <aquynh@gmail.com>
> wrote:
> > >
> > > > Forget to say that this patch is against kvm-66.
> > > >
> > > > Thanks,
> > > > Q
> > > >
> > > >
> > > >
> > > > On Mon, Apr 21, 2008 at 12:32 PM, Nguyen Anh Quynh <aquynh@gmail.com>
> wrote:
> > > >
> > > > > Hi,
> > > > >
> > > > > This should be submitted to upstream (but not to kvm-devel list),
> but
> > > > > this is only the test code that I want to quickly send out for
> > > > > comments. In case it looks OK, I will send it to upstream later.
> > > > >
> > > > > Inspired by extboot and conversations with Anthony and HPA, this
> > > > > linuxboot option ROM is a simple option ROM that intercepts int19 in
> > > > > order to execute linux setup code. This approach eliminates the need
> > > > > to manipulate the boot sector for this purpose.
> > > > >
> > > > > To test it, just load linux kernel with your KVM/QEMU image using
> > > > > -kernel option in normal way.
> > > > >
> > > > > I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10,
> guest
> > > > > Ubuntu 8.04.
> > > > >
> > > > > Thanks,
> > > > > Quynh
> > > > >
> > > > >
> > > > > # diffstat linuxboot1.diff
> > > > > Makefile | 13 ++++-
> > > > > linuxboot/Makefile | 40 +++++++++++++++
> > > > > linuxboot/boot.S | 54 +++++++++++++++++++++
> > > > > linuxboot/farvar.h | 130
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > linuxboot/rom.c | 104
> ++++++++++++++++++++++++++++++++++++++++
> > > > > linuxboot/signrom |binary
> > > > > linuxboot/signrom.c | 128
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > linuxboot/util.h | 69 +++++++++++++++++++++++++++
> > > > > qemu/Makefile | 3 -
> > > > > qemu/Makefile.target | 2
> > > > > qemu/hw/linuxboot.c | 39 +++++++++++++++
> > > > > qemu/hw/pc.c | 22 +++++++-
> > > > > qemu/hw/pc.h | 5 +
> > > > > 13 files changed, 600 insertions(+), 9 deletions(-)
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> > >
> >
> >
> >
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 13:50 ` Anthony Liguori
2008-04-22 15:02 ` Laurent Vivier
@ 2008-04-23 13:41 ` Nguyen Anh Quynh
1 sibling, 0 replies; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-23 13:41 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kvm-devel, qemu-devel, Paul Brook
On 4/22/08, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Nguyen Anh Quynh wrote:
>
> > Hi,
> >
> > This should be submitted to upstream (but not to kvm-devel list), but
> > this is only the test code that I want to quickly send out for
> > comments. In case it looks OK, I will send it to upstream later.
> >
> > Inspired by extboot and conversations with Anthony and HPA, this
> > linuxboot option ROM is a simple option ROM that intercepts int19 in
> > order to execute linux setup code. This approach eliminates the need
> > to manipulate the boot sector for this purpose.
> >
> > To test it, just load linux kernel with your KVM/QEMU image using
> > -kernel option in normal way.
> >
> > I succesfully compiled and tested it with kvm-66 on Ubuntu 7.10, guest
> > Ubuntu 8.04.
> >
> >
>
> For the next rounds, could you actually rebase against upstream QEMU and
> submit to qemu-devel? One of Paul Brook's objections to extboot had
> historically been that it wasn't not easily sharable with other
> architectures. With a C version, it seems more reasonable now to do that.
OK.
>
> Make sure you remove all the old linux boot code too within QEMU along with
> the -hda checks.
Sure.
Thanks,
Q
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] Re: [RFC] linuxboot Option ROM for Linux kernel booting
2008-04-22 16:23 ` H. Peter Anvin
@ 2008-04-23 13:49 ` Nguyen Anh Quynh
0 siblings, 0 replies; 12+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-23 13:49 UTC (permalink / raw)
To: H. Peter Anvin
Cc: kvm-devel, Alexander Graf, Anthony Liguori, qemu-devel,
Paul Brook
On 4/23/08, H. Peter Anvin <hpa@zytor.com> wrote:
> Nguyen Anh Quynh wrote:
>
> > Hi,
> >
> > I am thinking about comibing this ROM with the extboot. Both two ROM
> > are about "booting", so I think that is reasonable. So we will have
> > only 1 ROM that supports both external boot and Linux boot.
> >
> > Is that desirable or not?
> >
> >
>
> Does it make the code simpler and easier to understand? If not, then I would say no.
Actually no. I must say that it looks ugly to me.
The fact is that linuxboot ROM and extboot ROM are about different
things, and they only share a bit in that they both intercept int 19.
I very much like the the Unix principal, that is "Does one thing, and
does it well", so I prefer to have 2 independent ROM: one to boot
Linux, and one to do external boot. I see no problem that we have more
than one ROM, and these two can be independently loaded into the
memory.
So I think I agree with Peter here.
Thanks,
Q
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-04-23 13:49 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-21 3:32 [Qemu-devel] [RFC] linuxboot Option ROM for Linux kernel booting Nguyen Anh Quynh
2008-04-21 3:33 ` [Qemu-devel] " Nguyen Anh Quynh
2008-04-21 3:36 ` Nguyen Anh Quynh
2008-04-22 9:07 ` Nguyen Anh Quynh
2008-04-22 10:35 ` Alexander Graf
2008-04-23 13:40 ` Nguyen Anh Quynh
2008-04-22 13:45 ` Anthony Liguori
2008-04-22 16:23 ` H. Peter Anvin
2008-04-23 13:49 ` Nguyen Anh Quynh
2008-04-22 13:50 ` Anthony Liguori
2008-04-22 15:02 ` Laurent Vivier
2008-04-23 13:41 ` Nguyen Anh Quynh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).