Index: Makefile
===================================================================
--- Makefile	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ Makefile	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -42,5 +42,5 @@
 CONFIG_HEADER = config.h
 
-.PHONY: all precheck cscope autotool config_auto config_default config distclean clean check
+.PHONY: all precheck cscope autotool config_auto config_default config distclean clean check distfile dist
 
 all: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER)
@@ -64,4 +64,6 @@
 endif
 
+# Autotool (detects compiler features)
+
 $(COMMON_MAKEFILE): autotool
 $(COMMON_HEADER): autotool
@@ -70,4 +72,6 @@
 	$(AUTOTOOL)
 	-[ -f $(COMMON_HEADER_PREV) ] && diff -q $(COMMON_HEADER_PREV) $(COMMON_HEADER) && mv -f $(COMMON_HEADER_PREV) $(COMMON_HEADER)
+
+# Build-time configuration
 
 $(CONFIG_MAKEFILE): config_default
@@ -84,6 +88,16 @@
 	$(CONFIG) $<
 
+# Distribution files
+
+distfile: all
+	$(MAKE) -C dist distfile
+
+dist:
+	$(MAKE) -C dist dist
+
+# Cleaning
+
 distclean: clean
-	rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc
+	rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc dist/HelenOS-*
 
 clean:
Index: boot/arch/sparc64/include/arch.h
===================================================================
--- boot/arch/sparc64/include/arch.h	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ boot/arch/sparc64/include/arch.h	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -41,4 +41,5 @@
 #define STACK_BIAS                   2047
 #define STACK_WINDOW_SAVE_AREA_SIZE  (16 * 8)
+#define STACK_ARG_SAVE_AREA_SIZE     (6 * 8)
 
 #define NWINDOWS  8
Index: boot/arch/sparc64/src/asm.S
===================================================================
--- boot/arch/sparc64/src/asm.S	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ boot/arch/sparc64/src/asm.S	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -152,5 +152,5 @@
 .global ofw
 ofw:
-	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
 	set ofw_cif, %l0
 	ldx [%l0], %l0
Index: boot/arch/sparc64/src/main.c
===================================================================
--- boot/arch/sparc64/src/main.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ boot/arch/sparc64/src/main.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -190,4 +190,5 @@
 	bootinfo.memmap.zones[0].start += OBP_BIAS;
 	bootinfo.memmap.zones[0].size -= OBP_BIAS;
+	bootinfo.memmap.total -= OBP_BIAS;
 }
 
@@ -204,4 +205,7 @@
 	bootinfo.physmem_start = ofw_get_physmem_start();
 	ofw_memmap(&bootinfo.memmap);
+
+	if (arch == ARCH_SUN4V)
+		sun4v_fixups();
 	
 	void *bootinfo_pa = ofw_translate(&bootinfo);
@@ -253,21 +257,16 @@
 		
 		/*
-		 * At this point, we claim the physical memory that we are
-		 * going to use. We should be safe in case of the virtual
+		 * At this point, we claim and map the physical memory that we
+		 * are going to use. We should be safe in case of the virtual
 		 * address space because the OpenFirmware, according to its
-		 * SPARC binding, should restrict its use of virtual memory
-		 * to addresses from [0xffd00000; 0xffefffff] and
-		 * [0xfe000000; 0xfeffffff].
-		 *
-		 * We don't map this piece of memory. We simply rely on
-		 * SILO to have it done for us already in this case.
-		 *
-		 * XXX SILO only maps 8 MB for us here. We should improve
-		 *     this code to be totally independent on the behavior
-		 *     of SILO.
-		 *
+		 * SPARC binding, should restrict its use of virtual memory to
+		 * addresses from [0xffd00000; 0xffefffff] and [0xfe000000;
+		 * 0xfeffffff].
 		 */
 		ofw_claim_phys(bootinfo.physmem_start + dest[i - 1],
 		    ALIGN_UP(components[i - 1].inflated, PAGE_SIZE));
