[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Add stubdomain support. See stubdom/README for usage details.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1202826939 0 # Node ID a905c582a406f60cf44a8884843129c085b18a30 # Parent 88818d55e95a75f666839f38158488783245da87 Add stubdomain support. See stubdom/README for usage details. - Move PAGE_SIZE and STACK_SIZE into __PAGE_SIZE and __STACK_SIZE in arch_limits.h so as to permit getting them from there without pulling all the internal Mini-OS defines. - Setup a xen-elf cross-compilation environment in stubdom/cross-root - Add a POSIX layer on top of Mini-OS by linking against the newlib C library and lwIP, and implementing the Unixish part in mini-os/lib/sys.c - Cross-compile zlib and libpci too. - Add an xs.h-compatible layer on top of Mini-OS' xenbus. - Cross-compile libxc with an additional xc_minios.c and a few things disabled. - Cross-compile ioemu with an additional block-vbd, but without sound, tpm and other details. A few hacks are needed: - Align ide and scsi buffers at least on sector size to permit direct transmission to the block backend. While we are at it, just page-align it to possibly save a segment. Also, limit the scsi buffer size because of limitations of the block paravirtualization protocol. - Allocate big tables dynamically rather that letting them go to bss: when Mini-OS gets installed in memory, bss is not lazily allocated, and doing so during Mini-OS is unnecessarily trick while we can simply use malloc. - Had to change the Mini-OS compilation somehow, so as to export Mini-OS compilation flags to the Makefiles of libxc and ioemu. Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx> --- .hgignore | 11 Config.mk | 8 extras/mini-os/Config.mk | 76 ++ extras/mini-os/Makefile | 81 -- extras/mini-os/arch/ia64/Makefile | 4 extras/mini-os/arch/ia64/minios-ia64.lds | 12 extras/mini-os/arch/ia64/mm.c | 8 extras/mini-os/arch/x86/Makefile | 3 extras/mini-os/arch/x86/arch.mk | 8 extras/mini-os/arch/x86/minios-x86_32.lds | 12 extras/mini-os/arch/x86/minios-x86_64.lds | 12 extras/mini-os/arch/x86/mm.c | 17 extras/mini-os/arch/x86/x86_32.S | 6 extras/mini-os/arch/x86/x86_64.S | 6 extras/mini-os/blkfront.c | 48 + extras/mini-os/include/arch/cc.h | 7 extras/mini-os/include/byteswap.h | 22 extras/mini-os/include/console.h | 3 extras/mini-os/include/errno.h | 7 extras/mini-os/include/fcntl.h | 3 extras/mini-os/include/fs.h | 1 extras/mini-os/include/ia64/arch_limits.h | 12 extras/mini-os/include/ia64/arch_mm.h | 4 extras/mini-os/include/ia64/page.h | 6 extras/mini-os/include/lib.h | 59 + extras/mini-os/include/linux/types.h | 5 extras/mini-os/include/mm.h | 8 extras/mini-os/include/netfront.h | 4 extras/mini-os/include/posix/dirent.h | 24 extras/mini-os/include/posix/limits.h | 9 extras/mini-os/include/posix/netdb.h | 9 extras/mini-os/include/posix/netinet/in.h | 7 extras/mini-os/include/posix/netinet/tcp.h | 6 extras/mini-os/include/posix/pthread.h | 19 extras/mini-os/include/posix/stdlib.h | 8 extras/mini-os/include/posix/strings.h | 8 extras/mini-os/include/posix/sys/ioctl.h | 16 extras/mini-os/include/posix/sys/mman.h | 19 extras/mini-os/include/posix/sys/select.h | 7 extras/mini-os/include/posix/sys/socket.h | 31 extras/mini-os/include/posix/termios.h | 87 ++ extras/mini-os/include/posix/time.h | 10 extras/mini-os/include/posix/unistd.h | 12 extras/mini-os/include/sched.h | 3 extras/mini-os/include/sys/time.h | 4 extras/mini-os/include/time.h | 11 extras/mini-os/include/x86/arch_limits.h | 20 extras/mini-os/include/x86/arch_mm.h | 22 extras/mini-os/include/x86/arch_sched.h | 4 extras/mini-os/include/x86/arch_spinlock.h | 1 extras/mini-os/include/x86/os.h | 1 extras/mini-os/lib/sys.c | 1083 +++++++++++++++++++++++++++++ extras/mini-os/lib/xs.c | 187 +++++ extras/mini-os/main-caml.c | 42 + extras/mini-os/main.c | 167 ++++ extras/mini-os/minios.mk | 13 extras/mini-os/mm.c | 23 extras/mini-os/netfront.c | 98 ++ extras/mini-os/sched.c | 44 + stubdom/Makefile | 256 ++++++ stubdom/README | 41 + stubdom/caml/Makefile | 18 stubdom/caml/hello.ml | 4 stubdom/libpci.config.h | 5 stubdom/libpci.config.mak | 2 stubdom/stubdom-dm | 97 ++ tools/ioemu/Makefile.target | 42 - tools/ioemu/aes.c | 2 tools/ioemu/block-vbd.c | 341 +++++++++ tools/ioemu/block.c | 3 tools/ioemu/configure | 22 tools/ioemu/exec-all.h | 4 tools/ioemu/hw/ide.c | 4 tools/ioemu/hw/scsi-disk.c | 8 tools/ioemu/hw/xen_machine_fv.c | 3 tools/ioemu/vl.c | 69 + tools/ioemu/vl.h | 3 tools/ioemu/vnc.c | 21 tools/ioemu/xenstore.c | 19 tools/libxc/Makefile | 23 tools/libxc/ia64/Makefile | 2 tools/libxc/xc_minios.c | 313 ++++++++ 82 files changed, 3616 insertions(+), 134 deletions(-) diff -r 88818d55e95a -r a905c582a406 .hgignore --- a/.hgignore Tue Feb 12 11:37:45 2008 +0000 +++ b/.hgignore Tue Feb 12 14:35:39 2008 +0000 @@ -80,6 +80,17 @@ ^pristine-.*$ ^ref-.*$ ^tmp-.*$ +^stubdom/binutils.*$ +^stubdom/cross-root.*$ +^stubdom/gcc.*$ +^stubdom/include.*$ +^stubdom/ioemu.*$ +^stubdom/libxc.*$ +^stubdom/lwip.*$ +^stubdom/mini-os.*$ +^stubdom/newlib.*$ +^stubdom/pciutils.*$ +^stubdom/zlib.*$ ^tools/.*/TAGS$ ^tools/.*/build/lib.*/.*\.py$ ^tools/blktap/Makefile\.smh$ diff -r 88818d55e95a -r a905c582a406 Config.mk --- a/Config.mk Tue Feb 12 11:37:45 2008 +0000 +++ b/Config.mk Tue Feb 12 14:35:39 2008 +0000 @@ -27,6 +27,14 @@ DESTDIR ?= / include $(XEN_ROOT)/config/$(XEN_OS).mk include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk + +ifeq ($(stubdom),y) +include $(XEN_ROOT)/extras/mini-os/Config.mk +CFLAGS += $(DEF_CFLAGS) $(ARCH_CFLAGS) +CPPFLAGS += $(DEF_CPPFLAGS) $(ARCH_CPPFLAGS) $(extra_incl) +ASFLAGS += $(DEF_ASFLAGS) $(ARCH_ASFLAGS) +LDFLAGS += $(DEF_LDFLAGS) $(ARCH_LDFLAGS) +endif ifneq ($(EXTRA_PREFIX),) EXTRA_INCLUDES += $(EXTRA_PREFIX)/include diff -r 88818d55e95a -r a905c582a406 extras/mini-os/Config.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/Config.mk Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,76 @@ +# Set mini-os root path, used in mini-os.mk. +MINI-OS_ROOT=$(XEN_ROOT)/extras/mini-os +export MINI-OS_ROOT + +ifeq ($(XEN_TARGET_ARCH),x86_32) +export pae ?= y +endif +libc = $(stubdom) + +XEN_INTERFACE_VERSION := 0x00030205 +export XEN_INTERFACE_VERSION + +# Try to find out the architecture family TARGET_ARCH_FAM. +# First check whether x86_... is contained (for x86_32, x86_32y, x86_64). +# If not x86 then use $(XEN_TARGET_ARCH) -> for ia64, ... +ifeq ($(findstring x86_,$(XEN_TARGET_ARCH)),x86_) +TARGET_ARCH_FAM = x86 +else +TARGET_ARCH_FAM = $(XEN_TARGET_ARCH) +endif + +# The architecture family directory below mini-os. +TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM) + +# Export these variables for possible use in architecture dependent makefiles. +export TARGET_ARCH_DIR +export TARGET_ARCH_FAM +export XEN_TARGET_X86_PAE + +# This is used for architecture specific links. +# This can be overwritten from arch specific rules. +ARCH_LINKS = + +# The path pointing to the architecture specific header files. +ARCH_INC := $(TARGET_ARCH_FAM) + +# For possible special header directories. +# This can be overwritten from arch specific rules. +EXTRA_INC = $(ARCH_INC) + +# Include the architecture family's special makerules. +# This must be before include minios.mk! +include $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk + +extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir)) + +DEF_CPPFLAGS += -I$(MINI-OS_ROOT)/include + +ifeq ($(stubdom),y) +DEF_CPPFLAGS += -DCONFIG_STUBDOM +endif + +ifeq ($(libc),y) +DEF_CPPFLAGS += -DHAVE_LIBC +DEF_CPPFLAGS += -I$(MINI-OS_ROOT)/include/posix +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore +endif + +ifneq ($(LWIPDIR),) +lwip=y +DEF_CPPFLAGS += -DHAVE_LWIP +DEF_CPPFLAGS += -I$(LWIPDIR)/src/include +DEF_CPPFLAGS += -I$(LWIPDIR)/src/include/ipv4 +endif + +ifneq ($(QEMUDIR),) +qemu=y +endif + +ifneq ($(CAMLDIR),) +caml=y +endif + +ifeq ($(pae),y) +DEF_CPPFLAGS += -DCONFIG_X86_PAE +endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/Makefile --- a/extras/mini-os/Makefile Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -4,54 +4,11 @@ # Makefile and a arch.mk. # -XEN_ROOT = ../.. +export XEN_ROOT = ../.. include $(XEN_ROOT)/Config.mk -XEN_INTERFACE_VERSION := 0x00030205 -export XEN_INTERFACE_VERSION - -# Set TARGET_ARCH -override TARGET_ARCH := $(XEN_TARGET_ARCH) - -# Set mini-os root path, used in mini-os.mk. -MINI-OS_ROOT=$(PWD) -export MINI-OS_ROOT - -# Try to find out the architecture family TARGET_ARCH_FAM. -# First check whether x86_... is contained (for x86_32, x86_32y, x86_64). -# If not x86 then use $(TARGET_ARCH) -> for ia64, ... -ifeq ($(findstring x86_,$(TARGET_ARCH)),x86_) -TARGET_ARCH_FAM = x86 -else -TARGET_ARCH_FAM = $(TARGET_ARCH) -endif - -# The architecture family directory below mini-os. -TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM) - -# Export these variables for possible use in architecture dependent makefiles. -export TARGET_ARCH -export TARGET_ARCH_DIR -export TARGET_ARCH_FAM -export XEN_TARGET_X86_PAE - -# This is used for architecture specific links. -# This can be overwritten from arch specific rules. -ARCH_LINKS = - -# For possible special header directories. -# This can be overwritten from arch specific rules. -EXTRA_INC = - -# Include the architecture family's special makerules. -# This must be before include minios.mk! -include $(TARGET_ARCH_DIR)/arch.mk - -ifneq ($(LWIPDIR),) -lwip=y -DEF_CFLAGS += -DHAVE_LWIP -DEF_CFLAGS += -I$(LWIPDIR)/src/include -DEF_CFLAGS += -I$(LWIPDIR)/src/include/ipv4 +ifneq ($(stubdom),y) +include Config.mk endif # Include common mini-os makerules. @@ -63,7 +20,7 @@ include minios.mk # Define some default flags for linking. LDLIBS := LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME) -LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds +LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(XEN_TARGET_ARCH).lds # Prefix for global API names. All other symbols are localised before # linking with EXTRA_OBJS. @@ -112,14 +69,38 @@ lwip.a: $(LWO) $(AR) cqs $@ $^ OBJS += lwip.a +endif -OBJS := $(filter-out $(LWO), $(OBJS)) +OBJS := $(filter-out lwip%.o $(LWO), $(OBJS)) + +ifeq ($(caml),y) +CAMLLIB = $(shell ocamlc -where) +OBJS += $(CAMLDIR)/caml.o +OBJS += $(CAMLLIB)/libasmrun.a +CFLAGS += -I$(CAMLLIB) +LDLIBS += -lm else -OBJS := $(filter-out daytime.o lwip%.o, $(OBJS)) +OBJS := $(filter-out main-caml.o, $(OBJS)) +endif + +ifeq ($(qemu),y) +OBJS += $(QEMUDIR)/i386-dm-stubdom/qemu.a $(QEMUDIR)/i386-dm-stubdom/libqemu.a +CFLAGS += -DCONFIG_QEMU +endif + +ifeq ($(libc),y) +LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -lxenctrl -lxenguest +LDLIBS += -lpci +LDLIBS += -lz +LDLIBS += -lc +endif + +ifneq ($(caml)-$(qemu)-$(lwip),--y) +OBJS := $(filter-out daytime.o, $(OBJS)) endif $(TARGET): links $(OBJS) arch_lib - $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o + $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@ gzip -f -9 -c $@ >$@.gz diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/ia64/Makefile --- a/extras/mini-os/arch/ia64/Makefile Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/ia64/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -4,6 +4,8 @@ XEN_ROOT = ../../../.. include $(XEN_ROOT)/Config.mk + +include ../../Config.mk include arch.mk include ../../minios.mk @@ -41,7 +43,7 @@ ARCH_OBJS += __divdi3.o GEN_OFF_SRC := gen_off.c GEN_OFF_ASM := gen_off.s -GEN_OFF_H := $(ARCH_INC)/offsets.h +GEN_OFF_H := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h all: $(ARCH_LIB) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/ia64/minios-ia64.lds --- a/extras/mini-os/arch/ia64/minios-ia64.lds Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/ia64/minios-ia64.lds Tue Feb 12 14:35:39 2008 +0000 @@ -40,6 +40,18 @@ SECTIONS .rodata.str1.8 : AT(ADDR(.rodata.str1.8) - (((5<<(61))+0x100000000) - (1 << 20))) { *(.rodata.str1.8) } + /* newlib initialization functions */ + . = ALIGN(64 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); + .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - (((5<<(61))+0x100000000) - (1 << 20))) { *(.IA_64.unwind_info) } diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/ia64/mm.c --- a/extras/mini-os/arch/ia64/mm.c Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/ia64/mm.c Tue Feb 12 14:35:39 2008 +0000 @@ -42,6 +42,14 @@ extern uint64_t _text[], _etext[], _end[ extern uint64_t _text[], _etext[], _end[], kstack[], phys_start[]; uint64_t kernstart, kernend, kernsize, kernpstart, kernpend; + +#ifdef HAVE_LIBC +uint8_t _heap[512 * 1024]; +unsigned long heap = (unsigned long)_heap, + brk = (unsigned long)_heap, + heap_mapped = (unsigned long)_heap + sizeof(_heap), + heap_end = (unsigned long)_heap + sizeof(_heap); +#endif /* Print the available memory chunks. */ static void diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/Makefile --- a/extras/mini-os/arch/x86/Makefile Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -5,13 +5,14 @@ XEN_ROOT = ../../../.. include $(XEN_ROOT)/Config.mk +include ../../Config.mk # include arch.mk has to be before mini-os.mk! include arch.mk include ../../minios.mk -# Sources here are all *.c *.S without $(TARGET_ARCH).S +# Sources here are all *.c *.S without $(XEN_TARGET_ARCH).S # This is handled in $(HEAD_ARCH_OBJ) ARCH_SRCS := $(wildcard *.c) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/arch.mk --- a/extras/mini-os/arch/x86/arch.mk Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/arch.mk Tue Feb 12 14:35:39 2008 +0000 @@ -3,11 +3,11 @@ # (including x86_32, x86_32y and x86_64). # -ifeq ($(TARGET_ARCH),x86_32) +ifeq ($(XEN_TARGET_ARCH),x86_32) ARCH_CFLAGS := -m32 -march=i686 ARCH_LDFLAGS := -m elf_i386 ARCH_ASFLAGS := -m32 -EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) +EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH) EXTRA_SRC += arch/$(EXTRA_INC) ifeq ($(XEN_TARGET_X86_PAE),y) @@ -16,12 +16,12 @@ endif endif endif -ifeq ($(TARGET_ARCH),x86_64) +ifeq ($(XEN_TARGET_ARCH),x86_64) ARCH_CFLAGS := -m64 -mno-red-zone -fno-reorder-blocks ARCH_CFLAGS += -fno-asynchronous-unwind-tables ARCH_ASFLAGS := -m64 ARCH_LDFLAGS := -m elf_x86_64 -EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH) +EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH) EXTRA_SRC += arch/$(EXTRA_INC) endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/minios-x86_32.lds --- a/extras/mini-os/arch/x86/minios-x86_32.lds Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/minios-x86_32.lds Tue Feb 12 14:35:39 2008 +0000 @@ -15,6 +15,18 @@ SECTIONS .rodata : { *(.rodata) *(.rodata.*) } . = ALIGN(4096); _erodata = .; + + /* newlib initialization functions */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); .data : { /* Data */ *(.data) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/minios-x86_64.lds --- a/extras/mini-os/arch/x86/minios-x86_64.lds Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/minios-x86_64.lds Tue Feb 12 14:35:39 2008 +0000 @@ -15,6 +15,18 @@ SECTIONS .rodata : { *(.rodata) *(.rodata.*) } . = ALIGN(4096); _erodata = .; + + /* newlib initialization functions */ + . = ALIGN(64 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); .data : { /* Data */ *(.data) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/mm.c --- a/extras/mini-os/arch/x86/mm.c Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/mm.c Tue Feb 12 14:35:39 2008 +0000 @@ -448,6 +448,15 @@ static unsigned long demand_map_area_sta #define DEMAND_MAP_PAGES ((2ULL << 30) / PAGE_SIZE) #endif +#ifdef HAVE_LIBC +unsigned long heap, brk, heap_mapped, heap_end; +#ifdef __x86_64__ +#define HEAP_PAGES ((128ULL << 30) / PAGE_SIZE) +#else +#define HEAP_PAGES ((1ULL << 30) / PAGE_SIZE) +#endif +#endif + void arch_init_demand_mapping_area(unsigned long cur_pfn) { cur_pfn++; @@ -455,6 +464,14 @@ void arch_init_demand_mapping_area(unsig demand_map_area_start = (unsigned long) pfn_to_virt(cur_pfn); cur_pfn += DEMAND_MAP_PAGES; printk("Demand map pfns at %lx-%lx.\n", demand_map_area_start, pfn_to_virt(cur_pfn)); + +#ifdef HAVE_LIBC + cur_pfn++; + heap_mapped = brk = heap = (unsigned long) pfn_to_virt(cur_pfn); + cur_pfn += HEAP_PAGES; + heap_end = (unsigned long) pfn_to_virt(cur_pfn); + printk("Heap resides at %lx-%lx.\n", brk, heap_end); +#endif } #define MAP_BATCH ((STACK_SIZE / 2) / sizeof(mmu_update_t)) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/x86_32.S --- a/extras/mini-os/arch/x86/x86_32.S Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/x86_32.S Tue Feb 12 14:35:39 2008 +0000 @@ -1,5 +1,5 @@ #include <os.h> -#include <arch_mm.h> +#include <arch_limits.h> #include <xen/arch-x86_32.h> .section __xen_guest @@ -22,12 +22,12 @@ _start: _start: cld lss stack_start,%esp - andl $(~(STACK_SIZE-1)), %esp + andl $(~(__STACK_SIZE-1)), %esp push %esi call start_kernel stack_start: - .long stack+(2*STACK_SIZE), __KERNEL_SS + .long stack+(2*__STACK_SIZE), __KERNEL_SS /* Unpleasant -- the PTE that maps this page is actually overwritten */ /* to map the real shared-info page! :-) */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/arch/x86/x86_64.S --- a/extras/mini-os/arch/x86/x86_64.S Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/arch/x86/x86_64.S Tue Feb 12 14:35:39 2008 +0000 @@ -1,5 +1,5 @@ #include <os.h> -#include <arch_mm.h> +#include <arch_limits.h> #include <xen/features.h> .section __xen_guest @@ -19,12 +19,12 @@ _start: _start: cld movq stack_start(%rip),%rsp - andq $(~(STACK_SIZE-1)), %rsp + andq $(~(__STACK_SIZE-1)), %rsp movq %rsi,%rdi call start_kernel stack_start: - .quad stack+(2*STACK_SIZE) + .quad stack+(2*__STACK_SIZE) /* Unpleasant -- the PTE that maps this page is actually overwritten */ /* to map the real shared-info page! :-) */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/blkfront.c --- a/extras/mini-os/blkfront.c Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/blkfront.c Tue Feb 12 14:35:39 2008 +0000 @@ -15,6 +15,10 @@ #include <lib.h> #include <fcntl.h> +#ifndef HAVE_LIBC +#define strtoul simple_strtoul +#endif + /* Note: we generally don't need to disable IRQs since we hardly do anything in * the interrupt handler. */ @@ -49,6 +53,10 @@ struct blkfront_dev { int mode; int barrier; int flush; + +#ifdef HAVE_LIBC + int fd; +#endif }; static inline int xenblk_rxidx(RING_IDX idx) @@ -58,6 +66,12 @@ static inline int xenblk_rxidx(RING_IDX void blkfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { +#ifdef HAVE_LIBC + struct blkfront_dev *dev = data; + int fd = dev->fd; + + files[fd].read = 1; +#endif wake_up(&blkfront_queue); } @@ -148,7 +162,7 @@ done: printk("backend at %s\n", dev->backend); - dev->handle = simple_strtoul(strrchr(nodename, '/')+1, NULL, 0); + dev->handle = strtoul(strrchr(nodename, '/')+1, NULL, 0); { char path[strlen(dev->backend) + 1 + 19 + 1]; @@ -322,12 +336,16 @@ moretodo: { rsp = RING_GET_RESPONSE(&dev->ring, cons); + if (rsp->status != BLKIF_RSP_OKAY) + printk("block error %d for op %d\n", rsp->status, rsp->operation); + switch (rsp->operation) { case BLKIF_OP_READ: case BLKIF_OP_WRITE: { struct blkfront_aiocb *aiocbp = (void*) (uintptr_t) rsp->id; int j; + for (j = 0; j < aiocbp->n; j++) gnttab_end_access(aiocbp->gref[j]); @@ -365,6 +383,12 @@ static void blkfront_push_operation(stru i = dev->ring.req_prod_pvt; req = RING_GET_REQUEST(&dev->ring, i); req->operation = op; + req->nr_segments = 0; + req->handle = dev->handle; + /* Not used */ + req->id = 0; + /* Not needed anyway, but the backend will check it */ + req->sector_number = 0; dev->ring.req_prod_pvt = i + 1; wmb(); RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->ring, notify); @@ -375,11 +399,13 @@ void blkfront_sync(struct blkfront_dev * { unsigned long flags; - if (dev->barrier == 1) - blkfront_push_operation(dev, BLKIF_OP_WRITE_BARRIER); - - if (dev->flush == 1) - blkfront_push_operation(dev, BLKIF_OP_FLUSH_DISKCACHE); + if (dev->mode == O_RDWR) { + if (dev->barrier == 1) + blkfront_push_operation(dev, BLKIF_OP_WRITE_BARRIER); + + if (dev->flush == 1) + blkfront_push_operation(dev, BLKIF_OP_FLUSH_DISKCACHE); + } /* Note: This won't finish if another thread enqueues requests. */ local_irq_save(flags); @@ -397,3 +423,13 @@ void blkfront_sync(struct blkfront_dev * remove_waiter(w); local_irq_restore(flags); } + +#ifdef HAVE_LIBC +int blkfront_open(struct blkfront_dev *dev) +{ + dev->fd = alloc_fd(FTYPE_BLK); + printk("blk_open(%s) -> %d\n", dev->nodename, dev->fd); + files[dev->fd].blk.dev = dev; + return dev->fd; +} +#endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/arch/cc.h --- a/extras/mini-os/include/arch/cc.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/arch/cc.h Tue Feb 12 14:35:39 2008 +0000 @@ -54,7 +54,14 @@ extern void lwip_die(char *fmt, ...); #include <errno.h> /* Not required by the docs, but needed for network-order calculations */ +#ifdef HAVE_LIBC +#include <machine/endian.h> +#ifndef BIG_ENDIAN +#error endian.h does not define byte order +#endif +#else #include <endian.h> +#endif #include <inttypes.h> #define S16_F PRIi16 diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/byteswap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/byteswap.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,22 @@ +#ifndef _BYTESWAP_H_ +#define _BYTESWAP_H_ + +/* Unfortunately not provided by newlib. */ +#define bswap_16(x) \ + ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8)) + +#define bswap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#define bswap_64(x) \ + ((((x) & 0xff00000000000000ULL) >> 56) | \ + (((x) & 0x00ff000000000000ULL) >> 40) | \ + (((x) & 0x0000ff0000000000ULL) >> 24) | \ + (((x) & 0x000000ff00000000ULL) >> 8) | \ + (((x) & 0x00000000ff000000ULL) << 8) | \ + (((x) & 0x0000000000ff0000ULL) << 24) | \ + (((x) & 0x000000000000ff00ULL) << 40) | \ + (((x) & 0x00000000000000ffULL) << 56)) + +#endif /* _BYTESWAP_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/console.h --- a/extras/mini-os/include/console.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/console.h Tue Feb 12 14:35:39 2008 +0000 @@ -36,7 +36,9 @@ #ifndef _LIB_CONSOLE_H_ #define _LIB_CONSOLE_H_ +#include<os.h> #include<traps.h> +#include<stdarg.h> void print(int direct, const char *fmt, va_list args); void printk(const char *fmt, ...); @@ -48,5 +50,6 @@ void xencons_tx(void); void xencons_tx(void); void init_console(void); +void console_print(char *data, int length); #endif /* _LIB_CONSOLE_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/errno.h --- a/extras/mini-os/include/errno.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/errno.h Tue Feb 12 14:35:39 2008 +0000 @@ -107,4 +107,11 @@ #define EOWNERDEAD 130 /* Owner died */ #define ENOTRECOVERABLE 131 /* State not recoverable */ +#ifdef HAVE_LIBC +#include <sched.h> +extern int errno; +#define ERRNO +#define errno (get_current()->reent._errno) #endif + +#endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/fcntl.h --- a/extras/mini-os/include/fcntl.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/fcntl.h Tue Feb 12 14:35:39 2008 +0000 @@ -86,4 +86,7 @@ struct flock64 { #define F_LINUX_SPECIFIC_BASE 1024 */ + +int open(const char *path, int flags, ...); +int fcntl(int fd, int cmd, ...); #endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/fs.h --- a/extras/mini-os/include/fs.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/fs.h Tue Feb 12 14:35:39 2008 +0000 @@ -22,6 +22,7 @@ struct fs_import struct semaphore reqs_sem; /* Accounts requests resource */ }; +extern struct fs_import *fs_import; void init_fs_frontend(void); diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/ia64/arch_limits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/ia64/arch_limits.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,12 @@ + +#ifndef __ARCH_LIMITS_H__ +#define __ARCH_LIMITS_H__ + +/* Commonly 16K pages are used. */ +#define __PAGE_SHIFT 14 /* 16K pages */ +#define __PAGE_SIZE (1<<(__PAGE_SHIFT)) + +#define __STACK_SIZE_PAGE_ORDER 2 +#define __STACK_SIZE (__PAGE_SIZE * (1 << __STACK_SIZE_PAGE_ORDER)) + +#endif /* __ARCH_LIMITS_H__ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/ia64/arch_mm.h --- a/extras/mini-os/include/ia64/arch_mm.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/ia64/arch_mm.h Tue Feb 12 14:35:39 2008 +0000 @@ -35,11 +35,9 @@ #define virt_to_mfn(x) virt_to_pfn(x) #define virtual_to_mfn(x) (ia64_tpa((uint64_t)(x)) >> PAGE_SHIFT) -#define STACK_SIZE_PAGE_ORDER 1 -#define STACK_SIZE (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER)) - #define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, 0) /* TODO */ #define map_zero(n, a) map_frames_ex(NULL, n, 0, 0, a, DOMID_SELF, 0, 0) +#define do_map_zero(start, n) ((void)0) #endif /* __ARCH_MM_H__ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/ia64/page.h --- a/extras/mini-os/include/ia64/page.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/ia64/page.h Tue Feb 12 14:35:39 2008 +0000 @@ -43,9 +43,9 @@ /* The efi-pal page size for text and data. */ #define PAL_TR_PAGE_SIZE PTE_PS_1M -/* Commonly 16K pages are used. */ -#define PAGE_SHIFT 14 /* 16K pages */ -#define PAGE_SIZE (1<<(PAGE_SHIFT)) +#include "arch_limits.h" +#define PAGE_SHIFT __PAGE_SHIFT +#define PAGE_SIZE __PAGE_SIZE #define PAGE_MASK (~(PAGE_SIZE-1)) #define KSTACK_PAGES 4 /* 4 pages for the kernel stack + bsp */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/lib.h --- a/extras/mini-os/include/lib.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/lib.h Tue Feb 12 14:35:39 2008 +0000 @@ -57,6 +57,8 @@ #include <stdarg.h> #include <stddef.h> +#include <xen/xen.h> +#include <xen/event_channel.h> #ifdef HAVE_LIBC #include <stdio.h> @@ -103,6 +105,8 @@ char *strdup(const char *s); int rand(void); +#include <xenbus.h> + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) struct kvec { @@ -126,4 +130,59 @@ do { /* Consistency check as much as possible. */ void sanity_check(void); +#ifdef HAVE_LIBC +enum fd_type { + FTYPE_NONE = 0, + FTYPE_CONSOLE, + FTYPE_FILE, + FTYPE_XENBUS, + FTYPE_EVTCHN, + FTYPE_SOCKET, + FTYPE_TAP, + FTYPE_BLK, +}; + +#define MAX_EVTCHN_PORTS 16 + +extern struct file { + enum fd_type type; + union { + struct { + /* lwIP fd */ + int fd; + } socket; + struct { + /* FS import fd */ + int fd; + off_t offset; + } file; + struct { + /* To each event channel FD is associated a series of ports which + * wakes select for this FD. */ + struct { + evtchn_port_t port; + volatile unsigned long pending; + int bound; + } ports[MAX_EVTCHN_PORTS]; + } evtchn; + struct { + struct netfront_dev *dev; + } tap; + struct { + struct blkfront_dev *dev; + } blk; + struct { + /* To each xenbus FD is associated a queue of watch events for this + * FD. */ + struct xenbus_event *volatile events; + } xenbus; + }; + volatile int read; /* maybe available for read */ +} files[]; + +int alloc_fd(enum fd_type type); +void close_all_files(void); +extern struct thread *main_thread; +#endif + #endif /* _LIB_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/linux/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/linux/types.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,5 @@ +#ifndef _LINUX_TYPES_H_ +#define _LINUX_TYPES_H_ +#include <types.h> +typedef u64 __u64; +#endif /* _LINUX_TYPES_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/mm.h --- a/extras/mini-os/include/mm.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/mm.h Tue Feb 12 14:35:39 2008 +0000 @@ -36,7 +36,12 @@ #endif #include <lib.h> + +#include <arch_limits.h> #include <arch_mm.h> + +#define STACK_SIZE_PAGE_ORDER __STACK_SIZE_PAGE_ORDER +#define STACK_SIZE __STACK_SIZE void init_mm(void); @@ -61,5 +66,8 @@ void *map_frames_ex(unsigned long *f, un void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride, unsigned long increment, unsigned long alignment, domid_t id, int may_fail, unsigned long prot); +#ifdef HAVE_LIBC +extern unsigned long heap, brk, heap_mapped, heap_end; +#endif #endif /* _MM_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/netfront.h --- a/extras/mini-os/include/netfront.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/netfront.h Tue Feb 12 14:35:39 2008 +0000 @@ -6,6 +6,10 @@ struct netfront_dev *init_netfront(char struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned char *data, int len), unsigned char rawmac[6]); void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len); void shutdown_netfront(struct netfront_dev *dev); +#ifdef HAVE_LIBC +int netfront_tap_open(char *nodename); +ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len); +#endif extern struct wait_queue_head netfront_queue; diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/dirent.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/dirent.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,24 @@ +#ifndef _POSIX_DIRENT_H +#define _POSIX_DIRENT_H + +#include <sys/types.h> + +struct dirent { + char *d_name; +}; + +typedef struct { + struct dirent dirent; + char *name; + int32_t offset; + char **entries; + int32_t curentry; + int32_t nbentries; + int has_more; +} DIR; + +DIR *opendir(const char *name); +struct dirent *readdir(DIR *dir); +int closedir(DIR *dir); + +#endif /* _POSIX_DIRENT_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/limits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/limits.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,9 @@ +#ifndef _POSIX_LIMITS_H +#define _POSIX_LIMITS_H + +#include_next <limits.h> +#include <arch_limits.h> + +#define PATH_MAX __PAGE_SIZE + +#endif /* _POSIX_LIMITS_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/netdb.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/netdb.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,9 @@ +#ifndef _POSIX_NETDB_H_ +#define _POSIX_NETDB_H_ + +struct hostent { + char *h_addr; +}; +#define gethostbyname(buf) NULL + +#endif /* _POSIX_NETDB_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/netinet/in.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/netinet/in.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,7 @@ +#ifndef _POSIX_SYS_IN_H_ +#define _POSIX_SYS_IN_H_ + +#include <fcntl.h> +#include <lwip/sockets.h> + +#endif /* _POSIX_SYS_IN_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/netinet/tcp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/netinet/tcp.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,6 @@ +#ifndef _POSIX_SYS_TCP_H_ +#define _POSIX_SYS_TCP_H_ + +#include <lwip/tcp.h> + +#endif /* _POSIX_SYS_TCP_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/pthread.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/pthread.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,19 @@ +#ifndef _POSIX_PTHREAD_H +#define _POSIX_PTHREAD_H + +/* Let's be single-threaded for now. */ + +typedef void *pthread_key_t; +typedef struct {} pthread_mutex_t, pthread_once_t; +#define PTHREAD_MUTEX_INITIALIZER {} +#define PTHREAD_ONCE_INIT {} +static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return 0; } +static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return 0; } +static inline int pthread_key_create(pthread_key_t *key, void (*destr_function)(void*)) { *key = NULL; return 0; } +static inline int pthread_setspecific(pthread_key_t *key, const void *pointer) { *key = (void*) pointer; return 0; } +static inline void *pthread_getspecific(pthread_key_t *key) { return *key; } +static inline int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { init_routine(); return 0; } + +#define __thread + +#endif /* _POSIX_PTHREAD_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/stdlib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/stdlib.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,8 @@ +#ifndef _POSIX_STDLIB_H +#define _POSIX_STDLIB_H + +#include_next <stdlib.h> + +#define realpath(p,r) strcpy(r,p) + +#endif /* _POSIX_STDLIB_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/strings.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/strings.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,8 @@ +#ifndef _POSIX_STRINGS_H +#define _POSIX_STRINGS_H + +#include <string.h> + +#define bzero(ptr, size) (memset((ptr), '\0', (size)), (void) 0) + +#endif /* _POSIX_STRINGS_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/sys/ioctl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/sys/ioctl.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,16 @@ +#ifndef _POSIX_SYS_IOCTL_H +#define _POSIX_SYS_IOCTL_H + +int ioctl(int fd, int request, ...); + +#define _IOC_NONE 0 +#define _IOC_WRITE 1 +#define _IOC_READ 2 + +#define _IOC(rw, class, n, size) \ + (((rw ) << 30) | \ + ((class) << 22) | \ + ((n ) << 14) | \ + ((size ) << 0)) + +#endif /* _POSIX_SYS_IOCTL_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/sys/mman.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/sys/mman.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,19 @@ +#ifndef _POSIX_SYS_MMAN_H +#define _POSIX_SYS_MMAN_H + +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +#define PROT_EXEC 0x4 + +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_ANON 0x20 + +#define MAP_FAILED ((void*)0) + +void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); +int munmap(void *start, size_t length); +#define munlock(addr, len) ((void)addr, (void)len, 0) +#define mlock(addr, len) ((void)addr, (void)len, 0) + +#endif /* _POSIX_SYS_MMAN_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/sys/select.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/sys/select.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,7 @@ +#ifndef _POSIX_SELECT_H +#define _POSIX_SELECT_H + +#include <sys/time.h> +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); + +#endif /* _POSIX_SELECT_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/sys/socket.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/sys/socket.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,31 @@ +#ifndef _POSIX_SYS_SOCKET_H_ +#define _POSIX_SYS_SOCKET_H_ + +#include <fcntl.h> +#include <lwip/sockets.h> + +int accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int bind(int s, struct sockaddr *name, socklen_t namelen); +int shutdown(int s, int how); +int getpeername (int s, struct sockaddr *name, socklen_t *namelen); +int getsockname (int s, struct sockaddr *name, socklen_t *namelen); +int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); +int setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); +int close(int s); +int connect(int s, struct sockaddr *name, socklen_t namelen); +int listen(int s, int backlog); +int recv(int s, void *mem, int len, unsigned int flags); +//int read(int s, void *mem, int len); +int recvfrom(int s, void *mem, int len, unsigned int flags, + struct sockaddr *from, socklen_t *fromlen); +int send(int s, void *dataptr, int size, unsigned int flags); +int sendto(int s, void *dataptr, int size, unsigned int flags, + struct sockaddr *to, socklen_t tolen); +int socket(int domain, int type, int protocol); +//int write(int s, void *dataptr, int size); +int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout); +//int ioctl(int s, long cmd, void *argp); +int getsockname(int s, struct sockaddr *name, socklen_t *namelen); + +#endif /* _POSIX_SYS_SOCKET_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/termios.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/termios.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,87 @@ +#ifndef _POSIX_TERMIOS_H +#define _POSIX_TERMIOS_H + +#define NCC 32 + +struct termios { + unsigned long c_iflag; + unsigned long c_oflag; + unsigned long c_lflag; + unsigned long c_cflag; + unsigned char c_cc[NCC]; +}; + +/* modem lines */ +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RI 0x080 +#define TIOCM_DSR 0x100 + +/* c_iflag */ +#define IGNBRK 0x00000001 +#define BRKINT 0x00000002 +#define IGNPAR 0x00000004 +#define PARMRK 0x00000008 +#define INPCK 0x00000010 +#define ISTRIP 0x00000020 +#define INLCR 0x00000040 +#define IGNCR 0x00000080 +#define ICRNL 0x00000100 +#define IUCLC 0x00000200 +#define IXON 0x00000400 +#define IXANY 0x00000800 +#define IXOFF 0x00001000 +#define IMAXBEL 0x00002000 +#define IUTF8 0x00004000 + +/* c_oflag */ +#define OPOST 0x00000001 +#define OLCUC 0x00000002 +#define ONLCR 0x00000004 +#define OCRNL 0x00000008 +#define ONOCR 0x00000010 +#define ONLRET 0x00000020 +#define OFILL 0x00000040 +#define OFDEL 0x00000080 + +/* c_lflag */ +#define ISIG 0x00000001 +#define ICANON 0x00000002 +#define XCASE 0x00000004 +#define ECHO 0x00000008 +#define ECHOE 0x00000010 +#define ECHOK 0x00000020 +#define ECHONL 0x00000040 +#define NOFLSH 0x00000080 +#define TOSTOP 0x00000100 +#define ECHOCTL 0x00000200 +#define ECHOPRT 0x00000400 +#define ECHOKE 0x00000800 +#define FLUSHO 0x00002000 +#define PENDIN 0x00004000 +#define IEXTEN 0x00008000 + +/* c_cflag */ +#define CSIZE 0x00000030 +#define CS8 0x00000030 +#define CSTOPB 0x00000040 +#define CREAD 0x00000080 +#define PARENB 0x00000100 +#define PARODD 0x00000200 +#define HUPCL 0x00000400 +#define CLOCAL 0x00000800 + +/* c_cc */ +#define VTIME 5 +#define VMIN 6 + +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +int tcsetattr(int fildes, int action, const struct termios *tios); +int tcgetattr(int fildes, struct termios *tios); + +#endif /* _POSIX_TERMIOS_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/time.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/time.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,10 @@ +#ifndef _POSIX_TIME_H +#define _POSIX_TIME_H + +#include <sys/time.h> +#define CLOCK_MONOTONIC 2 +#include_next <time.h> + +int nanosleep(const struct timespec *req, struct timespec *rem); + +#endif /* _POSIX_TIME_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/posix/unistd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/posix/unistd.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,12 @@ +#ifndef _POSIX_UNISTD_H +#define _POSIX_UNISTD_H + +#include_next <unistd.h> +#include <sys/select.h> +#include <arch_limits.h> + +#define getpagesize() __PAGE_SIZE + +int ftruncate(int fd, off_t length); + +#endif /* _POSIX_UNISTD_H */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/sched.h --- a/extras/mini-os/include/sched.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/sched.h Tue Feb 12 14:35:39 2008 +0000 @@ -19,6 +19,9 @@ struct thread struct list_head thread_list; u32 flags; s_time_t wakeup_time; +#ifdef HAVE_LIBC + struct _reent reent; +#endif }; extern struct thread *idle_thread; diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/sys/time.h --- a/extras/mini-os/include/sys/time.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/sys/time.h Tue Feb 12 14:35:39 2008 +0000 @@ -20,6 +20,9 @@ #ifndef _MINIOS_SYS_TIME_H_ #define _MINIOS_SYS_TIME_H_ +#ifdef HAVE_LIBC +#include_next <sys/time.h> +#else struct timespec { time_t tv_sec; long tv_nsec; @@ -34,5 +37,6 @@ struct timeval { }; int gettimeofday(struct timeval *tv, void *tz); +#endif #endif /* _MINIOS_SYS_TIME_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/time.h --- a/extras/mini-os/include/time.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/time.h Tue Feb 12 14:35:39 2008 +0000 @@ -17,8 +17,9 @@ **************************************************************************** */ -#ifndef _TIME_H_ -#define _TIME_H_ +#ifndef _MINIOS_TIME_H_ +#define _MINIOS_TIME_H_ +#include <types.h> /* * System Time @@ -44,8 +45,12 @@ typedef s64 s_time_t; /* wall clock time */ typedef long time_t; typedef long suseconds_t; + #include <sys/time.h> +#ifdef HAVE_LIBC +#include_next <time.h> +#endif /* prototypes */ void init_time(void); @@ -54,4 +59,4 @@ u64 monotonic_clock(void); u64 monotonic_clock(void); void block_domain(s_time_t until); -#endif /* _TIME_H_ */ +#endif /* _MINIOS_TIME_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/x86/arch_limits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/x86/arch_limits.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,20 @@ + +#ifndef __ARCH_LIMITS_H__ +#define __ARCH_LIMITS_H__ + +#define __PAGE_SHIFT 12 + +#ifdef __ASSEMBLY__ +#define __PAGE_SIZE (1 << __PAGE_SHIFT) +#else +#ifndef CONFIG_X86_PAE +#define __PAGE_SIZE (1UL << __PAGE_SHIFT) +#else +#define __PAGE_SIZE (1ULL << __PAGE_SHIFT) +#endif +#endif + +#define __STACK_SIZE_PAGE_ORDER 4 +#define __STACK_SIZE (__PAGE_SIZE * (1 << __STACK_SIZE_PAGE_ORDER)) + +#endif /* __ARCH_LIMITS_H__ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/x86/arch_mm.h --- a/extras/mini-os/include/x86/arch_mm.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/x86/arch_mm.h Tue Feb 12 14:35:39 2008 +0000 @@ -157,16 +157,9 @@ typedef unsigned long pgentry_t; #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #endif /* __i386__ || __x86_64__ */ -#ifdef __ASSEMBLY__ -#define PAGE_SIZE (1 << L1_PAGETABLE_SHIFT) -#else -#ifndef CONFIG_X86_PAE -#define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT) -#else -#define PAGE_SIZE (1ULL << L1_PAGETABLE_SHIFT) -#endif -#endif -#define PAGE_SHIFT L1_PAGETABLE_SHIFT +#include "arch_limits.h" +#define PAGE_SIZE __PAGE_SIZE +#define PAGE_SHIFT __PAGE_SHIFT #define PAGE_MASK (~(PAGE_SIZE-1)) #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT) @@ -176,9 +169,6 @@ typedef unsigned long pgentry_t; /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -#define STACK_SIZE_PAGE_ORDER 1 -#define STACK_SIZE (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER)) #ifndef __ASSEMBLY__ /* Definitions for machine and pseudophysical addresses. */ @@ -257,5 +247,11 @@ static __inline__ paddr_t machine_to_phy #define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, L1_PROT) #define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, L1_PROT_RO) +#ifndef __ASSEMBLY__ +void do_map_frames(unsigned long addr, + unsigned long *f, unsigned long n, unsigned long stride, + unsigned long increment, domid_t id, int may_fail, unsigned long prot); +#endif +#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO) #endif /* _ARCH_MM_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/x86/arch_sched.h --- a/extras/mini-os/include/x86/arch_sched.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/x86/arch_sched.h Tue Feb 12 14:35:39 2008 +0000 @@ -2,7 +2,7 @@ #ifndef __ARCH_SCHED_H__ #define __ARCH_SCHED_H__ -#include <arch_mm.h> +#include <arch_limits.h> static inline struct thread* get_current(void) { @@ -12,7 +12,7 @@ static inline struct thread* get_current #else register unsigned long sp asm("rsp"); #endif - current = (void *)(unsigned long)(sp & ~(STACK_SIZE-1)); + current = (void *)(unsigned long)(sp & ~(__STACK_SIZE-1)); return *current; } diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/x86/arch_spinlock.h --- a/extras/mini-os/include/x86/arch_spinlock.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/x86/arch_spinlock.h Tue Feb 12 14:35:39 2008 +0000 @@ -4,6 +4,7 @@ #define __ARCH_ASM_SPINLOCK_H #include <lib.h> +#include "os.h" #define ARCH_SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } diff -r 88818d55e95a -r a905c582a406 extras/mini-os/include/x86/os.h --- a/extras/mini-os/include/x86/os.h Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/include/x86/os.h Tue Feb 12 14:35:39 2008 +0000 @@ -563,6 +563,7 @@ static __inline__ int synch_var_test_bit synch_var_test_bit((nr),(addr))) +#undef ADDR #endif /* not assembly */ #endif /* _OS_H_ */ diff -r 88818d55e95a -r a905c582a406 extras/mini-os/lib/sys.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/lib/sys.c Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,1083 @@ +/* + * POSIX-compatible libc layer + * + * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, October 2007 + * + * Provides the UNIXish part of the standard libc function. + * + * Relatively straight-forward: just multiplex the file descriptor operations + * among the various file types (console, FS, network, ...) + */ + +//#define LIBC_VERBOSE +//#define LIBC_DEBUG + +#ifdef LIBC_DEBUG +#define DEBUG(fmt,...) printk(fmt, ##__VA_ARGS__) +#else +#define DEBUG(fmt,...) +#endif + +#ifdef HAVE_LIBC +#include <os.h> +#include <console.h> +#include <sched.h> +#include <events.h> +#include <wait.h> +#include <netfront.h> +#include <blkfront.h> +#include <xenbus.h> +#include <xs.h> + +#include <sys/types.h> +#include <sys/unistd.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <time.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <assert.h> +#include <dirent.h> +#include <stdlib.h> +#include <math.h> + +#include <lwip/sockets.h> +#include <fs.h> + +#define debug(fmt, ...) \ + +#define print_unsupported(fmt, ...) \ + printk("Unsupported function "fmt" called in Mini-OS kernel\n", ## __VA_ARGS__); + +/* Crash on function call */ +#define unsupported_function_crash(function) \ + int __unsup_##function(void) asm(#function); \ + int __unsup_##function(void) \ + { \ + print_unsupported(#function); \ + do_exit(); \ + } + +/* Log and err out on function call */ +#define unsupported_function_log(type, function, ret) \ + type __unsup_##function(void) asm(#function); \ + type __unsup_##function(void) \ + { \ + print_unsupported(#function); \ + errno = ENOSYS; \ + return ret; \ + } + +/* Err out on function call */ +#define unsupported_function(type, function, ret) \ + type __unsup_##function(void) asm(#function); \ + type __unsup_##function(void) \ + { \ + errno = ENOSYS; \ + return ret; \ + } + +#define NOFILE 32 +extern int xc_evtchn_close(int fd); + +pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER; +struct file files[NOFILE] = { + { .type = FTYPE_CONSOLE }, /* stdin */ + { .type = FTYPE_CONSOLE }, /* stdout */ + { .type = FTYPE_CONSOLE }, /* stderr */ +}; + +DECLARE_WAIT_QUEUE_HEAD(event_queue); + +int alloc_fd(enum fd_type type) +{ + int i; + pthread_mutex_lock(&fd_lock); + for (i=0; i<NOFILE; i++) { + if (files[i].type == FTYPE_NONE) { + files[i].type = type; + pthread_mutex_unlock(&fd_lock); + return i; + } + } + pthread_mutex_unlock(&fd_lock); + printk("Too many opened files\n"); + do_exit(); +} + +void close_all_files(void) +{ + int i; + pthread_mutex_lock(&fd_lock); + for (i=NOFILE - 1; i > 0; i--) + if (files[i].type != FTYPE_NONE) + close(i); + pthread_mutex_unlock(&fd_lock); +} + +int dup2(int oldfd, int newfd) +{ + pthread_mutex_lock(&fd_lock); + if (files[newfd].type != FTYPE_NONE) + close(newfd); + // XXX: this is a bit bogus, as we are supposed to share the offset etc + files[newfd] = files[oldfd]; + pthread_mutex_unlock(&fd_lock); + return 0; +} + +pid_t getpid(void) +{ + return 1; +} + +pid_t getppid(void) +{ + return 1; +} + +pid_t setsid(void) +{ + return 1; +} + +char *getcwd(char *buf, size_t size) +{ + snprintf(buf, size, "/"); + return buf; +} + +#define LOG_PATH "/var/log/" + +int mkdir(const char *pathname, mode_t mode) +{ + int ret; + ret = fs_create(fs_import, (char *) pathname, 1, mode); + if (ret < 0) { + errno = EIO; + return -1; + } + return 0; +} + +int open(const char *pathname, int flags, ...) +{ + int fs_fd, fd; + /* Ugly, but fine. */ + if (!strncmp(pathname,LOG_PATH,strlen(LOG_PATH))) { + fd = alloc_fd(FTYPE_CONSOLE); + printk("open(%s) -> %d\n", pathname, fd); + return fd; + } + printk("open(%s)", pathname); + fs_fd = fs_open(fs_import, (void *) pathname); + if (fs_fd < 0) { + errno = EIO; + return -1; + } + fd = alloc_fd(FTYPE_FILE); + printk("-> %d\n", fd); + files[fd].file.fd = fs_fd; + files[fd].file.offset = 0; + return fd; +} +#if defined(__x86_64__) || defined(__ia64__) +__typeof__(open) open64 __attribute__((__alias__("open"))); +#endif + +int isatty(int fd) +{ + return files[fd].type == FTYPE_CONSOLE; +} + +int read(int fd, void *buf, size_t nbytes) +{ + switch (files[fd].type) { + case FTYPE_CONSOLE: + return 0; + case FTYPE_FILE: { + ssize_t ret; + if (nbytes > PAGE_SIZE) + nbytes = PAGE_SIZE; + ret = fs_read(fs_import, files[fd].file.fd, buf, nbytes, files[fd].file.offset); + if (ret > 0) { + files[fd].file.offset += ret; + return ret; + } else if (ret < 0) { + errno = EIO; + return -1; + } + return 0; + } + case FTYPE_SOCKET: + return lwip_read(files[fd].socket.fd, buf, nbytes); + case FTYPE_TAP: { + ssize_t ret; + ret = netfront_receive(files[fd].tap.dev, buf, nbytes); + if (ret <= 0) { + errno = EAGAIN; + return -1; + } + return ret; + } + case FTYPE_NONE: + case FTYPE_XENBUS: + case FTYPE_EVTCHN: + case FTYPE_BLK: + break; + } + printk("read(%d): Bad descriptor\n", fd); + errno = EBADF; + return -1; +} + +int write(int fd, const void *buf, size_t nbytes) +{ + switch (files[fd].type) { + case FTYPE_CONSOLE: + console_print((char *)buf, nbytes); + return nbytes; + case FTYPE_FILE: { + ssize_t ret; + if (nbytes > PAGE_SIZE) + nbytes = PAGE_SIZE; + ret = fs_write(fs_import, files[fd].file.fd, (void *) buf, nbytes, files[fd].file.offset); + if (ret > 0) { + files[fd].file.offset += ret; + return ret; + } else if (ret < 0) { + errno = EIO; + return -1; + } + return 0; + } + case FTYPE_SOCKET: + return lwip_write(files[fd].socket.fd, (void*) buf, nbytes); + case FTYPE_TAP: + netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes); + return nbytes; + case FTYPE_NONE: + case FTYPE_XENBUS: + case FTYPE_EVTCHN: + case FTYPE_BLK: + break; + } + printk("write(%d): Bad descriptor\n", fd); + errno = EBADF; + return -1; +} + +off_t lseek(int fd, off_t offset, int whence) +{ + if (files[fd].type != FTYPE_FILE) { + errno = ESPIPE; + return (off_t) -1; + } + switch (whence) { + case SEEK_SET: + files[fd].file.offset = offset; + break; + case SEEK_CUR: + files[fd].file.offset += offset; + break; + case SEEK_END: { + struct stat st; + int ret; + ret = fstat(fd, &st); + if (ret) + return -1; + files[fd].file.offset = st.st_size + offset; + break; + } + default: + errno = EINVAL; + return -1; + } + return files[fd].file.offset; +} +#if defined(__x86_64__) || defined(__ia64__) +__typeof__(lseek) lseek64 __attribute__((__alias__("lseek"))); +#endif + +int fsync(int fd) { + switch (files[fd].type) { + case FTYPE_FILE: { + int ret; + ret = fs_sync(fs_import, files[fd].file.fd); + if (ret < 0) { + errno = EIO; + return -1; + } + return 0; + } + case FTYPE_NONE: + case FTYPE_CONSOLE: + case FTYPE_SOCKET: + case FTYPE_XENBUS: + case FTYPE_EVTCHN: + case FTYPE_TAP: + case FTYPE_BLK: + break; + } + printk("fsync(%d): Bad descriptor\n", fd); + errno = EBADF; + return -1; +} + +int close(int fd) +{ + printk("close(%d)\n", fd); + switch (files[fd].type) { + case FTYPE_CONSOLE: + files[fd].type = FTYPE_NONE; + return 0; + case FTYPE_FILE: { + int ret = fs_close(fs_import, files[fd].file.fd); + files[fd].type = FTYPE_NONE; + if (ret < 0) { + errno = EIO; + return -1; + } + return 0; + } + case FTYPE_XENBUS: + xs_daemon_close((void*)(intptr_t) fd); + return 0; + case FTYPE_SOCKET: { + int res = lwip_close(files[fd].socket.fd); + files[fd].type = FTYPE_NONE; + return res; + } + case FTYPE_EVTCHN: + xc_evtchn_close(fd); + return 0; + case FTYPE_TAP: + shutdown_netfront(files[fd].tap.dev); + files[fd].type = FTYPE_NONE; + return 0; + case FTYPE_BLK: + shutdown_blkfront(files[fd].blk.dev); + files[fd].type = FTYPE_NONE; + return 0; + case FTYPE_NONE: + break; + } + printk("close(%d): Bad descriptor\n", fd); + errno = EBADF; + return -1; +} + +static void init_stat(struct stat *buf) +{ + memset(buf, 0, sizeof(*buf)); + buf->st_dev = 0; + buf->st_ino = 0; + buf->st_nlink = 1; + buf->st_rdev = 0; + buf->st_blksize = 4096; + buf->st_blocks = 0; +} + +static void stat_from_fs(struct stat *buf, struct fsif_stat_response *stat) +{ + buf->st_mode = stat->stat_mode; + buf->st_uid = stat->stat_uid; + buf->st_gid = stat->stat_gid; + buf->st_size = stat->stat_size; + buf->st_atime = stat->stat_atime; + buf->st_mtime = stat->stat_mtime; + buf->st_ctime = stat->stat_ctime; +} + +int stat(const char *path, struct stat *buf) +{ + struct fsif_stat_response stat; + int ret; + int fs_fd; + printk("stat(%s)\n", path); + fs_fd = fs_open(fs_import, (char*) path); + if (fs_fd < 0) { + errno = EIO; + ret = -1; + goto out; + } + ret = fs_stat(fs_import, fs_fd, &stat); + if (ret < 0) { + errno = EIO; + ret = -1; + goto outfd; + } + init_stat(buf); + stat_from_fs(buf, &stat); + ret = 0; + +outfd: + fs_close(fs_import, fs_fd); +out: + return ret; +} + +int fstat(int fd, struct stat *buf) +{ + init_stat(buf); + switch (files[fd].type) { + case FTYPE_CONSOLE: + case FTYPE_SOCKET: { + buf->st_mode = (files[fd].type == FTYPE_CONSOLE?S_IFCHR:S_IFSOCK) | S_IRUSR|S_IWUSR; + buf->st_uid = 0; + buf->st_gid = 0; + buf->st_size = 0; + buf->st_atime = + buf->st_mtime = + buf->st_ctime = time(NULL); + return 0; + } + case FTYPE_FILE: { + struct fsif_stat_response stat; + int ret; + ret = fs_stat(fs_import, files[fd].file.fd, &stat); + if (ret < 0) { + errno = EIO; + return -1; + } + /* The protocol is a bit evasive about this value */ + stat_from_fs(buf, &stat); + return 0; + } + case FTYPE_NONE: + case FTYPE_XENBUS: + case FTYPE_EVTCHN: + case FTYPE_TAP: + case FTYPE_BLK: + break; + } + + printk("statf(%d): Bad descriptor\n", fd); + errno = EBADF; + return -1; +} + +int ftruncate(int fd, off_t length) +{ + switch (files[fd].type) { + case FTYPE_FILE: { + int ret; + ret = fs_truncate(fs_import, files[fd].file.fd, length); + if (ret < 0) { + errno = EIO; + return -1; + } + return 0; + } + case FTYPE_NONE: + case FTYPE_CONSOLE: + case FTYPE_SOCKET: + case FTYPE_XENBUS: + case FTYPE_EVTCHN: + case FTYPE_TAP: + case FTYPE_BLK: + break; + } + + printk("ftruncate(%d): Bad descriptor\n", fd); + errno = EBADF; + return -1; +} + +int remove(const char *pathname) +{ + int ret; + printk("remove(%s)", pathname); + ret = fs_remove(fs_import, (char*) pathname); + if (ret < 0) { + errno = EIO; + return -1; + } + return 0; +} + +int unlink(const char *pathname) +{ + return remove(pathname); +} + +int rmdir(const char *pathname) +{ + return remove(pathname); +} + +int fcntl(int fd, int cmd, ...) +{ + long arg; + va_list ap; + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + + switch (cmd) { + case F_SETFL: + if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) { + /* Only flag supported: non-blocking mode */ + uint32_t nblock = !!(arg & O_NONBLOCK); + return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock); + } + /* Fallthrough */ + default: + printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg); + errno = ENOSYS; + return -1; + } +} + +DIR *opendir(const char *name) +{ + DIR *ret; + ret = malloc(sizeof(*ret)); + ret->name = strdup(name); + ret->offset = 0; + ret->entries = NULL; + ret->curentry = -1; + ret->nbentries = 0; + ret->has_more = 1; + return ret; +} + +struct dirent *readdir(DIR *dir) +{ + if (dir->curentry >= 0) { + free(dir->entries[dir->curentry]); + dir->entries[dir->curentry] = NULL; + } + dir->curentry++; + if (dir->curentry >= dir->nbentries) { + dir->offset += dir->nbentries; + free(dir->entries); + dir->curentry = -1; + dir->nbentries = 0; + if (!dir->has_more) + return NULL; + dir->entries = fs_list(fs_import, dir->name, dir->offset, &dir->nbentries, &dir->has_more); + if (!dir->entries || !dir->nbentries) + return NULL; + dir->curentry = 0; + } + dir->dirent.d_name = dir->entries[dir->curentry]; + return &dir->dirent; +} +int closedir(DIR *dir) +{ + int i; + for (i=0; i<dir->nbentries; i++) + free(dir->entries[i]); + free(dir->entries); + free(dir->name); + free(dir); + return 0; +} + +/* We assume that only the main thread calls select(). */ + +static const char file_types[] = { + [FTYPE_NONE] = 'N', + [FTYPE_CONSOLE] = 'C', + [FTYPE_FILE] = 'F', + [FTYPE_XENBUS] = 'X', + [FTYPE_EVTCHN] = 'E', + [FTYPE_SOCKET] = 'S', + [FTYPE_TAP] = 'T', + [FTYPE_BLK] = 'B', +}; +#ifdef LIBC_DEBUG +static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +{ + int i, comma; +#define printfds(set) do {\ + comma = 0; \ + for (i = 0; i < nfds; i++) { \ + if (FD_ISSET(i, set)) { \ + if (comma) \ + printk(", "); \ + printk("%d(%c)", i, file_types[files[i].type]); \ + comma = 1; \ + } \ + } \ +} while (0) + + printk("["); + if (readfds) + printfds(readfds); + printk("], ["); + if (writefds) + printfds(writefds); + printk("], ["); + if (exceptfds) + printfds(exceptfds); + printk("], "); + if (timeout) + printk("{ %ld, %ld }", timeout->tv_sec, timeout->tv_usec); +} +#else +#define dump_set(nfds, readfds, writefds, exceptfds, timeout) +#endif + +/* Just poll without blocking */ +static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) +{ + int i, n = 0, sock_n, sock_nfds = 0; + fd_set sock_readfds, sock_writefds, sock_exceptfds; + struct timeval timeout = { .tv_sec = 0, .tv_usec = 0}; + +#ifdef LIBC_VERBOSE + static int nb; + static int nbread[NOFILE], nbwrite[NOFILE], nbexcept[NOFILE]; + static s64_t lastshown; + + nb++; +#endif + + /* first poll network */ + FD_ZERO(&sock_readfds); + FD_ZERO(&sock_writefds); + FD_ZERO(&sock_exceptfds); + for (i = 0; i < nfds; i++) { + if (files[i].type == FTYPE_SOCKET) { + if (FD_ISSET(i, readfds)) { + FD_SET(files[i].socket.fd, &sock_readfds); + sock_nfds = i+1; + } + if (FD_ISSET(i, writefds)) { + FD_SET(files[i].socket.fd, &sock_writefds); + sock_nfds = i+1; + } + if (FD_ISSET(i, exceptfds)) { + FD_SET(files[i].socket.fd, &sock_exceptfds); + sock_nfds = i+1; + } + } + } + DEBUG("lwip_select("); + dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); + DEBUG("); -> "); + sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); + dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); + DEBUG("\n"); + + /* Then see others as well. */ + for (i = 0; i < nfds; i++) { + switch(files[i].type) { + case FTYPE_NONE: + if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds)) + printk("bogus fd %d in select\n", i); + /* Fallthrough. */ + case FTYPE_FILE: + FD_CLR(i, readfds); + FD_CLR(i, writefds); + FD_CLR(i, exceptfds); + break; + case FTYPE_CONSOLE: + FD_CLR(i, readfds); + if (FD_ISSET(i, writefds)) + n++; + FD_CLR(i, exceptfds); + break; + case FTYPE_XENBUS: + if (FD_ISSET(i, readfds)) { + if (files[i].xenbus.events) + n++; + else + FD_CLR(i, readfds); + } + FD_CLR(i, writefds); + FD_CLR(i, exceptfds); + break; + case FTYPE_EVTCHN: + case FTYPE_TAP: + case FTYPE_BLK: + if (FD_ISSET(i, readfds)) { + if (files[i].read) + n++; + else + FD_CLR(i, readfds); + } + FD_CLR(i, writefds); + FD_CLR(i, exceptfds); + break; + case FTYPE_SOCKET: + if (FD_ISSET(i, readfds)) { + /* Optimize no-network-packet case. */ + if (sock_n && FD_ISSET(files[i].socket.fd, &sock_readfds)) + n++; + else + FD_CLR(i, readfds); + } + if (FD_ISSET(i, writefds)) { + if (sock_n && FD_ISSET(files[i].socket.fd, &sock_writefds)) + n++; + else + FD_CLR(i, writefds); + } + if (FD_ISSET(i, exceptfds)) { + if (sock_n && FD_ISSET(files[i].socket.fd, &sock_exceptfds)) + n++; + else + FD_CLR(i, exceptfds); + } + break; + } +#ifdef LIBC_VERBOSE + if (FD_ISSET(i, readfds)) + nbread[i]++; + if (FD_ISSET(i, writefds)) + nbwrite[i]++; + if (FD_ISSET(i, exceptfds)) + nbexcept[i]++; +#endif + } +#ifdef LIBC_VERBOSE + if (NOW() > lastshown + 1000000000ull) { + lastshown = NOW(); + printk("%lu MB free, ", num_free_pages() / ((1 << 20) / PAGE_SIZE)); + printk("%d(%d): ", nb, sock_n); + for (i = 0; i < nfds; i++) { + if (nbread[i] || nbwrite[i] || nbexcept[i]) + printk(" %d(%c):", i, file_types[files[i].type]); + if (nbread[i]) + printk(" %dR", nbread[i]); + if (nbwrite[i]) + printk(" %dW", nbwrite[i]); + if (nbexcept[i]) + printk(" %dE", nbexcept[i]); + } + printk("\n"); + memset(nbread, 0, sizeof(nbread)); + memset(nbwrite, 0, sizeof(nbwrite)); + memset(nbexcept, 0, sizeof(nbexcept)); + nb = 0; + } +#endif + return n; +} + +/* The strategy is to + * - announce that we will maybe sleep + * - poll a bit ; if successful, return + * - if timeout, return + * - really sleep (except if somebody woke us in the meanwhile) */ +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + int n, ret; + fd_set myread, mywrite, myexcept; + struct thread *thread = get_current(); + s_time_t start = NOW(), stop; + DEFINE_WAIT(w1); + DEFINE_WAIT(w2); + DEFINE_WAIT(w3); + DEFINE_WAIT(w4); + + assert(thread == main_thread); + + DEBUG("select(%d, ", nfds); + dump_set(nfds, readfds, writefds, exceptfds, timeout); + DEBUG(");\n"); + + if (timeout) + stop = start + SECONDS(timeout->tv_sec) + timeout->tv_usec * 1000; + else + /* just make gcc happy */ + stop = start; + + /* Tell people we're going to sleep before looking at what they are + * saying, hence letting them wake us if events happen between here and + * schedule() */ + add_waiter(w1, netfront_queue); + add_waiter(w2, event_queue); + add_waiter(w3, blkfront_queue); + add_waiter(w4, xenbus_watch_queue); + + myread = *readfds; + mywrite = *writefds; + myexcept = *exceptfds; + DEBUG("polling "); + dump_set(nfds, &myread, &mywrite, &myexcept, timeout); + DEBUG("\n"); + n = select_poll(nfds, &myread, &mywrite, &myexcept); + + if (n) { + dump_set(nfds, readfds, writefds, exceptfds, timeout); + if (readfds) + *readfds = myread; + if (writefds) + *writefds = mywrite; + if (exceptfds) + *exceptfds = myexcept; + DEBUG(" -> "); + dump_set(nfds, readfds, writefds, exceptfds, timeout); + DEBUG("\n"); + wake(thread); + ret = n; + goto out; + } + if (timeout && NOW() >= stop) { + if (readfds) + FD_ZERO(readfds); + if (writefds) + FD_ZERO(writefds); + if (exceptfds) + FD_ZERO(exceptfds); + timeout->tv_sec = 0; + timeout->tv_usec = 0; + wake(thread); + ret = 0; + goto out; + } + + if (timeout) + thread->wakeup_time = stop; + schedule(); + + myread = *readfds; + mywrite = *writefds; + myexcept = *exceptfds; + n = select_poll(nfds, &myread, &mywrite, &myexcept); + + if (n) { + if (readfds) + *readfds = myread; + if (writefds) + *writefds = mywrite; + if (exceptfds) + *exceptfds = myexcept; + ret = n; + goto out; + } + errno = EINTR; + ret = -1; + +out: + remove_waiter(w1); + remove_waiter(w2); + remove_waiter(w3); + remove_waiter(w4); + return ret; +} + +int socket(int domain, int type, int protocol) +{ + int fd, res; + fd = lwip_socket(domain, type, protocol); + if (fd < 0) + return -1; + res = alloc_fd(FTYPE_SOCKET); + printk("socket -> %d\n", res); + files[res].socket.fd = fd; + return res; +} + +int accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + int fd, res; + if (files[s].type != FTYPE_SOCKET) { + printk("accept(%d): Bad descriptor\n", s); + errno = EBADF; + return -1; + } + fd = lwip_accept(files[s].socket.fd, addr, addrlen); + if (fd < 0) + return -1; + res = alloc_fd(FTYPE_SOCKET); + files[res].socket.fd = fd; + printk("accepted on %d -> %d\n", s, res); + return res; +} + +#define LWIP_STUB(ret, name, proto, args) \ +ret name proto \ +{ \ + if (files[s].type != FTYPE_SOCKET) { \ + printk(#name "(%d): Bad descriptor\n", s); \ + errno = EBADF; \ + return -1; \ + } \ + s = files[s].socket.fd; \ + return lwip_##name args; \ +} + +LWIP_STUB(int, bind, (int s, struct sockaddr *my_addr, socklen_t addrlen), (s, my_addr, addrlen)) +LWIP_STUB(int, getsockopt, (int s, int level, int optname, void *optval, socklen_t *optlen), (s, level, optname, optval, optlen)) +LWIP_STUB(int, setsockopt, (int s, int level, int optname, void *optval, socklen_t optlen), (s, level, optname, optval, optlen)) +LWIP_STUB(int, connect, (int s, struct sockaddr *serv_addr, socklen_t addrlen), (s, serv_addr, addrlen)) +LWIP_STUB(int, listen, (int s, int backlog), (s, backlog)); +LWIP_STUB(ssize_t, recv, (int s, void *buf, size_t len, int flags), (s, buf, len, flags)) +LWIP_STUB(ssize_t, recvfrom, (int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen), (s, buf, len, flags, from, fromlen)) +LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, len, flags)) +LWIP_STUB(ssize_t, sendto, (int s, void *buf, size_t len, int flags, struct sockaddr *to, socklen_t tolen), (s, buf, len, flags, to, tolen)) +LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen)) + +int nanosleep(const struct timespec *req, struct timespec *rem) +{ + s_time_t start = NOW(); + s_time_t stop = start + SECONDS(req->tv_sec) + req->tv_nsec; + s_time_t stopped; + struct thread *thread = get_current(); + + thread->wakeup_time = stop; + clear_runnable(thread); + schedule(); + stopped = NOW(); + + if (rem) + { + s_time_t remaining = stop - stopped; + if (remaining > 0) + { + rem->tv_nsec = remaining % 1000000000ULL; + rem->tv_sec = remaining / 1000000000ULL; + } else memset(rem, 0, sizeof(*rem)); + } + + return 0; +} + +int usleep(useconds_t usec) +{ + /* "usec shall be less than one million." */ + struct timespec req; + req.tv_nsec = usec * 1000; + req.tv_sec = 0; + + if (nanosleep(&req, NULL)) + return -1; + + return 0; +} + +unsigned int sleep(unsigned int seconds) +{ + struct timespec req, rem; + req.tv_sec = seconds; + req.tv_nsec = 0; + + if (nanosleep(&req, &rem)) + return -1; + + if (rem.tv_nsec > 0) + rem.tv_sec++; + + return rem.tv_sec; +} + +int clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + switch (clk_id) { + case CLOCK_MONOTONIC: + { + struct timeval tv; + + gettimeofday(&tv, NULL); + + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000; + + break; + } + case CLOCK_REALTIME: + { + u64 nsec = monotonic_clock(); + + tp->tv_sec = nsec / 1000000000ULL; + tp->tv_nsec = nsec % 1000000000ULL; + + break; + } + default: + print_unsupported("clock_gettime(%d)", clk_id); + errno = EINVAL; + return -1; + } + + return 0; +} + +void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + ASSERT(!start); + length = (length + PAGE_SIZE - 1) & PAGE_MASK; + ASSERT(prot == (PROT_READ|PROT_WRITE)); + ASSERT(flags == (MAP_SHARED|MAP_ANON) || flags == (MAP_PRIVATE|MAP_ANON)); + ASSERT(fd == -1); + ASSERT(offset == 0); + + return map_zero(length / PAGE_SIZE, 1); +} +#if defined(__x86_64__) || defined(__ia64__) +__typeof__(mmap) mmap64 __attribute__((__alias__("mmap"))); +#endif + +int munmap(void *start, size_t length) +{ + int i, n = length / PAGE_SIZE; + multicall_entry_t call[n]; + unsigned char (*data)[PAGE_SIZE] = start; + int ret; + ASSERT(!((unsigned long)start & ~PAGE_MASK)); + ASSERT(!(length & ~PAGE_MASK)); + + for (i = 0; i < n; i++) { + call[i].op = __HYPERVISOR_update_va_mapping; + call[i].args[0] = (unsigned long) &data[i]; + call[i].args[1] = 0; + call[i].args[2] = 0; + call[i].args[3] = UVMF_INVLPG | UVMF_ALL; + } + + ret = HYPERVISOR_multicall(call, n); + if (ret) { + errno = -ret; + return -1; + } + + for (i = 0; i < n; i++) { + if (call[i].result) { + errno = call[i].result; + return -1; + } + } + return 0; +} + +/* Not supported by FS yet. */ +unsupported_function_crash(link); +unsupported_function(int, readlink, -1); + +/* We could support that. */ +unsupported_function_log(int, chdir, -1); + +/* No dynamic library support. */ +unsupported_function_log(void *, dlopen, NULL); +unsupported_function_log(void *, dlsym, NULL); +unsupported_function_log(char *, dlerror, NULL); +unsupported_function_log(int, dlclose, -1); + +/* We don't raise signals anyway. */ +unsupported_function(int, sigemptyset, -1); +unsupported_function(int, sigfillset, -1); +unsupported_function(int, sigaddset, -1); +unsupported_function(int, sigdelset, -1); +unsupported_function(int, sigismember, -1); +unsupported_function(int, sigprocmask, -1); +unsupported_function(int, sigaction, -1); +unsupported_function(int, __sigsetjmp, 0); +unsupported_function(int, sigaltstack, -1); +unsupported_function_crash(kill); + +/* Linuxish abi for the Caml runtime, don't support */ +unsupported_function_log(struct dirent *, readdir64, NULL); +unsupported_function_log(int, getrusage, -1); +unsupported_function_log(int, getrlimit, -1); +unsupported_function_log(int, getrlimit64, -1); +unsupported_function_log(int, __xstat64, -1); +unsupported_function_log(long, __strtol_internal, LONG_MIN); +unsupported_function_log(double, __strtod_internal, HUGE_VAL); +#endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/lib/xs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/lib/xs.c Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,187 @@ +/* + * libxs-compatible layer + * + * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, 2007-2008 + * + * Mere wrapper around xenbus_* + */ + +#ifdef HAVE_LIBC +#include <os.h> +#include <lib.h> +#include <xs.h> +#include <xenbus.h> +#include <stdlib.h> +#include <unistd.h> + +static inline int _xs_fileno(struct xs_handle *h) { + return (intptr_t) h; +} + +struct xs_handle *xs_daemon_open() +{ + int fd = alloc_fd(FTYPE_XENBUS); + files[fd].xenbus.events = NULL; + printk("xs_daemon_open -> %d, %p\n", fd, &files[fd].xenbus.events); + return (void*)(intptr_t) fd; +} + +void xs_daemon_close(struct xs_handle *h) +{ + int fd = _xs_fileno(h); + struct xenbus_event *event; + for (event = files[fd].xenbus.events; event; event = event->next) + free(event); + files[fd].type = FTYPE_NONE; +} + +int xs_fileno(struct xs_handle *h) +{ + return _xs_fileno(h); +} + +void *xs_read(struct xs_handle *h, xs_transaction_t t, + const char *path, unsigned int *len) +{ + char *value; + char *msg; + + msg = xenbus_read(t, path, &value); + if (msg) { + printk("xs_read(%s): %s\n", path, msg); + return NULL; + } + + if (len) + *len = strlen(value); + return value; +} + +bool xs_write(struct xs_handle *h, xs_transaction_t t, + const char *path, const void *data, unsigned int len) +{ + char value[len + 1]; + char *msg; + + memcpy(value, data, len); + value[len] = 0; + + msg = xenbus_write(t, path, value); + if (msg) { + printk("xs_write(%s): %s\n", path, msg); + return false; + } + return true; +} + +static bool xs_bool(char *reply) +{ + if (!reply) + return true; + free(reply); + return false; +} + +bool xs_rm(struct xs_handle *h, xs_transaction_t t, const char *path) +{ + return xs_bool(xenbus_rm(t, path)); +} + +static void *xs_talkv(struct xs_handle *h, xs_transaction_t t, + enum xsd_sockmsg_type type, + struct write_req *iovec, + unsigned int num_vecs, + unsigned int *len) +{ + struct xsd_sockmsg *msg; + void *ret; + + msg = xenbus_msg_reply(type, t, iovec, num_vecs); + ret = malloc(msg->len); + memcpy(ret, (char*) msg + sizeof(*msg), msg->len); + if (len) + *len = msg->len - 1; + free(msg); + return ret; +} + +static void *xs_single(struct xs_handle *h, xs_transaction_t t, + enum xsd_sockmsg_type type, + const char *string, + unsigned int *len) +{ + struct write_req iovec; + + iovec.data = (void *)string; + iovec.len = strlen(string) + 1; + + return xs_talkv(h, t, type, &iovec, 1, len); +} + +char *xs_get_domain_path(struct xs_handle *h, unsigned int domid) +{ + char domid_str[MAX_STRLEN(domid)]; + + sprintf(domid_str, "%u", domid); + + return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL); +} + +char **xs_directory(struct xs_handle *h, xs_transaction_t t, + const char *path, unsigned int *num) +{ + char *msg; + char **entries, **res; + char *entry; + int i, n; + int size; + + msg = xenbus_ls(t, path, &res); + if (msg) { + printk("xs_directory(%s): %s\n", path, msg); + return NULL; + } + + size = 0; + for (n = 0; res[n]; n++) + size += strlen(res[n]) + 1; + + entries = malloc(n * sizeof(char *) + size); + entry = (char *) (&entries[n]); + + for (i = 0; i < n; i++) { + int l = strlen(res[i]) + 1; + memcpy(entry, res[i], l); + free(res[i]); + entries[i] = entry; + entry += l; + } + + *num = n; + return entries; +} + +bool xs_watch(struct xs_handle *h, const char *path, const char *token) +{ + int fd = _xs_fileno(h); + printk("xs_watch(%s, %s)\n", path, token); + return xs_bool(xenbus_watch_path_token(XBT_NULL, path, token, &files[fd].xenbus.events)); +} + +char **xs_read_watch(struct xs_handle *h, unsigned int *num) +{ + int fd = _xs_fileno(h); + struct xenbus_event *event; + event = files[fd].xenbus.events; + files[fd].xenbus.events = event->next; + printk("xs_read_watch() -> %s %s\n", event->path, event->token); + *num = 2; + return (char **) &event->path; +} + +bool xs_unwatch(struct xs_handle *h, const char *path, const char *token) +{ + printk("xs_unwatch(%s, %s)\n", path, token); + return xs_bool(xenbus_unwatch_path_token(XBT_NULL, path, token)); +} +#endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/main-caml.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/main-caml.c Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,42 @@ +/* + * Caml bootstrap + * + * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, January 2008 + */ + +#include <stdio.h> +#include <errno.h> + +#include <caml/mlvalues.h> +#include <caml/callback.h> +#include <unistd.h> + +/* Ugly binary compatibility with Linux */ +FILE *_stderr asm("stderr"); +int *__errno_location; +/* Will probably break everything, probably need to fetch from glibc */ +void *__ctype_b_loc; + +int main(int argc, char *argv[], char *envp[]) +{ + value *val; + + /* Get current thread's value */ + _stderr = stderr; + __errno_location = &errno; + + printf("starting caml\n"); + + /* Wait before things might hang up */ + sleep(1); + + caml_startup(argv); + val = caml_named_value("main"); + if (!val) { + printf("Couldn't find Caml main"); + return 1; + } + caml_callback(*val, Val_int(0)); + printf("callback returned\n"); + return 0; +} diff -r 88818d55e95a -r a905c582a406 extras/mini-os/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/main.c Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,167 @@ +/* + * POSIX-compatible main layer + * + * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, October 2007 + */ + +#ifdef HAVE_LIBC +#include <os.h> +#include <sched.h> +#include <console.h> +#include <netfront.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> +#include <fs.h> +#include <xenbus.h> +#include <events.h> + +extern int main(int argc, char *argv[], char *envp[]); +extern void __libc_init_array(void); +extern void __libc_fini_array(void); + +struct thread *main_thread; + +#if 0 +#include <stdio.h> +int main(int argc, char *argv[], char *envp[]) +{ + printf("Hello, World!\n"); + return 1; +} +#endif + +void _init(void) +{ +} + +void _fini(void) +{ +} + +static void call_main(void *p) +{ + char *args, /**path,*/ *msg, *c; + int argc; + char **argv; + char *envp[] = { NULL }; + char *vm; + int i; + char path[128]; + + /* Let other parts initialize (including console output) before maybe + * crashing. */ + //sleep(1); + + start_networking(); + init_fs_frontend(); + +#ifdef CONFIG_QEMU + if (!fs_import) { + printk("No FS backend found, is it running?\n"); + do_exit(); + } + + /* Fetch argc, argv from XenStore */ + char domid_s[10]; + int domid; + domid = xenbus_read_integer("target"); + if (domid == -1) { + printk("Couldn't read target\n"); + do_exit(); + } + snprintf(domid_s, sizeof(domid_s), "%d", domid); + + snprintf(path, sizeof(path), "/local/domain/%d/vm", domid); + msg = xenbus_read(XBT_NIL, path, &vm); + if (msg) { + printk("Couldn't read vm path\n"); + do_exit(); + } + printk("vm is at %s\n", vm); +#else + msg = xenbus_read(XBT_NIL, "vm", &vm); + if (msg) { + printk("Couldn't read vm path\n"); + do_exit(); + } +#endif + + snprintf(path, sizeof(path), "%s/image/dmargs", vm); + free(vm); + msg = xenbus_read(XBT_NIL, path, &args); + + if (msg) { + printk("Couldn't get stubdom args: %s\n", msg); + args = strdup(""); + } + + argc = 1; +#ifdef CONFIG_QEMU + argc += 2; +#endif + c = args; + while (*c) { + if (*c != ' ') { + argc++; + while (*c && *c != ' ') + c++; + } else { + while (*c == ' ') + c++; + } + } + argv = alloca((argc + 1) * sizeof(char *)); + argv[0] = "main"; + argc = 1; +#ifdef CONFIG_QEMU + argv[1] = "-d"; + argv[2] = domid_s; + argc += 2; +#endif + c = args; + while (*c) { + if (*c != ' ') { + argv[argc++] = c; + while (*c && *c != ' ') + c++; + } else { + *c++ = 0; + while (*c == ' ') + c++; + } + } + argv[argc] = NULL; + + for (i = 0; i < argc; i++) + printf("\"%s\" ", argv[i]); + printf("\n"); + + __libc_init_array(); + environ = envp; + tzset(); + + exit(main(argc, argv, envp)); +} + +void _exit(int ret) +{ + close_all_files(); + __libc_fini_array(); + printk("main returned %d\n", ret); + unbind_all_ports(); + if (!ret) { + /* No problem, just shutdown. */ + struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff }; + HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); + } + do_exit(); +} + +int app_main(start_info_t *si) +{ + printk("Dummy main: start_info=%p\n", si); + main_thread = create_thread("main", call_main, si); + return 0; +} +#endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/minios.mk --- a/extras/mini-os/minios.mk Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/minios.mk Tue Feb 12 14:35:39 2008 +0000 @@ -9,7 +9,7 @@ DEF_CFLAGS += -fno-builtin -Wall -Werror DEF_CFLAGS += -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,) DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline -DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION) +DEF_CPPFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION) DEF_ASFLAGS = -D__ASSEMBLY__ DEF_LDFLAGS = @@ -24,11 +24,9 @@ endif # DEF_... flags are the common mini-os flags, # ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS) +CPPFLAGS := $(DEF_CPPFLAGS) $(ARCH_CPPFLAGS) ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS) LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS) - -# The path pointing to the architecture specific header files. -ARCH_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM) # Special build dependencies. # Rebuild all after touching this/these file(s) @@ -44,18 +42,17 @@ HDRS += $(extra_heads) HDRS += $(extra_heads) # Add the special header directories to the include paths. -extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir)) -override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_INC) $(extra_incl) +override CPPFLAGS := $(CPPFLAGS) $(extra_incl) # The name of the architecture specific library. # This is on x86_32: libx86_32.a # $(ARCH_LIB) has to built in the architecture specific directory. -ARCH_LIB_NAME = $(TARGET_ARCH) +ARCH_LIB_NAME = $(XEN_TARGET_ARCH) ARCH_LIB := lib$(ARCH_LIB_NAME).a # This object contains the entrypoint for startup from Xen. # $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory. -HEAD_ARCH_OBJ := $(TARGET_ARCH).o +HEAD_ARCH_OBJ := $(XEN_TARGET_ARCH).o HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/mm.c --- a/extras/mini-os/mm.c Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/mm.c Tue Feb 12 14:35:39 2008 +0000 @@ -360,6 +360,29 @@ void free_pages(void *pointer, int order } +#ifdef HAVE_LIBC +void *sbrk(ptrdiff_t increment) +{ + unsigned long old_brk = brk; + unsigned long new_brk = old_brk + increment; + + if (new_brk > heap_end) { + printk("Heap exhausted: %p + %lx = %p > %p\n", old_brk, increment, new_brk, heap_end); + return NULL; + } + + if (new_brk > heap_mapped) { + unsigned long n = (new_brk - heap_mapped + PAGE_SIZE - 1) / PAGE_SIZE; + do_map_zero(heap_mapped, n); + heap_mapped += n * PAGE_SIZE; + } + + brk = new_brk; + + return (void *) old_brk; +} +#endif + void init_mm(void) diff -r 88818d55e95a -r a905c582a406 extras/mini-os/netfront.c --- a/extras/mini-os/netfront.c Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/netfront.c Tue Feb 12 14:35:39 2008 +0000 @@ -19,7 +19,10 @@ DECLARE_WAIT_QUEUE_HEAD(netfront_queue); +#ifdef HAVE_LIBC #define NETIF_SELECT_RX ((void*)-1) +#endif + #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE) @@ -50,6 +53,13 @@ struct netfront_dev { char *nodename; char *backend; +#ifdef HAVE_LIBC + int fd; + unsigned char *data; + size_t len; + size_t rlen; +#endif + void (*netif_rx)(unsigned char* data, int len); }; @@ -92,7 +102,8 @@ moretodo: cons = dev->rx.rsp_cons; int nr_consumed=0; - while ((cons != rp)) + int some = 0; + while ((cons != rp) && !some) { struct net_buffer* buf; unsigned char* page; @@ -116,7 +127,18 @@ moretodo: if(rx->status>0) { - dev->netif_rx(page+rx->offset,rx->status); +#ifdef HAVE_LIBC + if (dev->netif_rx == NETIF_SELECT_RX) { + int len = rx->status; + ASSERT(current == main_thread); + if (len > dev->len) + len = dev->len; + memcpy(dev->data, page+rx->offset, len); + dev->rlen = len; + some = 1; + } else +#endif + dev->netif_rx(page+rx->offset,rx->status); } nr_consumed++; @@ -127,7 +149,7 @@ moretodo: int more; RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more); - if(more) goto moretodo; + if(more && !some) goto moretodo; RING_IDX req_prod = dev->rx.req_prod_pvt; @@ -177,6 +199,9 @@ void network_tx_buf_gc(struct netfront_d txrsp = RING_GET_RESPONSE(&dev->tx, cons); if (txrsp->status == NETIF_RSP_NULL) continue; + + if (txrsp->status == NETIF_RSP_ERROR) + printk("packet error\n"); id = txrsp->id; struct net_buffer* buf = &dev->tx_buffers[id]; @@ -218,6 +243,22 @@ void netfront_handler(evtchn_port_t port local_irq_restore(flags); } +#ifdef HAVE_LIBC +void netfront_select_handler(evtchn_port_t port, struct pt_regs *regs, void *data) +{ + int flags; + struct netfront_dev *dev = data; + int fd = dev->fd; + + local_irq_save(flags); + network_tx_buf_gc(dev); + local_irq_restore(flags); + + files[fd].read = 1; + wake_up(&netfront_queue); +} +#endif + struct netfront_dev *init_netfront(char *nodename, void (*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6]) { xenbus_transaction_t xbt; @@ -266,7 +307,12 @@ struct netfront_dev *init_netfront(char dev->dom = op.remote_dom = xenbus_read_integer(path); HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); clear_evtchn(op.port); /* Without, handler gets invoked now! */ - dev->local_port = bind_evtchn(op.port, netfront_handler, dev); +#ifdef HAVE_LIBC + if (thenetif_rx == NETIF_SELECT_RX) + dev->local_port = bind_evtchn(op.port, netfront_select_handler, dev); + else +#endif + dev->local_port = bind_evtchn(op.port, netfront_handler, dev); dev->evtchn=op.port; txs = (struct netif_tx_sring*) alloc_page(); @@ -381,6 +427,23 @@ done: return dev; } +#ifdef HAVE_LIBC +int netfront_tap_open(char *nodename) { + struct netfront_dev *dev; + + dev = init_netfront(nodename, NETIF_SELECT_RX, NULL); + if (!dev) { + printk("TAP open failed\n"); + errno = EIO; + return -1; + } + dev->fd = alloc_fd(FTYPE_TAP); + printk("tap_open(%s) -> %d\n", nodename, dev->fd); + files[dev->fd].tap.dev = dev; + return dev->fd; +} +#endif + void shutdown_netfront(struct netfront_dev *dev) { char* err; @@ -481,3 +544,30 @@ void netfront_xmit(struct netfront_dev * network_tx_buf_gc(dev); local_irq_restore(flags); } + +#ifdef HAVE_LIBC +ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len) +{ + unsigned long flags; + int fd = dev->fd; + ASSERT(current == main_thread); + + dev->rlen = 0; + dev->data = data; + dev->len = len; + + local_irq_save(flags); + network_rx(dev); + if (!dev->rlen) + /* No data for us, make select stop returning */ + files[fd].read = 0; + /* Before re-enabling the interrupts, in case a packet just arrived in the + * meanwhile. */ + local_irq_restore(flags); + + dev->data = NULL; + dev->len = 0; + + return dev->rlen; +} +#endif diff -r 88818d55e95a -r a905c582a406 extras/mini-os/sched.c --- a/extras/mini-os/sched.c Tue Feb 12 11:37:45 2008 +0000 +++ b/extras/mini-os/sched.c Tue Feb 12 14:35:39 2008 +0000 @@ -56,6 +56,7 @@ struct thread *idle_thread = NULL; LIST_HEAD(exited_threads); +static int threads_started; void inline print_runqueue(void) { @@ -172,6 +173,9 @@ struct thread* create_thread(char *name, /* Not runable, not exited, not sleeping */ thread->flags = 0; thread->wakeup_time = 0LL; +#ifdef HAVE_LIBC + _REENT_INIT_PTR((&thread->reent)) +#endif set_runnable(thread); local_irq_save(flags); if(idle_thread != NULL) { @@ -184,6 +188,42 @@ struct thread* create_thread(char *name, local_irq_restore(flags); return thread; } + +#ifdef HAVE_LIBC +static struct _reent callback_reent; +struct _reent *__getreent(void) +{ + struct _reent *_reent; + + if (!threads_started) + _reent = _impure_ptr; + else if (in_callback) + _reent = &callback_reent; + else + _reent = &get_current()->reent; + +#ifndef NDEBUG +#if defined(__x86_64__) || defined(__x86__) + { +#ifdef __x86_64__ + register unsigned long sp asm ("rsp"); +#else + register unsigned long sp asm ("esp"); +#endif + if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) { + static int overflowing; + if (!overflowing) { + overflowing = 1; + printk("stack overflow\n"); + BUG(); + } + } + } +#endif +#endif + return _reent; +} +#endif void exit_thread(void) { @@ -228,6 +268,7 @@ void idle_thread_fn(void *unused) void idle_thread_fn(void *unused) { s_time_t until; + threads_started = 1; unsigned long flags; struct list_head *iterator; struct thread *next, *thread; @@ -297,6 +338,9 @@ void init_sched(void) { printk("Initialising scheduler\n"); +#ifdef HAVE_LIBC + _REENT_INIT_PTR((&callback_reent)) +#endif idle_thread = create_thread("Idle", idle_thread_fn, NULL); INIT_LIST_HEAD(&idle_thread->thread_list); } diff -r 88818d55e95a -r a905c582a406 stubdom/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,256 @@ +XEN_ROOT = .. + +include $(XEN_ROOT)/Config.mk +export stubdom=y +export debug=y + +IOEMU_OPTIONS=--disable-vnc-tls +BINUTILS_VERSION=2.18 +GCC_VERSION=4.2.2 +ZLIB_VERSION=1.2.3 +LIBPCI_VERSION=2.2.9 +NEWLIB_DATE=2008-01-01 +LWIP_DATE=2008-02-08 + +WGET=wget -c + +GNU_TARGET_ARCH:=$(XEN_TARGET_ARCH) +ifeq ($(XEN_TARGET_ARCH),x86_32) +GNU_TARGET_ARCH:=i686 +endif + +ifeq ($(GNU_TARGET_ARCH), i686) +TARGET_CFLAGS= +endif +ifeq ($(GNU_TARGET_ARCH), x86_64) +TARGET_CFLAGS=-mno-red-zone +endif +ifeq ($(GNU_TARGET_ARCH), ia64) +TARGET_CFLAGS=-mconstant-gp +endif + +CROSS_ROOT=cross-root-$(GNU_TARGET_ARCH) +CROSS_PREFIX=$(CURDIR)/$(CROSS_ROOT) +export CROSS_COMPILE=$(GNU_TARGET_ARCH)-xen-elf- +export PATH:=$(CROSS_PREFIX)/bin:$(PATH) + +.PHONY: all +all: qemu-stubdom + +################ +# Cross-binutils +################ + +binutils-$(BINUTILS_VERSION).tar.bz2: + $(WGET) http://ftp.gnu.org/gnu/binutils/$@ +binutils-$(BINUTILS_VERSION): binutils-$(BINUTILS_VERSION).tar.bz2 + tar xjf $@.tar.bz2 + ( cd binutils-$(BINUTILS_VERSION) && patch -p1 < ../binutils.patch ) + touch $@ + +BINUTILS_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-ar +.PHONY: cross-binutils +cross-binutils: $(BINUTILS_STAMPFILE) +$(BINUTILS_STAMPFILE): binutils-$(BINUTILS_VERSION) + mkdir -p binutils.build + ( cd binutils.build && \ + ../binutils-$(BINUTILS_VERSION)/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf && \ + $(MAKE) && \ + $(MAKE) check && \ + $(MAKE) install ) + +########### +# Cross-gcc +########### + +gcc-$(GCC_VERSION).tar.bz2: + $(WGET) http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.bz2 +gcc-$(GCC_VERSION): gcc-$(GCC_VERSION).tar.bz2 + tar xjf gcc-$(GCC_VERSION).tar.bz2 + ( cd gcc-$(GCC_VERSION) && patch -p1 < ../gcc.patch ) + touch $@ + +GCC_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-gcc-$(GCC_VERSION) +.PHONY: cross-gcc +cross-gcc: $(GCC_STAMPFILE) +$(GCC_STAMPFILE): gcc-$(GCC_VERSION) $(BINUTILS_STAMPFILE) + mkdir -p gcc.build + ( cd gcc.build && \ + ../gcc-$(GCC_VERSION)/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-languages=c --disable-libssp --with-gnu-as --with-gnu-ld && \ + $(MAKE) GCC_FOR_TARGET='$$$$r/gcc/xgcc -B$$$$r/gcc/ '"$(TARGET_CFLAGS)"' $$(FLAGS_FOR_TARGET)' && \ + $(MAKE) install ) + +############## +# Cross-newlib +############## + +newlib: + cvs -z 9 -d :pserver:anoncvs@xxxxxxxxxxxxxxxxxx:/cvs/src co -D $(NEWLIB_DATE) newlib + mv src newlib + ( cd newlib && patch -p0 < ../newlib.patch) + +NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a +.PHONY: cross-newlib +cross-newlib: $(NEWLIB_STAMPFILE) +$(NEWLIB_STAMPFILE): newlib $(GCC_STAMPFILE) + mkdir -p newlib.build + ( cd newlib.build && \ + CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" ../newlib/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \ + $(MAKE) && \ + $(MAKE) install ) + +############ +# Cross-zlib +############ + +zlib-$(ZLIB_VERSION).tar.gz: + $(WGET) http://www.zlib.net/zlib-$(ZLIB_VERSION).tar.gz + +ZLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libz.a +.PHONY: cross-zlib +cross-zlib: $(ZLIB_STAMPFILE) +$(ZLIB_STAMPFILE): zlib-$(ZLIB_VERSION).tar.gz $(NEWLIB_STAMPFILE) + tar xzf $< + ( cd zlib-$(ZLIB_VERSION) && \ + CFLAGS="$(TARGET_CFLAGS)" CC=$(GNU_TARGET_ARCH)-xen-elf-gcc ./configure --prefix=$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf && \ + $(MAKE) libz.a && \ + $(MAKE) install ) + +############## +# Cross-libpci +############## + +pciutils-$(LIBPCI_VERSION).tar.bz2: + $(WGET) http://www.kernel.org/pub/software/utils/pciutils/pciutils-$(LIBPCI_VERSION).tar.bz2 + +LIBPCI_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libpci.a +.PHONY: cross-libpci +cross-libpci: $(LIBPCI_STAMPFILE) +$(LIBPCI_STAMPFILE): pciutils-$(LIBPCI_VERSION).tar.bz2 $(NEWLIB_STAMPFILE) $(ZLIB_STAMPFILE) + tar xjf $< + ( cd pciutils-$(LIBPCI_VERSION) && \ + cp ../libpci.config.h lib/config.h && \ + echo '#define PCILIB_VERSION "$(LIBPCI_VERSION)"' >> lib/config.h && \ + cp ../libpci.config.mak lib/config.mk && \ + $(MAKE) CC="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" lib/libpci.a && \ + $(INSTALL_DATA) lib/libpci.a $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib/ && \ + $(INSTALL_DIR) $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci && \ + $(INSTALL_DATA) lib/{config,header,pci,types}.h $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci/ \ + ) + +###### +# lwIP +###### + +lwip: + cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/lwip co -D $(LWIP_DATE) lwip + +####### +# Links +####### + +.PHONY: $(CROSS_ROOT) +$(CROSS_ROOT): cross-newlib cross-zlib cross-libpci + +.PHONY: mk-symlinks +mk-symlinks: + [ -h include ] || ln -sf ../tools/include . + mkdir -p libxc + [ -h libxc/Makefile ] || ( cd libxc && \ + ln -sf ../../tools/libxc/*.h . && \ + ln -sf ../../tools/libxc/*.c . && \ + ln -sf ../../tools/libxc/Makefile . ) + mkdir -p libxc/$(XEN_TARGET_ARCH) + [ -h libxc/$(XEN_TARGET_ARCH) ] || ( cd libxc/$(XEN_TARGET_ARCH) && \ + ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \ + ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \ + ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/Makefile . ) + mkdir -p ioemu + [ -h ioemu/Makefile ] || ( cd ioemu && \ + ln -sf ../../tools/ioemu/* . && \ + ([ ! -h config-host.h ] || rm -f config-host.h) && \ + ([ ! -h config-host.mak ] || rm -f config-host.mak) ) + [ -h mini-os ] || ln -sf ../extras/mini-os . + +####### +# libxc +####### + +.PHONY: libxc +libxc: cross-zlib mk-symlinks + $(MAKE) -C $@ + +####### +# ioemu +####### + +.PHONY: ioemu +ioemu: cross-zlib cross-libpci mk-symlinks libxc + [ -f ioemu/config-host.mak ] || \ + ( cd ioemu ; XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) sh configure --prefix=/usr --enable-stubdom $(IOEMU_OPTIONS)) + $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip + +###### +# caml +###### + +.PHONY: caml +caml: + $(MAKE) -C $@ + +######## +# minios +######## + +.PHONY: qemu-stubdom +qemu-stubdom: mk-symlinks lwip libxc ioemu + $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip QEMUDIR=$(CURDIR)/ioemu + +.PHONY: caml-stubdom +caml-stubdom: mk-symlinks lwip libxc cross-libpci caml + $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip CAMLDIR=$(CURDIR)/caml + +######### +# install +######### + +install: mini-os/mini-os.gz + $(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin" + $(INSTALL_PROG) mini-os/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz" + +####### +# clean +####### + +# Only clean the libxc/ioemu/mini-os part +.PHONY: clean +clean: + -$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip clean + $(MAKE) -C caml clean + rm -fr libxc ioemu mini-os include + +# clean the cross-compilation result +.PHONY: crossclean +crossclean: clean + rm -fr $(CROSS_ROOT) + rm -fr binutils.build gcc.build newlib.build + rm -fr zlib-$(ZLIB_VERSION) pciutils-$(LIBPCI_VERSION) + +# clean patched sources +.PHONY: patchclean +patchclean: crossclean + rm -fr binutils-$(BINUTILS_VERSION) + rm -fr gcc-$(GCC_VERSION) + rm -fr newlib + rm -fr lwip + +# clean downloads +.PHONY: downloadclean +downloadclean: patchclean + rm -f binutils-$(BINUTILS_VERSION).tar.bz2 + rm -f gcc-$(GCC_VERSION).tar.bz2 + rm -f zlib-$(ZLIB_VERSION).tar.gz + rm -f pciutils-$(LIBPCI_VERSION).tar.bz2 + +.PHONY: distclean +distclean: downloadclean diff -r 88818d55e95a -r a905c582a406 stubdom/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/README Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,41 @@ +To compile +========== + +Just run make -j 4, that will download / patch / compile +Then make install to install the result. + +Also, run make and make install in $XEN_ROOT/tools/fs-back + +To run +====== + +mkdir -p /exports/usr/share/qemu +ln -s /usr/share/qemu/keymaps /exports/usr/share/qemu +/usr/sbin/fs-backend & + + +In your HVM config "hvmconfig", + +- use VNC, set vnclisten to "172.30.206.1" for instance: + +vnc=1 +vnclisten="172.30.206.1" + +- use /usr/lib/xen/bin/stubdom-dm as dm script + +device_model = '/usr/lib/xen/bin/stubdom-dm' + +- comment the disk statement: +#disk = [ 'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ] + +Create /etc/xen/stubdom-hvmconfig ("hvmconfig" must match your main config file) +with + +kernel="/usr/lib/xen/boot/stubdom.gz" +vif=[ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34'] +disk = [ 'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ] + +where +- 172.30.206.1 is the IP for vnc, +- 'ip=10.0.1.1,mac=' is the same net configuration as in the hvmconfig script, +- and disk = is the same block configuration as in the hvmconfig script. diff -r 88818d55e95a -r a905c582a406 stubdom/caml/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/caml/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,18 @@ +XEN_ROOT = ../.. + +include $(XEN_ROOT)/Config.mk + +OCAMLFIND=ocamlfind +OCAMLOPT=ocamlopt + +OBJS := hello.cmx +LIBS := + +%.cmx: %.ml + $(OCAMLFIND) $(OCAMLOPT) -c $< -o $@ + +caml.o: $(OBJS) + $(OCAMLFIND) $(OCAMLOPT) $(LIBS) $^ -output-obj -o $@ + +clean: + rm -f *.o *.cmx *.cmi diff -r 88818d55e95a -r a905c582a406 stubdom/caml/hello.ml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/caml/hello.ml Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,4 @@ +let main arg = + Printf.printf "Hello, world!\n%!." + +let _ = Callback.register "main" main diff -r 88818d55e95a -r a905c582a406 stubdom/libpci.config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/libpci.config.h Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,5 @@ +#define PCI_OS_STUBDOM +#define PCI_HAVE_STDINT_H +#define PCI_PATH_IDS_DIR "." +#define PCI_COMPRESSED_IDS +#define PCI_IDS "pci.ids.gz" diff -r 88818d55e95a -r a905c582a406 stubdom/libpci.config.mak --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/libpci.config.mak Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,2 @@ +LIBZ=-lz +LDLIBS+=$(LIBZ) diff -r 88818d55e95a -r a905c582a406 stubdom/stubdom-dm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/stubdom-dm Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Copyright 2007-2008 Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx> +# +# dm script around stubdomains. +# + +# To fit xterms nicely +height=339 + +# Parse arguments + +domid= +domname= +vncviewer=0 +vncpid= +while [ "$#" -gt 0 ]; +do + if [ "$#" -ge 2 ]; + then + case "$1" in + -d) domid=$2; shift ;; + -domain-name) domname=$2; shift ;; + -vnc) + ip=${2%:*}; + vnc_port=${2#*:}; + shift + ;; + esac + fi + case "$1" in + -vncviewer) vncviewer=1 ;; + esac + shift +done + +[ -z "$domid" ] && ( echo "couldn't find domain ID" ; exit 1 ) +[ -z "$domname" ] && ( echo "couldn't find domain name" ; exit 1 ) + +# Termination handler + +term() { + kill %1 + ( + [ -n "$vncpid" ] && kill -9 $vncpid + xm destroy stubdom-$domname + #xm destroy $domname + ) & + # We need to exit immediately so as to let xend do the commands above + exit 0 +} + +trap term SIGHUP + +############ +# stubdomain +# Wait for any previous stubdom to terminate +while xm list | grep stubdom-$domname +do + sleep 1 +done + +creation="xm create -c stubdom-$domname target=$domid memory=32" + +(while true ; do sleep 60 ; done) | $creation & +#xterm -geometry +0+0 -e /bin/sh -c "$creation ; echo ; echo press ENTER to shut down ; read" & +consolepid=$! + + +while ! vnc_port=`xenstore-read /local/domain/$domid/console/vnc-port` +do + # Check that the stubdom job is still alive + kill -0 $consolepid || term + sleep 1 +done + +################ +# DEBUG: tcpdump +#while ! stubdomid=`xm domid stubdom-$domname` +#do +# sleep 1 +#done +#xterm -geometry 160x25+0+$height -e /bin/sh -c "tcpdump -n -i vif$stubdomid.0" & +#xterm -geometry 160x25+0+$((2 * $height)) -e /bin/sh -c "tcpdump -n -i vif$stubdomid.1" & + +########### +# vncviewer +if [ "$vncviewer" = 1 ] +then + vncviewer $ip:$vnc_port & + vncpid=$! +fi + +# wait for SIGHUP or stubdom termination +wait $consolepid + +term diff -r 88818d55e95a -r a905c582a406 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/Makefile.target Tue Feb 12 14:35:39 2008 +0000 @@ -15,7 +15,7 @@ endif endif TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB) VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio -CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) +CPPFLAGS+=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore CPPFLAGS+= -I$(XEN_ROOT)/tools/include @@ -66,7 +66,11 @@ QEMU_SYSTEM=qemu-fast QEMU_SYSTEM=qemu-fast endif +ifdef CONFIG_STUBDOM +QEMU_SYSTEM=qemu.a +else QEMU_SYSTEM=qemu-dm +endif ifdef CONFIG_USER_ONLY PROGS=$(QEMU_USER) @@ -345,14 +349,25 @@ VL_OBJS+=cutils.o VL_OBJS+=cutils.o VL_OBJS+=block.o block-raw.o VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o +ifdef CONFIG_STUBDOM +VL_OBJS+=block-vbd.o +endif ifdef CONFIG_WIN32 VL_OBJS+=tap-win32.o endif -ifeq (,$(wildcard /usr/include/pci)) +ifdef CONFIG_STUBDOM +CONFIG_PASSTHROUGH=1 +else + ifeq (,$(wildcard /usr/include/pci)) $(warning *** pciutils-devl package not found - missing /usr/include/pci) $(warning *** PCI passthrough capability has been disabled) -else + else +CONFIG_PASSTHROUGH=1 + endif +endif + +ifdef CONFIG_PASSTHROUGH LIBS+=-lpci VL_OBJS+= pass-through.o CFLAGS += -DCONFIG_PASSTHROUGH @@ -404,13 +419,13 @@ VL_OBJS+= ne2000.o rtl8139.o pcnet.o e10 ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support -VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) extboot.o +VL_OBJS+= ide.o pckbd.o ps2.o vga.o dma.o extboot.o ifeq ($(ARCH),ia64) VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o else VL_OBJS+= fdc.o serial.o pc.o endif -VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o +VL_OBJS+= cirrus_vga.o parallel.o acpi.o VL_OBJS+= usb-uhci.o smbus_eeprom.o VL_OBJS+= piix4acpi.o VL_OBJS+= xenstore.o @@ -419,22 +434,31 @@ VL_OBJS+= xen_machine_pv.o VL_OBJS+= xen_machine_pv.o VL_OBJS+= xenfb.o VL_OBJS+= xen_console.o +ifndef CONFIG_STUBDOM VL_OBJS+= tpm_tis.o +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o CPPFLAGS += -DHAS_TPM CPPFLAGS += -DHAS_AUDIO endif +endif ifeq ($(TARGET_BASE_ARCH), ppc) -VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) +VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o dma.o VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o +ifndef CONFIG_STUBDOM +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) CPPFLAGS += -DHAS_AUDIO +endif endif ifeq ($(TARGET_ARCH), mips) VL_OBJS+= mips_r4k.o mips_malta.o mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o -VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV) +VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o +ifndef CONFIG_STUBDOM +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) DEFINES += -DHAS_AUDIO +endif endif ifeq ($(TARGET_BASE_ARCH), sparc) ifeq ($(TARGET_ARCH), sparc64) @@ -513,7 +537,11 @@ endif endif $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a +ifdef CONFIG_STUBDOM + $(AR) rcs $@ $(VL_OBJS) +else $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) +endif cocoa.o: cocoa.m $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $< diff -r 88818d55e95a -r a905c582a406 tools/ioemu/aes.c --- a/tools/ioemu/aes.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/aes.c Tue Feb 12 14:35:39 2008 +0000 @@ -33,9 +33,11 @@ #define NDEBUG #include <assert.h> +#ifndef CONFIG_STUBDOM typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; +#endif #define MAXKC (256/32) #define MAXKB (256/8) diff -r 88818d55e95a -r a905c582a406 tools/ioemu/block-vbd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/block-vbd.c Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,341 @@ +/* + * Block driver for Mini-os PV devices + * Based on block-raw.c + * + * Copyright (c) 2006 Fabrice Bellard, 2007 Samuel Thibault + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "vl.h" +#include "block_int.h" +#include <assert.h> +#include <xenbus.h> +#include <blkfront.h> +#include <malloc.h> + +#define SECTOR_SIZE 512 + +#ifndef QEMU_TOOL +#include "exec-all.h" +#endif + +#define DEBUG_BLOCK +#ifdef DEBUG_BLOCK +#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile ) +#else +#define DEBUG_BLOCK_PRINT( formatCstr, args... ) +#endif + +#define FTYPE_FILE 0 +#define FTYPE_CD 1 +#define FTYPE_FD 2 + +typedef struct BDRVVbdState { + struct blkfront_dev *dev; + int fd; + int type; + int mode; + uint64_t sectors; + unsigned sector_size; + QEMU_LIST_ENTRY(BDRVVbdState) list; +} BDRVVbdState; + +QEMU_LIST_HEAD(, BDRVVbdState) vbds; + +static int vbd_probe(const uint8_t *buf, int buf_size, const char *filename) +{ + char *value; + if (xenbus_read(XBT_NIL, filename, &value)) + return 0; + free(value); + return 100; +} + +static int vbd_open(BlockDriverState *bs, const char *filename, int flags) +{ + BDRVVbdState *s = bs->opaque; + + //handy to test posix access + //return -EIO; + + s->dev = init_blkfront((char *) filename, &s->sectors, &s->sector_size, &s->mode); + + if (!s->dev) + return -EIO; + + if (SECTOR_SIZE % s->sector_size) { + printf("sector size is %d, we only support sector sizes that divide %d\n", s->sector_size, SECTOR_SIZE); + return -EIO; + } + + s->fd = blkfront_open(s->dev); + + QEMU_LIST_INSERT_HEAD(&vbds, s, list); + + return 0; +} + +typedef struct VbdAIOCB { + BlockDriverAIOCB common; + struct blkfront_aiocb aiocb; +} VbdAIOCB; + +void qemu_aio_init(void) +{ +} + +void qemu_aio_poll(void) +{ + BDRVVbdState *s; + for (s = vbds.lh_first; s; s = s->list.le_next) + blkfront_aio_poll(s->dev); +} + +/* Wait for all IO requests to complete. */ +void qemu_aio_flush(void) +{ + BDRVVbdState *s; + for (s = vbds.lh_first; s; s = s->list.le_next) + blkfront_sync(s->dev); +} + +void qemu_aio_wait_start(void) +{ +} + +void qemu_aio_wait(void) +{ + int some = 0; + DEFINE_WAIT(w); + while (1) { + BDRVVbdState *s; + add_waiter(w, blkfront_queue); + for (s = vbds.lh_first; s; s = s->list.le_next) + if (blkfront_aio_poll(s->dev)) + some = 1; + if (some) + break; + schedule(); + } + remove_waiter(w); +} + +void qemu_aio_wait_end(void) +{ +} + +static void vbd_aio_callback(struct blkfront_aiocb *aiocbp, int ret) { + VbdAIOCB *acb = aiocbp->data; + + acb->common.cb(acb->common.opaque, ret); + qemu_aio_release(acb); +} + +static VbdAIOCB *vbd_aio_setup(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + BDRVVbdState *s = bs->opaque; + VbdAIOCB *acb; + + acb = qemu_aio_get(bs, cb, opaque); + if (!acb) + return NULL; + acb->aiocb.aio_dev = s->dev; + acb->aiocb.aio_buf = buf; + acb->aiocb.aio_nbytes = nb_sectors * SECTOR_SIZE; + acb->aiocb.aio_offset = sector_num * SECTOR_SIZE; + acb->aiocb.aio_cb = vbd_aio_callback; + acb->aiocb.data = acb; + + return acb; +} + +static BlockDriverAIOCB *vbd_aio_read(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + VbdAIOCB *acb; + + acb = vbd_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque); + if (!acb) + return NULL; + blkfront_aio(&acb->aiocb, 0); + return &acb->common; +} + +static BlockDriverAIOCB *vbd_aio_write(BlockDriverState *bs, + int64_t sector_num, const uint8_t *buf, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + VbdAIOCB *acb; + + acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, cb, opaque); + if (!acb) + return NULL; + blkfront_aio(&acb->aiocb, 1); + return &acb->common; +} + +static void vbd_cb(void *data, int ret) { + int *result = data; + result[0] = 1; + result[1] = ret; +} + +static int vbd_aligned_io(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors, int write) +{ + VbdAIOCB *acb; + int result[2]; + result[0] = 0; + qemu_aio_wait_start(); + acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, vbd_cb, &result); + blkfront_aio(&acb->aiocb, write); + while (!result[0]) + qemu_aio_wait(); + qemu_aio_wait_end(); + return result[1]; +} + +static int vbd_read(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors) +{ + uint8_t *iobuf; + int ret; + /* page alignment would be a bit better, but that's still fine compared to + * copying */ + if (!((uintptr_t)buf & (SECTOR_SIZE-1))) + return vbd_aligned_io(bs, sector_num, buf, nb_sectors, 0); + iobuf = memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE); + ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 0); + memcpy(buf, iobuf, nb_sectors * SECTOR_SIZE); + free(iobuf); + if (ret < 0) + return ret; + else if (ret != nb_sectors * SECTOR_SIZE) + return -EINVAL; + else + return 0; +} + +static int vbd_write(BlockDriverState *bs, + int64_t sector_num, const uint8_t *buf, int nb_sectors) +{ + uint8_t *iobuf; + int ret; + if (!((uintptr_t)buf & (SECTOR_SIZE-1))) + return vbd_aligned_io(bs, sector_num, (uint8_t*) buf, nb_sectors, 1); + iobuf = memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE); + memcpy(iobuf, buf, nb_sectors * SECTOR_SIZE); + ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 1); + free(iobuf); + if (ret < 0) + return ret; + else if (ret != nb_sectors * SECTOR_SIZE) + return -EINVAL; + else + return 0; +} + +static void vbd_aio_cancel(BlockDriverAIOCB *blockacb) +{ + /* TODO */ + //VbdAIOCB *acb = (VbdAIOCB *)blockacb; + + // Try to cancel. If can't, wait for it, drop the callback and call qemu_aio_release(acb) +} + +static void vbd_close(BlockDriverState *bs) +{ + BDRVVbdState *s = bs->opaque; + bs->total_sectors = 0; + if (s->fd >= 0) { + close(s->fd); + s->fd = -1; + } + QEMU_LIST_REMOVE(s, list); +} + +static int64_t vbd_getlength(BlockDriverState *bs) +{ + BDRVVbdState *s = bs->opaque; + return s->sectors * s->sector_size; +} + +static void vbd_flush(BlockDriverState *bs) +{ + BDRVVbdState *s = bs->opaque; + blkfront_sync(s->dev); +} + +/***********************************************/ +/* host device */ + +static int vbd_is_inserted(BlockDriverState *bs) +{ + /* TODO: monitor the backend */ + return 1; +} + +/* currently only used by fdc.c, but a CD version would be good too */ +static int vbd_media_changed(BlockDriverState *bs) +{ + /* TODO: monitor the backend */ + return -ENOTSUP; +} + +static int vbd_eject(BlockDriverState *bs, int eject_flag) +{ + /* TODO: Xen support needed */ + return -ENOTSUP; +} + +static int vbd_set_locked(BlockDriverState *bs, int locked) +{ + /* TODO: Xen support needed */ + return -ENOTSUP; +} + +BlockDriver bdrv_vbd = { + "vbd", + sizeof(BDRVVbdState), + vbd_probe, + vbd_open, + NULL, + NULL, + vbd_close, + NULL, + vbd_flush, + + .bdrv_aio_read = vbd_aio_read, + .bdrv_aio_write = vbd_aio_write, + .bdrv_aio_cancel = vbd_aio_cancel, + .aiocb_size = sizeof(VbdAIOCB), + .bdrv_read = vbd_read, + .bdrv_write = vbd_write, + .bdrv_getlength = vbd_getlength, + + /* removable device support */ + .bdrv_is_inserted = vbd_is_inserted, + .bdrv_media_changed = vbd_media_changed, + .bdrv_eject = vbd_eject, + .bdrv_set_locked = vbd_set_locked, +}; + diff -r 88818d55e95a -r a905c582a406 tools/ioemu/block.c --- a/tools/ioemu/block.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/block.c Tue Feb 12 14:35:39 2008 +0000 @@ -1235,6 +1235,9 @@ void bdrv_init(void) { bdrv_register(&bdrv_raw); bdrv_register(&bdrv_host_device); +#ifdef CONFIG_STUBDOM + bdrv_register(&bdrv_vbd); +#endif #ifndef _WIN32 bdrv_register(&bdrv_cow); #endif diff -r 88818d55e95a -r a905c582a406 tools/ioemu/configure --- a/tools/ioemu/configure Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/configure Tue Feb 12 14:35:39 2008 +0000 @@ -74,6 +74,7 @@ linux_user="no" linux_user="no" darwin_user="no" build_docs="no" +stubdom="no" uname_release="" # OS specific @@ -230,6 +231,8 @@ for opt do --enable-darwin-user) darwin_user="yes" ;; --enable-uname-release=*) uname_release="$optarg" + ;; + --enable-stubdom) stubdom="yes" ;; esac done @@ -416,7 +419,11 @@ if test -z "$target_list" ; then target_list="i386-darwin-user ppc-darwin-user $target_list" fi # the i386-dm target - target_list="i386-dm" + if test "$stubdom" = "yes"; then + target_list="i386-dm-stubdom" + else + target_list="i386-dm" + fi else target_list=`echo "$target_list" | sed -e 's/,/ /g'` fi @@ -573,6 +580,11 @@ docdir="$prefix/share/doc/qemu" docdir="$prefix/share/doc/qemu" bindir="$prefix/$libdir/xen/bin" configdir="/etc/xen" +fi + +if test "$stubdom" = "yes"; then + oss="no" + sdl="no" fi echo "Install prefix $prefix" @@ -943,6 +955,14 @@ if expr $target : '.*-dm' > /dev/null ; echo "#define CONFIG_DM 1" >> $config_h fi +if test "$stubdom" = "yes" ; then + echo "CONFIG_STUBDOM=yes" >> $config_mak + echo "#define CONFIG_STUBDOM 1" >> $config_h + echo "#define NO_UNIX_SOCKETS 1" >> $config_h + echo "#define NO_DAEMONIZE 1" >> $config_h + echo "#define NO_AIO 1" >> $config_h +fi + if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64" -o "$target_cpu" = "m68k"; then echo "CONFIG_SOFTFLOAT=yes" >> $config_mak echo "#define CONFIG_SOFTFLOAT 1" >> $config_h diff -r 88818d55e95a -r a905c582a406 tools/ioemu/exec-all.h --- a/tools/ioemu/exec-all.h Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/exec-all.h Tue Feb 12 14:35:39 2008 +0000 @@ -481,6 +481,9 @@ static inline int testandset (int *p) } #endif +#ifdef CONFIG_STUBDOM +#include <spinlock.h> +#else typedef int spinlock_t; #define SPIN_LOCK_UNLOCKED 0 @@ -513,6 +516,7 @@ static inline int spin_trylock(spinlock_ { return 1; } +#endif #endif extern spinlock_t tb_lock; diff -r 88818d55e95a -r a905c582a406 tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/hw/ide.c Tue Feb 12 14:35:39 2008 +0000 @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "vl.h" +#include <malloc.h> /* debug IDE devices */ //#define DEBUG_IDE @@ -347,7 +348,7 @@ typedef struct IDEState { EndTransferFunc *end_transfer_func; uint8_t *data_ptr; uint8_t *data_end; - uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; + uint8_t *io_buffer; QEMUTimer *sector_write_timer; /* only used for win2k instal hack */ uint32_t irq_count; /* counts IRQs when using win2k install hack */ } IDEState; @@ -2305,6 +2306,7 @@ static void ide_init2(IDEState *ide_stat for(i = 0; i < 2; i++) { s = ide_state + i; + s->io_buffer = memalign(getpagesize(), MAX_MULT_SECTORS*512 + 4); if (i == 0) s->bs = hd0; else diff -r 88818d55e95a -r a905c582a406 tools/ioemu/hw/scsi-disk.c --- a/tools/ioemu/hw/scsi-disk.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/hw/scsi-disk.c Tue Feb 12 14:35:39 2008 +0000 @@ -26,13 +26,18 @@ do { fprintf(stderr, "scsi-disk: " fmt , do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0) #include "vl.h" +#include <malloc.h> #define SENSE_NO_SENSE 0 #define SENSE_NOT_READY 2 #define SENSE_HARDWARE_ERROR 4 #define SENSE_ILLEGAL_REQUEST 5 +#ifdef CONFIG_STUBDOM +#define SCSI_DMA_BUF_SIZE 32768 +#else #define SCSI_DMA_BUF_SIZE 65536 +#endif typedef struct SCSIRequest { SCSIDevice *dev; @@ -44,7 +49,7 @@ typedef struct SCSIRequest { int sector_count; /* The amounnt of data in the buffer. */ int buf_len; - uint8_t dma_buf[SCSI_DMA_BUF_SIZE]; + uint8_t *dma_buf; BlockDriverAIOCB *aiocb; struct SCSIRequest *next; } SCSIRequest; @@ -76,6 +81,7 @@ static SCSIRequest *scsi_new_request(SCS free_requests = r->next; } else { r = qemu_malloc(sizeof(SCSIRequest)); + r->dma_buf = memalign(getpagesize(), SCSI_DMA_BUF_SIZE); } r->dev = s; r->tag = tag; diff -r 88818d55e95a -r a905c582a406 tools/ioemu/hw/xen_machine_fv.c --- a/tools/ioemu/hw/xen_machine_fv.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/hw/xen_machine_fv.c Tue Feb 12 14:35:39 2008 +0000 @@ -24,6 +24,9 @@ */ #include "vl.h" +#ifdef CONFIG_STUBDOM +#include <xenbus.h> +#endif #include <xen/hvm/params.h> #include <sys/mman.h> diff -r 88818d55e95a -r a905c582a406 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/vl.c Tue Feb 12 14:35:39 2008 +0000 @@ -36,22 +36,29 @@ #include <sys/times.h> #include <sys/wait.h> #include <termios.h> +#ifndef CONFIG_STUBDOM #include <sys/poll.h> +#endif #include <sys/mman.h> #include <sys/ioctl.h> #include <sys/resource.h> #include <sys/socket.h> #include <netinet/in.h> +#ifndef CONFIG_STUBDOM #include <net/if.h> +#endif #if defined(__NetBSD__) #include <net/if_tap.h> #endif #if defined(__linux__) || defined(__Linux__) #include <linux/if_tun.h> #endif +#ifndef CONFIG_STUBDOM #include <arpa/inet.h> #include <dirent.h> +#endif #include <netdb.h> +#ifndef CONFIG_STUBDOM #ifdef _BSD #include <sys/stat.h> #ifndef _BSD @@ -70,6 +77,7 @@ #include <stropts.h> #endif #endif +#endif #if defined(CONFIG_SLIRP) #include "libslirp.h" @@ -132,10 +140,9 @@ #define MAX_IOPORTS 65536 const char *bios_dir = CONFIG_QEMU_SHAREDIR; -char phys_ram_file[1024]; -void *ioport_opaque[MAX_IOPORTS]; -IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; -IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; +void **ioport_opaque; +IOPortReadFunc *(*ioport_read_table)[MAX_IOPORTS]; +IOPortWriteFunc *(*ioport_write_table)[MAX_IOPORTS]; /* Note: bs_table[MAX_DISKS] is a dummy block driver if none available to store the VM snapshots */ BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1], *fd_table[MAX_FD]; @@ -270,6 +277,9 @@ void default_ioport_writel(void *opaque, void init_ioports(void) { + ioport_opaque = malloc(MAX_IOPORTS * sizeof(*ioport_opaque)); + ioport_read_table = malloc(3 * MAX_IOPORTS * sizeof(**ioport_read_table)); + ioport_write_table = malloc(3 * MAX_IOPORTS * sizeof(**ioport_write_table)); } /* size is the word size in byte */ @@ -797,9 +807,6 @@ static MMRESULT timerID; static MMRESULT timerID; static HANDLE host_alarm = NULL; static unsigned int period = 1; -#else -/* frequency of the times() clock tick */ -static int timer_freq; #endif QEMUClock *qemu_new_clock(int type) @@ -1137,9 +1144,6 @@ static void init_timer_alarm(void) struct itimerval itv; #endif - /* get times() syscall frequency */ - timer_freq = sysconf(_SC_CLK_TCK); - #ifndef CONFIG_DM /* timer signal */ sigfillset(&act.sa_mask); @@ -1497,6 +1501,7 @@ static CharDriverState *qemu_chr_open_fi return qemu_chr_open_fd(-1, fd_out); } +#ifndef CONFIG_STUBDOM static CharDriverState *qemu_chr_open_pipe(const char *filename) { int fd_in, fd_out; @@ -1742,6 +1747,7 @@ static CharDriverState *qemu_chr_open_st } return chr; } +#endif /* * Create a store entry for a device (e.g., monitor, serial/parallel lines). @@ -1751,6 +1757,9 @@ static int store_dev_info(char *devName, static int store_dev_info(char *devName, int domid, CharDriverState *cState, char *storeString) { +#ifdef CONFIG_STUBDOM + return 0; +#else int xc_handle; struct xs_handle *xs; char *path; @@ -1826,8 +1835,10 @@ static int store_dev_info(char *devName, close(xc_handle); return 0; -} - +#endif +} + +#ifndef CONFIG_STUBDOM #ifdef __sun__ /* Once Solaris has openpty(), this is going to be removed. */ int openpty(int *amaster, int *aslave, char *name, @@ -2486,6 +2497,7 @@ static CharDriverState *qemu_chr_open_wi return qemu_chr_open_win_file(fd_out); } #endif +#endif /***********************************************************/ /* UDP Net console */ @@ -2978,12 +2990,14 @@ CharDriverState *qemu_chr_open(const cha return qemu_chr_open_tcp(p, 0, 1); } else if (strstart(filename, "file:", &p)) { return qemu_chr_open_file_out(p); +#ifndef CONFIG_STUBDOM } else if (strstart(filename, "pipe:", &p)) { return qemu_chr_open_pipe(p); } else if (!strcmp(filename, "pty")) { return qemu_chr_open_pty(); } else if (!strcmp(filename, "stdio")) { return qemu_chr_open_stdio(); +#endif } else #endif #if defined(__linux__) @@ -3473,7 +3487,16 @@ static TAPState *net_tap_fd_init(VLANSta return s; } -#ifdef _BSD +#ifdef CONFIG_STUBDOM +#include <netfront.h> +static int tap_open(char *ifname, int ifname_size) +{ + char nodename[64]; + static int num = 1; // 0 is for our own TCP/IP networking + snprintf(nodename, sizeof(nodename), "device/vif/%d", num++); + return netfront_tap_open(nodename); +} +#elif defined(_BSD) static int tap_open(char *ifname, int ifname_size) { int fd; @@ -3561,6 +3584,7 @@ static int net_tap_init(VLANState *vlan, if (fd < 0) return -1; +#ifndef CONFIG_STUBDOM if (!setup_script || !strcmp(setup_script, "no")) setup_script = ""; if (setup_script[0] != '\0') { @@ -3593,6 +3617,7 @@ static int net_tap_init(VLANState *vlan, } } } +#endif s = net_tap_fd_init(vlan, fd); if (!s) return -1; @@ -7041,12 +7066,14 @@ int main(int argc, char **argv) char usb_devices[MAX_USB_CMDLINE][128]; int usb_devices_index; int fds[2]; +#ifndef CONFIG_STUBDOM struct rlimit rl; +#endif sigset_t set; char qemu_dm_logfilename[128]; const char *direct_pci = NULL; -#ifndef __sun__ +#if !defined(__sun__) && !defined(CONFIG_STUBDOM) /* Maximise rlimits. Needed where default constraints are tight (*BSD). */ if (getrlimit(RLIMIT_STACK, &rl) != 0) { perror("getrlimit(RLIMIT_STACK)"); @@ -7072,6 +7099,7 @@ int main(int argc, char **argv) perror("setrlimit(RLIMIT_MEMLOCK)"); #endif +#ifndef CONFIG_STUBDOM /* Ensure that SIGUSR2 is blocked by default when a new thread is created, then only the threads that use the signal unblock it -- this fixes a race condition in Qcow support where the AIO signal is misdelivered. */ @@ -7113,6 +7141,7 @@ int main(int argc, char **argv) } } } +#endif #endif register_machines(); @@ -7631,7 +7660,15 @@ int main(int argc, char **argv) #ifdef CONFIG_DM bdrv_init(); xc_handle = xc_interface_open(); +#ifdef CONFIG_STUBDOM + char *domid_s, *msg; + if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s))) + fprintf(stderr,"Can not read our own domid\n", msg); + else + xenstore_parse_domain_config(atoi(domid_s)); +#else /* CONFIG_STUBDOM */ xenstore_parse_domain_config(domid); +#endif /* CONFIG_STUBDOM */ #endif /* CONFIG_DM */ #ifdef USE_KQEMU @@ -7799,8 +7836,10 @@ int main(int argc, char **argv) vnc_display_password(ds, password); if ((vnc_display_port = vnc_display_open(ds, vnc_display, vncunused)) < 0) exit (0); +#ifndef CONFIG_STUBDOM if (vncviewer) vnc_start_viewer(vnc_display_port); +#endif xenstore_write_vncport(vnc_display_port); } else { #if defined(CONFIG_SDL) @@ -7928,6 +7967,7 @@ int main(int argc, char **argv) } #endif +#ifndef CONFIG_STUBDOM /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */ signal(SIGHUP, SIG_DFL); sigemptyset(&set); @@ -7935,6 +7975,7 @@ int main(int argc, char **argv) sigaddset(&set, SIGHUP); if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) fprintf(stderr, "Failed to unblock SIGTERM and SIGHUP\n"); +#endif main_loop(); quit_timers(); diff -r 88818d55e95a -r a905c582a406 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/vl.h Tue Feb 12 14:35:39 2008 +0000 @@ -574,6 +574,9 @@ typedef struct BlockDriver BlockDriver; extern BlockDriver bdrv_raw; extern BlockDriver bdrv_host_device; +#ifdef CONFIG_STUBDOM +extern BlockDriver bdrv_vbd; +#endif extern BlockDriver bdrv_cow; extern BlockDriver bdrv_qcow; extern BlockDriver bdrv_vmdk; diff -r 88818d55e95a -r a905c582a406 tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/vnc.c Tue Feb 12 14:35:39 2008 +0000 @@ -27,10 +27,12 @@ #include <sys/stat.h> #include <sys/socket.h> #include <netinet/in.h> -#include <arpa/inet.h> #include "vl.h" #include "qemu_socket.h" #include <assert.h> +#ifdef CONFIG_STUBDOM +#include <netfront.h> +#endif /* The refresh interval starts at BASE. If we scan the buffer and find no change, we increase by INC, up to MAX. If the mouse moves @@ -2407,7 +2409,9 @@ int vnc_display_open(DisplayState *ds, c #ifndef NO_UNIX_SOCKETS struct sockaddr_un uaddr; #endif +#ifndef CONFIG_STUBDOM int reuse_addr, ret; +#endif socklen_t addrlen; const char *p; VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; @@ -2539,6 +2543,15 @@ int vnc_display_open(DisplayState *ds, c return -1; } +#ifdef CONFIG_STUBDOM + { + struct ip_addr ipaddr = { iaddr.sin_addr.s_addr }; + struct ip_addr netmask = { 0 }; + struct ip_addr gw = { 0 }; + networking_set_addr(&ipaddr, &netmask, &gw); + } +#endif + iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); vs->lsock = socket(PF_INET, SOCK_STREAM, 0); @@ -2549,6 +2562,7 @@ int vnc_display_open(DisplayState *ds, c return -1; } +#ifndef CONFIG_STUBDOM reuse_addr = 1; ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse_addr, sizeof(reuse_addr)); @@ -2560,6 +2574,7 @@ int vnc_display_open(DisplayState *ds, c vs->display = NULL; return -1; } +#endif } while (bind(vs->lsock, addr, addrlen) == -1) { @@ -2590,6 +2605,7 @@ int vnc_display_open(DisplayState *ds, c return ntohs(iaddr.sin_port); } +#ifndef CONFIG_STUBDOM int vnc_start_viewer(int port) { int pid, i, open_max; @@ -2617,4 +2633,5 @@ int vnc_start_viewer(int port) return pid; } } - +#endif + diff -r 88818d55e95a -r a905c582a406 tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/xenstore.c Tue Feb 12 14:35:39 2008 +0000 @@ -11,8 +11,10 @@ #include "vl.h" #include "block_int.h" #include <unistd.h> +#ifndef CONFIG_STUBDOM #include <sys/ipc.h> #include <sys/shm.h> +#endif #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -219,10 +221,18 @@ void xenstore_parse_domain_config(int do } /* open device now if media present */ +#ifdef CONFIG_STUBDOM + if (pasprintf(&buf, "%s/device/vbd/%s", path, e[i]) == -1) + continue; + if (bdrv_open2(bs, buf, 0 /* snapshot */, &bdrv_vbd) == 0) { + pstrcpy(bs->filename, sizeof(bs->filename), params); + continue; + } +#endif + if (params[0]) { if (bdrv_open(bs, params, 0 /* snapshot */) < 0) - fprintf(stderr, "qemu: could not open hard disk image '%s'\n", - params); + fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s'\n", buf, params); } } @@ -265,6 +275,10 @@ extern int vga_ram_size, bios_size; void xenstore_process_logdirty_event(void) { +#ifdef CONFIG_STUBDOM + /* XXX we just can't use shm. */ + return; +#else char *act; static char *active_path = NULL; static char *next_active_path = NULL; @@ -367,6 +381,7 @@ void xenstore_process_logdirty_event(voi /* Ack that we've switched */ xs_write(xsh, XBT_NULL, active_path, act, len); free(act); +#endif } diff -r 88818d55e95a -r a905c582a406 tools/libxc/Makefile --- a/tools/libxc/Makefile Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/libxc/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -5,10 +5,12 @@ MINOR = 0 MINOR = 0 CTRL_SRCS-y := +ifneq ($(stubdom),y) CTRL_SRCS-y += xc_core.c CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c CTRL_SRCS-$(CONFIG_POWERPC) += xc_core_powerpc.c +endif CTRL_SRCS-y += xc_domain.c CTRL_SRCS-y += xc_evtchn.c CTRL_SRCS-y += xc_misc.c @@ -19,21 +21,29 @@ CTRL_SRCS-y += xc_sedf.c CTRL_SRCS-y += xc_sedf.c CTRL_SRCS-y += xc_csched.c CTRL_SRCS-y += xc_tbuf.c +ifneq ($(stubdom),y) CTRL_SRCS-y += xc_resume.c +endif CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c +ifneq ($(stubdom),y) CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c +endif +CTRL_SRCS-$(stubdom) += xc_minios.c GUEST_SRCS-y := GUEST_SRCS-y += xg_private.c +ifneq ($(stubdom),y) GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c +endif VPATH = ../../xen/common/libelf CFLAGS += -I../../xen/common/libelf +ifneq ($(stubdom),y) GUEST_SRCS-y += libelf-tools.c libelf-loader.c GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c @@ -46,6 +56,7 @@ GUEST_SRCS-$(CONFIG_X86) += xc_dom_x GUEST_SRCS-$(CONFIG_X86) += xc_dom_x86.c GUEST_SRCS-$(CONFIG_IA64) += xc_dom_ia64.c GUEST_SRCS-$(CONFIG_POWERPC) += xc_dom_powerpc.c +endif -include $(XEN_TARGET_ARCH)/Makefile @@ -64,6 +75,10 @@ LDFLAGS += -L. LDFLAGS += -L. DEPS = .*.d +ifneq ($(stubdom),y) +LDLIBS = -lpthread +endif + CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y)) CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y)) @@ -71,10 +86,14 @@ GUEST_PIC_OBJS := $(patsubst %.c,%.opic, GUEST_PIC_OBJS := $(patsubst %.c,%.opic,$(GUEST_SRCS-y)) LIB := libxenctrl.a +ifneq ($(stubdom),y) LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR) +endif LIB += libxenguest.a +ifneq ($(stubdom),y) LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR) +endif .PHONY: all all: build @@ -133,7 +152,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$( ln -sf $< $@ libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ -lpthread + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ $(LDLIBS) # libxenguest @@ -146,7 +165,7 @@ libxenguest.so.$(MAJOR): libxenguest.so. ln -sf $< $@ libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl -lpthread + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl $(LDLIBS) -include $(DEPS) diff -r 88818d55e95a -r a905c582a406 tools/libxc/ia64/Makefile --- a/tools/libxc/ia64/Makefile Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/libxc/ia64/Makefile Tue Feb 12 14:35:39 2008 +0000 @@ -1,3 +1,4 @@ CTRL_SRCS-y += ia64/xc_ia64_stubs.c +ifneq ($(stubdom),y) CTRL_SRCS-y += ia64/xc_ia64_stubs.c GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c @@ -8,6 +9,7 @@ GUEST_SRCS-y += ia64/dom_fw_acpi.c GUEST_SRCS-y += ia64/dom_fw_acpi.c DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S +endif DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE)) $(DOMFW_SRCS): ln -sf ../$(XEN_ROOT)/xen/arch/ia64/xen/$(@F) $@ diff -r 88818d55e95a -r a905c582a406 tools/libxc/xc_minios.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_minios.c Tue Feb 12 14:35:39 2008 +0000 @@ -0,0 +1,313 @@ +/****************************************************************************** + * + * Copyright 2007-2008 Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>. + * All rights reserved. + * Use is subject to license terms. + * + * 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, version 2 of the + * License. + */ + +#undef NDEBUG +#include <types.h> +#include <os.h> +#include <mm.h> +#include <lib.h> +#include <events.h> +#include <wait.h> +#include <sys/mman.h> +#include <errno.h> + +#include <xen/memory.h> +#include <xen/sys/evtchn.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <assert.h> +#include <stdint.h> +#include <inttypes.h> + +#include "xc_private.h" + +extern struct wait_queue_head event_queue; + +int xc_interface_open(void) +{ + return 0; +} + +int xc_interface_close(int xc_handle) +{ + return 0; +} + +void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot, + xen_pfn_t *arr, int num) +{ + unsigned long pt_prot = 0; +#ifdef __ia64__ + /* TODO */ +#else + if (prot & PROT_READ) + pt_prot = L1_PROT_RO; + if (prot & PROT_WRITE) + pt_prot = L1_PROT; +#endif + return map_frames_ex(arr, num, 1, 0, 1, dom, 1, pt_prot); +} + +void *xc_map_foreign_range(int xc_handle, uint32_t dom, + int size, int prot, + unsigned long mfn) +{ + unsigned long pt_prot = 0; + printf("xc_map_foreign_range(%lx, %d)\n", mfn, size); +#ifdef __ia64__ + /* TODO */ +#else + if (prot & PROT_READ) + pt_prot = L1_PROT_RO; + if (prot & PROT_WRITE) + pt_prot = L1_PROT; +#endif + assert(!(size % getpagesize())); + return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, 0, pt_prot); +} + +int xc_map_foreign_ranges(int xc_handle, uint32_t dom, + privcmd_mmap_entry_t *entries, int nr) +{ + printf("xc_map_foreign_ranges, TODO\n"); + do_exit(); +} + +int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall) +{ + multicall_entry_t call; + int i, ret; + + call.op = hypercall->op; + for (i = 0; i < sizeof(hypercall->arg) / sizeof(*hypercall->arg); i++) + call.args[i] = hypercall->arg[i]; + + ret = HYPERVISOR_multicall(&call, 1); + + if (ret < 0) { + errno = -ret; + return -1; + } + if (call.result < 0) { + errno = -call.result; + return -1; + } + return call.result; +} + +int xc_find_device_number(const char *name) +{ + printf("xc_find_device_number(%s)\n", name); + do_exit(); +} + +int xc_evtchn_open(void) +{ + int fd = alloc_fd(FTYPE_EVTCHN), i; + for (i = 0; i < MAX_EVTCHN_PORTS; i++) { + files[fd].evtchn.ports[i].port = -1; + files[fd].evtchn.ports[i].bound = 0; + } + printf("evtchn_open() -> %d\n", fd); + return fd; +} + +int xc_evtchn_close(int xce_handle) +{ + int i; + for (i = 0; i < MAX_EVTCHN_PORTS; i++) + if (files[xce_handle].evtchn.ports[i].bound) + unbind_evtchn(files[xce_handle].evtchn.ports[i].port); + files[xce_handle].type = FTYPE_NONE; + return 0; +} + +int xc_evtchn_fd(int xce_handle) +{ + return xce_handle; +} + +int xc_evtchn_notify(int xce_handle, evtchn_port_t port) +{ + int ret; + + ret = notify_remote_via_evtchn(port); + + if (ret < 0) { + errno = -ret; + ret = -1; + } + return ret; +} + +/* XXX Note: This is not threadsafe */ +static int port_alloc(int xce_handle) { + int i; + for (i= 0; i < MAX_EVTCHN_PORTS; i++) + if (files[xce_handle].evtchn.ports[i].port == -1) + break; + if (i == MAX_EVTCHN_PORTS) { + printf("Too many ports in xc handle\n"); + errno = EMFILE; + return -1; + } + files[xce_handle].evtchn.ports[i].pending = 0; + return i; +} + +static void poke_port(int xce_handle, evtchn_port_t port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + printk("poking port %d\n", port); + synch_set_bit(port, &s->evtchn_pending[0]); + xc_evtchn_unmask(xce_handle, port); +} + +static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) +{ + int xce_handle = (intptr_t) data; + int i; + assert(files[xce_handle].type == FTYPE_EVTCHN); + mask_evtchn(port); + for (i= 0; i < MAX_EVTCHN_PORTS; i++) + if (files[xce_handle].evtchn.ports[i].port == port) + break; + if (i == MAX_EVTCHN_PORTS) { + printk("Unknown port for handle %d\n", xce_handle); + return; + } + files[xce_handle].evtchn.ports[i].pending++; + files[xce_handle].read = 1; + wake_up(&event_queue); +} + +evtchn_port_or_error_t xc_evtchn_bind_unbound_port(int xce_handle, int domid) +{ + int ret, i; + evtchn_port_t port; + + assert(get_current() == main_thread); + i = port_alloc(xce_handle); + if (i == -1) + return -1; + + printf("xc_evtchn_bind_unbound_port(%d)", domid); + ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)xce_handle, &port); + printf(" = %d\n", ret); + + if (ret < 0) { + errno = -ret; + return -1; + } + files[xce_handle].evtchn.ports[i].bound = 1; + files[xce_handle].evtchn.ports[i].port = port; + return port; +} + +evtchn_port_or_error_t xc_evtchn_bind_interdomain(int xce_handle, int domid, + evtchn_port_t remote_port) +{ + evtchn_port_t local_port; + int ret, i; + + assert(get_current() == main_thread); + i = port_alloc(xce_handle); + if (i == -1) + return -1; + + printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port); + ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)xce_handle, &local_port); + printf(" = %d\n", ret); + + if (ret < 0) { + errno = -ret; + return -1; + } + files[xce_handle].evtchn.ports[i].bound = 1; + files[xce_handle].evtchn.ports[i].port = local_port; +/* Poke port on start: HVM won't send an event for the very first request since + * we were not ready yet */ + poke_port(xce_handle, local_port); + return local_port; +} + +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port) +{ + int i; + for (i = 0; i < MAX_EVTCHN_PORTS; i++) + if (files[xce_handle].evtchn.ports[i].port == port) { + files[xce_handle].evtchn.ports[i].port = -1; + break; + } + if (i == MAX_EVTCHN_PORTS) + printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle); + files[xce_handle].evtchn.ports[i].bound = 0; + unbind_evtchn(port); + return 0; +} + +evtchn_port_or_error_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq) +{ + evtchn_port_t port; + int i; + + assert(get_current() == main_thread); + i = port_alloc(xce_handle); + if (i == -1) + return -1; + + printf("xc_evtchn_bind_virq(%d)", virq); + port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)xce_handle); + + if (port < 0) { + errno = -port; + return -1; + } + files[xce_handle].evtchn.ports[i].bound = 1; + files[xce_handle].evtchn.ports[i].port = port; + return port; +} + +evtchn_port_or_error_t xc_evtchn_pending(int xce_handle) +{ + int i; + unsigned long flags; + local_irq_save(flags); + for (i = 0; i < MAX_EVTCHN_PORTS; i++) { + evtchn_port_t port = files[xce_handle].evtchn.ports[i].port; + if (port != -1 && files[xce_handle].evtchn.ports[i].pending) { + files[xce_handle].evtchn.ports[i].pending--; + local_irq_restore(flags); + return port; + } + } + files[xce_handle].read = 0; + local_irq_restore(flags); + return -1; +} + +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port) +{ + unmask_evtchn(port); + return 0; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |