Hello, At last, here is the big patch that adds the stubdomain support. I guess some reviewing will be needed before commiting it. Add stubdomain support. - 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. - Have the domain killer send SIGHUP to the device-model script, allow the script 10s to clean up, and if still not dead, send SIGKILL. - 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@eu.citrix.com> diff -r 7b0c0ab0566b .hgignore --- a/.hgignore Mon Feb 11 14:55:33 2008 +0000 +++ b/.hgignore Mon Feb 11 17:16:12 2008 +0000 @@ -221,6 +221,17 @@ ^tools/xm-test/lib/XmTestLib/config.py$ ^tools/xm-test/lib/XmTestReport/xmtest.py$ ^tools/xm-test/tests/.*\.test$ +^stubdom/binutils.*$ +^stubdom/cross-root.*$ +^stubdom/gcc.*$ +^stubdom/include.*$ +^stubdom/ioemu.*$ +^stubdom/libxc.*$ +^stubdom/lwip.*$ +^stubdom/mini-os.*$ +^stubdom/newlib.*$ +^stubdom/pciutils.*$ +^stubdom/zlib.*$ ^xen/BLOG$ ^xen/System.map$ ^xen/TAGS$ diff -r 7b0c0ab0566b Config.mk --- a/Config.mk Mon Feb 11 14:55:33 2008 +0000 +++ b/Config.mk Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/Config.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/Config.mk Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,75 @@ +# 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 +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 7b0c0ab0566b extras/mini-os/Makefile --- a/extras/mini-os/Makefile Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/Makefile Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/ia64/Makefile --- a/extras/mini-os/arch/ia64/Makefile Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/ia64/Makefile Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/ia64/minios-ia64.lds --- a/extras/mini-os/arch/ia64/minios-ia64.lds Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/ia64/minios-ia64.lds Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/ia64/mm.c --- a/extras/mini-os/arch/ia64/mm.c Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/ia64/mm.c Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/x86/Makefile --- a/extras/mini-os/arch/x86/Makefile Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/x86/Makefile Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/x86/arch.mk --- a/extras/mini-os/arch/x86/arch.mk Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/x86/arch.mk Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/x86/minios-x86_32.lds --- a/extras/mini-os/arch/x86/minios-x86_32.lds Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/x86/minios-x86_32.lds Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/x86/minios-x86_64.lds --- a/extras/mini-os/arch/x86/minios-x86_64.lds Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/x86/minios-x86_64.lds Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/arch/x86/mm.c --- a/extras/mini-os/arch/x86/mm.c Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/arch/x86/mm.c Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/blkfront.c --- a/extras/mini-os/blkfront.c Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/blkfront.c Mon Feb 11 17:16:12 2008 +0000 @@ -14,6 +14,10 @@ #include <blkfront.h> #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->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); + 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 7b0c0ab0566b extras/mini-os/include/arch/cc.h --- a/extras/mini-os/include/arch/cc.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/arch/cc.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/byteswap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/byteswap.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/console.h --- a/extras/mini-os/include/console.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/console.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/errno.h --- a/extras/mini-os/include/errno.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/errno.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/fcntl.h --- a/extras/mini-os/include/fcntl.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/fcntl.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/fs.h --- a/extras/mini-os/include/fs.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/fs.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/ia64/arch_mm.h --- a/extras/mini-os/include/ia64/arch_mm.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/ia64/arch_mm.h Mon Feb 11 17:16:12 2008 +0000 @@ -35,11 +35,12 @@ #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_ORDER 2 #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 7b0c0ab0566b extras/mini-os/include/ia64/os.h --- a/extras/mini-os/include/ia64/os.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/ia64/os.h Mon Feb 11 17:16:12 2008 +0000 @@ -292,9 +292,12 @@ do { \ /* This is a barrier for the compiler only, NOT the processor! */ #define barrier() __asm__ __volatile__("": : :"memory") +#ifndef __barriers_defined +#define __barriers_defined #define mb() ia64_mf() #define rmb() mb() #define wmb() mb() +#endif #define BUG() \ diff -r 7b0c0ab0566b extras/mini-os/include/lib.h --- a/extras/mini-os/include/lib.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/lib.h Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/mm.h --- a/extras/mini-os/include/mm.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/mm.h Mon Feb 11 17:16:12 2008 +0000 @@ -61,5 +61,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 7b0c0ab0566b extras/mini-os/include/netfront.h --- a/extras/mini-os/include/netfront.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/netfront.h Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,8 @@ +#ifndef _POSIX_LIMITS_H +#define _POSIX_LIMITS_H + +#include_next <limits.h> + +#define PATH_MAX PAGE_SIZE + +#endif /* _POSIX_LIMITS_H */ diff -r 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 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 7b0c0ab0566b 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 Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,11 @@ +#ifndef _POSIX_UNISTD_H +#define _POSIX_UNISTD_H + +#include_next <unistd.h> +#include <sys/select.h> + +#define getpagesize() PAGE_SIZE + +int ftruncate(int fd, off_t length); + +#endif /* _POSIX_UNISTD_H */ diff -r 7b0c0ab0566b extras/mini-os/include/sched.h --- a/extras/mini-os/include/sched.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/sched.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/sys/time.h --- a/extras/mini-os/include/sys/time.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/sys/time.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/time.h --- a/extras/mini-os/include/time.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/time.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/x86/arch_mm.h --- a/extras/mini-os/include/x86/arch_mm.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/x86/arch_mm.h Mon Feb 11 17:16:12 2008 +0000 @@ -177,7 +177,7 @@ 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_ORDER 4 #define STACK_SIZE (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER)) #ifndef __ASSEMBLY__ @@ -257,5 +257,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 7b0c0ab0566b extras/mini-os/include/x86/arch_spinlock.h --- a/extras/mini-os/include/x86/arch_spinlock.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/x86/arch_spinlock.h Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/include/x86/os.h --- a/extras/mini-os/include/x86/os.h Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/include/x86/os.h Mon Feb 11 17:16:12 2008 +0000 @@ -139,6 +139,8 @@ do { \ /* This is a barrier for the compiler only, NOT the processor! */ #define barrier() __asm__ __volatile__("": : :"memory") +#ifndef __barriers_defined +#define __barriers_defined #if defined(__i386__) #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") #define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") @@ -147,6 +149,7 @@ do { \ #define mb() __asm__ __volatile__ ("mfence":::"memory") #define rmb() __asm__ __volatile__ ("lfence":::"memory") #define wmb() __asm__ __volatile__ ("sfence" ::: "memory") /* From CONFIG_UNORDERED_IO (linux) */ +#endif #endif @@ -563,6 +566,7 @@ static __inline__ int synch_var_test_bit synch_var_test_bit((nr),(addr))) +#undef ADDR #endif /* not assembly */ #endif /* _OS_H_ */ diff -r 7b0c0ab0566b extras/mini-os/include/xs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/xs.h Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,168 @@ +/* + Xen Store Daemon providing simple tree-like database. + Copyright (C) 2005 Rusty Russell IBM Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _XS_H +#define _XS_H + +#include <xs_lib.h> + +#define XBT_NULL 0 + +struct xs_handle; +typedef uint32_t xs_transaction_t; + +/* On failure, these routines set errno. */ + +/* Connect to the xs daemon. + * Returns a handle or NULL. + */ +struct xs_handle *xs_daemon_open(void); +struct xs_handle *xs_domain_open(void); + +/* Connect to the xs daemon (readonly for non-root clients). + * Returns a handle or NULL. + */ +struct xs_handle *xs_daemon_open_readonly(void); + +/* Close the connection to the xs daemon. */ +void xs_daemon_close(struct xs_handle *); + +/* Get contents of a directory. + * Returns a malloced array: call free() on it after use. + * Num indicates size. + */ +char **xs_directory(struct xs_handle *h, xs_transaction_t t, + const char *path, unsigned int *num); + +/* Get the value of a single file, nul terminated. + * Returns a malloced value: call free() on it after use. + * len indicates length in bytes, not including terminator. + */ +void *xs_read(struct xs_handle *h, xs_transaction_t t, + const char *path, unsigned int *len); + +/* Write the value of a single file. + * Returns false on failure. + */ +bool xs_write(struct xs_handle *h, xs_transaction_t t, + const char *path, const void *data, unsigned int len); + +/* Create a new directory. + * Returns false on failure, or success if it already exists. + */ +bool xs_mkdir(struct xs_handle *h, xs_transaction_t t, + const char *path); + +/* Destroy a file or directory (and children). + * Returns false on failure, or if it doesn''t exist. + */ +bool xs_rm(struct xs_handle *h, xs_transaction_t t, + const char *path); + +/* Get permissions of node (first element is owner, first perms is "other"). + * Returns malloced array, or NULL: call free() after use. + */ +struct xs_permissions *xs_get_permissions(struct xs_handle *h, + xs_transaction_t t, + const char *path, unsigned int *num); + +/* Set permissions of node (must be owner). + * Returns false on failure. + */ +bool xs_set_permissions(struct xs_handle *h, xs_transaction_t t, + const char *path, struct xs_permissions *perms, + unsigned int num_perms); + +/* Watch a node for changes (poll on fd to detect, or call read_watch()). + * When the node (or any child) changes, fd will become readable. + * Token is returned when watch is read, to allow matching. + * Returns false on failure. + */ +bool xs_watch(struct xs_handle *h, const char *path, const char *token); + +/* Return the FD to poll on to see if a watch has fired. */ +int xs_fileno(struct xs_handle *h); + +/* Find out what node change was on (will block if nothing pending). + * Returns array containing the path and token. Use XS_WATCH_* to access these + * elements. Call free() after use. + */ +char **xs_read_watch(struct xs_handle *h, unsigned int *num); + +/* Remove a watch on a node: implicitly acks any outstanding watch. + * Returns false on failure (no watch on that node). + */ +bool xs_unwatch(struct xs_handle *h, const char *path, const char *token); + +/* Start a transaction: changes by others will not be seen during this + * transaction, and changes will not be visible to others until end. + * You can only have one transaction at any time. + * Returns NULL on failure. + */ +xs_transaction_t xs_transaction_start(struct xs_handle *h); + +/* End a transaction. + * If abandon is true, transaction is discarded instead of committed. + * Returns false on failure: if errno == EAGAIN, you have to restart + * transaction. + */ +bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t, + bool abort); + +/* Introduce a new domain. + * This tells the store daemon about a shared memory page, event channel and + * store path associated with a domain: the domain uses these to communicate. + */ +bool xs_introduce_domain(struct xs_handle *h, + unsigned int domid, + unsigned long mfn, + unsigned int eventchn); +/* Resume a domain. + * Clear the shutdown flag for this domain in the store. + */ +bool xs_resume_domain(struct xs_handle *h, unsigned int domid); + +/* Release a domain. + * Tells the store domain to release the memory page to the domain. + */ +bool xs_release_domain(struct xs_handle *h, unsigned int domid); + +/* Query the home path of a domain. Call free() after use. + */ +char *xs_get_domain_path(struct xs_handle *h, unsigned int domid); + +/* Return whether the domain specified has been introduced to xenstored. + */ +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid); + +/* Only useful for DEBUG versions */ +char *xs_debug_command(struct xs_handle *h, const char *cmd, + void *data, unsigned int len); + +#endif /* _XS_H */ + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r 7b0c0ab0566b extras/mini-os/include/xs_lib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/xs_lib.h Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,69 @@ +/* + Common routines between Xen store user library and daemon. + Copyright (C) 2005 Rusty Russell IBM Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _XS_LIB_H +#define _XS_LIB_H + +#include <stdbool.h> +#include <limits.h> +#include <errno.h> +#include <stdint.h> +#include <xen/io/xs_wire.h> + +/* Bitmask of permissions. */ +enum xs_perm_type { + XS_PERM_NONE = 0, + XS_PERM_READ = 1, + XS_PERM_WRITE = 2, + /* Internal use. */ + XS_PERM_ENOENT_OK = 4, + XS_PERM_OWNER = 8, +}; + +struct xs_permissions +{ + unsigned int id; + enum xs_perm_type perms; +}; + +/* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */ +#define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2) + +/* Path for various daemon things: env vars can override. */ +const char *xs_daemon_rootdir(void); +const char *xs_daemon_rundir(void); +const char *xs_daemon_socket(void); +const char *xs_daemon_socket_ro(void); +const char *xs_domain_dev(void); +const char *xs_daemon_tdb(void); + +/* Simple write function: loops for you. */ +bool xs_write_all(int fd, const void *data, unsigned int len); + +/* Convert strings to permissions. False if a problem. */ +bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num, + const char *strings); + +/* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */ +bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer); + +/* Given a string and a length, count how many strings (nul terms). */ +unsigned int xs_count_strings(const char *strings, unsigned int len); + +#endif /* _XS_LIB_H */ diff -r 7b0c0ab0566b extras/mini-os/lib/sys.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/lib/sys.c Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,1083 @@ +/* + * POSIX-compatible libc layer + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 7b0c0ab0566b extras/mini-os/lib/xs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/lib/xs.c Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,187 @@ +/* + * libxs-compatible layer + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 7b0c0ab0566b extras/mini-os/main-caml.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/main-caml.c Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,42 @@ +/* + * Caml bootstrap + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 7b0c0ab0566b extras/mini-os/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/main.c Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,167 @@ +/* + * POSIX-compatible main layer + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 7b0c0ab0566b extras/mini-os/minios.mk --- a/extras/mini-os/minios.mk Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/minios.mk Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/mm.c --- a/extras/mini-os/mm.c Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/mm.c Mon Feb 11 17:16:12 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 7b0c0ab0566b extras/mini-os/netfront.c --- a/extras/mini-os/netfront.c Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/netfront.c Mon Feb 11 17:16:12 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) @@ -49,6 +52,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; @@ -178,6 +200,9 @@ void network_tx_buf_gc(struct netfront_d 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]; gnttab_end_access(buf->gref); @@ -217,6 +242,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]) { @@ -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 7b0c0ab0566b extras/mini-os/sched.c --- a/extras/mini-os/sched.c Mon Feb 11 14:55:33 2008 +0000 +++ b/extras/mini-os/sched.c Mon Feb 11 17:16:12 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 7b0c0ab0566b stubdom/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/Makefile Mon Feb 11 17:16:12 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:=i386 +endif + +ifeq ($(GNU_TARGET_ARCH), i386) +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@sources.redhat.com:/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 -d :pserver:anonymous@cvs.savannah.nongnu.org:/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 7b0c0ab0566b stubdom/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/README Mon Feb 11 17:16:12 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 7b0c0ab0566b stubdom/binutils.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/binutils.patch Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,14 @@ +It looks like binutils has troubles with makeinfo and the doc generation. +We don''t need it anyway + +--- binutils-2.18/bfd/Makefile.inorig 2008-01-16 16:17:43.004484000 +0000 ++++ binutils-2.18/bfd/Makefile.in 2008-01-16 16:17:50.505526000 +0000 +@@ -271,7 +271,7 @@ + INCDIR = $(srcdir)/../include + CSEARCH = -I. -I$(srcdir) -I$(INCDIR) + MKDEP = gcc -MM +-SUBDIRS = doc po ++SUBDIRS = po + bfddocdir = doc + bfdlib_LTLIBRARIES = libbfd.la + AM_CFLAGS = $(WARN_CFLAGS) diff -r 7b0c0ab0566b stubdom/caml/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/caml/Makefile Mon Feb 11 17:16:12 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 7b0c0ab0566b stubdom/caml/hello.ml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/caml/hello.ml Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,4 @@ +let main arg + Printf.printf "Hello, world!\n%!." + +let _ = Callback.register "main" main diff -r 7b0c0ab0566b stubdom/gcc.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/gcc.patch Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,31 @@ +Backported from later versions + +--- gcc-4.2.2/gcc/config.gcc 2007-11-22 16:27:45.000000000 +0000 ++++ gcc-4.2.2/gcc/config.gcc 2007-11-22 16:23:00.000000000 +0000 +@@ -1033,6 +1033,11 @@ + tmake_file="i386/t-i386elf t-svr4" + use_fixproto=yes + ;; ++x86_64-*-elf*) ++ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/x86-64.h" ++ tmake_file="i386/t-i386elf t-svr4" ++ use_fixproto=yes ++ ;; + i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) + if test x$gas = xyes + then + +We don''t have a libc yet at this stage. Unused anyway + +--- gcc-4.2.2/gcc/unwind-generic.h.orig 2008-01-11 18:54:40.000000000 +0100 ++++ gcc-4.2.2/gcc/unwind-generic.h 2008-01-11 18:54:31.000000000 +0100 +@@ -203,7 +203,6 @@ + compatible with the standard ABI for IA-64, we inline these. */ + + #ifdef __ia64__ +-#include <stdlib.h> + + static inline _Unwind_Ptr + _Unwind_GetDataRelBase (struct _Unwind_Context *_C) +Backported from later versions + diff -r 7b0c0ab0566b stubdom/libpci.config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/libpci.config.h Mon Feb 11 17:16:12 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 7b0c0ab0566b stubdom/libpci.config.mak --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/libpci.config.mak Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,2 @@ +LIBZ=-lz +LDLIBS+=$(LIBZ) diff -r 7b0c0ab0566b stubdom/newlib.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/newlib.patch Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,183 @@ +There is a mix between longs and long longs. + +Index: newlib/libc/include/inttypes.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/inttypes.h,v +retrieving revision 1.3 +diff -u -p -r1.3 inttypes.h +--- newlib/libc/include/inttypes.h 16 Dec 2005 19:03:12 -0000 1.3 ++++ newlib/libc/include/inttypes.h 8 Nov 2007 16:32:44 -0000 +@@ -163,12 +163,12 @@ + + + /* 64-bit types */ +-#if __have_longlong64 +-#define __PRI64(x) __STRINGIFY(ll##x) +-#define __SCN64(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRI64(x) __STRINGIFY(l##x) + #define __SCN64(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRI64(x) __STRINGIFY(ll##x) ++#define __SCN64(x) __STRINGIFY(ll##x) + #else + #define __PRI64(x) __STRINGIFY(x) + #define __SCN64(x) __STRINGIFY(x) +@@ -217,12 +217,12 @@ + #endif + + /* max-bit types */ +-#if __have_longlong64 +-#define __PRIMAX(x) __STRINGIFY(ll##x) +-#define __SCNMAX(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRIMAX(x) __STRINGIFY(l##x) + #define __SCNMAX(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRIMAX(x) __STRINGIFY(ll##x) ++#define __SCNMAX(x) __STRINGIFY(ll##x) + #else + #define __PRIMAX(x) __STRINGIFY(x) + #define __SCNMAX(x) __STRINGIFY(x) +@@ -242,12 +242,12 @@ + #define SCNxMAX __SCNMAX(x) + + /* ptr types */ +-#if __have_longlong64 +-#define __PRIPTR(x) __STRINGIFY(ll##x) +-#define __SCNPTR(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRIPTR(x) __STRINGIFY(l##x) + #define __SCNPTR(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRIPTR(x) __STRINGIFY(ll##x) ++#define __SCNPTR(x) __STRINGIFY(ll##x) + #else + #define __PRIPTR(x) __STRINGIFY(x) + #define __SCNPTR(x) __STRINGIFY(x) + +Define the basic ia64 jump buffer + +Index: newlib/libc/include/machine/setjmp.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/machine/setjmp.h,v +retrieving revision 1.34 +diff -u -p -r1.34 setjmp.h +--- newlib/libc/include/machine/setjmp.h 7 Nov 2007 21:42:24 -0000 1.34 ++++ newlib/libc/include/machine/setjmp.h 11 Jan 2008 18:10:43 -0000 +@@ -72,6 +72,11 @@ _BEGIN_STD_C + #define _JBLEN 8 + #endif + ++#ifdef __ia64__ ++#define _JBTYPE long ++#define _JBLEN 70 ++#endif ++ + #ifdef __i960__ + #define _JBLEN 35 + #endif + +In mini-os we use a dynamic reentrency buffer. + +Index: newlib/libc/include/sys/config.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/sys/config.h,v +retrieving revision 1.47 +diff -u -p -r1.47 config.h +--- newlib/libc/include/sys/config.h 15 Mar 2007 21:32:12 -0000 1.47 ++++ newlib/libc/include/sys/config.h 8 Nov 2007 16:32:44 -0000 +@@ -71,6 +71,10 @@ + #endif + #endif + ++#ifndef __DYNAMIC_REENT__ ++#define __DYNAMIC_REENT__ ++#endif ++ + #ifdef __mn10200__ + #define __SMALL_BITFIELDS + #endif + +Dynamic pointer to our reentrancy zone + +Index: newlib/libc/reent/getreent.c +==================================================================+RCS file: /cvs/src/src/newlib/libc/reent/getreent.c,v +retrieving revision 1.2 +diff -u -p -r1.2 getreent.c +--- newlib/libc/reent/getreent.c 7 Sep 2007 00:45:55 -0000 1.2 ++++ newlib/libc/reent/getreent.c 8 Nov 2007 16:32:44 -0000 +@@ -3,12 +3,20 @@ + #include <_ansi.h> + #include <reent.h> + ++#define weak_alias(name, aliasname) \ ++ extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); ++ + #ifdef __getreent + #undef __getreent + #endif ++#ifdef __libc_getreent ++#undef __libc_getreent ++#endif + + struct _reent * +-_DEFUN_VOID(__getreent) ++__libc_getreent (void) + { + return _impure_ptr; + } ++weak_alias(__libc_getreent,__getreent) ++ + +We can''t provide a red zone in mini-os. + +Index: newlib/libc/machine/x86_64/memcpy.S +==================================================================+RCS file: /cvs/src/src/newlib/libc/machine/x86_64/memcpy.S,v +retrieving revision 1.1 +diff -u -p -r1.1 memcpy.S +--- newlib/libc/machine/x86_64/memcpy.S 28 Aug 2007 21:56:49 -0000 1.1 ++++ newlib/libc/machine/x86_64/memcpy.S 8 Nov 2007 16:32:44 -0000 +@@ -30,10 +30,18 @@ quadword_aligned: + cmpq $256, rdx + jb quadword_copy + ++#if 1 ++ subq $32, rsp ++ movq rax, 24 (rsp) ++ movq r12, 16 (rsp) ++ movq r13, 8 (rsp) ++ movq r14, 0 (rsp) ++#else + movq rax, -8 (rsp) + movq r12, -16 (rsp) + movq r13, -24 (rsp) + movq r14, -32 (rsp) ++#endif + + movq rdx, rcx /* Copy 128 bytes at a time with minimum cache polution */ + shrq $7, rcx +@@ -89,10 +97,18 @@ loop: + movq rdx, rcx + andq $127, rcx + rep movsb ++#if 1 ++ movq 24 (rsp), rax ++ movq 16 (rsp), r12 ++ movq 8 (rsp), r13 ++ movq 0 (rsp), r14 ++ addq $32, rsp ++#else + movq -8 (rsp), rax + movq -16 (rsp), r12 + movq -24 (rsp), r13 + movq -32 (rsp), r14 ++#endif + ret + + diff -r 7b0c0ab0566b stubdom/stubdom-dm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/stubdom-dm Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.net> +# +# 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 7b0c0ab0566b tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/Makefile.target Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/aes.c --- a/tools/ioemu/aes.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/aes.c Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/block-vbd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/block-vbd.c Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/block.c --- a/tools/ioemu/block.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/block.c Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/configure --- a/tools/ioemu/configure Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/configure Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/exec-all.h --- a/tools/ioemu/exec-all.h Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/exec-all.h Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/hw/ide.c Mon Feb 11 17:16:12 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(PAGE_SIZE, MAX_MULT_SECTORS*512 + 4); if (i == 0) s->bs = hd0; else diff -r 7b0c0ab0566b tools/ioemu/hw/scsi-disk.c --- a/tools/ioemu/hw/scsi-disk.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/hw/scsi-disk.c Mon Feb 11 17:16:12 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(PAGE_SIZE, SCSI_DMA_BUF_SIZE); } r->dev = s; r->tag = tag; diff -r 7b0c0ab0566b tools/ioemu/hw/xen_machine_fv.c --- a/tools/ioemu/hw/xen_machine_fv.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/hw/xen_machine_fv.c Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/vl.c --- a/tools/ioemu/vl.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/vl.c Mon Feb 11 17:16:12 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 @@ -68,6 +75,7 @@ #endif #if defined(__sun__) #include <stropts.h> +#endif #endif #endif @@ -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,11 +7967,15 @@ int main(int argc, char **argv) } #endif - /* Unblock SIGTERM, which may have been blocked by the caller */ +#ifndef CONFIG_STUBDOM + /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */ + signal(SIGHUP, SIG_DFL); sigemptyset(&set); sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) - fprintf(stderr, "Failed to unblock SIGTERM\n"); + fprintf(stderr, "Failed to unblock SIGTERM and SIGHUP\n"); +#endif main_loop(); quit_timers(); diff -r 7b0c0ab0566b tools/ioemu/vl.h --- a/tools/ioemu/vl.h Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/vl.h Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/vnc.c Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/ioemu/xenstore.c Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/libxc/Makefile --- a/tools/libxc/Makefile Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/libxc/Makefile Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/libxc/ia64/Makefile --- a/tools/libxc/ia64/Makefile Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/libxc/ia64/Makefile Mon Feb 11 17:16:12 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 7b0c0ab0566b tools/libxc/xc_minios.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/xc_minios.c Mon Feb 11 17:16:12 2008 +0000 @@ -0,0 +1,308 @@ +/****************************************************************************** + * + * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>. + * 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 "xc_private.h" +#include <mm.h> +#include <lib.h> +#include <events.h> +#include <wait.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> + +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 % PAGE_SIZE)); + return map_frames_ex(&mfn, size / PAGE_SIZE, 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: + */ diff -r 7b0c0ab0566b tools/libxc/xc_pagetab.c --- a/tools/libxc/xc_pagetab.c Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/libxc/xc_pagetab.c Mon Feb 11 17:16:12 2008 +0000 @@ -5,14 +5,20 @@ */ #include "xc_private.h" +#ifdef CONFIG_STUBDOM +#include <arch_mm.h> +#endif + #if defined(__i386__) #define L1_PAGETABLE_SHIFT_PAE 12 #define L2_PAGETABLE_SHIFT_PAE 21 #define L3_PAGETABLE_SHIFT_PAE 30 +#ifndef CONFIG_STUBDOM #define L1_PAGETABLE_SHIFT 12 #define L2_PAGETABLE_SHIFT 22 +#endif #define L0_PAGETABLE_MASK_PAE 0x00000ffffffff000ULL #define L1_PAGETABLE_MASK_PAE 0x1ffULL @@ -30,8 +36,10 @@ #define L3_PAGETABLE_SHIFT_PAE 30 #define L4_PAGETABLE_SHIFT_PAE 39 +#ifndef CONFIG_STUBDOM #define L1_PAGETABLE_SHIFT L1_PAGETABLE_SHIFT_PAE #define L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_PAE +#endif #define L0_PAGETABLE_MASK_PAE 0x000ffffffffff000ULL #define L1_PAGETABLE_MASK_PAE 0x1ffULL diff -r 7b0c0ab0566b tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/libxc/xc_private.h Mon Feb 11 17:16:12 2008 +0000 @@ -30,12 +30,16 @@ #define DECLARE_SYSCTL struct xen_sysctl sysctl #endif +#ifdef CONFIG_STUBDOM +#include <os.h> +#else #undef PAGE_SHIFT #undef PAGE_SIZE #undef PAGE_MASK #define PAGE_SHIFT XC_PAGE_SHIFT #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) +#endif #define DEBUG 1 #define INFO 1 diff -r 7b0c0ab0566b tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/libxc/xenctrl.h Mon Feb 11 17:16:12 2008 +0000 @@ -42,6 +42,8 @@ * DEFINITIONS FOR CPU BARRIERS */ +#ifndef __barriers_defined +#define __barriers_defined #if defined(__i386__) #define mb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) #define rmb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) @@ -61,6 +63,7 @@ #define wmb() __asm__ __volatile__ ("sync" : : : "memory") /* eieio? */ #else #error "Define barriers" +#endif #endif /* diff -r 7b0c0ab0566b tools/libxc/xg_private.h --- a/tools/libxc/xg_private.h Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/libxc/xg_private.h Mon Feb 11 17:16:12 2008 +0000 @@ -34,6 +34,9 @@ char *xc_inflate_buffer(const char *in_b unsigned long csum_page (void * page); +#ifdef CONFIG_STUBDOM +#include <os.h> +#else #define _PAGE_PRESENT 0x001 #define _PAGE_RW 0x002 #define _PAGE_USER 0x004 @@ -129,6 +132,7 @@ typedef l4_pgentry_64_t l4_pgentry_t; #define l3_table_offset(_a) l3_table_offset_x86_64(_a) #define l4_table_offset(_a) l4_table_offset_x86_64(_a) #endif +#endif #define PAGE_SHIFT_X86 12 #define PAGE_SIZE_X86 (1UL << PAGE_SHIFT_X86) diff -r 7b0c0ab0566b tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Mon Feb 11 14:55:33 2008 +0000 +++ b/tools/python/xen/xend/image.py Mon Feb 11 17:16:12 2008 +0000 @@ -335,11 +335,19 @@ class ImageHandler: return if self.pid: try: - os.kill(self.pid, signal.SIGKILL) + os.kill(self.pid, signal.SIGHUP) except OSError, exn: log.exception(exn) try: - os.waitpid(self.pid, 0) + for i in xrange(10): + (p, rv) = os.waitpid(self.pid, os.WNOHANG) + log.debug("waitpid returned %s %s" % (p,rv)) + if p == self.pid: + break + time.sleep(1) + else: + os.kill(self.pid, signal.SIGKILL) + os.waitpid(self.pid, 0) except OSError, exn: # This is expected if Xend has been restarted within the # life of this domain. In this case, we can kill the process, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 11/2/08 17:40, "Samuel Thibault" <samuel.thibault@eu.citrix.com> wrote:> - 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.You hack the libxc headers a bit: is this because you need different definitions of certain things in minios environment (seems unlikely for things like memory barriers and page sizes) or because of namespace conflicts? If the latter we should be able to clean up namespace usage and avoid ifdef''ery. We don''t really want CONFIG_MINIOS all over the place, it should be able to behave nicely like any other POSIXish host of libxc. Apart from that it seems pretty clean. I suppose others may comment on the cleanliness of the changes to qemu code. Trying this patch out is probably the quickest way for me to find out how you''ve integrated into the build process. e.g., do you symlink out to libxc and so on, and store the object files and build targets somewhere under stubdom/? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser, le Mon 11 Feb 2008 19:14:16 +0000, a écrit :> You hack the libxc headers a bit: is this because you need different > definitions of certain things in minios environment (seems unlikely for > things like memory barriers and page sizes) or because of namespace > conflicts?Conflicts. Actually they get defined to the same things... Maybe we could have these go to public Xen headers so as to be simply shared.> do you symlink out to libxc and so on, and store the object > files and build targets somewhere under stubdom/?Exactly, except for extras/mini-os for now because there are various subdirectories and by default it is not compiled in any other way. Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 11/2/08 19:21, "Samuel Thibault" <samuel.thibault@eu.citrix.com> wrote:>> You hack the libxc headers a bit: is this because you need different >> definitions of certain things in minios environment (seems unlikely for >> things like memory barriers and page sizes) or because of namespace >> conflicts? > > Conflicts. Actually they get defined to the same things... Maybe we > could have these go to public Xen headers so as to be simply shared.It''s not really for Xen to define processor-architectural stuff. I''d rather just clean up libxc''s namespace usage. Or perhaps it is more appropriate to clean up stubdom''s -- it''s private architectural definitions shouldn''t be leaking into code that includes stubdom''s public high-level headers. libxc''s namespace should largely be its own playground. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser, le Mon 11 Feb 2008 21:23:37 +0000, a écrit :> perhaps it is more appropriate to clean up stubdom''s -- it''s private > architectural definitions shouldn''t be leaking into code that includes > stubdom''s public high-level headers.Ok, actually I just had to move the actual definitions of PAGE_SIZE and STACK_SIZE to a separate header, and that let me avoid pulling all internal definitions. BTW, one of the reason for not enabling its compilation by default could at least be that since we need to setup a cross-compilation environment (binutils, gcc, newlib), we have to download about 70MB of source... Add stubdomain support. - 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. - Have the domain killer send SIGHUP to the device-model script, allow the script 10s to clean up, and if still not dead, send SIGKILL. - 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@eu.citrix.com> diff -r 88818d55e95a .hgignore --- a/.hgignore Tue Feb 12 11:37:45 2008 +0000 +++ b/.hgignore Tue Feb 12 14:02:15 2008 +0000 @@ -221,6 +221,17 @@ ^tools/xm-test/lib/XmTestLib/config.py$ ^tools/xm-test/lib/XmTestReport/xmtest.py$ ^tools/xm-test/tests/.*\.test$ +^stubdom/binutils.*$ +^stubdom/cross-root.*$ +^stubdom/gcc.*$ +^stubdom/include.*$ +^stubdom/ioemu.*$ +^stubdom/libxc.*$ +^stubdom/lwip.*$ +^stubdom/mini-os.*$ +^stubdom/newlib.*$ +^stubdom/pciutils.*$ +^stubdom/zlib.*$ ^xen/BLOG$ ^xen/System.map$ ^xen/TAGS$ diff -r 88818d55e95a Config.mk --- a/Config.mk Tue Feb 12 11:37:45 2008 +0000 +++ b/Config.mk Tue Feb 12 14:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 2008 +0000 @@ -14,6 +14,10 @@ #include <blkfront.h> #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->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); + 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 2008 +0000 @@ -0,0 +1,1083 @@ +/* + * POSIX-compatible libc layer + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 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:02:15 2008 +0000 @@ -0,0 +1,187 @@ +/* + * libxs-compatible layer + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 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:02:15 2008 +0000 @@ -0,0 +1,42 @@ +/* + * Caml bootstrap + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 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:02:15 2008 +0000 @@ -0,0 +1,167 @@ +/* + * POSIX-compatible main layer + * + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 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 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:02:15 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 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:02:15 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 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:02:15 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) @@ -49,6 +52,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; @@ -178,6 +200,9 @@ void network_tx_buf_gc(struct netfront_d 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]; gnttab_end_access(buf->gref); @@ -217,6 +242,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]) { @@ -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 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:02:15 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 stubdom/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/Makefile Tue Feb 12 14:02:15 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@sources.redhat.com:/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@cvs.savannah.nongnu.org:/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 stubdom/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/README Tue Feb 12 14:02:15 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 stubdom/binutils.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/binutils.patch Tue Feb 12 14:02:15 2008 +0000 @@ -0,0 +1,14 @@ +It looks like binutils has troubles with makeinfo and the doc generation. +We don''t need it anyway + +--- binutils-2.18/bfd/Makefile.inorig 2008-01-16 16:17:43.004484000 +0000 ++++ binutils-2.18/bfd/Makefile.in 2008-01-16 16:17:50.505526000 +0000 +@@ -271,7 +271,7 @@ + INCDIR = $(srcdir)/../include + CSEARCH = -I. -I$(srcdir) -I$(INCDIR) + MKDEP = gcc -MM +-SUBDIRS = doc po ++SUBDIRS = po + bfddocdir = doc + bfdlib_LTLIBRARIES = libbfd.la + AM_CFLAGS = $(WARN_CFLAGS) diff -r 88818d55e95a stubdom/caml/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/caml/Makefile Tue Feb 12 14:02:15 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 stubdom/caml/hello.ml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/caml/hello.ml Tue Feb 12 14:02:15 2008 +0000 @@ -0,0 +1,4 @@ +let main arg + Printf.printf "Hello, world!\n%!." + +let _ = Callback.register "main" main diff -r 88818d55e95a stubdom/gcc.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/gcc.patch Tue Feb 12 14:02:15 2008 +0000 @@ -0,0 +1,31 @@ +Backported from later versions + +--- gcc-4.2.2/gcc/config.gcc 2007-11-22 16:27:45.000000000 +0000 ++++ gcc-4.2.2/gcc/config.gcc 2007-11-22 16:23:00.000000000 +0000 +@@ -1033,6 +1033,11 @@ + tmake_file="i386/t-i386elf t-svr4" + use_fixproto=yes + ;; ++x86_64-*-elf*) ++ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/x86-64.h" ++ tmake_file="i386/t-i386elf t-svr4" ++ use_fixproto=yes ++ ;; + i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) + if test x$gas = xyes + then + +We don''t have a libc yet at this stage. Unused anyway + +--- gcc-4.2.2/gcc/unwind-generic.h.orig 2008-01-11 18:54:40.000000000 +0100 ++++ gcc-4.2.2/gcc/unwind-generic.h 2008-01-11 18:54:31.000000000 +0100 +@@ -203,7 +203,6 @@ + compatible with the standard ABI for IA-64, we inline these. */ + + #ifdef __ia64__ +-#include <stdlib.h> + + static inline _Unwind_Ptr + _Unwind_GetDataRelBase (struct _Unwind_Context *_C) +Backported from later versions + diff -r 88818d55e95a stubdom/libpci.config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/libpci.config.h Tue Feb 12 14:02:15 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 stubdom/libpci.config.mak --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/libpci.config.mak Tue Feb 12 14:02:15 2008 +0000 @@ -0,0 +1,2 @@ +LIBZ=-lz +LDLIBS+=$(LIBZ) diff -r 88818d55e95a stubdom/newlib.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/newlib.patch Tue Feb 12 14:02:15 2008 +0000 @@ -0,0 +1,203 @@ +There is a mix between longs and long longs. + +Index: newlib/libc/include/inttypes.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/inttypes.h,v +retrieving revision 1.3 +diff -u -p -r1.3 inttypes.h +--- newlib/libc/include/inttypes.h 16 Dec 2005 19:03:12 -0000 1.3 ++++ newlib/libc/include/inttypes.h 8 Nov 2007 16:32:44 -0000 +@@ -163,12 +163,12 @@ + + + /* 64-bit types */ +-#if __have_longlong64 +-#define __PRI64(x) __STRINGIFY(ll##x) +-#define __SCN64(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRI64(x) __STRINGIFY(l##x) + #define __SCN64(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRI64(x) __STRINGIFY(ll##x) ++#define __SCN64(x) __STRINGIFY(ll##x) + #else + #define __PRI64(x) __STRINGIFY(x) + #define __SCN64(x) __STRINGIFY(x) +@@ -217,12 +217,12 @@ + #endif + + /* max-bit types */ +-#if __have_longlong64 +-#define __PRIMAX(x) __STRINGIFY(ll##x) +-#define __SCNMAX(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRIMAX(x) __STRINGIFY(l##x) + #define __SCNMAX(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRIMAX(x) __STRINGIFY(ll##x) ++#define __SCNMAX(x) __STRINGIFY(ll##x) + #else + #define __PRIMAX(x) __STRINGIFY(x) + #define __SCNMAX(x) __STRINGIFY(x) +@@ -242,12 +242,12 @@ + #define SCNxMAX __SCNMAX(x) + + /* ptr types */ +-#if __have_longlong64 +-#define __PRIPTR(x) __STRINGIFY(ll##x) +-#define __SCNPTR(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRIPTR(x) __STRINGIFY(l##x) + #define __SCNPTR(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRIPTR(x) __STRINGIFY(ll##x) ++#define __SCNPTR(x) __STRINGIFY(ll##x) + #else + #define __PRIPTR(x) __STRINGIFY(x) + #define __SCNPTR(x) __STRINGIFY(x) + +We don''t want u?int32_t to be long as our code assume in a lot of places to be +int. + +Index: newlib/libc/include/stdint.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/stdint.h,v +retrieving revision 1.10 +diff -u -p -r1.10 stdint.h +--- newlib/libc/include/stdint.h 16 Aug 2006 21:39:43 -0000 1.10 ++++ newlib/libc/include/stdint.h 12 Feb 2008 13:07:52 -0000 +@@ -38,7 +38,7 @@ extern "C" { + #if __STDINT_EXP(LONG_MAX) > 0x7fffffff + #define __have_long64 1 + #elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) +-#define __have_long32 1 ++/* #define __have_long32 1 */ + #endif + + #if __STDINT_EXP(SCHAR_MAX) == 0x7f + +Define the basic ia64 jump buffer + +Index: newlib/libc/include/machine/setjmp.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/machine/setjmp.h,v +retrieving revision 1.34 +diff -u -p -r1.34 setjmp.h +--- newlib/libc/include/machine/setjmp.h 7 Nov 2007 21:42:24 -0000 1.34 ++++ newlib/libc/include/machine/setjmp.h 11 Jan 2008 18:10:43 -0000 +@@ -72,6 +72,11 @@ _BEGIN_STD_C + #define _JBLEN 8 + #endif + ++#ifdef __ia64__ ++#define _JBTYPE long ++#define _JBLEN 70 ++#endif ++ + #ifdef __i960__ + #define _JBLEN 35 + #endif + +In mini-os we use a dynamic reentrency buffer. + +Index: newlib/libc/include/sys/config.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/sys/config.h,v +retrieving revision 1.47 +diff -u -p -r1.47 config.h +--- newlib/libc/include/sys/config.h 15 Mar 2007 21:32:12 -0000 1.47 ++++ newlib/libc/include/sys/config.h 8 Nov 2007 16:32:44 -0000 +@@ -71,6 +71,10 @@ + #endif + #endif + ++#ifndef __DYNAMIC_REENT__ ++#define __DYNAMIC_REENT__ ++#endif ++ + #ifdef __mn10200__ + #define __SMALL_BITFIELDS + #endif + +Dynamic pointer to our reentrancy zone + +Index: newlib/libc/reent/getreent.c +==================================================================+RCS file: /cvs/src/src/newlib/libc/reent/getreent.c,v +retrieving revision 1.2 +diff -u -p -r1.2 getreent.c +--- newlib/libc/reent/getreent.c 7 Sep 2007 00:45:55 -0000 1.2 ++++ newlib/libc/reent/getreent.c 8 Nov 2007 16:32:44 -0000 +@@ -3,12 +3,20 @@ + #include <_ansi.h> + #include <reent.h> + ++#define weak_alias(name, aliasname) \ ++ extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); ++ + #ifdef __getreent + #undef __getreent + #endif ++#ifdef __libc_getreent ++#undef __libc_getreent ++#endif + + struct _reent * +-_DEFUN_VOID(__getreent) ++__libc_getreent (void) + { + return _impure_ptr; + } ++weak_alias(__libc_getreent,__getreent) ++ + +We can''t provide a red zone in mini-os. + +Index: newlib/libc/machine/x86_64/memcpy.S +==================================================================+RCS file: /cvs/src/src/newlib/libc/machine/x86_64/memcpy.S,v +retrieving revision 1.1 +diff -u -p -r1.1 memcpy.S +--- newlib/libc/machine/x86_64/memcpy.S 28 Aug 2007 21:56:49 -0000 1.1 ++++ newlib/libc/machine/x86_64/memcpy.S 8 Nov 2007 16:32:44 -0000 +@@ -30,10 +30,18 @@ quadword_aligned: + cmpq $256, rdx + jb quadword_copy + ++#if 1 ++ subq $32, rsp ++ movq rax, 24 (rsp) ++ movq r12, 16 (rsp) ++ movq r13, 8 (rsp) ++ movq r14, 0 (rsp) ++#else + movq rax, -8 (rsp) + movq r12, -16 (rsp) + movq r13, -24 (rsp) + movq r14, -32 (rsp) ++#endif + + movq rdx, rcx /* Copy 128 bytes at a time with minimum cache polution */ + shrq $7, rcx +@@ -89,10 +97,18 @@ loop: + movq rdx, rcx + andq $127, rcx + rep movsb ++#if 1 ++ movq 24 (rsp), rax ++ movq 16 (rsp), r12 ++ movq 8 (rsp), r13 ++ movq 0 (rsp), r14 ++ addq $32, rsp ++#else + movq -8 (rsp), rax + movq -16 (rsp), r12 + movq -24 (rsp), r13 + movq -32 (rsp), r14 ++#endif + ret + + diff -r 88818d55e95a stubdom/stubdom-dm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/stubdom-dm Tue Feb 12 14:02:15 2008 +0000 @@ -0,0 +1,97 @@ +#!/bin/bash +# +# Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.net> +# +# 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 tools/ioemu/configure --- a/tools/ioemu/configure Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/ioemu/configure Tue Feb 12 14:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 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:02:15 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 @@ -68,6 +75,7 @@ #endif #if defined(__sun__) #include <stropts.h> +#endif #endif #endif @@ -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 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:02:15 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 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:02:15 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 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:02:15 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 tools/libxc/Makefile --- a/tools/libxc/Makefile Tue Feb 12 11:37:45 2008 +0000 +++ b/tools/libxc/Makefile Tue Feb 12 14:02:15 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 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:02:15 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 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:02:15 2008 +0000 @@ -0,0 +1,313 @@ +/****************************************************************************** + * + * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>. + * 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-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 12/2/08 14:04, "Samuel Thibault" <samuel.thibault@eu.citrix.com> wrote:> Ok, actually I just had to move the actual definitions of PAGE_SIZE > and STACK_SIZE to a separate header, and that let me avoid pulling all > internal definitions. > > BTW, one of the reason for not enabling its compilation by default could > at least be that since we need to setup a cross-compilation environment > (binutils, gcc, newlib), we have to download about 70MB of source...Applied, but please send another patch to override XEN_OS and hence present yourself as a new ''OS environment'' to the overall build system. That''ll clean up a good number of your Makefile changes outside stubdom/. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser, le Tue 12 Feb 2008 14:32:25 +0000, a écrit :> AppliedCool!> please send another patch to override XEN_OS and hence present > yourself as a new ''OS environment'' to the overall build system. That''ll > clean up a good number of your Makefile changes outside stubdom/.It does indeed, here it is. Make stubdom/Makefile override XEN_OS to MiniOS, and add config/MiniOS.mk. Add PTHREAD_LIBS to configs (usually holding -lpthread). Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r d0b12316994b Config.mk --- a/Config.mk Tue Feb 12 14:47:14 2008 +0000 +++ b/Config.mk Tue Feb 12 14:51:43 2008 +0000 @@ -27,14 +27,6 @@ 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 d0b12316994b config/MiniOS.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/MiniOS.mk Tue Feb 12 14:51:43 2008 +0000 @@ -0,0 +1,9 @@ +include $(XEN_ROOT)/config/StdGNU.mk +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) + +# Override settings for this OS +PTHREAD_LIBS diff -r d0b12316994b config/StdGNU.mk --- a/config/StdGNU.mk Tue Feb 12 14:47:14 2008 +0000 +++ b/config/StdGNU.mk Tue Feb 12 14:51:43 2008 +0000 @@ -35,6 +35,7 @@ PRIVATE_BINDIR = $(PRIVATE_PREFIX)/bin SOCKET_LIBS CURSES_LIBS = -lncurses +PTHREAD_LIBS = -lpthread UTIL_LIBS = -lutil SONAME_LDFLAG = -soname SHLIB_CFLAGS = -shared diff -r d0b12316994b config/SunOS.mk --- a/config/SunOS.mk Tue Feb 12 14:47:14 2008 +0000 +++ b/config/SunOS.mk Tue Feb 12 14:51:43 2008 +0000 @@ -39,6 +39,7 @@ SunOS_LIBDIR_x86_64 = /usr/sfw/lib/amd64 SOCKET_LIBS = -lsocket CURSES_LIBS = -lcurses +PTHREAD_LIBS = -lpthread UTIL_LIBS SONAME_LDFLAG = -h SHLIB_CFLAGS = -R $(SunOS_LIBDIR) -shared diff -r d0b12316994b stubdom/Makefile --- a/stubdom/Makefile Tue Feb 12 14:47:14 2008 +0000 +++ b/stubdom/Makefile Tue Feb 12 14:51:43 2008 +0000 @@ -1,4 +1,6 @@ XEN_ROOT = .. XEN_ROOT = .. + +export XEN_OS=MiniOS include $(XEN_ROOT)/Config.mk export stubdom=y diff -r d0b12316994b tools/libxc/Makefile --- a/tools/libxc/Makefile Tue Feb 12 14:47:14 2008 +0000 +++ b/tools/libxc/Makefile Tue Feb 12 14:51:43 2008 +0000 @@ -25,13 +25,11 @@ CTRL_SRCS-y += xc_resume.c 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 +CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c GUEST_SRCS-y : GUEST_SRCS-y += xg_private.c @@ -74,10 +72,6 @@ CFLAGS += -Wp,-MD,.$(@F).d CFLAGS += -Wp,-MD,.$(@F).d 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)) @@ -152,7 +146,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 $@ $^ $(LDLIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ $(PTHREAD_LIBS) # libxenguest @@ -165,7 +159,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 $(LDLIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl $(PTHREAD_LIBS) -include $(DEPS) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
It looks like the stubdom/ patches for binutils, gcc, and newlib didn''t make through, here they are again. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r 7e91007fa727 stubdom/binutils.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/binutils.patch Tue Feb 12 15:11:04 2008 +0000 @@ -0,0 +1,14 @@ +It looks like binutils has troubles with makeinfo and the doc generation. +We don''t need it anyway + +--- binutils-2.18/bfd/Makefile.inorig 2008-01-16 16:17:43.004484000 +0000 ++++ binutils-2.18/bfd/Makefile.in 2008-01-16 16:17:50.505526000 +0000 +@@ -271,7 +271,7 @@ + INCDIR = $(srcdir)/../include + CSEARCH = -I. -I$(srcdir) -I$(INCDIR) + MKDEP = gcc -MM +-SUBDIRS = doc po ++SUBDIRS = po + bfddocdir = doc + bfdlib_LTLIBRARIES = libbfd.la + AM_CFLAGS = $(WARN_CFLAGS) diff -r 7e91007fa727 stubdom/gcc.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/gcc.patch Tue Feb 12 15:11:04 2008 +0000 @@ -0,0 +1,31 @@ +Backported from later versions + +--- gcc-4.2.2/gcc/config.gcc 2007-11-22 16:27:45.000000000 +0000 ++++ gcc-4.2.2/gcc/config.gcc 2007-11-22 16:23:00.000000000 +0000 +@@ -1033,6 +1033,11 @@ + tmake_file="i386/t-i386elf t-svr4" + use_fixproto=yes + ;; ++x86_64-*-elf*) ++ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/x86-64.h" ++ tmake_file="i386/t-i386elf t-svr4" ++ use_fixproto=yes ++ ;; + i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) + if test x$gas = xyes + then + +We don''t have a libc yet at this stage. Unused anyway + +--- gcc-4.2.2/gcc/unwind-generic.h.orig 2008-01-11 18:54:40.000000000 +0100 ++++ gcc-4.2.2/gcc/unwind-generic.h 2008-01-11 18:54:31.000000000 +0100 +@@ -203,7 +203,6 @@ + compatible with the standard ABI for IA-64, we inline these. */ + + #ifdef __ia64__ +-#include <stdlib.h> + + static inline _Unwind_Ptr + _Unwind_GetDataRelBase (struct _Unwind_Context *_C) +Backported from later versions + diff -r 7e91007fa727 stubdom/newlib.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/newlib.patch Tue Feb 12 15:11:04 2008 +0000 @@ -0,0 +1,203 @@ +There is a mix between longs and long longs. + +Index: newlib/libc/include/inttypes.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/inttypes.h,v +retrieving revision 1.3 +diff -u -p -r1.3 inttypes.h +--- newlib/libc/include/inttypes.h 16 Dec 2005 19:03:12 -0000 1.3 ++++ newlib/libc/include/inttypes.h 8 Nov 2007 16:32:44 -0000 +@@ -163,12 +163,12 @@ + + + /* 64-bit types */ +-#if __have_longlong64 +-#define __PRI64(x) __STRINGIFY(ll##x) +-#define __SCN64(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRI64(x) __STRINGIFY(l##x) + #define __SCN64(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRI64(x) __STRINGIFY(ll##x) ++#define __SCN64(x) __STRINGIFY(ll##x) + #else + #define __PRI64(x) __STRINGIFY(x) + #define __SCN64(x) __STRINGIFY(x) +@@ -217,12 +217,12 @@ + #endif + + /* max-bit types */ +-#if __have_longlong64 +-#define __PRIMAX(x) __STRINGIFY(ll##x) +-#define __SCNMAX(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRIMAX(x) __STRINGIFY(l##x) + #define __SCNMAX(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRIMAX(x) __STRINGIFY(ll##x) ++#define __SCNMAX(x) __STRINGIFY(ll##x) + #else + #define __PRIMAX(x) __STRINGIFY(x) + #define __SCNMAX(x) __STRINGIFY(x) +@@ -242,12 +242,12 @@ + #define SCNxMAX __SCNMAX(x) + + /* ptr types */ +-#if __have_longlong64 +-#define __PRIPTR(x) __STRINGIFY(ll##x) +-#define __SCNPTR(x) __STRINGIFY(ll##x) +-#elif __have_long64 ++#if __have_long64 + #define __PRIPTR(x) __STRINGIFY(l##x) + #define __SCNPTR(x) __STRINGIFY(l##x) ++#elif __have_longlong64 ++#define __PRIPTR(x) __STRINGIFY(ll##x) ++#define __SCNPTR(x) __STRINGIFY(ll##x) + #else + #define __PRIPTR(x) __STRINGIFY(x) + #define __SCNPTR(x) __STRINGIFY(x) + +We don''t want u?int32_t to be long as our code assume in a lot of places to be +int. + +Index: newlib/libc/include/stdint.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/stdint.h,v +retrieving revision 1.10 +diff -u -p -r1.10 stdint.h +--- newlib/libc/include/stdint.h 16 Aug 2006 21:39:43 -0000 1.10 ++++ newlib/libc/include/stdint.h 12 Feb 2008 13:07:52 -0000 +@@ -38,7 +38,7 @@ extern "C" { + #if __STDINT_EXP(LONG_MAX) > 0x7fffffff + #define __have_long64 1 + #elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) +-#define __have_long32 1 ++/* #define __have_long32 1 */ + #endif + + #if __STDINT_EXP(SCHAR_MAX) == 0x7f + +Define the basic ia64 jump buffer + +Index: newlib/libc/include/machine/setjmp.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/machine/setjmp.h,v +retrieving revision 1.34 +diff -u -p -r1.34 setjmp.h +--- newlib/libc/include/machine/setjmp.h 7 Nov 2007 21:42:24 -0000 1.34 ++++ newlib/libc/include/machine/setjmp.h 11 Jan 2008 18:10:43 -0000 +@@ -72,6 +72,11 @@ _BEGIN_STD_C + #define _JBLEN 8 + #endif + ++#ifdef __ia64__ ++#define _JBTYPE long ++#define _JBLEN 70 ++#endif ++ + #ifdef __i960__ + #define _JBLEN 35 + #endif + +In mini-os we use a dynamic reentrency buffer. + +Index: newlib/libc/include/sys/config.h +==================================================================+RCS file: /cvs/src/src/newlib/libc/include/sys/config.h,v +retrieving revision 1.47 +diff -u -p -r1.47 config.h +--- newlib/libc/include/sys/config.h 15 Mar 2007 21:32:12 -0000 1.47 ++++ newlib/libc/include/sys/config.h 8 Nov 2007 16:32:44 -0000 +@@ -71,6 +71,10 @@ + #endif + #endif + ++#ifndef __DYNAMIC_REENT__ ++#define __DYNAMIC_REENT__ ++#endif ++ + #ifdef __mn10200__ + #define __SMALL_BITFIELDS + #endif + +Dynamic pointer to our reentrancy zone + +Index: newlib/libc/reent/getreent.c +==================================================================+RCS file: /cvs/src/src/newlib/libc/reent/getreent.c,v +retrieving revision 1.2 +diff -u -p -r1.2 getreent.c +--- newlib/libc/reent/getreent.c 7 Sep 2007 00:45:55 -0000 1.2 ++++ newlib/libc/reent/getreent.c 8 Nov 2007 16:32:44 -0000 +@@ -3,12 +3,20 @@ + #include <_ansi.h> + #include <reent.h> + ++#define weak_alias(name, aliasname) \ ++ extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); ++ + #ifdef __getreent + #undef __getreent + #endif ++#ifdef __libc_getreent ++#undef __libc_getreent ++#endif + + struct _reent * +-_DEFUN_VOID(__getreent) ++__libc_getreent (void) + { + return _impure_ptr; + } ++weak_alias(__libc_getreent,__getreent) ++ + +We can''t provide a red zone in mini-os. + +Index: newlib/libc/machine/x86_64/memcpy.S +==================================================================+RCS file: /cvs/src/src/newlib/libc/machine/x86_64/memcpy.S,v +retrieving revision 1.1 +diff -u -p -r1.1 memcpy.S +--- newlib/libc/machine/x86_64/memcpy.S 28 Aug 2007 21:56:49 -0000 1.1 ++++ newlib/libc/machine/x86_64/memcpy.S 8 Nov 2007 16:32:44 -0000 +@@ -30,10 +30,18 @@ quadword_aligned: + cmpq $256, rdx + jb quadword_copy + ++#if 1 ++ subq $32, rsp ++ movq rax, 24 (rsp) ++ movq r12, 16 (rsp) ++ movq r13, 8 (rsp) ++ movq r14, 0 (rsp) ++#else + movq rax, -8 (rsp) + movq r12, -16 (rsp) + movq r13, -24 (rsp) + movq r14, -32 (rsp) ++#endif + + movq rdx, rcx /* Copy 128 bytes at a time with minimum cache polution */ + shrq $7, rcx +@@ -89,10 +97,18 @@ loop: + movq rdx, rcx + andq $127, rcx + rep movsb ++#if 1 ++ movq 24 (rsp), rax ++ movq 16 (rsp), r12 ++ movq 8 (rsp), r13 ++ movq 0 (rsp), r14 ++ addq $32, rsp ++#else + movq -8 (rsp), rax + movq -16 (rsp), r12 + movq -24 (rsp), r13 + movq -32 (rsp), r14 ++#endif + ret + + _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 12/2/08 15:13, "Samuel Thibault" <samuel.thibault@eu.citrix.com> wrote:> It looks like the stubdom/ patches for binutils, gcc, and newlib didn''t > make through, here they are again. > > Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>The files are in my local tree but masked by .hgignore. Please send me a patch to .hgignore: that will reveal the missing files and I''ll check in the whole lot (.hgignore + missing patches) in one changeset. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser, le Tue 12 Feb 2008 15:24:39 +0000, a écrit :> On 12/2/08 15:13, "Samuel Thibault" <samuel.thibault@eu.citrix.com> wrote: > > > It looks like the stubdom/ patches for binutils, gcc, and newlib didn''t > > make through, here they are again. > > > > Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> > > The files are in my local tree but masked by .hgignore.Oh right, I had paid attention to the few lines that mention "patch", but not the stubdom/ ones which match a bit too much. Here is a patch. Rename stubdom/*.build into stubdom/*-build, newlib into newlib-cvs, lwip into lwip-cvs. Fix .hgignore to ignore only them and not the patches. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r f7ec8df22304 .hgignore --- a/.hgignore Tue Feb 12 15:04:26 2008 +0000 +++ b/.hgignore Tue Feb 12 15:36:52 2008 +0000 @@ -80,17 +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.*$ +^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 f7ec8df22304 stubdom/Makefile --- a/stubdom/Makefile Tue Feb 12 15:04:26 2008 +0000 +++ b/stubdom/Makefile Tue Feb 12 15:36:52 2008 +0000 @@ -54,8 +54,8 @@ BINUTILS_STAMPFILE=$(CROSS_ROOT)/bin/$(G .PHONY: cross-binutils cross-binutils: $(BINUTILS_STAMPFILE) $(BINUTILS_STAMPFILE): binutils-$(BINUTILS_VERSION) - mkdir -p binutils.build - ( cd binutils.build && \ + mkdir -p binutils-build + ( cd binutils-build && \ ../binutils-$(BINUTILS_VERSION)/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf && \ $(MAKE) && \ $(MAKE) check && \ @@ -76,8 +76,8 @@ GCC_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TA .PHONY: cross-gcc cross-gcc: $(GCC_STAMPFILE) $(GCC_STAMPFILE): gcc-$(GCC_VERSION) $(BINUTILS_STAMPFILE) - mkdir -p gcc.build - ( cd gcc.build && \ + 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 ) @@ -88,16 +88,16 @@ cross-gcc: $(GCC_STAMPFILE) newlib: cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co -D $(NEWLIB_DATE) newlib - mv src newlib - ( cd newlib && patch -p0 < ../newlib.patch) + mv src newlib-cvs + ( cd newlib-cvs && 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 && \ + mkdir -p newlib-build + ( cd newlib-build && \ + CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" ../newlib-cvs/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \ $(MAKE) && \ $(MAKE) install ) @@ -144,8 +144,9 @@ cross-libpci: $(LIBPCI_STAMPFILE) # lwIP ###### -lwip: +lwip-cvs: cvs -z 9 -d :pserver:anonymous@cvs.savannah.nongnu.org:/sources/lwip co -D $(LWIP_DATE) lwip + mv lwip lwip-cvs ####### # Links @@ -190,7 +191,7 @@ ioemu: cross-zlib cross-libpci mk-symlin 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 + $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip-cvs ###### # caml @@ -205,12 +206,12 @@ caml: ######## .PHONY: qemu-stubdom -qemu-stubdom: mk-symlinks lwip libxc ioemu - $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip QEMUDIR=$(CURDIR)/ioemu +qemu-stubdom: mk-symlinks lwip-cvs libxc ioemu + $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs 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 +caml-stubdom: mk-symlinks lwip-cvs libxc cross-libpci caml + $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwia-cvs CAMLDIR=$(CURDIR)/caml ######### # install @@ -227,7 +228,7 @@ install: mini-os/mini-os.gz # Only clean the libxc/ioemu/mini-os part .PHONY: clean clean: - -$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip clean + -$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs clean $(MAKE) -C caml clean rm -fr libxc ioemu mini-os include @@ -235,7 +236,7 @@ clean: .PHONY: crossclean crossclean: clean rm -fr $(CROSS_ROOT) - rm -fr binutils.build gcc.build newlib.build + rm -fr binutils-build gcc-build newlib-build rm -fr zlib-$(ZLIB_VERSION) pciutils-$(LIBPCI_VERSION) # clean patched sources @@ -243,8 +244,8 @@ patchclean: crossclean patchclean: crossclean rm -fr binutils-$(BINUTILS_VERSION) rm -fr gcc-$(GCC_VERSION) - rm -fr newlib - rm -fr lwip + rm -fr newlib-cvs + rm -fr lwip-cvs # clean downloads .PHONY: downloadclean _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
stubdom: missing two renames to avoid always re-compiling newlib. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com> diff -r f3eb383d2bd5 stubdom/Makefile --- a/stubdom/Makefile Tue Feb 12 16:51:36 2008 +0000 +++ b/stubdom/Makefile Tue Feb 12 16:54:31 2008 +0000 @@ -86,7 +86,7 @@ cross-gcc: $(GCC_STAMPFILE) # Cross-newlib ############## -newlib: +newlib-cvs: cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co -D $(NEWLIB_DATE) newlib mv src newlib-cvs ( cd newlib-cvs && patch -p0 < ../newlib.patch) @@ -94,7 +94,7 @@ NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TAR NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a .PHONY: cross-newlib cross-newlib: $(NEWLIB_STAMPFILE) -$(NEWLIB_STAMPFILE): newlib $(GCC_STAMPFILE) +$(NEWLIB_STAMPFILE): newlib-cvs $(GCC_STAMPFILE) mkdir -p newlib-build ( cd newlib-build && \ CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" ../newlib-cvs/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 11/02/08 17:40 +0000, Samuel Thibault wrote:> Hello, > > At last, here is the big patch that adds the stubdomain support. I > guess some reviewing will be needed before commiting it.> diff -r 7b0c0ab0566b extras/mini-os/include/byteswap.h > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/extras/mini-os/include/byteswap.h Mon Feb 11 17:16:12 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)) > +Perhaps make these inline for type checking. Just wondering about some of the TODO notes in the patchset. I''ll take a closer look. Mike -- Mike D. Day IBM LTC Cell: 919 412-3900 Sametime: ncmike@us.ibm.com AIM: ncmikeday Yahoo: ultra.runner PGP key: http://www.ncultra.org/ncmike/pubkey.asc _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel