* [Qemu-devel] [PATCH 0/2] port over extboot from kvm @ 2009-09-08 9:17 Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 1/2] extboot: add option rom Gerd Hoffmann ` (4 more replies) 0 siblings, 5 replies; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 9:17 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann $subject says pretty much everything. extboot.[cS] are a straight copy from the kvm tree. The windup in vl,c and hw/pc.c is done slightly different, I've added a function to lookup the boot drive instead of adding a new global variable. Booting from scsi and virtio works, using the boot=on flag. With the usb+scsi patches in anthonys patch queue applied booting from usb works too. Syntax is this: -drive if=none,id=pendrive,file=/path/to/image,boot=on -usb -device usb-storage,drive=pendrive Booting a rawhide install from a virtual usb stick doesn't actually work though, looks like it stresses qemus usb emulation too much. ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 1/2] extboot: add option rom. 2009-09-08 9:17 [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann @ 2009-09-08 9:17 ` Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 2/2] extboot: qemu code Gerd Hoffmann ` (3 subsequent siblings) 4 siblings, 0 replies; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 9:17 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- Makefile | 2 +- pc-bios/optionrom/Makefile | 2 +- pc-bios/optionrom/extboot.S | 695 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 697 insertions(+), 2 deletions(-) create mode 100644 pc-bios/optionrom/extboot.S diff --git a/Makefile b/Makefile index 2e0b85c..104351e 100644 --- a/Makefile +++ b/Makefile @@ -212,7 +212,7 @@ BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ video.x openbios-sparc32 openbios-sparc64 openbios-ppc \ pxe-ne2k_pci.bin pxe-rtl8139.bin pxe-pcnet.bin pxe-e1000.bin \ bamboo.dtb petalogix-s3adsp1800.dtb \ -multiboot.bin +multiboot.bin extboot.bin else BLOBS= endif diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile index 1d84c07..840c895 100644 --- a/pc-bios/optionrom/Makefile +++ b/pc-bios/optionrom/Makefile @@ -11,7 +11,7 @@ CFLAGS = -Wall -Wstrict-prototypes -Werror -fomit-frame-pointer -fno-builtin CFLAGS += -I$(SRC_PATH) CFLAGS += $(call cc-option, $(CFLAGS), -fno-stack-protector,"") -build-all: multiboot.bin +build-all: multiboot.bin extboot.bin %.img: %.o $(call quiet-command,$(LD) -Ttext 0 -e _start -s -o $@ $<," Building $(TARGET_DIR)$@") diff --git a/pc-bios/optionrom/extboot.S b/pc-bios/optionrom/extboot.S new file mode 100644 index 0000000..1e60f68 --- /dev/null +++ b/pc-bios/optionrom/extboot.S @@ -0,0 +1,695 @@ +/* + * 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> + */ + +.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 + + /* there is one more bootable HD */ + incb 0x0475 + + /* save old int 19 */ + mov (0x19*4), %eax + mov %eax, %cs:old_int19 + + /* install out int 19 handler */ + movw $int19_handler, (0x19*4) + mov %cs, (0x19*4+2) + + pop %ds + pop %eax + lret + +int19_handler: + push %eax + push %bx + push %cx + push %dx + push %ds + + /* setup ds to access IVT */ + xor %ax, %ax + mov %ax, %ds + + movw $0x404, %dx + inb %dx, %al + cmp $1, %al + je 1f + cmp $2, %al + je 2f + jmp 3f + +1: /* hook int13: intb(0x404) == 1 */ + /* save old int 13 to int 2c */ + mov (0x13*4), %eax + mov %eax, %cs:old_int13 + + /* install our int 13 handler */ + movw $int13_handler, (0x13*4) + mov %cs, (0x13*4+2) + jmp 3f + +2: /* linux boot: intb(0x404) == 2 */ + cli + cld + mov $0x9000, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + mov $0x8ffe, %sp + ljmp $0x9000 + 0x20, $0 + +3: /* fall through: inb(0x404) == 0 */ + /* restore previous int $0x19 handler */ + mov %cs:old_int19,%eax + mov %eax,(0x19*4) + + pop %ds + pop %dx + pop %cx + pop %bx + pop %eax + ljmpw *%cs:old_int19 + +#define FLAGS_CF 0x01 + +/* The two macro below clear/set the carry flag to indicate the status + * of the interrupt execution. It is not enough to issue a clc/stc instruction, + * since the value of the flags register will be overwritten by whatever is + * in the stack frame + */ +.macro clc_stack + push %bp + mov %sp, %bp + /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */ + and $(~FLAGS_CF), 8(%bp) + pop %bp +.endm + +.macro stc_stack + push %bp + /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */ + or $(FLAGS_CF), 8(%bp) + pop %bp +.endm + +/* we clobber %bx */ +.macro alloca size + push %ds + push %bp + mov %sp, %bp /* remember the current stack position */ + + mov %ss, %bx + mov %bx, %ds + + sub \size, %sp + and $(~0x0F), %sp + mov %sp, %bx + + push %bp + mov 0(%bp), %bp +.endm + +/* we clobber %bp */ +.macro allocbpa size + mov %sp, %bp /* remember the current stack position */ + sub \size, %sp + and $(~0x0F), %sp + push %bp + mov %sp, %bp + add $2, %bp +.endm + +.macro freea + pop %sp + add $2, %sp + pop %ds +.endm + +.macro freebpa + pop %sp +.endm + +.macro dump reg + push %ax + push %dx + + mov \reg, %ax + mov $0x406, %dx + outw %ax, %dx + + pop %dx + pop %ax +.endm + +.macro callout value + push %bp + push %bx + mov %sp, %bp + alloca $16 + push %ax + push %dx + + mov %ax, 0(%bx) /* ax */ + mov 0(%bp), %ax /* bx */ + mov %ax, 2(%bx) + mov %cx, 4(%bx) /* cx */ + mov %dx, 6(%bx) /* dx */ + mov %si, 8(%bx) /* si */ + mov %ds, 10(%bx) /* ds */ + mov %es, 12(%bx) /* ds */ + movw \value, 14(%bx) /* value */ + + mov %bx, %ax + shr $4, %ax + mov %ds, %dx + add %dx, %ax + + mov $0x407, %dx + outw %ax, %dx + + pop %dx + pop %ax + freea + pop %bx + pop %bp +.endm + +send_command: + push %bp + mov %sp, %bp + push %ax + push %bx + push %dx + + mov 4(%bp), %ax + shr $4, %ax + and $0x0FFF, %ax + mov %ss, %bx + add %bx, %ax + + mov $0x405, %dx + outw %ax, %dx + + pop %dx + pop %bx + pop %ax + pop %bp + + push %ax + mov 2(%bx), %ax + pop %ax + + ret + +add32: /* lo, hi, lo, hi */ + push %bp + mov %sp, %bp + + movw 4(%bp), %cx /* hi */ + movw 6(%bp), %dx /* lo */ + + add 10(%bp), %dx + jnc 1f + add $1, %cx +1: add 8(%bp), %cx + + pop %bp + ret + +mul32: /* lo, hi, lo, hi */ + /* 10(%bp), 8(%bp), 6(%bp), 4(%bp) */ + push %bp + mov %sp, %bp + push %ax + push %bx + + xor %cx, %cx + xor %dx, %dx + + /* for (i = 0; i < 16;) */ + xor %bx, %bx +0: + cmp $16, %bx + jge 2f + + mov 6(%bp), %ax + and $1, %ax + cmp $1, %ax + jne 1f + push 10(%bp) + push 8(%bp) + push %dx + push %cx + call add32 + add $8, %sp +1: + shlw $1, 8(%bp) + movw 10(%bp), %ax + and $0x8000, %ax + cmp $0x8000, %ax + jne 1f + orw $1, 8(%bp) +1: + shlw $1, 10(%bp) + shrw $1, 6(%bp) + + /* i++) { */ + add $1, %bx + jmp 0b + +2: + pop %bx + pop %ax + pop %bp + ret + +disk_reset: + movb $0, %ah + clc_stack + ret + +/* this really should be a function, not a macro but i'm lazy */ +.macro read_write_disk_sectors cmd + push %ax + push %bx + push %cx + push %dx + push %si + + push %bp + sub $10, %sp + mov %sp, %bp + + /* save nb_sectors */ + mov %al, 6(%bp) + movb $0, 7(%bp) + + /* save buffer */ + mov %bx, 8(%bp) + + /* cylinders */ + xor %ax, %ax + mov %cl, %al + shl $2, %ax + and $0x300, %ax + mov %ch, %al + mov %ax, 0(%bp) + + /* heads */ + xor %ax, %ax + mov %dh, %al + mov %ax, 2(%bp) + + /* sectors - 1 */ + xor %ax, %ax + mov %cl, %al + and $0x3F, %al + sub $1, %ax + mov %ax, 4(%bp) + + alloca $16 + + movw $0, 0(%bx) /* read c,h,s */ + push %bx + call send_command + add $2, %sp + + mov 6(%bx), %ax /* total_sectors */ + mov 2(%bp), %si /* *= heads */ + mul %si + add 4(%bp), %ax /* += sectors - 1 */ + + push 4(%bx) /* total_heads */ + push $0 + push 6(%bx) /* total_sectors */ + push $0 + call mul32 + add $8, %sp + + push 0(%bp) /* cylinders */ + push $0 + push %dx + push %cx + call mul32 + add $8, %sp + + add %ax, %dx + jnc 1f + add $1, %cx +1: + freea + + alloca $16 + + movw \cmd, 0(%bx) /* read */ + movw 6(%bp), %ax /* nb_sectors */ + movw %ax, 2(%bx) + movw %es, 4(%bx) /* segment */ + movw 8(%bp), %ax /* offset */ + mov %ax, 6(%bx) + movw %dx, 8(%bx) /* sector */ + movw %cx, 10(%bx) + movw $0, 12(%bx) + movw $0, 14(%bx) + + push %bx + call send_command + add $2, %sp + + freea + + add $10, %sp + pop %bp + + pop %si + pop %dx + pop %cx + pop %bx + pop %ax + + mov $0, %ah + clc_stack + ret +.endm + +read_disk_sectors: + read_write_disk_sectors $0x01 + +write_disk_sectors: + read_write_disk_sectors $0x02 + +read_disk_drive_parameters: + push %bx + + /* allocate memory for packet, pointer gets returned in bx */ + alloca $16 + + /* issue command */ + movw $0, 0(%bx) /* cmd = 0, read c,h,s */ + push %bx + call send_command + add $2, %sp + + /* normalize sector value */ + movb 6(%bx), %cl + andb $0x3F, %cl + movb %cl, 6(%bx) + + /* normalize cylinders */ + subw $2, 2(%bx) + + /* normalize heads */ + subw $1, 4(%bx) + + /* return code */ + mov $0, %ah + + /* cylinders */ + movb 2(%bx), %ch + movb 3(%bx), %cl + shlb $6, %cl + andb $0xC0, %cl + + /* sectors */ + orb 6(%bx), %cl + + /* heads */ + movb 4(%bx), %dh + + /* drives */ + movb $1, %dl + + /* status */ + mov $0, %ah + + freea + + pop %bx + + /* do this last since it's the most sensitive */ + clc_stack + ret + +alternate_disk_reset: + movb $0, %ah + clc_stack + ret + +read_disk_drive_size: + push %bx + alloca $16 + + movw $0, 0(%bx) /* cmd = 0, read c,h,s */ + push %bx + call send_command + add $2, %sp + + /* cylinders - 1 to cx:dx */ + mov 2(%bx), %dx + xor %cx, %cx + sub $1, %dx + + /* heads */ + push 4(%bx) + push $0 + push %dx + push %cx + call mul32 + add $8, %sp + + /* sectors */ + push 6(%bx) + push $0 + push %dx + push %cx + call mul32 + add $8, %sp + + /* status */ + mov $3, %ah + + freea + pop %bx + + clc_stack + ret + +check_if_extensions_present: + mov $0x30, %ah + mov $0xAA55, %bx + mov $0x07, %cx + clc_stack + ret + +.macro extended_read_write_sectors cmd + cmpb $10, 0(%si) + jg 1f + mov $1, %ah + stc_stack + ret +1: + push %ax + push %bp + allocbpa $16 + + movw \cmd, 0(%bp) /* read */ + movw 2(%si), %ax /* nb_sectors */ + movw %ax, 2(%bp) + movw 4(%si), %ax /* offset */ + movw %ax, 6(%bp) + movw 6(%si), %ax /* segment */ + movw %ax, 4(%bp) + movw 8(%si), %ax /* block */ + movw %ax, 8(%bp) + movw 10(%si), %ax + movw %ax, 10(%bp) + movw 12(%si), %ax + movw %ax, 12(%bp) + movw 14(%si), %ax + movw %ax, 14(%bp) + + push %bp + call send_command + add $2, %sp + + freebpa + pop %bp + pop %ax + + mov $0, %ah + clc_stack + ret +.endm + +extended_read_sectors: + extended_read_write_sectors $0x01 + +extended_write_sectors: + extended_read_write_sectors $0x02 + +get_extended_drive_parameters: + push %ax + push %bp + push %cx + push %dx + + allocbpa $16 + + movw $0, 0(%bp) /* read c,h,s */ + push %bp + call send_command + add $2, %sp + + /* write size */ + movw $26, 0(%si) + + /* set flags to 2 */ + movw $2, 2(%si) + + /* cylinders */ + mov 2(%bp), %ax + mov %ax, 4(%si) + xor %ax, %ax + mov %ax, 6(%si) + + /* heads */ + mov 4(%bp), %ax + mov %ax, 8(%si) + xor %ax, %ax + mov %ax, 10(%si) + + /* sectors */ + mov 6(%bp), %ax + mov %ax, 12(%si) + xor %ax, %ax + mov %ax, 14(%si) + + /* set total number of sectors */ + mov 8(%bp), %ax + mov %ax, 16(%si) + mov 10(%bp), %ax + mov %ax, 18(%si) + mov 12(%bp), %ax + mov %ax, 20(%si) + mov 14(%bp), %ax + mov %ax, 22(%si) + + /* number of bytes per sector */ + movw $512, 24(%si) + + freebpa + + pop %dx + pop %cx + pop %bp + pop %ax + + mov $0, %ah + clc_stack + ret + +terminate_disk_emulation: + mov $1, %ah + stc_stack + ret + +int13_handler: + cmp $0x80, %dl + je 1f + ljmpw *%cs:old_int13 +1: + cmp $0x0, %ah + jne 1f + call disk_reset + iret +1: + cmp $0x2, %ah + jne 1f + call read_disk_sectors + iret +1: + cmp $0x8, %ah + jne 1f + call read_disk_drive_parameters + iret +1: + cmp $0x15, %ah + jne 1f + call read_disk_drive_size + iret +1: + cmp $0x41, %ah + jne 1f + call check_if_extensions_present + iret +1: + cmp $0x42, %ah + jne 1f + call extended_read_sectors + iret +1: + cmp $0x48, %ah + jne 1f + call get_extended_drive_parameters + iret +1: + cmp $0x4b, %ah + jne 1f + call terminate_disk_emulation + iret +1: + cmp $0x0d, %ah + jne 1f + call alternate_disk_reset + iret +1: + cmp $0x03, %ah + jne 1f + call write_disk_sectors + iret +1: + cmp $0x43, %ah + jne 1f + call extended_write_sectors + iret +1: + int $0x18 /* boot failed */ + iret + +/* Variables */ +.align 4, 0 +old_int13: .long 0 +old_int19: .long 0 + +.align 512, 0 +_end: -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 2/2] extboot: qemu code. 2009-09-08 9:17 [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 1/2] extboot: add option rom Gerd Hoffmann @ 2009-09-08 9:17 ` Gerd Hoffmann 2009-09-08 11:59 ` [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann ` (2 subsequent siblings) 4 siblings, 0 replies; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 9:17 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann booting from scsi + virtio works now. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- Makefile.target | 1 + hw/extboot.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pc.c | 15 +++++- hw/pc.h | 4 ++ qemu-config.c | 4 ++ qemu-options.hx | 2 +- sysemu.h | 1 + vl.c | 12 +++++ 8 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 hw/extboot.c diff --git a/Makefile.target b/Makefile.target index 67bd4d7..2314812 100644 --- a/Makefile.target +++ b/Makefile.target @@ -188,6 +188,7 @@ obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o +obj-i386-y += extboot.o # shared objects obj-ppc-y = ppc.o ide/core.o ide/isa.o ide/pci.o ide/macio.o diff --git a/hw/extboot.c b/hw/extboot.c new file mode 100644 index 0000000..b91d54f --- /dev/null +++ b/hw/extboot.c @@ -0,0 +1,135 @@ +/* + * Extended boot option ROM support. + * + * Copyright IBM, Corp. 2007 + * + * Authors: + * Anthony Liguori <aliguori@us.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "hw.h" +#include "pc.h" +#include "isa.h" +#include "block.h" + +/* Extended Boot ROM suport */ + +union extboot_cmd +{ + uint16_t type; + struct { + uint16_t type; + uint16_t cylinders; + uint16_t heads; + uint16_t sectors; + uint64_t nb_sectors; + } query_geometry; + struct { + uint16_t type; + uint16_t nb_sectors; + uint16_t segment; + uint16_t offset; + uint64_t sector; + } xfer; +}; + +static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s) +{ + bdrv_get_geometry_hint(bs, c, h, s); + + if (*c <= 1024) { + *c >>= 0; + *h <<= 0; + } else if (*c <= 2048) { + *c >>= 1; + *h <<= 1; + } else if (*c <= 4096) { + *c >>= 2; + *h <<= 2; + } else if (*c <= 8192) { + *c >>= 3; + *h <<= 3; + } else { + *c >>= 4; + *h <<= 4; + } + + /* what is the correct algorithm for this?? */ + if (*h == 256) { + *h = 255; + *c = *c + 1; + } +} + +static uint32_t extboot_read(void *opaque, uint32_t addr) +{ + int *pcmd = opaque; + return *pcmd; +} + +static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value) +{ + union extboot_cmd cmd; + BlockDriverState *bs = opaque; + int cylinders, heads, sectors, err; + uint64_t nb_sectors; + target_phys_addr_t pa = 0; + int blen = 0; + void *buf = NULL; + + cpu_physical_memory_read((value & 0xFFFF) << 4, (uint8_t *)&cmd, + sizeof(cmd)); + + if (cmd.type == 0x01 || cmd.type == 0x02) { + pa = cmd.xfer.segment * 16 + cmd.xfer.offset; + blen = cmd.xfer.nb_sectors * 512; + buf = qemu_memalign(512, blen); + } + + switch (cmd.type) { + case 0x00: + get_translated_chs(bs, &cylinders, &heads, §ors); + bdrv_get_geometry(bs, &nb_sectors); + cmd.query_geometry.cylinders = cylinders; + cmd.query_geometry.heads = heads; + cmd.query_geometry.sectors = sectors; + cmd.query_geometry.nb_sectors = nb_sectors; + break; + case 0x01: + err = bdrv_read(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors); + if (err) + printf("Read failed\n"); + + cpu_physical_memory_write(pa, buf, blen); + + break; + case 0x02: + cpu_physical_memory_read(pa, buf, blen); + + err = bdrv_write(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors); + if (err) + printf("Write failed\n"); + + break; + } + + cpu_physical_memory_write((value & 0xFFFF) << 4, (uint8_t *)&cmd, + sizeof(cmd)); + if (buf) + qemu_free(buf); +} + +void extboot_init(BlockDriverState *bs, int cmd) +{ + int *pcmd; + + pcmd = qemu_mallocz(sizeof(int)); + + *pcmd = cmd; + register_ioport_read(0x404, 1, 1, extboot_read, pcmd); + register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs); +} diff --git a/hw/pc.c b/hw/pc.c index 6292001..a17dbd0 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -47,6 +47,7 @@ #define BIOS_FILENAME "bios.bin" #define VGABIOS_FILENAME "vgabios.bin" #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin" +#define EXTBOOT_FILENAME "extboot.bin" #define PC_MAX_BIOS_SIZE (4 * 1024 * 1024) @@ -1130,7 +1131,7 @@ static void pc_init1(ram_addr_t ram_size, qemu_irq *isa_irq; qemu_irq *i8259; IsaIrqState *isa_irq_state; - DriveInfo *dinfo; + DriveInfo *dinfo, *boot_drive; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BlockDriverState *fd[MAX_FD]; int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled; @@ -1218,7 +1219,10 @@ static void pc_init1(ram_addr_t ram_size, isa_bios_size, (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); - + boot_drive = drive_get_boot(); + if (boot_drive) { + option_rom[nb_option_roms++] = qemu_strdup(EXTBOOT_FILENAME); + } option_rom_offset = qemu_ram_alloc(0x20000); oprom_area_size = 0; @@ -1428,6 +1432,13 @@ static void pc_init1(ram_addr_t ram_size, } } } + + if (boot_drive) { + int cyls, heads, secs; + bdrv_guess_geometry(boot_drive->bdrv, &cyls, &heads, &secs); + bdrv_set_geometry_hint(boot_drive->bdrv, cyls, heads, secs); + extboot_init(boot_drive->bdrv, 1); + } } static void pc_init_pci(ram_addr_t ram_size, diff --git a/hw/pc.h b/hw/pc.h index ec5735b..bd3c20a 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -151,4 +151,8 @@ void isa_cirrus_vga_init(void); void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd); int cpu_is_bsp(CPUState *env); + +/* extboot.c */ +void extboot_init(BlockDriverState *bs, int cmd); + #endif diff --git a/qemu-config.c b/qemu-config.c index 4808db0..efea7f4 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -70,6 +70,10 @@ QemuOptsList qemu_drive_opts = { .name = "addr", .type = QEMU_OPT_STRING, .help = "pci address (virtio only)", + },{ + .name = "boot", + .type = QEMU_OPT_BOOL, + .help = "make this a boot drive", }, { /* end if list */ } }, diff --git a/qemu-options.hx b/qemu-options.hx index ce38a3b..df751ca 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -103,7 +103,7 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive, "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n" " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n" " [,cache=writethrough|writeback|none][,format=f][,serial=s]\n" - " [,addr=A][,id=name][,aio=threads|native]\n" + " [,addr=A][,id=name][,aio=threads|native][,boot=on]\n" " use 'file' as a drive image\n") DEF("set", HAS_ARG, QEMU_OPTION_set, "-set group.id.arg=value\n" diff --git a/sysemu.h b/sysemu.h index ac16c21..dd24444 100644 --- a/sysemu.h +++ b/sysemu.h @@ -186,6 +186,7 @@ extern TAILQ_HEAD(driveoptlist, DriveOpt) driveopts; extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); extern DriveInfo *drive_get_by_id(const char *id); +extern DriveInfo *drive_get_boot(void); extern int drive_get_max_bus(BlockInterfaceType type); extern void drive_uninit(BlockDriverState *bdrv); extern const char *drive_get_serial(BlockDriverState *bdrv); diff --git a/vl.c b/vl.c index 098daaa..982b418 100644 --- a/vl.c +++ b/vl.c @@ -1843,6 +1843,18 @@ DriveInfo *drive_get_by_id(const char *id) return NULL; } +DriveInfo *drive_get_boot(void) +{ + DriveInfo *dinfo; + + TAILQ_FOREACH(dinfo, &drives, next) { + if (qemu_opt_get_bool(dinfo->opts, "boot", 0) == 0) + continue; + return dinfo; + } + return NULL; +} + int drive_get_max_bus(BlockInterfaceType type) { int max_bus; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-09-08 9:17 [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 1/2] extboot: add option rom Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 2/2] extboot: qemu code Gerd Hoffmann @ 2009-09-08 11:59 ` Gerd Hoffmann 2009-09-08 13:47 ` [Qemu-devel] " Jan Kiszka 2009-09-08 14:16 ` [Qemu-devel] " Anthony Liguori 4 siblings, 0 replies; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 11:59 UTC (permalink / raw) To: qemu-devel [-- Attachment #1: Type: text/plain, Size: 325 bytes --] Hi,, > Booting a rawhide install from a virtual usb stick doesn't actually work > though, looks like it stresses qemus usb emulation too much. Hmm, might be linux simply doesn't like the speed of usb 1.1 for mass storage. With the attached debug patch rawhide boots up to the login prompt just fine. cheers, Gerd [-- Attachment #2: 0001-make-usb-1.1-go-insane-fast.patch --] [-- Type: text/plain, Size: 587 bytes --] >From 4c94383b57d66e7eedb11c4a07d579fb374bec6b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann <kraxel@redhat.com> Date: Tue, 8 Sep 2009 13:53:15 +0200 Subject: [PATCH] make usb 1.1 go insane fast --- hw/usb-uhci.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index 09ffd4b..4a627ab 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -63,7 +63,7 @@ #define UHCI_PORT_CSC (1 << 1) #define UHCI_PORT_CCS (1 << 0) -#define FRAME_TIMER_FREQ 1000 +#define FRAME_TIMER_FREQ 100000 #define FRAME_MAX_LOOPS 100 -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 9:17 [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann ` (2 preceding siblings ...) 2009-09-08 11:59 ` [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann @ 2009-09-08 13:47 ` Jan Kiszka 2009-09-08 14:22 ` Gerd Hoffmann 2009-09-08 14:16 ` [Qemu-devel] " Anthony Liguori 4 siblings, 1 reply; 29+ messages in thread From: Jan Kiszka @ 2009-09-08 13:47 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel Gerd Hoffmann wrote: > $subject says pretty much everything. > > extboot.[cS] are a straight copy from the kvm tree. The windup in vl,c > and hw/pc.c is done slightly different, I've added a function to lookup > the boot drive instead of adding a new global variable. > > Booting from scsi and virtio works, using the boot=on flag. > > With the usb+scsi patches in anthonys patch queue applied booting from > usb works too. Syntax is this: > > -drive if=none,id=pendrive,file=/path/to/image,boot=on > -usb -device usb-storage,drive=pendrive > > Booting a rawhide install from a virtual usb stick doesn't actually work > though, looks like it stresses qemus usb emulation too much. > Before setting this definitely useful feature in stone, I have two questions though: - -drive ...,boot=on is logically in conflict with -boot. Yes, -boot for x86 currently cannot differentiate between multiple disks, only between boot media types. Still, this two-stage configuration is rather unintuitive and looks like a patchwork. Given that we have full control over all components, is it really the preferred approach? I already thought about, e.g., -boot c2 to select the second disk. Not that nice, but I would rather vote for a consistent configuration than a scattered one. - This is just an implementation detail: Do we really need to implement booting from virtio and scsi via an extension rom? Isn't it possible to merge the corresponding support into the main bios? Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 13:47 ` [Qemu-devel] " Jan Kiszka @ 2009-09-08 14:22 ` Gerd Hoffmann 2009-09-08 14:32 ` Anthony Liguori 2009-09-08 14:40 ` Jan Kiszka 0 siblings, 2 replies; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 14:22 UTC (permalink / raw) To: Jan Kiszka; +Cc: qemu-devel On 09/08/09 15:47, Jan Kiszka wrote: > Before setting this definitely useful feature in stone, I have two > questions though: > > - -drive ...,boot=on is logically in conflict with -boot. Yes, -boot > for x86 currently cannot differentiate between multiple disks, only > between boot media types. Still, this two-stage configuration is > rather unintuitive and looks like a patchwork. Given that we have > full control over all components, is it really the preferred > approach? I already thought about, e.g., -boot c2 to select the > second disk. Not that nice, but I would rather vote for a consistent > configuration than a scattered one. Disk numbers are bad. Define "second hard disk". Especially for a system with different kinds of disks (say one scsi and one virtio). Drives have names though which can be used to reference the disks, so we could use that instead. -boot cmd line syntax becomes a bit tricky then though, we somehow have to figure whenever the user gave us names or old-style letters. Something like this ... -drive if=virtio,id=sys,file=/path/to/disk.img -cdrom /path/to/install.iso -boot order=[sys],once=d,menu=off ... might work out nicely. I suspect the libvirt folks will hate us for that though. > - This is just an implementation detail: Do we really need to implement > booting from virtio and scsi via an extension rom? Isn't it possible > to merge the corresponding support into the main bios? Well. There are quite a few. bochs pcbios, seabios, coreboot ... cheers, Gerd ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 14:22 ` Gerd Hoffmann @ 2009-09-08 14:32 ` Anthony Liguori 2009-09-08 16:05 ` Avi Kivity 2009-09-08 14:40 ` Jan Kiszka 1 sibling, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 14:32 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: Jan Kiszka, qemu-devel Gerd Hoffmann wrote: > On 09/08/09 15:47, Jan Kiszka wrote: > >> Before setting this definitely useful feature in stone, I have two >> questions though: >> >> - -drive ...,boot=on is logically in conflict with -boot. Yes, -boot x86 boot is strange. The BIOS boots from the "first hard disk" What extboot allows you do to is redefine to the bios what constitutes the "first hard disk". This is the motivation for making it a -drive option. Perhaps this is something we want to hide from the user but that was the motivation. For instance, it would not be possible to define a boot sequence of "first virtio disk, then second virtio disk, then cdrom" because we can't present two disks as the first hard disk. If extboot supported BCV and our bios did, the above would be possible. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 14:32 ` Anthony Liguori @ 2009-09-08 16:05 ` Avi Kivity 2009-09-08 17:21 ` Anthony Liguori 2009-09-12 15:03 ` Kevin O'Connor 0 siblings, 2 replies; 29+ messages in thread From: Avi Kivity @ 2009-09-08 16:05 UTC (permalink / raw) To: Anthony Liguori; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel On 09/08/2009 05:32 PM, Anthony Liguori wrote: > Gerd Hoffmann wrote: >> On 09/08/09 15:47, Jan Kiszka wrote: >> >>> Before setting this definitely useful feature in stone, I have two >>> questions though: >>> >>> - -drive ...,boot=on is logically in conflict with -boot. Yes, -boot > > x86 boot is strange. The BIOS boots from the "first hard disk" What > extboot allows you do to is redefine to the bios what constitutes the > "first hard disk". It's not just booting - it's the int 0x13 interface. Grub for example continues to use it and can boot from the second hard disk if desired. > > This is the motivation for making it a -drive option. Perhaps this is > something we want to hide from the user but that was the motivation. I agree with this and I think we should extend it to boot=0x80|0x81.... boot=on is an alias to boot=0x80. > > For instance, it would not be possible to define a boot sequence of > "first virtio disk, then second virtio disk, then cdrom" because we > can't present two disks as the first hard disk. > > If extboot supported BCV and our bios did, the above would be possible. > -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 16:05 ` Avi Kivity @ 2009-09-08 17:21 ` Anthony Liguori 2009-09-08 19:11 ` Avi Kivity 2009-09-12 15:03 ` Kevin O'Connor 1 sibling, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 17:21 UTC (permalink / raw) To: Avi Kivity; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel Avi Kivity wrote: > On 09/08/2009 05:32 PM, Anthony Liguori wrote: >> Gerd Hoffmann wrote: >>> On 09/08/09 15:47, Jan Kiszka wrote: >>> >>>> Before setting this definitely useful feature in stone, I have two >>>> questions though: >>>> >>>> - -drive ...,boot=on is logically in conflict with -boot. Yes, -boot >> >> x86 boot is strange. The BIOS boots from the "first hard disk" What >> extboot allows you do to is redefine to the bios what constitutes the >> "first hard disk". > > It's not just booting - it's the int 0x13 interface. Grub for example > continues to use it and can boot from the second hard disk if desired. Our BIOS can only support booting from the 0x80 and this is pretty normal. The right way to do this from a BBS perspective would be to implement BCV support. We could then have BCV entries for every possible disk. Option roms (like extboot/gpxe) can register add new BCV entries. We'd want the user to be able to specify the priority of each disk, so.. > I agree with this and I think we should extend it to > boot=0x80|0x81.... boot=on is an alias to boot=0x80. Would be better to stick with 0-based integers. We would then use this to generate BCV priorities. The highest priority BCV device is still exposed as int13 disk 0x80. I suspect certain OSes will only boot from disk 0x80 (probably Windows). Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 17:21 ` Anthony Liguori @ 2009-09-08 19:11 ` Avi Kivity 2009-09-08 19:46 ` Anthony Liguori 0 siblings, 1 reply; 29+ messages in thread From: Avi Kivity @ 2009-09-08 19:11 UTC (permalink / raw) To: Anthony Liguori; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel On 09/08/2009 08:21 PM, Anthony Liguori wrote: > Avi Kivity wrote: >> On 09/08/2009 05:32 PM, Anthony Liguori wrote: >>> Gerd Hoffmann wrote: >>>> On 09/08/09 15:47, Jan Kiszka wrote: >>>> >>>>> Before setting this definitely useful feature in stone, I have two >>>>> questions though: >>>>> >>>>> - -drive ...,boot=on is logically in conflict with -boot. Yes, >>>>> -boot >>> >>> x86 boot is strange. The BIOS boots from the "first hard disk" >>> What extboot allows you do to is redefine to the bios what >>> constitutes the "first hard disk". >> >> It's not just booting - it's the int 0x13 interface. Grub for >> example continues to use it and can boot from the second hard disk if >> desired. > > Our BIOS can only support booting from the 0x80 and this is pretty > normal. The bios exports the "bios drives". You can tell grub to load a kernel from the first partition of the second disk: (hd1,0) or even chain-load another boot loaded from another disk. > > The right way to do this from a BBS perspective would be to implement > BCV support. We could then have BCV entries for every possible disk. > Option roms (like extboot/gpxe) can register add new BCV entries. > We'd want the user to be able to specify the priority of each disk, so.. I don't know anything about BBS/BCV but it seems reasonable. > >> I agree with this and I think we should extend it to >> boot=0x80|0x81.... boot=on is an alias to boot=0x80. > > Would be better to stick with 0-based integers. We would then use > this to generate BCV priorities. Sure. > > The highest priority BCV device is still exposed as int13 disk 0x80. > I suspect certain OSes will only boot from disk 0x80 (probably Windows). Windows has its own boot loader drive format that can specify other drives (I think using its own drivers, not the bios). -- Do not meddle in the internals of kernels, for they are subtle and quick to panic. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 19:11 ` Avi Kivity @ 2009-09-08 19:46 ` Anthony Liguori 2009-09-08 20:00 ` Avi Kivity 0 siblings, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 19:46 UTC (permalink / raw) To: Avi Kivity; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel Avi Kivity wrote: > The bios exports the "bios drives". You can tell grub to load a > kernel from the first partition of the second disk: (hd1,0) or even > chain-load another boot loaded from another disk. The whole point of device.map is that grub doesn't intrinsically know how to map from bios drives to real drives. In fact, when you chain-load with grub, you often have to "swap" device mappings which has the effect of hooking int13 and faking the primary drive for another OS. See http://www.gnu.org/software/grub/manual/html_node/DOS_002fWindows.html All else aside, from a BIOS perspective, you can usually only boot from 0x80 and that can be mapped to different drives via BCV. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 19:46 ` Anthony Liguori @ 2009-09-08 20:00 ` Avi Kivity 2009-09-08 20:10 ` Anthony Liguori 0 siblings, 1 reply; 29+ messages in thread From: Avi Kivity @ 2009-09-08 20:00 UTC (permalink / raw) To: Anthony Liguori; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel On 09/08/2009 10:46 PM, Anthony Liguori wrote: > Avi Kivity wrote: >> The bios exports the "bios drives". You can tell grub to load a >> kernel from the first partition of the second disk: (hd1,0) or even >> chain-load another boot loaded from another disk. > > The whole point of device.map is that grub doesn't intrinsically know > how to map from bios drives to real drives. device.map is a wonderful thing, but unrelated to the bios exposing drive 0x81. > In fact, when you chain-load with grub, you often have to "swap" > device mappings which has the effect of hooking int13 and faking the > primary drive for another OS. See > http://www.gnu.org/software/grub/manual/html_node/DOS_002fWindows.html But grub still has to issue a real int 13 for drive 0x81. If we don't expose it, it can't. Until a real OS is loaded, the only way to access a drive is through int 13 and if we don't expose it, it's invisible. > All else aside, from a BIOS perspective, you can usually only boot > from 0x80 and that can be mapped to different drives via BCV. There things you can do with a drive other than boot it. For example, access it via int 13. How will you access D:\ from DOS? -- Do not meddle in the internals of kernels, for they are subtle and quick to panic. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 20:00 ` Avi Kivity @ 2009-09-08 20:10 ` Anthony Liguori 0 siblings, 0 replies; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 20:10 UTC (permalink / raw) To: Avi Kivity; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel Avi Kivity wrote: >> In fact, when you chain-load with grub, you often have to "swap" >> device mappings which has the effect of hooking int13 and faking the >> primary drive for another OS. See >> http://www.gnu.org/software/grub/manual/html_node/DOS_002fWindows.html > > But grub still has to issue a real int 13 for drive 0x81. If we don't > expose it, it can't. Until a real OS is loaded, the only way to > access a drive is through int 13 and if we don't expose it, it's > invisible. extboot ignores any non-0x80 access today FWIW so this is already broken. Only 0x80 is generally bootable. This means even on modern systems, you still have per-adapter config menus that allow the user to configure which drive ends up getting 0x80. It's awfully messy and not worth exposing to users. >> All else aside, from a BIOS perspective, you can usually only boot >> from 0x80 and that can be mapped to different drives via BCV. > > There things you can do with a drive other than boot it. For example, > access it via int 13. > > How will you access D:\ from DOS? Let the user specify BCV priority, let the BIOS determine how to assign drive numbering. It may turn out that bios drive number isn't stable but this is also true on real machines. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 16:05 ` Avi Kivity 2009-09-08 17:21 ` Anthony Liguori @ 2009-09-12 15:03 ` Kevin O'Connor 1 sibling, 0 replies; 29+ messages in thread From: Kevin O'Connor @ 2009-09-12 15:03 UTC (permalink / raw) To: Avi Kivity; +Cc: Jan Kiszka, Gerd Hoffmann, qemu-devel On Tue, Sep 08, 2009 at 07:05:15PM +0300, Avi Kivity wrote: > On 09/08/2009 05:32 PM, Anthony Liguori wrote: >> x86 boot is strange. The BIOS boots from the "first hard disk" What >> extboot allows you do to is redefine to the bios what constitutes the >> "first hard disk". > > It's not just booting - it's the int 0x13 interface. Grub for example > continues to use it and can boot from the second hard disk if desired. Some time back, I tried implementing booting from the second hard drive by passing 0x81 in "dl" during the boot. All the boot loaders I tested failed to work. I think grub may have worked if I re-configured it, but I figured it wasn't worth it due to the confusion it would cause. So, the experience suggested to me that bootloaders today still require the boot harddrive to be mapped to 0x80. (Though, interestingly, cdrom booting is okay with any drive id..) >> For instance, it would not be possible to define a boot sequence of >> "first virtio disk, then second virtio disk, then cdrom" because we >> can't present two disks as the first hard disk. >> >> If extboot supported BCV and our bios did, the above would be possible. FWIW, SeaBIOS does support BCVs. SeaBIOS will find all the drives and present them on the boot menu - the user can then select which drive to boot from (either floppy, any number of cdroms, any of the builtin or external "BCV" hard drives). For floppy and hard drive booting the selection is implemented by manipulating the drive mappings. Also, as an aside, it seams likely that USB booting will be added to SeaBIOS (either directly or as an option rom). I'm not sure if this has any overlap with extboot. -Kevin ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 14:22 ` Gerd Hoffmann 2009-09-08 14:32 ` Anthony Liguori @ 2009-09-08 14:40 ` Jan Kiszka 2009-09-08 14:52 ` Gerd Hoffmann 2009-09-12 15:43 ` Kevin O'Connor 1 sibling, 2 replies; 29+ messages in thread From: Jan Kiszka @ 2009-09-08 14:40 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: libvir-list, qemu-devel@nongnu.org Gerd Hoffmann wrote: > On 09/08/09 15:47, Jan Kiszka wrote: > >> Before setting this definitely useful feature in stone, I have two >> questions though: >> >> - -drive ...,boot=on is logically in conflict with -boot. Yes, -boot >> for x86 currently cannot differentiate between multiple disks, only >> between boot media types. Still, this two-stage configuration is >> rather unintuitive and looks like a patchwork. Given that we have >> full control over all components, is it really the preferred >> approach? I already thought about, e.g., -boot c2 to select the >> second disk. Not that nice, but I would rather vote for a consistent >> configuration than a scattered one. > > Disk numbers are bad. Define "second hard disk". Especially for a > system with different kinds of disks (say one scsi and one virtio). One could use the specification order, but I agree it's not very handy. > > Drives have names though which can be used to reference the disks, so we > could use that instead. -boot cmd line syntax becomes a bit tricky then > though, we somehow have to figure whenever the user gave us names or > old-style letters. Something like this ... > > -drive if=virtio,id=sys,file=/path/to/disk.img > -cdrom /path/to/install.iso > -boot order=[sys],once=d,menu=off Yes, this looks powerful and clean. One could even still define probe orders like "-boot order=[sys][backup]d". > > ... might work out nicely. I suspect the libvirt folks will hate us for > that though. Does anyone from libvirt want to comment on this? > >> - This is just an implementation detail: Do we really need to implement >> booting from virtio and scsi via an extension rom? Isn't it possible >> to merge the corresponding support into the main bios? > > Well. There are quite a few. bochs pcbios, seabios, coreboot ... Ok, but that's only an argument to have extboot as a workaround for bioses not yet supporting scsi and virtio natively, isn't it? I'm thinking long-term here, not arguing against a extboot-based short-term solution. Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 14:40 ` Jan Kiszka @ 2009-09-08 14:52 ` Gerd Hoffmann 2009-09-08 16:15 ` Jan Kiszka 2009-09-12 15:43 ` Kevin O'Connor 1 sibling, 1 reply; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 14:52 UTC (permalink / raw) To: Jan Kiszka; +Cc: libvir-list, qemu-devel@nongnu.org >> -drive if=virtio,id=sys,file=/path/to/disk.img >> -cdrom /path/to/install.iso >> -boot order=[sys],once=d,menu=off > > Yes, this looks powerful and clean. One could even still define probe > orders like "-boot order=[sys][backup]d". Well, except that boot orders with two hard drives in there don't work in the PC world ... >>> - This is just an implementation detail: Do we really need to implement >>> booting from virtio and scsi via an extension rom? Isn't it possible >>> to merge the corresponding support into the main bios? >> >> Well. There are quite a few. bochs pcbios, seabios, coreboot ... > > Ok, but that's only an argument to have extboot as a workaround for > bioses not yet supporting scsi and virtio natively, isn't it? I'm > thinking long-term here, not arguing against a extboot-based short-term > solution. I think it would be useful. Adding a fw_cfg knob to signal 'please boot via extboot protocol instead of ide disk' should be enougth to allow bioses supporting extboot directly. Additional plus is we can probably code it in C not asm then. cheers, Gerd ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 14:52 ` Gerd Hoffmann @ 2009-09-08 16:15 ` Jan Kiszka 2009-09-08 17:12 ` Anthony Liguori 0 siblings, 1 reply; 29+ messages in thread From: Jan Kiszka @ 2009-09-08 16:15 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: libvir-list@redhat.com, qemu-devel@nongnu.org Gerd Hoffmann wrote: >>> -drive if=virtio,id=sys,file=/path/to/disk.img >>> -cdrom /path/to/install.iso >>> -boot order=[sys],once=d,menu=off >> Yes, this looks powerful and clean. One could even still define probe >> orders like "-boot order=[sys][backup]d". > > Well, except that boot orders with two hard drives in there don't work > in the PC world ... That depends on your bios. I've seen many that allow disk boot ordering, though they may not support "[sys]d[backup]". However, I see no technical reason for artificially restricting qemu bios capabilities. > >>>> - This is just an implementation detail: Do we really need to implement >>>> booting from virtio and scsi via an extension rom? Isn't it possible >>>> to merge the corresponding support into the main bios? >>> Well. There are quite a few. bochs pcbios, seabios, coreboot ... >> Ok, but that's only an argument to have extboot as a workaround for >> bioses not yet supporting scsi and virtio natively, isn't it? I'm >> thinking long-term here, not arguing against a extboot-based short-term >> solution. > > I think it would be useful. Adding a fw_cfg knob to signal 'please boot > via extboot protocol instead of ide disk' should be enougth to allow > bioses supporting extboot directly. Additional plus is we can probably > code it in C not asm then. I'm still not convinced we need extboot for all bioses on the long term. And I think we should define new interfaces in a way that finally makes it obsolete, at least for our "home bios" (whatever it will be). Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 16:15 ` Jan Kiszka @ 2009-09-08 17:12 ` Anthony Liguori 2009-09-08 19:03 ` Gerd Hoffmann 0 siblings, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 17:12 UTC (permalink / raw) To: Jan Kiszka; +Cc: libvir-list@redhat.com, Gerd Hoffmann, qemu-devel@nongnu.org Jan Kiszka wrote: >>>>> - This is just an implementation detail: Do we really need to implement >>>>> booting from virtio and scsi via an extension rom? Isn't it possible >>>>> to merge the corresponding support into the main bios? >>>>> >>>> Well. There are quite a few. bochs pcbios, seabios, coreboot ... >>>> >>> Ok, but that's only an argument to have extboot as a workaround for >>> bioses not yet supporting scsi and virtio natively, isn't it? I'm >>> thinking long-term here, not arguing against a extboot-based short-term >>> solution. >>> >> I think it would be useful. Adding a fw_cfg knob to signal 'please boot >> via extboot protocol instead of ide disk' should be enougth to allow >> bioses supporting extboot directly. Additional plus is we can probably >> code it in C not asm then. >> > > I'm still not convinced we need extboot for all bioses on the long term. > And I think we should define new interfaces in a way that finally makes > it obsolete, at least for our "home bios" (whatever it will be). > What we won't need long term is the extboot interface (hw/extboot.c). Ideally, we would rewrite the extboot option rom to have a proper virtio-blk driver in it. Better yet, to finish up Laurent's work of adding virtio-blk support to gpxe since it gives us bcv for free. We woudl then support booting from multiple disks by specifying the bcv entry index in cmos. Then we would need a new syntax for boot (like -boot c3 to chose the 3rd disk device). Regards, Anthony Liguori > Jan > > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 17:12 ` Anthony Liguori @ 2009-09-08 19:03 ` Gerd Hoffmann 2009-09-08 19:39 ` Anthony Liguori 0 siblings, 1 reply; 29+ messages in thread From: Gerd Hoffmann @ 2009-09-08 19:03 UTC (permalink / raw) To: Anthony Liguori; +Cc: libvir-list@redhat.com, Jan Kiszka, qemu-devel@nongnu.org On 09/08/09 19:12, Anthony Liguori wrote: >> I'm still not convinced we need extboot for all bioses on the long term. >> And I think we should define new interfaces in a way that finally makes >> it obsolete, at least for our "home bios" (whatever it will be). > > What we won't need long term is the extboot interface (hw/extboot.c). > Ideally, we would rewrite the extboot option rom to have a proper > virtio-blk driver in it. Better yet, to finish up Laurent's work of > adding virtio-blk support to gpxe since it gives us bcv for free. That doesn't cover booting from scsi. It also doesn't cover booting from usb. cheers, Gerd ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 19:03 ` Gerd Hoffmann @ 2009-09-08 19:39 ` Anthony Liguori 0 siblings, 0 replies; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 19:39 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: libvir-list@redhat.com, Jan Kiszka, qemu-devel@nongnu.org Gerd Hoffmann wrote: > On 09/08/09 19:12, Anthony Liguori wrote: >>> I'm still not convinced we need extboot for all bioses on the long >>> term. >>> And I think we should define new interfaces in a way that finally makes >>> it obsolete, at least for our "home bios" (whatever it will be). >> >> What we won't need long term is the extboot interface (hw/extboot.c). >> Ideally, we would rewrite the extboot option rom to have a proper >> virtio-blk driver in it. Better yet, to finish up Laurent's work of >> adding virtio-blk support to gpxe since it gives us bcv for free. > > That doesn't cover booting from scsi. > It also doesn't cover booting from usb. It assumes support for both in option roms. The big advantage to gpxe is that it already has generic scsi support. Regards, Anthony Liguori > cheers, > Gerd ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 0/2] port over extboot from kvm 2009-09-08 14:40 ` Jan Kiszka 2009-09-08 14:52 ` Gerd Hoffmann @ 2009-09-12 15:43 ` Kevin O'Connor 1 sibling, 0 replies; 29+ messages in thread From: Kevin O'Connor @ 2009-09-12 15:43 UTC (permalink / raw) To: Jan Kiszka; +Cc: libvir-list, Gerd Hoffmann, qemu-devel@nongnu.org On Tue, Sep 08, 2009 at 04:40:15PM +0200, Jan Kiszka wrote: > Gerd Hoffmann wrote: > > On 09/08/09 15:47, Jan Kiszka wrote: > >> - This is just an implementation detail: Do we really need to implement > >> booting from virtio and scsi via an extension rom? Isn't it possible > >> to merge the corresponding support into the main bios? > > > > Well. There are quite a few. bochs pcbios, seabios, coreboot ... > > Ok, but that's only an argument to have extboot as a workaround for > bioses not yet supporting scsi and virtio natively, isn't it? I'm > thinking long-term here, not arguing against a extboot-based short-term > solution. I doubt we'll see native scsi support as I believe each scsi controller needs its own initialization. However, usb booting will bring along with it mass storage class support. I'm not familiar with virtio, however, I don't think it would be difficult to add support to SeaBIOS. The disk access code in SeaBIOS has an intermediate layer which makes it easier to add new backends. For an example of this, see the ramdisk.c code: http://git.linuxtogo.org/?p=kevin/seabios.git;a=blob;f=src/ramdisk.c;h=7ac72f82befebb9fc6f18838c24044ace2312b1f;hb=HEAD The above code adds support for a virtual floppy drive that is populated with a floppy image stored in flash (useful with coreboot). Basically, its possible to add driver support by adding a new drive type (eg, DTYPE_RAMDISK) and implementing a new drive handler (eg, process_ramdisk_op). The handler just has to implement read and write capability - the bios call handlers, interfaces, and lba manipulation are handled by SeaBIOS. -Kevin ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-09-08 9:17 [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann ` (3 preceding siblings ...) 2009-09-08 13:47 ` [Qemu-devel] " Jan Kiszka @ 2009-09-08 14:16 ` Anthony Liguori 2009-11-09 16:06 ` Paul Brook 4 siblings, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-09-08 14:16 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: qemu-devel Gerd Hoffmann wrote: > $subject says pretty much everything. > > extboot.[cS] are a straight copy from the kvm tree. The windup in vl,c > and hw/pc.c is done slightly different, I've added a function to lookup > the boot drive instead of adding a new global variable. > I think the function here is high even if the implementation is ugly. In the past, Paul strongly objected to this. Paul, care to comment? Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-09-08 14:16 ` [Qemu-devel] " Anthony Liguori @ 2009-11-09 16:06 ` Paul Brook 2009-11-09 16:31 ` Gerd Hoffmann 0 siblings, 1 reply; 29+ messages in thread From: Paul Brook @ 2009-11-09 16:06 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann On Tuesday 08 September 2009, Anthony Liguori wrote: > Gerd Hoffmann wrote: > > $subject says pretty much everything. > > > > extboot.[cS] are a straight copy from the kvm tree. The windup in vl,c > > and hw/pc.c is done slightly different, I've added a function to lookup > > the boot drive instead of adding a new global variable. > > I think the function here is high even if the implementation is ugly. > In the past, Paul strongly objected to this. Paul, care to comment? Doesn't gpxe support virtio-blk, without requiring any additional qemu "features"? Paul ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-11-09 16:06 ` Paul Brook @ 2009-11-09 16:31 ` Gerd Hoffmann 2009-11-09 16:40 ` Anthony Liguori 0 siblings, 1 reply; 29+ messages in thread From: Gerd Hoffmann @ 2009-11-09 16:31 UTC (permalink / raw) To: Paul Brook; +Cc: qemu-devel On 11/09/09 17:06, Paul Brook wrote: > On Tuesday 08 September 2009, Anthony Liguori wrote: >> Gerd Hoffmann wrote: >>> $subject says pretty much everything. >>> >>> extboot.[cS] are a straight copy from the kvm tree. The windup in vl,c >>> and hw/pc.c is done slightly different, I've added a function to lookup >>> the boot drive instead of adding a new global variable. >> >> I think the function here is high even if the implementation is ugly. >> In the past, Paul strongly objected to this. Paul, care to comment? > > Doesn't gpxe support virtio-blk, without requiring any additional qemu > "features"? As far I know patches exist but where never merged. Also there is no way to boot from scsi+usb ... cheers, Gerd ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-11-09 16:31 ` Gerd Hoffmann @ 2009-11-09 16:40 ` Anthony Liguori 2009-11-11 13:01 ` Hannes Reinecke 0 siblings, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-11-09 16:40 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: Paul Brook, qemu-devel Gerd Hoffmann wrote: > On 11/09/09 17:06, Paul Brook wrote: >> On Tuesday 08 September 2009, Anthony Liguori wrote: >>> Gerd Hoffmann wrote: >>>> $subject says pretty much everything. >>>> >>>> extboot.[cS] are a straight copy from the kvm tree. The windup in >>>> vl,c >>>> and hw/pc.c is done slightly different, I've added a function to >>>> lookup >>>> the boot drive instead of adding a new global variable. >>> >>> I think the function here is high even if the implementation is ugly. >>> In the past, Paul strongly objected to this. Paul, care to comment? >> >> Doesn't gpxe support virtio-blk, without requiring any additional qemu >> "features"? > > As far I know patches exist but where never merged. > Also there is no way to boot from scsi+usb ... I think Kevin mentioned he would likely to usb boot support for SeaBIOS. Adding virtio-blk support to SeaBIOS would also be pretty reasonable. SCSI is a bit more tough. Doing an LSI driver in SeaBIOS would be a bit tougher. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-11-09 16:40 ` Anthony Liguori @ 2009-11-11 13:01 ` Hannes Reinecke 2009-11-11 13:25 ` Anthony Liguori 0 siblings, 1 reply; 29+ messages in thread From: Hannes Reinecke @ 2009-11-11 13:01 UTC (permalink / raw) To: Anthony Liguori; +Cc: qemu-devel, Gerd Hoffmann, Paul Brook Anthony Liguori wrote: > Gerd Hoffmann wrote: >> On 11/09/09 17:06, Paul Brook wrote: >>> On Tuesday 08 September 2009, Anthony Liguori wrote: >>>> Gerd Hoffmann wrote: >>>>> $subject says pretty much everything. >>>>> >>>>> extboot.[cS] are a straight copy from the kvm tree. The windup in >>>>> vl,c >>>>> and hw/pc.c is done slightly different, I've added a function to >>>>> lookup >>>>> the boot drive instead of adding a new global variable. >>>> >>>> I think the function here is high even if the implementation is ugly. >>>> In the past, Paul strongly objected to this. Paul, care to comment? >>> >>> Doesn't gpxe support virtio-blk, without requiring any additional qemu >>> "features"? >> >> As far I know patches exist but where never merged. >> Also there is no way to boot from scsi+usb ... > > I think Kevin mentioned he would likely to usb boot support for > SeaBIOS. Adding virtio-blk support to SeaBIOS would also be pretty > reasonable. > > SCSI is a bit more tough. Doing an LSI driver in SeaBIOS would be a bit > tougher. > But why? Why do we have to emulate the entire HBA for the BIOS? The HBA is emulated, too, and just uses the bdrv interface internally anyway. So IMHO it makes far more sense to skip the HBA emulation in the BIOS completely and just use the bdrv interface directly here. Where is the drawback? (Apart from the missing BIOS initialization of the HBA?) Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage hare@suse.de +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Markus Rex, HRB 16746 (AG Nürnberg) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-11-11 13:01 ` Hannes Reinecke @ 2009-11-11 13:25 ` Anthony Liguori 2009-11-11 13:54 ` Paul Brook 0 siblings, 1 reply; 29+ messages in thread From: Anthony Liguori @ 2009-11-11 13:25 UTC (permalink / raw) To: Hannes Reinecke; +Cc: qemu-devel, Gerd Hoffmann, Paul Brook Hannes Reinecke wrote: > But why? Why do we have to emulate the entire HBA for the BIOS? > The HBA is emulated, too, and just uses the bdrv interface > internally anyway. > So IMHO it makes far more sense to skip the HBA emulation in > the BIOS completely and just use the bdrv interface directly > here. > If you use the bdrv interface (ala extboot), you couldn't boot via scsi passthrough. VirtualBox implements a paravirtual SCSI bus to allow SCSI boot without having to implement a full LSI driver. That's another way to solve the problem. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [Qemu-devel] [PATCH 0/2] port over extboot from kvm 2009-11-11 13:25 ` Anthony Liguori @ 2009-11-11 13:54 ` Paul Brook 0 siblings, 0 replies; 29+ messages in thread From: Paul Brook @ 2009-11-11 13:54 UTC (permalink / raw) To: qemu-devel; +Cc: Hannes Reinecke, Gerd Hoffmann On Wednesday 11 November 2009, Anthony Liguori wrote: > Hannes Reinecke wrote: > > But why? Why do we have to emulate the entire HBA for the BIOS? > > The HBA is emulated, too, and just uses the bdrv interface > > internally anyway. > > So IMHO it makes far more sense to skip the HBA emulation in > > the BIOS completely and just use the bdrv interface directly > > here. > > If you use the bdrv interface (ala extboot), you couldn't boot via scsi > passthrough. > > VirtualBox implements a paravirtual SCSI bus to allow SCSI boot without > having to implement a full LSI driver. That's another way to solve the > problem. This has its own issues. How do you prevent the guest enumerating both the paravirt and "real" adapters, and getting the same disk twice? If this isn't a problem, then surely the user can do this explicitly. In this case "guest" includes future fancy versions of the BIOS/bootloader. Paul ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 0/2] extboot reloaded. @ 2009-11-16 18:04 Gerd Hoffmann 2009-11-16 18:04 ` [Qemu-devel] [PATCH 1/2] extboot: add option rom Gerd Hoffmann 0 siblings, 1 reply; 29+ messages in thread From: Gerd Hoffmann @ 2009-11-16 18:04 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Hi, How about this one? extboot rom and interface are unmodified. The windup in qemu is very different though. It is now implemented as isa bus device (which is what extboot actually is). It is properly integrated into qdev. It is much less invasive than the previous version. The patch just drops a hw/extboot.c file into the tree and adds it to Makefile.target. No code changes anywhere else in qemu. The magic words to activate extboot are '-device extboot,drive=<name>'. cheers, Gerd ^ permalink raw reply [flat|nested] 29+ messages in thread
* [Qemu-devel] [PATCH 1/2] extboot: add option rom. 2009-11-16 18:04 [Qemu-devel] [PATCH 0/2] extboot reloaded Gerd Hoffmann @ 2009-11-16 18:04 ` Gerd Hoffmann 0 siblings, 0 replies; 29+ messages in thread From: Gerd Hoffmann @ 2009-11-16 18:04 UTC (permalink / raw) To: qemu-devel; +Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- Makefile | 2 +- pc-bios/optionrom/Makefile | 2 +- pc-bios/optionrom/extboot.S | 680 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 682 insertions(+), 2 deletions(-) create mode 100644 pc-bios/optionrom/extboot.S diff --git a/Makefile b/Makefile index fe5d868..2d6f244 100644 --- a/Makefile +++ b/Makefile @@ -260,7 +260,7 @@ pxe-e1000.bin pxe-i82559er.bin \ pxe-ne2k_pci.bin pxe-pcnet.bin \ pxe-rtl8139.bin pxe-virtio.bin \ bamboo.dtb petalogix-s3adsp1800.dtb \ -multiboot.bin +multiboot.bin extboot.bin else BLOBS= endif diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile index b01a54e..73e74d8 100644 --- a/pc-bios/optionrom/Makefile +++ b/pc-bios/optionrom/Makefile @@ -13,7 +13,7 @@ CFLAGS += -I$(SRC_PATH) CFLAGS += $(call cc-option, $(CFLAGS), -fno-stack-protector) QEMU_CFLAGS = $(CFLAGS) -build-all: multiboot.bin +build-all: multiboot.bin extboot.bin %.img: %.o $(call quiet-command,$(LD) -Ttext 0 -e _start -s -o $@ $<," Building $(TARGET_DIR)$@") diff --git a/pc-bios/optionrom/extboot.S b/pc-bios/optionrom/extboot.S new file mode 100644 index 0000000..79a4674 --- /dev/null +++ b/pc-bios/optionrom/extboot.S @@ -0,0 +1,680 @@ +/* + * 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> + */ + +.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 + + /* there is one more bootable HD */ + incb 0x0475 + + /* save old int 19 */ + mov (0x19*4), %eax + mov %eax, %cs:old_int19 + + /* install out int 19 handler */ + movw $int19_handler, (0x19*4) + mov %cs, (0x19*4+2) + + pop %ds + pop %eax + lret + +int19_handler: + push %eax + push %bx + push %cx + push %dx + push %ds + + /* setup ds to access IVT */ + xor %ax, %ax + mov %ax, %ds + + movw $0x404, %dx + inb %dx, %al + cmp $1, %al + je 1f + jmp 3f + +1: /* hook int13: intb(0x404) == 1 */ + /* save old int 13 to int 2c */ + mov (0x13*4), %eax + mov %eax, %cs:old_int13 + + /* install our int 13 handler */ + movw $int13_handler, (0x13*4) + mov %cs, (0x13*4+2) + +3: /* fall through: inb(0x404) == anything else */ + /* restore previous int $0x19 handler */ + mov %cs:old_int19,%eax + mov %eax,(0x19*4) + + pop %ds + pop %dx + pop %cx + pop %bx + pop %eax + ljmpw *%cs:old_int19 + +#define FLAGS_CF 0x01 + +/* The two macro below clear/set the carry flag to indicate the status + * of the interrupt execution. It is not enough to issue a clc/stc instruction, + * since the value of the flags register will be overwritten by whatever is + * in the stack frame + */ +.macro clc_stack + push %bp + mov %sp, %bp + /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */ + and $(~FLAGS_CF), 8(%bp) + pop %bp +.endm + +.macro stc_stack + push %bp + /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */ + or $(FLAGS_CF), 8(%bp) + pop %bp +.endm + +/* we clobber %bx */ +.macro alloca size + push %ds + push %bp + mov %sp, %bp /* remember the current stack position */ + + mov %ss, %bx + mov %bx, %ds + + sub \size, %sp + and $(~0x0F), %sp + mov %sp, %bx + + push %bp + mov 0(%bp), %bp +.endm + +/* we clobber %bp */ +.macro allocbpa size + mov %sp, %bp /* remember the current stack position */ + sub \size, %sp + and $(~0x0F), %sp + push %bp + mov %sp, %bp + add $2, %bp +.endm + +.macro freea + pop %sp + add $2, %sp + pop %ds +.endm + +.macro freebpa + pop %sp +.endm + +.macro dump reg + push %ax + push %dx + + mov \reg, %ax + mov $0x406, %dx + outw %ax, %dx + + pop %dx + pop %ax +.endm + +.macro callout value + push %bp + push %bx + mov %sp, %bp + alloca $16 + push %ax + push %dx + + mov %ax, 0(%bx) /* ax */ + mov 0(%bp), %ax /* bx */ + mov %ax, 2(%bx) + mov %cx, 4(%bx) /* cx */ + mov %dx, 6(%bx) /* dx */ + mov %si, 8(%bx) /* si */ + mov %ds, 10(%bx) /* ds */ + mov %es, 12(%bx) /* ds */ + movw \value, 14(%bx) /* value */ + + mov %bx, %ax + shr $4, %ax + mov %ds, %dx + add %dx, %ax + + mov $0x407, %dx + outw %ax, %dx + + pop %dx + pop %ax + freea + pop %bx + pop %bp +.endm + +send_command: + push %bp + mov %sp, %bp + push %ax + push %bx + push %dx + + mov 4(%bp), %ax + shr $4, %ax + and $0x0FFF, %ax + mov %ss, %bx + add %bx, %ax + + mov $0x405, %dx + outw %ax, %dx + + pop %dx + pop %bx + pop %ax + pop %bp + + push %ax + mov 2(%bx), %ax + pop %ax + + ret + +add32: /* lo, hi, lo, hi */ + push %bp + mov %sp, %bp + + movw 4(%bp), %cx /* hi */ + movw 6(%bp), %dx /* lo */ + + add 10(%bp), %dx + jnc 1f + add $1, %cx +1: add 8(%bp), %cx + + pop %bp + ret + +mul32: /* lo, hi, lo, hi */ + /* 10(%bp), 8(%bp), 6(%bp), 4(%bp) */ + push %bp + mov %sp, %bp + push %ax + push %bx + + xor %cx, %cx + xor %dx, %dx + + /* for (i = 0; i < 16;) */ + xor %bx, %bx +0: + cmp $16, %bx + jge 2f + + mov 6(%bp), %ax + and $1, %ax + cmp $1, %ax + jne 1f + push 10(%bp) + push 8(%bp) + push %dx + push %cx + call add32 + add $8, %sp +1: + shlw $1, 8(%bp) + movw 10(%bp), %ax + and $0x8000, %ax + cmp $0x8000, %ax + jne 1f + orw $1, 8(%bp) +1: + shlw $1, 10(%bp) + shrw $1, 6(%bp) + + /* i++) { */ + add $1, %bx + jmp 0b + +2: + pop %bx + pop %ax + pop %bp + ret + +disk_reset: + movb $0, %ah + clc_stack + ret + +/* this really should be a function, not a macro but i'm lazy */ +.macro read_write_disk_sectors cmd + push %ax + push %bx + push %cx + push %dx + push %si + + push %bp + sub $10, %sp + mov %sp, %bp + + /* save nb_sectors */ + mov %al, 6(%bp) + movb $0, 7(%bp) + + /* save buffer */ + mov %bx, 8(%bp) + + /* cylinders */ + xor %ax, %ax + mov %cl, %al + shl $2, %ax + and $0x300, %ax + mov %ch, %al + mov %ax, 0(%bp) + + /* heads */ + xor %ax, %ax + mov %dh, %al + mov %ax, 2(%bp) + + /* sectors - 1 */ + xor %ax, %ax + mov %cl, %al + and $0x3F, %al + sub $1, %ax + mov %ax, 4(%bp) + + alloca $16 + + movw $0, 0(%bx) /* read c,h,s */ + push %bx + call send_command + add $2, %sp + + mov 6(%bx), %ax /* total_sectors */ + mov 2(%bp), %si /* *= heads */ + mul %si + add 4(%bp), %ax /* += sectors - 1 */ + + push 4(%bx) /* total_heads */ + push $0 + push 6(%bx) /* total_sectors */ + push $0 + call mul32 + add $8, %sp + + push 0(%bp) /* cylinders */ + push $0 + push %dx + push %cx + call mul32 + add $8, %sp + + add %ax, %dx + jnc 1f + add $1, %cx +1: + freea + + alloca $16 + + movw \cmd, 0(%bx) /* read */ + movw 6(%bp), %ax /* nb_sectors */ + movw %ax, 2(%bx) + movw %es, 4(%bx) /* segment */ + movw 8(%bp), %ax /* offset */ + mov %ax, 6(%bx) + movw %dx, 8(%bx) /* sector */ + movw %cx, 10(%bx) + movw $0, 12(%bx) + movw $0, 14(%bx) + + push %bx + call send_command + add $2, %sp + + freea + + add $10, %sp + pop %bp + + pop %si + pop %dx + pop %cx + pop %bx + pop %ax + + mov $0, %ah + clc_stack + ret +.endm + +read_disk_sectors: + read_write_disk_sectors $0x01 + +write_disk_sectors: + read_write_disk_sectors $0x02 + +read_disk_drive_parameters: + push %bx + + /* allocate memory for packet, pointer gets returned in bx */ + alloca $16 + + /* issue command */ + movw $0, 0(%bx) /* cmd = 0, read c,h,s */ + push %bx + call send_command + add $2, %sp + + /* normalize sector value */ + movb 6(%bx), %cl + andb $0x3F, %cl + movb %cl, 6(%bx) + + /* normalize cylinders */ + subw $2, 2(%bx) + + /* normalize heads */ + subw $1, 4(%bx) + + /* return code */ + mov $0, %ah + + /* cylinders */ + movb 2(%bx), %ch + movb 3(%bx), %cl + shlb $6, %cl + andb $0xC0, %cl + + /* sectors */ + orb 6(%bx), %cl + + /* heads */ + movb 4(%bx), %dh + + /* drives */ + movb $1, %dl + + /* status */ + mov $0, %ah + + freea + + pop %bx + + /* do this last since it's the most sensitive */ + clc_stack + ret + +alternate_disk_reset: + movb $0, %ah + clc_stack + ret + +read_disk_drive_size: + push %bx + alloca $16 + + movw $0, 0(%bx) /* cmd = 0, read c,h,s */ + push %bx + call send_command + add $2, %sp + + /* cylinders - 1 to cx:dx */ + mov 2(%bx), %dx + xor %cx, %cx + sub $1, %dx + + /* heads */ + push 4(%bx) + push $0 + push %dx + push %cx + call mul32 + add $8, %sp + + /* sectors */ + push 6(%bx) + push $0 + push %dx + push %cx + call mul32 + add $8, %sp + + /* status */ + mov $3, %ah + + freea + pop %bx + + clc_stack + ret + +check_if_extensions_present: + mov $0x30, %ah + mov $0xAA55, %bx + mov $0x07, %cx + clc_stack + ret + +.macro extended_read_write_sectors cmd + cmpb $10, 0(%si) + jg 1f + mov $1, %ah + stc_stack + ret +1: + push %ax + push %bp + allocbpa $16 + + movw \cmd, 0(%bp) /* read */ + movw 2(%si), %ax /* nb_sectors */ + movw %ax, 2(%bp) + movw 4(%si), %ax /* offset */ + movw %ax, 6(%bp) + movw 6(%si), %ax /* segment */ + movw %ax, 4(%bp) + movw 8(%si), %ax /* block */ + movw %ax, 8(%bp) + movw 10(%si), %ax + movw %ax, 10(%bp) + movw 12(%si), %ax + movw %ax, 12(%bp) + movw 14(%si), %ax + movw %ax, 14(%bp) + + push %bp + call send_command + add $2, %sp + + freebpa + pop %bp + pop %ax + + mov $0, %ah + clc_stack + ret +.endm + +extended_read_sectors: + extended_read_write_sectors $0x01 + +extended_write_sectors: + extended_read_write_sectors $0x02 + +get_extended_drive_parameters: + push %ax + push %bp + push %cx + push %dx + + allocbpa $16 + + movw $0, 0(%bp) /* read c,h,s */ + push %bp + call send_command + add $2, %sp + + /* write size */ + movw $26, 0(%si) + + /* set flags to 2 */ + movw $2, 2(%si) + + /* cylinders */ + mov 2(%bp), %ax + mov %ax, 4(%si) + xor %ax, %ax + mov %ax, 6(%si) + + /* heads */ + mov 4(%bp), %ax + mov %ax, 8(%si) + xor %ax, %ax + mov %ax, 10(%si) + + /* sectors */ + mov 6(%bp), %ax + mov %ax, 12(%si) + xor %ax, %ax + mov %ax, 14(%si) + + /* set total number of sectors */ + mov 8(%bp), %ax + mov %ax, 16(%si) + mov 10(%bp), %ax + mov %ax, 18(%si) + mov 12(%bp), %ax + mov %ax, 20(%si) + mov 14(%bp), %ax + mov %ax, 22(%si) + + /* number of bytes per sector */ + movw $512, 24(%si) + + freebpa + + pop %dx + pop %cx + pop %bp + pop %ax + + mov $0, %ah + clc_stack + ret + +terminate_disk_emulation: + mov $1, %ah + stc_stack + ret + +int13_handler: + cmp $0x80, %dl + je 1f + ljmpw *%cs:old_int13 +1: + cmp $0x0, %ah + jne 1f + call disk_reset + iret +1: + cmp $0x2, %ah + jne 1f + call read_disk_sectors + iret +1: + cmp $0x8, %ah + jne 1f + call read_disk_drive_parameters + iret +1: + cmp $0x15, %ah + jne 1f + call read_disk_drive_size + iret +1: + cmp $0x41, %ah + jne 1f + call check_if_extensions_present + iret +1: + cmp $0x42, %ah + jne 1f + call extended_read_sectors + iret +1: + cmp $0x48, %ah + jne 1f + call get_extended_drive_parameters + iret +1: + cmp $0x4b, %ah + jne 1f + call terminate_disk_emulation + iret +1: + cmp $0x0d, %ah + jne 1f + call alternate_disk_reset + iret +1: + cmp $0x03, %ah + jne 1f + call write_disk_sectors + iret +1: + cmp $0x43, %ah + jne 1f + call extended_write_sectors + iret +1: + int $0x18 /* boot failed */ + iret + +/* Variables */ +.align 4, 0 +old_int13: .long 0 +old_int19: .long 0 + +.align 512, 0 +_end: -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 29+ messages in thread
end of thread, other threads:[~2009-11-16 18:04 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-09-08 9:17 [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 1/2] extboot: add option rom Gerd Hoffmann 2009-09-08 9:17 ` [Qemu-devel] [PATCH 2/2] extboot: qemu code Gerd Hoffmann 2009-09-08 11:59 ` [Qemu-devel] [PATCH 0/2] port over extboot from kvm Gerd Hoffmann 2009-09-08 13:47 ` [Qemu-devel] " Jan Kiszka 2009-09-08 14:22 ` Gerd Hoffmann 2009-09-08 14:32 ` Anthony Liguori 2009-09-08 16:05 ` Avi Kivity 2009-09-08 17:21 ` Anthony Liguori 2009-09-08 19:11 ` Avi Kivity 2009-09-08 19:46 ` Anthony Liguori 2009-09-08 20:00 ` Avi Kivity 2009-09-08 20:10 ` Anthony Liguori 2009-09-12 15:03 ` Kevin O'Connor 2009-09-08 14:40 ` Jan Kiszka 2009-09-08 14:52 ` Gerd Hoffmann 2009-09-08 16:15 ` Jan Kiszka 2009-09-08 17:12 ` Anthony Liguori 2009-09-08 19:03 ` Gerd Hoffmann 2009-09-08 19:39 ` Anthony Liguori 2009-09-12 15:43 ` Kevin O'Connor 2009-09-08 14:16 ` [Qemu-devel] " Anthony Liguori 2009-11-09 16:06 ` Paul Brook 2009-11-09 16:31 ` Gerd Hoffmann 2009-11-09 16:40 ` Anthony Liguori 2009-11-11 13:01 ` Hannes Reinecke 2009-11-11 13:25 ` Anthony Liguori 2009-11-11 13:54 ` Paul Brook -- strict thread matches above, loose matches on Subject: below -- 2009-11-16 18:04 [Qemu-devel] [PATCH 0/2] extboot reloaded Gerd Hoffmann 2009-11-16 18:04 ` [Qemu-devel] [PATCH 1/2] extboot: add option rom Gerd Hoffmann
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).