* Extboot Option ROM rewritten in C - v3
@ 2008-04-17 1:30 Nguyen Anh Quynh
2008-04-17 5:58 ` H. Peter Anvin
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-17 1:30 UTC (permalink / raw)
To: kvm-devel
[-- Attachment #1: Type: text/plain, Size: 651 bytes --]
This patch replaces the current assembly code of Extboot option rom
with new C code. Patch is against kvm-66.
This version returns an error code in case int 13 handler cannot
handle a requested function.
Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
# diffstat extboot3.diff
b/extboot/Makefile | 67 ++--
b/extboot/boot.S | 119 ++++++++
b/extboot/farvar.h | 113 ++++++++
b/extboot/rom.c | 366 ++++++++++++++++++++++++++
b/extboot/signrom.c | 83 ++++--
b/extboot/util.h | 89 ++++++
extboot/extboot.S | 705 ----------------------------------------------------
7 files changed, 786 insertions(+), 756 deletions(-)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: extboot3.diff --]
[-- Type: text/x-diff; name=extboot3.diff, Size: 36905 bytes --]
commit bd0c778b70bbbcc5f120478278a965f87b8af7f4
Author: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Thu Apr 17 10:22:00 2008 +0900
Extboot Option ROM rewritten in C
Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
diff --git a/extboot/Makefile b/extboot/Makefile
index ab2dae7..8ac5b7b 100644
--- a/extboot/Makefile
+++ b/extboot/Makefile
@@ -1,35 +1,34 @@
-OBJCOPY=objcopy
-
-# from kernel sources - scripts/Kbuild.include
-# try-run
-# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
-# Exit code chooses option. "$$TMP" is can be used as temporary file and
-# is automatically cleaned up.
-try-run = $(shell set -e; \
- TMP="$(TMPOUT).$$$$.tmp"; \
- if ($(1)) >/dev/null 2>&1; \
- then echo "$(2)"; \
- else echo "$(3)"; \
- fi; \
- rm -f "$$TMP")
-
-# cc-option-yn
-# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
-cc-option-yn = $(call try-run,\
- $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",y,n)
-
-CFLAGS = -Wall -Wstrict-prototypes -Werror -fomit-frame-pointer -fno-builtin
-ifeq ($(call cc-option-yn,-fno-stack-protector),y)
-CFLAGS += -fno-stack-protector
-endif
-
-all: extboot.bin
+# Makefile for extboot Option ROM
+# Nguyen Anh Quynh <aquynh@gmail.com>
-%.o: %.S
- $(CC) $(CFLAGS) -o $@ -c $<
+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 extboot.bin
+
+.PHONY: install
+install: extboot.bin
+ cp extboot.bin $(INSTALLDIR)
+
+.PHONY: save
+save:
+ mv $(INSTALLDIR)/extboot.bin $(INSTALLDIR)/extboot.bin.org
+
+.PHONY: clean
+clean:
+ $(RM) *.o *.img *.bin signrom *~
-extboot.img: extboot.o
- $(LD) --oformat binary -Ttext 0 -o $@ $<
+extboot.img: boot.o rom.o
+ $(LD) --oformat binary -Ttext 0 $^ -o $@
extboot.bin: extboot.img signrom
./signrom extboot.img extboot.bin
@@ -37,5 +36,9 @@ extboot.bin: extboot.img signrom
signrom: signrom.c
$(CC) -o $@ -g -Wall $^
-clean:
- $(RM) *.o *.img *.bin signrom *~
+%.o: %.c
+ $(CC) $(CCFLAGS) -c $<
+
+%.o: %.S
+ $(CC) $(CCFLAGS) -c $<
+
diff --git a/extboot/boot.S b/extboot/boot.S
new file mode 100644
index 0000000..bc7e20c
--- /dev/null
+++ b/extboot/boot.S
@@ -0,0 +1,119 @@
+/*
+ * extboot.c
+ * Extended Boot Option ROM for QEMU.
+
+ * Copyright (C) by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * Based on the ASM version extboot.S of Anthony Liguori <aliguori@us.ibm.com>
+
+ * 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
+ /* -fomit-frame-pointer might clobber %ebp */
+ pushl %ebp
+ call setup
+ popl %ebp
+ popw %es
+ popal
+ lretw
+
+ /* interrupt 19 handler */
+ .globl int19_handler
+ .extern int19_handler_C
+ .extern linux_boot
+ int19_handler:
+ pushal
+ /* %es is clobbered, so save it */
+ pushw %es
+ /* -fomit-frame-pointer might clobber %ebp */
+ pushl %ebp
+ call int19_handler_C
+ popl %ebp
+ popw %es
+ orw %ax, %ax /* Do we need to execute original INT 19? */
+ popal
+ jnz linux_boot /* No, just boot Linux kernel */
+ int $0x2b
+
+ /* interrupt 13 handler */
+ .globl int13_handler
+ .extern int13_handler_C
+int13_handler:
+ cmpb $0x80, %dl
+ /* only interested in 1st IDE HDD */
+ je 1f
+ /* call original int13 */
+ int $0x2c
+ iretw
+
+ 1:
+ /* Pass a set of registers to C code.
+ * These registers might be modified on return. */
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ pushw %es
+ pushw %ds
+ /* Set %ds = %ss */
+ movw %ss, %ax
+ movw %ax, %ds
+ /* Backup %esp, then clear high bits */
+ movl %esp, %ebx
+ movzwl %sp, %esp
+ /* We use -regparm(1), so %eax points to struct ibregs */
+ movl %esp, %eax
+ /* -fomit-frame-pointer might clobber %ebp */
+ pushl %ebp
+ calll int13_handler_C
+ popl %ebp
+ /* Restore %esp (including high bits) */
+ movl %ebx, %esp
+ /* Restore registers. These registers might be modified in C code */
+ popw %ds
+ popw %es
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %edx
+ popl %ecx
+ popl %eax
+ iretw
+
+ .globl linux_boot
+linux_boot:
+ 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
diff --git a/extboot/extboot.S b/extboot/extboot.S
deleted file mode 100644
index 9eb9333..0000000
--- a/extboot/extboot.S
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * 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 %ax
- push %bx
- push %cx
- push %dx
- push %ds
-
- /* setup ds so we can access the IVT */
- xor %ax, %ax
- mov %ax, %ds
-
- /* save old int 19 at int 2b */
- mov $(0x19 * 4), %bx
- mov 0(%bx), %ax
- mov 2(%bx), %cx
-
- mov $(0x2b * 4), %bx
- mov %ax, 0(%bx)
- mov %cx, 2(%bx)
-
- /* install out int 19 handler */
- mov $(0x19 * 4), %bx
- mov $int19_handler, %ax
- mov %ax, 0(%bx)
- mov %cs, 2(%bx)
-
- pop %ds
- pop %dx
- pop %cx
- pop %bx
- pop %ax
- lret
-
-int19_handler:
- push %ax
- push %bx
- push %cx
- push %dx
- push %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 */
- /* setup ds to access IVT */
- xor %ax, %ax
- mov %ax, %ds
-
- /* save old int 13 to int 2c */
- mov $(0x13 * 4), %bx
- mov 0(%bx), %ax
- mov 2(%bx), %cx
-
- mov $(0x2c * 4), %bx
- mov %ax, 0(%bx)
- mov %cx, 2(%bx)
-
- /* install our int 13 handler */
- mov $(0x13 * 4), %bx
- mov $int13_handler, %ax
-
- mov %ax, 0(%bx)
- mov %cs, 2(%bx)
- 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 */
- pop %ds
- pop %dx
- pop %cx
- pop %bx
- pop %ax
- int $0x2b
-
-#define FLAGS_CF 0x01
-
-.macro clc
- push %ax
- pushf
- pop %ax
- and $(~FLAGS_CF), %ax
- push %ax
- popf
- pop %ax
-.endm
-
-.macro stc
- push %ax
- pushf
- pop %ax
- or $(FLAGS_CF), %ax
- push %ax
- popf
- pop %ax
-.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
- 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
- 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
- ret
-
-alternate_disk_reset:
- movb $0, %ah
- clc
- 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
- ret
-
-check_if_extensions_present:
- mov $0x30, %ah
- mov $0xAA55, %bx
- mov $0x07, %cx
- clc
- ret
-
-.macro extended_read_write_sectors cmd
- cmpb $10, 0(%si)
- jg 1f
- mov $1, %ah
- stc
- 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
- 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
- ret
-
-terminate_disk_emulation:
- mov $1, %ah
- stc
- ret
-
-int13_handler:
- cmp $0x80, %dl
- je 1f
- int $0x2c
- iret
-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
-
-.align 512, 0
-_end:
diff --git a/extboot/farvar.h b/extboot/farvar.h
new file mode 100644
index 0000000..b0c7be7
--- /dev/null
+++ b/extboot/farvar.h
@@ -0,0 +1,113 @@
+// Code to access multiple segments within gcc.
+//
+// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+#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_ES, __segment_CS, __segment_DS, __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 %b0, %%" #SEG ":%1" : \
+ : "Q"(value), "m"(var), "m"(__segment_ ## SEG))
+#define __WRITE16_SEG(SEG, var, value) \
+ __asm__("movw %w0, %%" #SEG ":%1" : \
+ : "r"(value), "m"(var), "m"(__segment_ ## SEG))
+#define __WRITE32_SEG(SEG, var, value) \
+ __asm__("movl %0, %%" #SEG ":%1" : \
+ : "r"(value), "m"(var), "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/extboot/rom.c b/extboot/rom.c
new file mode 100644
index 0000000..f70c99e
--- /dev/null
+++ b/extboot/rom.c
@@ -0,0 +1,366 @@
+/*
+ * extboot.c
+ * Extended Boot Option ROM for QEMU.
+ *
+ * Copyright (C) by Nguyen Anh Quynh <aquynh@gmail.com>, 2008.
+ *
+ * Based on the ASM version extboot.S of Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * 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");
+
+union extboot_cmd {
+ uint16_t type;
+ struct {
+ uint16_t type;
+ uint16_t cylinders;
+ uint16_t heads;
+ uint16_t sectors; /* sectors per track */
+ uint64_t nb_sectors; /* total number of sectors in drive */
+ } query_geometry;
+ struct {
+ uint16_t type;
+ uint16_t nb_sectors;
+ uint16_t segment;
+ uint16_t offset;
+ uint64_t sector;
+ } xfer;
+};
+
+#define EXTBOOT_READ_PORT 0x404
+#define EXTBOOT_WRITE_PORT 0x405
+
+#define MODE_READ 1
+#define MODE_WRITE 2
+
+#define INT13_INVALID_FUNC_PARAM 1
+
+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()
+{
+ uint16_t seg, off;
+
+ /* save original INT 19 into -unused- INT 2b */
+ seg = GET_IVT_ENTRY(0x19, segment);
+ off = GET_IVT_ENTRY(0x19, offset);
+ SET_IVT_ENTRY(0x2b, segment, seg);
+ SET_IVT_ENTRY(0x2b, offset, off);
+
+ /* install our INT 19 handler */
+ extern void int19_handler;
+ seg = GET_SEG(CS);
+ SET_IVT_ENTRY(0x19, segment, seg);
+ SET_IVT_ENTRY(0x19, offset, (uint16_t)&int19_handler);
+}
+
+/* send command to QEMU via a dedicated IO port */
+static void send_command(union extboot_cmd *cmd)
+{
+ uint16_t seg;
+ char tmp[16 + sizeof(*cmd)], *p;
+
+ /* align to 16 */
+ p = (char *)(((uint32_t)tmp + 0xF) & ~0xF);
+ memcpy(p, cmd, sizeof(*cmd));
+
+ /* send segment contained cmd to QEMU */
+ seg = ((uint32_t)p >> 4) + GET_SEG(SS);
+ outw(seg, EXTBOOT_WRITE_PORT);
+
+ /* now copy back the result to cmd */
+ memcpy(cmd, p, sizeof(*cmd));
+}
+
+/* interrupt returns succesfully */
+static void set_result_ok(struct iregs *regs, uint8_t status)
+{
+ /* set status in AH */
+ regs->ah = status;
+
+ /* succesfull, clear CF */
+ set_cf(regs, 0);
+}
+
+/* interrupt returns with failure */
+static void set_result_fail(struct iregs *regs, uint8_t status)
+{
+ /* set status in AH */
+ regs->ah = status;
+
+ /* set CF to indicate failure */
+ set_cf(regs, 1);
+}
+
+static void reset_disk(struct iregs *regs)
+{
+ set_result_ok(regs, 0);
+}
+
+/* mode == 1: read, mode ==2: write */
+static void read_write_sectors(struct iregs *regs, int mode)
+{
+ union extboot_cmd cmd;
+ uint8_t num_sectors = regs->al;
+ uint16_t buffer_offset = regs->bx;
+ uint16_t cylinder = regs->ch | ((regs->cl << 2) & 0x300);
+ uint8_t head = regs->dh;
+ uint8_t start_sector = (regs->cl & 0x3F) - 1;
+
+ /* query drive info */
+ cmd.type = 0;
+ send_command(&cmd);
+
+ /* convert chs to lba */
+ uint64_t lba =
+ (cylinder*cmd.query_geometry.heads + head)*cmd.query_geometry.sectors +
+ start_sector;
+
+ cmd.xfer.type = mode;
+ cmd.xfer.nb_sectors = num_sectors;
+ cmd.xfer.segment = regs->es;
+ cmd.xfer.offset = buffer_offset;
+ cmd.xfer.sector = lba;
+ send_command(&cmd);
+
+ /* everything is OK */
+ set_result_ok(regs, 0);
+}
+
+/* mode == 1: read, mode ==2: write */
+static void extend_read_write_sectors(struct iregs *regs, int mode)
+{
+ union extboot_cmd cmd;
+ struct disk_addr_packet {
+ uint8_t size;
+ uint8_t _r; /* reserved */
+ uint16_t blocks; /* number of blocks to transfer */
+ uint16_t offset;
+ uint16_t segment;
+ uint32_t lba_lo;
+ uint32_t lba_hi;
+ } PACKED;
+#define GET_DISK_ADDR_PACKET(var) \
+ GET_FARVAR((regs->ds), ((struct disk_addr_packet *)(regs->si+0))->var)
+
+ /*
+ * extern void copy_to_ss(void *, uint16_t, uint16_t, uint16_t);
+ * copy_to_ss(&packet, regs->ds, regs->si, sizeof(packet));
+ */
+ uint8_t packet_size = GET_DISK_ADDR_PACKET(size);
+ uint16_t packet_blocks = GET_DISK_ADDR_PACKET(blocks);
+ uint16_t packet_offset = GET_DISK_ADDR_PACKET(offset);
+ uint16_t packet_segment = GET_DISK_ADDR_PACKET(segment);
+ uint32_t lba_lo = GET_DISK_ADDR_PACKET(lba_lo);
+ uint32_t lba_hi = GET_DISK_ADDR_PACKET(lba_hi);
+ uint64_t packet_lba = ((uint64_t)lba_hi << 32) | lba_lo;
+
+ if (packet_size != sizeof(struct disk_addr_packet)) {
+ /* wrong packet size */
+ set_result_fail(regs, INT13_INVALID_FUNC_PARAM);
+ return;
+ }
+
+ cmd.xfer.type = mode;
+ cmd.xfer.nb_sectors = packet_blocks;
+ cmd.xfer.segment = packet_segment;
+ cmd.xfer.offset = packet_offset;
+ cmd.xfer.sector = packet_lba;
+ send_command(&cmd);
+
+ /* everything is OK */
+ set_result_ok(regs, 0);
+}
+
+static void get_drive_param(struct iregs *regs)
+{
+ union extboot_cmd cmd;
+
+ /* query drive info */
+ cmd.type = 0;
+ send_command(&cmd);
+
+ /* normalize sectors value */
+ cmd.query_geometry.sectors &= 0x3F;
+ /* normalize cylinders value: 0 based, last sector not used */
+ cmd.query_geometry.cylinders -= 2;
+ /* normalize heads value */
+ cmd.query_geometry.heads--;
+
+ regs->ch = cmd.query_geometry.cylinders & 0xFF;
+ regs->cl = cmd.query_geometry.sectors | ((cmd.query_geometry.cylinders >> 2) & 0xC0);
+ regs->dh = cmd.query_geometry.heads & 0xFF;
+ regs->dl = 1; /* only 1 drive */
+ regs->al = 0;
+
+ /* everything is OK */
+ set_result_ok(regs, 0);
+}
+
+static void get_extend_drive_param(struct iregs *regs)
+{
+ union extboot_cmd cmd;
+ struct extend_drive_param {
+ uint16_t size;
+ uint16_t flags;
+ uint32_t cylinders;
+ uint32_t heads;
+ uint32_t sectors_per_track; /* per track */
+ uint32_t total_sectors_lo;
+ uint32_t total_sectors_hi;
+ /* uint32_t total_sectors; */
+ uint16_t sector_size; /* in bytes */
+ } PACKED;
+#define SET_EXTEND_DRIVE_PARAM(var, value) \
+ SET_FARVAR((regs->ds), ((struct extend_drive_param *)(regs->si+0))->var, value)
+
+ /* query drive info */
+ cmd.type = 0;
+ send_command(&cmd);
+
+ /* We support Int13 extension 1.x format only */
+ SET_EXTEND_DRIVE_PARAM(size, sizeof(struct extend_drive_param));
+ /* flags: cylinder/head/sectors-per-track information is valid. See table 00274 */
+ SET_EXTEND_DRIVE_PARAM(flags, 2);
+ SET_EXTEND_DRIVE_PARAM(cylinders, cmd.query_geometry.cylinders);
+ SET_EXTEND_DRIVE_PARAM(heads, cmd.query_geometry.heads);
+ SET_EXTEND_DRIVE_PARAM(sectors_per_track, cmd.query_geometry.sectors);
+ SET_EXTEND_DRIVE_PARAM(total_sectors_hi, cmd.query_geometry.nb_sectors & 0xFFFFFFFF);
+ SET_EXTEND_DRIVE_PARAM(total_sectors_lo, cmd.query_geometry.nb_sectors >> 32);
+ SET_EXTEND_DRIVE_PARAM(sector_size, 512);
+
+ /* everything is OK */
+ set_result_ok(regs, 0);
+}
+
+static void get_drive_size(struct iregs *regs)
+{
+ union extboot_cmd cmd;
+
+ /* query drive info */
+ cmd.type = 0;
+ send_command(&cmd);
+
+ uint32_t total_sectors =
+ cmd.query_geometry.heads * (cmd.query_geometry.cylinders - 1) *
+ cmd.query_geometry.sectors;
+
+ /* cx:dx keeps total_sectors */
+ regs->dx = total_sectors & 0xFFFF;
+ regs->cx = total_sectors >> 16;
+
+ /* everything is OK */
+ set_result_ok(regs, 3);
+}
+
+static void check_extend_installation(struct iregs *regs)
+{
+ /* yes, extended function is supported */
+ regs->bx = 0xAA55;
+
+ /* cx keeps API support bitmap.
+ * Extended disk access + Removable + EDD funcs (Table 00271) */
+ regs->cx = 7; /* 0b111 */
+
+ /* everything is OK */
+ set_result_ok(regs, 0x30); /* EDD 3.0 extension */
+}
+
+static void terminate_disk_emu(struct iregs *regs)
+{
+ set_result_fail(regs, 1);
+}
+
+/* called from ASM code in boot.S */
+void __attribute__((regparm(1))) int13_handler_C(struct iregs *regs)
+{
+ switch (regs->ah) {
+ case 0x0:
+ /* reset disk */
+ return reset_disk(regs);
+ case 0x2:
+ /* read sectors */
+ return read_write_sectors(regs, MODE_READ);
+ case 0x3:
+ /* write sectors */
+ return read_write_sectors(regs, MODE_WRITE);
+ case 0x8:
+ /* query drive info */
+ return get_drive_param(regs);
+ case 0x0d:
+ /* alternate reset disk */
+ /* For now, do the same thing as our friend 0x0 above */
+ return reset_disk(regs);
+ case 0x15:
+ return get_drive_size(regs);
+ case 0x41:
+ /* installation check */
+ return check_extend_installation(regs);
+ case 0x42:
+ /* extended read sectors */
+ return extend_read_write_sectors(regs, MODE_READ);
+ case 0x43:
+ /* extended write sectors */
+ return extend_read_write_sectors(regs, MODE_WRITE);
+ case 0x48:
+ /* query extended drive info */
+ return get_extend_drive_param(regs);
+ case 0x4b:
+ return terminate_disk_emu(regs);
+ default:
+ /* invalid function */
+ return set_result_fail(regs, INT13_INVALID_FUNC_PARAM);
+ }
+}
+
+/* called from ASM code in boot.S */
+/* return 0 to fall-thru to original int19, 1 otherwise */
+int int19_handler_C()
+{
+ uint8_t x;
+
+ x = inb(EXTBOOT_READ_PORT);
+ switch (x) {
+ case 1: /* hook INT 13 */
+ /* save INT 13 into -unused- INT 2c */
+ SET_IVT_ENTRY(0x2c, segment, GET_IVT_ENTRY(0x13, segment));
+ SET_IVT_ENTRY(0x2c, offset, GET_IVT_ENTRY(0x13, offset));
+
+ /* install our INT 13 handler */
+ extern void int13_handler;
+ SET_IVT_ENTRY(0x13, segment, GET_SEG(CS));
+ SET_IVT_ENTRY(0x13, offset, (uint16_t)&int13_handler);
+ /* and call original INT 19 after getting back */
+ return 0;
+ case 2:
+ default:
+ /* do NOT call original INT 19 */
+ return 1;
+ }
+}
diff --git a/extboot/signrom.c b/extboot/signrom.c
index fe8d677..d4dad48 100644
--- a/extboot/signrom.c
+++ b/extboot/signrom.c
@@ -17,21 +17,42 @@
*
* 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[512], oldbuffer[512];
- int i, size, lag = 0;
+ 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]);
+ printf("Usage: %s <ROM> <OUTPUT>\n", argv[0]);
return 1;
}
@@ -43,31 +64,55 @@ int main(int argc, char **argv)
return 1;
}
- do {
- size = fread(buffer, 512, 1, fin);
+ 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) {
- for (i = 0; i < 512; i++)
- sum += buffer[i];
-
- if (lag) {
- if (fwrite(oldbuffer, 512, 1, fout) != 1) {
- fprintf(stderr, "Write failed\n");
- return 1;
- }
+ if (i == 0) {
+ /* first block, lets set ROM size */
+ buffer[2] = (uint8_t)rom_size;
}
- lag = 1;
- memcpy(oldbuffer, buffer, 512);
+
+ 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;
}
- } while (size == 1);
+ }
- if (size != 0) {
+ /* 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;
}
- oldbuffer[511] = -sum;
+ for (i = 0; i < size; i++)
+ sum += buffer[i];
+
+ /* set checksum in final byte */
+ buffer[BLOCK - 1] = -sum;
- if (fwrite(oldbuffer, 512, 1, fout) != 1) {
+ if (fwrite(buffer, BLOCK, 1, fout) != 1) {
fprintf(stderr, "Failed to write to output file\n");
return 1;
}
diff --git a/extboot/util.h b/extboot/util.h
new file mode 100644
index 0000000..4a1c142
--- /dev/null
+++ b/extboot/util.h
@@ -0,0 +1,89 @@
+/*
+ * util.h
+ *
+ * Copyright (C) 2008, Nguyen Anh Quynh <aquynh@gmail.com>
+ *
+ * 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>
+
+#define PACKED __attribute__((packed))
+
+static inline void outw(uint16_t value, uint16_t port)
+{
+ asm volatile("outw %w0, %w1" : : "a"(value), "Nd"(port));
+}
+
+static inline uint8_t inb(uint16_t port)
+{
+ uint8_t value;
+
+ asm volatile("inb %w1, %b0" : "=a"(value) : "Nd"(port));
+
+ return value;
+}
+
+#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;
+} PACKED;
+
+/* CF bit in FLAGS register */
+#define FLAG_CF (1<<0)
+
+static inline void set_cf(struct iregs *regs, int on)
+{
+ if (on)
+ regs->flags |= FLAG_CF;
+ else
+ regs->flags &= ~FLAG_CF;
+}
+
+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
[-- Attachment #3: Type: text/plain, Size: 320 bytes --]
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
[-- Attachment #4: Type: text/plain, Size: 158 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: Extboot Option ROM rewritten in C - v3
2008-04-17 1:30 Extboot Option ROM rewritten in C - v3 Nguyen Anh Quynh
@ 2008-04-17 5:58 ` H. Peter Anvin
2008-04-18 10:57 ` Nguyen Anh Quynh
2008-04-17 6:00 ` H. Peter Anvin
2008-04-17 7:36 ` Carlo Marcelo Arenas Belon
2 siblings, 1 reply; 17+ messages in thread
From: H. Peter Anvin @ 2008-04-17 5:58 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel
Nguyen Anh Quynh wrote:
> This patch replaces the current assembly code of Extboot option rom
> with new C code. Patch is against kvm-66.
>
> This version returns an error code in case int 13 handler cannot
> handle a requested function.
>
> Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
>
+ /* -fomit-frame-pointer might clobber %ebp */
+ pushl %ebp
+ call setup
+ popl %ebp
No, it might not. %ebx, %ebp, %esi, and %edi are guaranteed preserved;
%eax, %ecx and %edx are clobbered.
It's also prudent to call cld before jumping to C code.
-hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-17 5:58 ` H. Peter Anvin
@ 2008-04-18 10:57 ` Nguyen Anh Quynh
0 siblings, 0 replies; 17+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-18 10:57 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: kvm-devel
On Thu, Apr 17, 2008 at 2:58 PM, H. Peter Anvin <hpa@zytor.com> wrote:
> Nguyen Anh Quynh wrote:
>
> > This patch replaces the current assembly code of Extboot option rom
> > with new C code. Patch is against kvm-66.
> >
> > This version returns an error code in case int 13 handler cannot
> > handle a requested function.
> >
> > Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
> >
> >
>
> + /* -fomit-frame-pointer might clobber %ebp */
> + pushl %ebp
> + call setup
> + popl %ebp
>
>
> No, it might not. %ebx, %ebp, %esi, and %edi are guaranteed preserved;
> %eax, %ecx and %edx are clobbered.
>
> It's also prudent to call cld before jumping to C code.
OK, I will fix these in the next version.
Thanks,
Q
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-17 1:30 Extboot Option ROM rewritten in C - v3 Nguyen Anh Quynh
2008-04-17 5:58 ` H. Peter Anvin
@ 2008-04-17 6:00 ` H. Peter Anvin
2008-04-18 11:00 ` Nguyen Anh Quynh
2008-04-17 7:36 ` Carlo Marcelo Arenas Belon
2 siblings, 1 reply; 17+ messages in thread
From: H. Peter Anvin @ 2008-04-17 6:00 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel
> + .globl linux_boot
> +linux_boot:
> + 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
The hard use of segment 9000 is really highly unfortunate for bzImage,
since it restricts its heap more than necessary. I suggest following
the patterns used by the (new) Qemu loader.
-hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-17 6:00 ` H. Peter Anvin
@ 2008-04-18 11:00 ` Nguyen Anh Quynh
2008-04-18 12:21 ` H. Peter Anvin
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-18 11:00 UTC (permalink / raw)
To: H. Peter Anvin, Anthony Liguori; +Cc: kvm-devel
On Thu, Apr 17, 2008 at 3:00 PM, H. Peter Anvin <hpa@zytor.com> wrote:
> > + .globl linux_boot
> > +linux_boot:
> > + 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
> >
>
> The hard use of segment 9000 is really highly unfortunate for bzImage,
> since it restricts its heap more than necessary. I suggest following the
> patterns used by the (new) Qemu loader.
Actually, this code is left from the original code of Anthony, and it
seems he took it from qemu 0.8 version.
Anthony, may you explain why you want to hijact the linux boot process
here? If I understand correctly, we can just let the original int19
execute, and if linux boot is desired, it would work in normal way. So
why you want to do this?
Thanks,
Q
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 11:00 ` Nguyen Anh Quynh
@ 2008-04-18 12:21 ` H. Peter Anvin
2008-04-18 13:19 ` Anthony Liguori
2008-04-18 12:24 ` H. Peter Anvin
2008-04-18 13:19 ` Anthony Liguori
2 siblings, 1 reply; 17+ messages in thread
From: H. Peter Anvin @ 2008-04-18 12:21 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel
Nguyen Anh Quynh wrote:
>
> Actually, this code is left from the original code of Anthony, and it
> seems he took it from qemu 0.8 version.
>
> Anthony, may you explain why you want to hijact the linux boot process
> here? If I understand correctly, we can just let the original int19
> execute, and if linux boot is desired, it would work in normal way. So
> why you want to do this?
>
I'm having exactly the *opposite* question... why does extboot have code
to hook int 13h?
-hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 12:21 ` H. Peter Anvin
@ 2008-04-18 13:19 ` Anthony Liguori
0 siblings, 0 replies; 17+ messages in thread
From: Anthony Liguori @ 2008-04-18 13:19 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: kvm-devel
H. Peter Anvin wrote:
> Nguyen Anh Quynh wrote:
>>
>> Actually, this code is left from the original code of Anthony, and it
>> seems he took it from qemu 0.8 version.
>>
>> Anthony, may you explain why you want to hijact the linux boot process
>> here? If I understand correctly, we can just let the original int19
>> execute, and if linux boot is desired, it would work in normal way. So
>> why you want to do this?
>>
>
> I'm having exactly the *opposite* question... why does extboot have
> code to hook int 13h?
extboot is primarily intended to allow scsi boot or boot from a pv
disk. It hooks int13h to fake out disk access.
Regards,
Anthony Liguori
> -hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 11:00 ` Nguyen Anh Quynh
2008-04-18 12:21 ` H. Peter Anvin
@ 2008-04-18 12:24 ` H. Peter Anvin
2008-04-18 13:19 ` Anthony Liguori
2 siblings, 0 replies; 17+ messages in thread
From: H. Peter Anvin @ 2008-04-18 12:24 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel
Nguyen Anh Quynh wrote:
>
> Actually, this code is left from the original code of Anthony, and it
> seems he took it from qemu 0.8 version.
>
> Anthony, may you explain why you want to hijact the linux boot process
> here? If I understand correctly, we can just let the original int19
> execute, and if linux boot is desired, it would work in normal way. So
> why you want to do this?
>
I'm having exactly the *opposite* question... why does extboot have code
to hook int 13h?
-hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 11:00 ` Nguyen Anh Quynh
2008-04-18 12:21 ` H. Peter Anvin
2008-04-18 12:24 ` H. Peter Anvin
@ 2008-04-18 13:19 ` Anthony Liguori
2008-04-18 13:31 ` H. Peter Anvin
2008-04-18 13:56 ` Nguyen Anh Quynh
2 siblings, 2 replies; 17+ messages in thread
From: Anthony Liguori @ 2008-04-18 13:19 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel, H. Peter Anvin
Nguyen Anh Quynh wrote:
> On Thu, Apr 17, 2008 at 3:00 PM, H. Peter Anvin <hpa@zytor.com> wrote:
>
>>> + .globl linux_boot
>>> +linux_boot:
>>> + 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
>>>
>>>
>> The hard use of segment 9000 is really highly unfortunate for bzImage,
>> since it restricts its heap more than necessary. I suggest following the
>> patterns used by the (new) Qemu loader.
>>
>
> Actually, this code is left from the original code of Anthony, and it
> seems he took it from qemu 0.8 version.
>
> Anthony, may you explain why you want to hijact the linux boot process
> here? If I understand correctly, we can just let the original int19
> execute, and if linux boot is desired, it would work in normal way. So
> why you want to do this?
>
The thinking is to eliminate the need to hijack the boot sector when
using the -kernel option. However, the linux boot stuff in extboot has
been broken since hpa rewrote the boot code. It can be removed for now
and I'll eventually revisit it.
Regards,
Anthony Liguori
> Thanks,
> Q
>
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 13:19 ` Anthony Liguori
@ 2008-04-18 13:31 ` H. Peter Anvin
2008-04-18 13:56 ` Nguyen Anh Quynh
1 sibling, 0 replies; 17+ messages in thread
From: H. Peter Anvin @ 2008-04-18 13:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kvm-devel
Anthony Liguori wrote:
>
> The thinking is to eliminate the need to hijack the boot sector when
> using the -kernel option. However, the linux boot stuff in extboot has
> been broken since hpa rewrote the boot code. It can be removed for now
> and I'll eventually revisit it.
>
It probably makes more sense to have a different boot ROM for that. I
thought this was extboot, but apparently not. I probably can throw
something together.
-hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 13:19 ` Anthony Liguori
2008-04-18 13:31 ` H. Peter Anvin
@ 2008-04-18 13:56 ` Nguyen Anh Quynh
2008-04-18 14:51 ` Anthony Liguori
1 sibling, 1 reply; 17+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-18 13:56 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kvm-devel, H. Peter Anvin
On 4/18/08, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Nguyen Anh Quynh wrote:
>
> > On Thu, Apr 17, 2008 at 3:00 PM, H. Peter Anvin <hpa@zytor.com> wrote:
> >
> >
> > >
> > > > + .globl linux_boot
> > > > +linux_boot:
> > > > + 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
> > > >
> > > >
> > > >
> > > The hard use of segment 9000 is really highly unfortunate for bzImage,
> > > since it restricts its heap more than necessary. I suggest following
> the
> > > patterns used by the (new) Qemu loader.
> > >
> > >
> >
> > Actually, this code is left from the original code of Anthony, and it
> > seems he took it from qemu 0.8 version.
> >
> > Anthony, may you explain why you want to hijact the linux boot process
> > here? If I understand correctly, we can just let the original int19
> > execute, and if linux boot is desired, it would work in normal way. So
> > why you want to do this?
> >
> >
>
> The thinking is to eliminate the need to hijack the boot sector when using
> the -kernel option.
I see, but does that offer any advantage over the current approach?
Thanks,
Q
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 13:56 ` Nguyen Anh Quynh
@ 2008-04-18 14:51 ` Anthony Liguori
2008-04-18 14:50 ` H. Peter Anvin
2008-04-18 15:02 ` Nguyen Anh Quynh
0 siblings, 2 replies; 17+ messages in thread
From: Anthony Liguori @ 2008-04-18 14:51 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel, H. Peter Anvin
Nguyen Anh Quynh wrote:
>>
>> The thinking is to eliminate the need to hijack the boot sector when using
>> the -kernel option.
>>
>
> I see, but does that offer any advantage over the current approach?
>
You no longer have to specify a -hda option when using -kernel.
Regards,
Anthony Liguori
> Thanks,
> Q
>
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 14:51 ` Anthony Liguori
@ 2008-04-18 14:50 ` H. Peter Anvin
2008-04-18 15:02 ` Nguyen Anh Quynh
1 sibling, 0 replies; 17+ messages in thread
From: H. Peter Anvin @ 2008-04-18 14:50 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kvm-devel
Anthony Liguori wrote:
> Nguyen Anh Quynh wrote:
>>>
>>> The thinking is to eliminate the need to hijack the boot sector when
>>> using
>>> the -kernel option.
>>>
>>
>> I see, but does that offer any advantage over the current approach?
>>
>
> You no longer have to specify a -hda option when using -kernel.
>
Plus, you don't have funny side effects if you do -- and I suspect there
is ad hoc code in the disk driver which can be removed.
-hpa
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-18 14:51 ` Anthony Liguori
2008-04-18 14:50 ` H. Peter Anvin
@ 2008-04-18 15:02 ` Nguyen Anh Quynh
2008-04-18 15:19 ` Anthony Liguori
1 sibling, 1 reply; 17+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-18 15:02 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kvm-devel
On 4/18/08, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Nguyen Anh Quynh wrote:
>
> >
> > >
> > > The thinking is to eliminate the need to hijack the boot sector when
> using
> > > the -kernel option.
> > >
> > >
> >
> > I see, but does that offer any advantage over the current approach?
> >
> >
>
> You no longer have to specify a -hda option when using -kernel.
Without -hda, how can we load disk image? Or you mean you only want to
test the kernel?
Thanks,
Q
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-17 1:30 Extboot Option ROM rewritten in C - v3 Nguyen Anh Quynh
2008-04-17 5:58 ` H. Peter Anvin
2008-04-17 6:00 ` H. Peter Anvin
@ 2008-04-17 7:36 ` Carlo Marcelo Arenas Belon
2008-04-18 11:01 ` Nguyen Anh Quynh
2 siblings, 1 reply; 17+ messages in thread
From: Carlo Marcelo Arenas Belon @ 2008-04-17 7:36 UTC (permalink / raw)
To: Nguyen Anh Quynh; +Cc: kvm-devel
On Thu, Apr 17, 2008 at 10:30:27AM +0900, Nguyen Anh Quynh wrote:
+++ b/extboot/farvar.h
@@ -0,0 +1,113 @@
+// Code to access multiple segments within gcc.
+//
+// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
IANAL but wouldn't this make extboot GPLv3 only? how that will interact
with the GPLv2 extboot qemu?
Carlo
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Extboot Option ROM rewritten in C - v3
2008-04-17 7:36 ` Carlo Marcelo Arenas Belon
@ 2008-04-18 11:01 ` Nguyen Anh Quynh
0 siblings, 0 replies; 17+ messages in thread
From: Nguyen Anh Quynh @ 2008-04-18 11:01 UTC (permalink / raw)
To: Carlo Marcelo Arenas Belon; +Cc: kvm-devel
On Thu, Apr 17, 2008 at 4:36 PM, Carlo Marcelo Arenas Belon
<carenas@sajinet.com.pe> wrote:
> On Thu, Apr 17, 2008 at 10:30:27AM +0900, Nguyen Anh Quynh wrote:
>
> +++ b/extboot/farvar.h
> @@ -0,0 +1,113 @@
> +// Code to access multiple segments within gcc.
> +//
> +// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
> +//
> +// This file may be distributed under the terms of the GNU GPLv3 license.
>
> IANAL but wouldn't this make extboot GPLv3 only? how that will interact
> with the GPLv2 extboot qemu?
I am not sure if that is fine, but it might be better to have the same
license for every code. I will contact Kevin when the next version is
ready (I am still fixing something)
Thanks,
Q
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-04-18 15:19 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-17 1:30 Extboot Option ROM rewritten in C - v3 Nguyen Anh Quynh
2008-04-17 5:58 ` H. Peter Anvin
2008-04-18 10:57 ` Nguyen Anh Quynh
2008-04-17 6:00 ` H. Peter Anvin
2008-04-18 11:00 ` Nguyen Anh Quynh
2008-04-18 12:21 ` H. Peter Anvin
2008-04-18 13:19 ` Anthony Liguori
2008-04-18 12:24 ` H. Peter Anvin
2008-04-18 13:19 ` Anthony Liguori
2008-04-18 13:31 ` H. Peter Anvin
2008-04-18 13:56 ` Nguyen Anh Quynh
2008-04-18 14:51 ` Anthony Liguori
2008-04-18 14:50 ` H. Peter Anvin
2008-04-18 15:02 ` Nguyen Anh Quynh
2008-04-18 15:19 ` Anthony Liguori
2008-04-17 7:36 ` Carlo Marcelo Arenas Belon
2008-04-18 11:01 ` 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