+		
+		ofw_map(bootinfo.physmem_start + dest[i - 1], dest[i - 1],
+		    ALIGN_UP(components[i - 1].inflated, PAGE_SIZE), -1);
 		
 		int err = inflate(components[i - 1].start, components[i - 1].size,
@@ -304,7 +303,4 @@
 		sun4u_smp();
 	
-	if (arch == ARCH_SUN4V)
-		sun4v_fixups();
-	
 	printf("Booting the kernel ...\n");
 	jump_to_kernel(bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, subarch,
Index: boot/generic/src/balloc.c
===================================================================
--- boot/generic/src/balloc.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ boot/generic/src/balloc.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -65,4 +65,4 @@
 void *balloc_rebase(void *ptr)
 {
-	return (void *) ((uintptr_t) ptr - phys_base + ballocs->base);
+	return (void *) (((uintptr_t) ptr - phys_base) + ballocs->base);
 }
Index: dist/Makefile
===================================================================
--- dist/Makefile	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
+++ dist/Makefile	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2011 Jiri Svoboda
+# 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.
+#
+
+-include ../version
+-include ../Makefile.config
+-include ../boot/arch/$(BARCH)/Makefile.inc
+-include ../boot/Makefile.common
+
+PROFILES = amd64 arm32/GXemul arm32/integratorcp arm32/gta02 ia32 \
+    ia64/i460GX ia64/ski mips32/GXemul mips32/msim sparc64/niagara \
+    sparc64/serengeti sparc64/ultra
+
+ifdef POST_OUTPUT
+	IMGFILE = $(POST_OUTPUT)
+else
+	IMGFILE = $(BOOT_OUTPUT)
+endif
+
+SUFFIX = $(suffix $(IMGFILE))
+DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX)
+
+.PHONY: all clean dist distfile
+
+all: distfile
+distfile: $(DISTFILE)
+
+$(DISTFILE): $(IMGFILE)
+	cp $< $@
+
+dist:
+	for profile in $(PROFILES); do \
+		$(MAKE) -C .. clean ; \
+		$(MAKE) -C .. PROFILE=$$profile distfile ; \
+	done
+
+clean:
+	rm -f $(DISTFILE)
Index: kernel/arch/sparc64/src/sun4v/asm.S
===================================================================
--- kernel/arch/sparc64/src/sun4v/asm.S	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ kernel/arch/sparc64/src/sun4v/asm.S	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -41,6 +41,5 @@
 .global switch_to_userspace
 switch_to_userspace:
-	wrpr PSTATE_PRIV_BIT, %pstate
-	save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
+	save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
 	flushw
 	wrpr %g0, 0, %cleanwin		! avoid information leak
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ tools/toolchain.sh	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -28,4 +28,74 @@
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
+
+GMP_MAIN=<<EOF
+#define GCC_GMP_VERSION_NUM(a, b, c) \
+	(((a) << 16L) | ((b) << 8) | (c))
+
+#define GCC_GMP_VERSION \
+	GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)
+
+#if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4,3,2)
+	choke me
+#endif
+EOF
+
+MPFR_MAIN=<<EOF
+#if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)
+choke me
+	#endif
+EOF
+
+MPC_MAIN=<<EOF
+#if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)
+	choke me
+#endif
+EOF
+
+#
+# Check if the library described in the argument
+# exists and has acceptable version.
+#
+check_dependency() {
+	DEPENDENCY="$1"
+	HEADER="$2"
+	BODY="$3"
+	
+	FNAME="/tmp/conftest-$$"
+	
+	echo "#include ${HEADER}" > "${FNAME}.c"
+	echo >> "${FNAME}.c"
+	echo "int main()" >> "${FNAME}.c"
+	echo "{" >> "${FNAME}.c"
+	echo "${BODY}" >> "${FNAME}.c"
+	echo "	return 0;" >> "${FNAME}.c"
+	echo "}" >> "${FNAME}.c"
+	
+	cc -c -o "${FNAME}.o" "${FNAME}.c" 2> "${FNAME}.log"
+	RC="$?"
+	
+	if [ "$RC" -ne "0" ] ; then
+		echo " ${DEPENDENCY} not found, too old or compiler error."
+		echo " Please recheck manually the source file \"${FNAME}.c\"."
+		echo " The compilation of the toolchain is probably going to fail,"
+		echo " you have been warned."
+		echo
+		echo " ===== Compiler output ====="
+		cat "${FNAME}.log"
+		echo " ==========================="
+		echo
+	else
+		echo " ${DEPENDENCY} found"
+		rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"
+	fi
+}
+
+check_dependecies() {
+	echo ">>> Basic dependency check"
+	check_dependency "GMP" "<gmp.h>" "${GMP_MAIN}"
+	check_dependency "MPFR" "<mpfr.h>" "${MPFR_MAIN}"
+	check_dependency "MPC" "<mpc.h>" "${MPC_MAIN}"
+	echo
+}
 
 check_error() {
@@ -69,4 +139,8 @@
 	echo " sparc64    SPARC V9"
 	echo " all        build all targets"
+	echo
+	echo "The toolchain will be installed to the directory specified by"
+	echo "the CROSS_PREFIX environment variable. If the variable is not"
+	echo "defined, /usr/local will be used by default."
 	echo
 	
@@ -118,6 +192,4 @@
 	echo " - native C library with headers"
 	echo
-	
-	show_countdown 10
 }
 
@@ -281,4 +353,6 @@
 
 show_dependencies
+check_dependecies
+show_countdown 10
 
 case "$1" in
