Index: kernel/arch/xen32/include/boot/boot.h
===================================================================
--- kernel/arch/xen32/include/boot/boot.h	(revision d227101926028711e095e37ad2b5e2f5f3d340a9)
+++ kernel/arch/xen32/include/boot/boot.h	(revision 4965a84656b633f118cbd1342b876ad4c815691b)
@@ -36,6 +36,32 @@
 #define __xen32_BOOT_H__
 
+#define GUEST_CMDLINE	1024
+#define START_INFO_SIZE	1104
 #define BOOT_OFFSET		0x0000
-#define TEMP_STACK_SIZE	0x400
+
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+typedef struct {
+	char magic[32];             /**< "xen-<version>-<platform>" */
+	unsigned long nr_pages;     /**< Total pages allocated to this domain */
+	unsigned long shared_info;  /**< Physical address of shared info struct */
+	uint32_t flags;             /**< SIF_xxx flags */
+	unsigned long store_mfn;    /**< Physical page number of shared page */
+	uint32_t store_evtchn;      /**< Event channel for store communication */
+	unsigned long console_mfn;  /**< Physical address of console page */
+	uint32_t console_evtchn;    /**< Event channel for console messages */
+	unsigned long pt_base;      /**< Virtual address of page directory */
+	unsigned long nr_pt_frames; /**< Number of bootstrap p.t. frames */
+	unsigned long mfn_list;     /**< Virtual address of page-frame list */
+	unsigned long mod_start;    /**< Virtual address of pre-loaded module */
+	unsigned long mod_len;      /**< Size (bytes) of pre-loaded module */
+	int8_t cmd_line[GUEST_CMDLINE];
+} start_info_t;
+
+extern start_info_t start_info;
+
+#endif
 
 #endif
Index: kernel/arch/xen32/include/hypercall.h
===================================================================
--- kernel/arch/xen32/include/hypercall.h	(revision 4965a84656b633f118cbd1342b876ad4c815691b)
+++ kernel/arch/xen32/include/hypercall.h	(revision 4965a84656b633f118cbd1342b876ad4c815691b)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2006 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __xen32_HYPERCALL_H__
+#define __xen32_HYPERCALL_H__
+
+#include <arch/types.h>
+
+#define hypercall0(id)	\
+	({	\
+		unative_t ret;	\
+		asm volatile (	\
+			"call hypercall_page + (" STRING(id) " * 32)\n"	\
+			: "=a" (ret)	\
+			:	\
+			: "memory"	\
+		);	\
+		ret;	\
+	})
+
+#define hypercall1(id, p1)	\
+	({	\
+		unative_t ret, __ign1;	\
+		asm volatile (	\
+			"call hypercall_page + (" STRING(id) " * 32)\n"	\
+			: "=a" (ret), \
+			  "=b" (__ign1)	\
+			: "1" (p1)	\
+			: "memory"	\
+		);	\
+		ret;	\
+	})
+
+#define hypercall2(id, p1, p2)	\
+	({	\
+		unative_t ret, __ign1, __ign2;	\
+		asm volatile (	\
+			"call hypercall_page + (" STRING(id) " * 32)\n"	\
+			: "=a" (ret), \
+			  "=b" (__ign1),	\
+			  "=c" (__ign2)	\
+			: "1" (p1),	\
+			  "2" (p2)	\
+			: "memory"	\
+		);	\
+		ret;	\
+	})
+
+#define hypercall3(id, p1, p2, p3)	\
+	({	\
+		unative_t ret, __ign1, __ign2, __ign3;	\
+		asm volatile (	\
+			"call hypercall_page + (" STRING(id) " * 32)\n"	\
+			: "=a" (ret), \
+			  "=b" (__ign1),	\
+			  "=c" (__ign2),	\
+			  "=d" (__ign3)	\
+			: "1" (p1),	\
+			  "2" (p2),	\
+			  "3" (p3),	\
+			: "memory"	\
+		);	\
+		ret;	\
+	})
+
+#define hypercall4(id, p1, p2, p3, p4)	\
+	({	\
+		unative_t ret, __ign1, __ign2, __ign3, __ign4;	\
+		asm volatile (	\
+			"call hypercall_page + (" STRING(id) " * 32)\n"	\
+			: "=a" (ret), \
+			  "=b" (__ign1),	\
+			  "=c" (__ign2),	\
+			  "=d" (__ign3),	\
+			  "=S" (__ign4)	\
+			: "1" (p1),	\
+			  "2" (p2),	\
+			  "3" (p3),	\
+			  "4" (p4),	\
+			: "memory"	\
+		);	\
+		ret;	\
+	})
+
+#define hypercall5(id, p1, p2, p3, p4, p5)	\
+	({	\
+		unative_t ret, __ign1, __ign2, __ign3, __ign4, __ing5;	\
+		asm volatile (	\
+			"call hypercall_page + (" STRING(id) " * 32)\n"	\
+			: "=a" (ret), \
+			  "=b" (__ign1),	\
+			  "=c" (__ign2),	\
+			  "=d" (__ign3),	\
+			  "=S" (__ign4),	\
+			  "=D" (__ign5)	\
+			: "1" (p1),	\
+			  "2" (p2),	\
+			  "3" (p3),	\
+			  "4" (p4),	\
+			  "5" (p5),	\
+			: "memory"	\
+		);	\
+		ret;	\
+	})
+
+
+static inline int xen_console_io(int cmd, int count, char *str)
+{
+	return hypercall3(XEN_CONSOLE_IO, cmd, count, str);
+}
+
+#endif
Index: kernel/arch/xen32/src/boot/boot.S
===================================================================
--- kernel/arch/xen32/src/boot/boot.S	(revision d227101926028711e095e37ad2b5e2f5f3d340a9)
+++ kernel/arch/xen32/src/boot/boot.S	(revision 4965a84656b633f118cbd1342b876ad4c815691b)
@@ -35,5 +35,5 @@
 	.ascii  "GUEST_OS=HelenOS,"
 	.ascii  "XEN_VER=xen-3.0,"