Index: uspace/app/bdsh/cmds/modules/mount/mount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -31,4 +31,5 @@
 #include <vfs/vfs.h>
 #include <errno.h>
+#include <getopt.h>
 #include "config.h"
 #include "util.h"
@@ -40,5 +41,11 @@
 static const char *cmdname = "mount";
 
-/* Dispays help for mount in various levels */
+static struct option const long_options[] = {
+	{ "help", no_argument, 0, 'h' },
+	{ 0, 0, 0, 0 }
+};
+
+
+/* Displays help for mount in various levels */
 void help_cmd_mount(unsigned int level)
 {
@@ -59,10 +66,19 @@
 	unsigned int argc;
 	const char *mopts = "";
-	int rc;
+	int rc, c, opt_ind;
 
 	argc = cli_count_args(argv);
 
+	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
+		c = getopt_long(argc, argv, "h", long_options, &opt_ind);
+		switch (c) {
+		case 'h':
+			help_cmd_mount(HELP_LONG);
+			return CMD_SUCCESS;
+		}
+	}
+
 	if ((argc < 4) || (argc > 5)) {
-		printf("%s: invalid number of arguments.\n",
+		printf("%s: invalid number of arguments. Try `mount --help'\n",
 		    cmdname);
 		return CMD_FAILURE;
Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ uspace/lib/c/generic/loader.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -160,4 +160,5 @@
 	int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
 	if (rc != EOK) {
+		free(pa);
 		async_wait_for(req, NULL);
 		return rc;
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -69,4 +69,5 @@
 	char *ncwd_path;
 	char *ncwd_path_nc;
+	size_t total_size; 
 
 	fibril_mutex_lock(&cwd_mutex);
@@ -77,14 +78,16 @@
 			return NULL;
 		}
-		ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
+		total_size = cwd_size + 1 + size + 1;
+		ncwd_path_nc = malloc(total_size);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
 			return NULL;
 		}
-		str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
+		str_cpy(ncwd_path_nc, total_size, cwd_path);
 		ncwd_path_nc[cwd_size] = '/';
 		ncwd_path_nc[cwd_size + 1] = '\0';
 	} else {
-		ncwd_path_nc = malloc(size + 1);
+		total_size = size + 1;
+		ncwd_path_nc = malloc(total_size);
 		if (!ncwd_path_nc) {
 			fibril_mutex_unlock(&cwd_mutex);
@@ -93,5 +96,5 @@
 		ncwd_path_nc[0] = '\0';
 	}
-	str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
+	str_append(ncwd_path_nc, total_size, path);
 	ncwd_path = canonify(ncwd_path_nc, retlen);
 	if (!ncwd_path) {
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ uspace/srv/devmap/devmap.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -123,4 +123,10 @@
 static devmap_handle_t last_handle = 0;
 static devmap_device_t *null_devices[NULL_DEVICES];
+
+/*
+ * Dummy list for null devices. This is necessary so that null devices can
+ * be used just as any other devices, e.g. in devmap_device_unregister_core().
+ */
+static LIST_INITIALIZE(dummy_null_driver_devices);
 
 static devmap_handle_t devmap_create_handle(void)
@@ -953,7 +959,11 @@
 	device->name = dev_name;
 	
-	/* Insert device into list of all devices
-	   and into null devices array */
+	/*
+	 * Insert device into list of all devices and into null devices array.
+	 * Insert device into a dummy list of null driver's devices so that it
+	 * can be safely removed later.
+	 */
 	list_append(&device->devices, &devices_list);
+	list_append(&device->driver_devices, &dummy_null_driver_devices);
 	null_devices[i] = device;
 	
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 4c7c25135dc43993f0c90327f035578a98ef0c2f)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 37b1651de7d2b2fb0e5e2ee69dd1cfbdc338bfe1)
@@ -325,4 +325,5 @@
 		    uint16_t_le2host(d->firstc));
 		if (rc != EOK) {
+			(void) block_put(b);
 			(void) fat_node_put(FS_NODE(nodep));
 			return rc;
@@ -811,4 +812,5 @@
 	fibril_mutex_unlock(&childp->idx->lock);
 	childp->lnkcnt = 0;
+	childp->refcnt++;	/* keep the node in memory until destroyed */
 	childp->dirty = true;
 	fibril_mutex_unlock(&childp->lock);
@@ -1488,4 +1490,5 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	fs_node_t *fn;
+	fat_node_t *nodep;
 	int rc;
 
@@ -1499,4 +1502,11 @@
 		return;
 	}
+
+	nodep = FAT_NODE(fn);
+	/*
+	 * We should have exactly two references. One for the above
+	 * call to fat_node_get() and one from fat_unlink().
+	 */
+	assert(nodep->refcnt == 2);
 
 	rc = fat_destroy_node(fn);