-	.ascii  "HYPERCALL_PAGE=0x2,"
+	.ascii  "HYPERCALL_PAGE=0x0002,"
 	.ascii  "LOADER=generic,"
 	.ascii  "PT_MODE_WRITABLE"
@@ -48,6 +48,12 @@
 kernel_image_start:
 	cld
-	movl $kernel_stack, %esp         # initialize stack pointer
 	
+	# copy start_info (esi initialized by Xen)
+	
+	movl $start_info, %edi
+	movl $START_INFO_SIZE >> 2, %ecx
+	cld
+	rep movsb
+
 	call main_bsp								# never returns
 
@@ -55,11 +61,7 @@
 	hlt
 
-.data
+.global hypercall_page
 
-.align 4096
-page_directory:
-	.space 4096, 0
-
-kernel_stack_bottom:
-	.space TEMP_STACK_SIZE
-kernel_stack:
+.org (0x0002 * PAGE_SIZE)
+hypercall_page:
+	.space PAGE_SIZE
Index: kernel/arch/xen32/src/mm/memory_init.c
===================================================================
--- kernel/arch/xen32/src/mm/memory_init.c	(revision d227101926028711e095e37ad2b5e2f5f3d340a9)
+++ kernel/arch/xen32/src/mm/memory_init.c	(revision 4965a84656b633f118cbd1342b876ad4c815691b)
@@ -35,9 +35,10 @@
 #include <arch/mm/memory_init.h>
 #include <arch/mm/page.h>
+#include <arch/boot/boot.h>
 #include <print.h>
 
 size_t get_memory_size(void) 
 {
-	return 0;
+	return start_info.nr_pages * PAGE_SIZE;
 }
 
Index: kernel/arch/xen32/src/xen32.c
===================================================================
--- kernel/arch/xen32/src/xen32.c	(revision d227101926028711e095e37ad2b5e2f5f3d340a9)
+++ kernel/arch/xen32/src/xen32.c	(revision 4965a84656b633f118cbd1342b876ad4c815691b)
@@ -56,4 +56,5 @@
 #include <arch/bios/bios.h>
 
+#include <arch/boot/boot.h>
 #include <arch/mm/memory_init.h>
 #include <interrupt.h>
@@ -62,4 +63,6 @@
 #include <syscall/syscall.h>
 #include <console/console.h>
+
+start_info_t start_info;
 
 void arch_pre_mm_init(void)
