Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ boot/Makefile.common	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -60,4 +60,5 @@
 	$(USPACEDIR)/app/getterm/getterm \
 	$(USPACEDIR)/app/klog/klog \
+	$(USPACEDIR)/app/mkfat/mkfat \
 	$(USPACEDIR)/app/redir/redir \
 	$(USPACEDIR)/app/tester/tester \
Index: kernel/Makefile.build
===================================================================
--- kernel/Makefile.build	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/Makefile.build	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -186,4 +186,5 @@
 	generic/src/ddi/device.c \
 	generic/src/debug/symtab.c \
+	generic/src/debug/stacktrace.c \
 	generic/src/interrupt/interrupt.c \
 	generic/src/main/main.c \
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -38,5 +38,5 @@
 
 FPU_NO_CFLAGS = -mno-sse -mno-sse2
-CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables
+CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
 GCC_CFLAGS += $(CMN1)
 ICC_CFLAGS += $(CMN1)
@@ -60,4 +60,6 @@
 	arch/$(KARCH)/src/boot/boot.S \
 	arch/$(KARCH)/src/boot/memmap.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/pm.c \
 	arch/$(KARCH)/src/context.S \
Index: kernel/arch/amd64/_link.ld.in
===================================================================
--- kernel/arch/amd64/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -44,4 +44,5 @@
 		*(COMMON);		/* global variables */
 
+		. = ALIGN(8);
 		symbol_table = .;
 		*(symtab.*);            /* Symbol table, must be LAST symbol!*/
Index: kernel/arch/amd64/include/context.h
===================================================================
--- kernel/arch/amd64/include/context.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/include/context.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -46,4 +46,11 @@
 #define SP_DELTA     16
 
+#define context_set(c, _pc, stack, size) \
+	do { \
+		(c)->pc = (uintptr_t) (_pc); \
+		(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
+		(c)->rbp = 0; \
+	} while (0)
+
 #endif /* KERNEL */
 
Index: kernel/arch/amd64/include/interrupt.h
===================================================================
--- kernel/arch/amd64/include/interrupt.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/include/interrupt.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -70,5 +70,5 @@
 
 /** This is passed to interrupt handlers */
-typedef struct {
+typedef struct istate {
 	uint64_t rax;
 	uint64_t rcx;
@@ -80,4 +80,5 @@
 	uint64_t r10;
 	uint64_t r11;
+	uint64_t rbp;
 	uint64_t error_word;
 	uint64_t rip;
@@ -101,4 +102,8 @@
 	return istate->rip;
 }
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return istate->rbp;
+}
 
 extern void (* disable_irqs_function)(uint16_t irqmask);
Index: kernel/arch/amd64/src/asm_utils.S
===================================================================
--- kernel/arch/amd64/src/asm_utils.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/src/asm_utils.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -27,5 +27,5 @@
 #
 
-#define IREGISTER_SPACE	72 
+#define IREGISTER_SPACE	80
 
 #define IOFFSET_RAX	0x0
@@ -38,4 +38,5 @@
 #define IOFFSET_R10	0x38
 #define IOFFSET_R11	0x40
+#define IOFFSET_RBP	0x48
 
 #  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
@@ -179,4 +180,5 @@
 	movq %r10, IOFFSET_R10(%rsp)
 	movq %r11, IOFFSET_R11(%rsp)
+	movq %rbp, IOFFSET_RBP(%rsp)
 .endm
 
@@ -191,4 +193,5 @@
 	movq IOFFSET_R10(%rsp), %r10
 	movq IOFFSET_R11(%rsp), %r11
+	movq IOFFSET_RBP(%rsp), %rbp
 .endm
 
@@ -235,4 +238,7 @@
 	cld
 
+	# Stop stack traces here
+	xorq %rbp, %rbp
+
 	movq $(\i), %rdi   	# %rdi - first parameter
 	movq %rsp, %rsi   	# %rsi - pointer to istate
Index: kernel/arch/amd64/src/boot/boot.S
===================================================================
--- kernel/arch/amd64/src/boot/boot.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/src/boot/boot.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -174,4 +174,8 @@
 	call arch_pre_main
 	
+	# create the first stack frame
+	pushq $0
+	movq %rsp, %rbp
+
 	call main_bsp
 	
@@ -329,11 +333,11 @@
 
 extended_cpuid_msg:
-	.asciz "Extended CPUID not supported. System halted."
+	.asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
 long_mode_msg:
-	.asciz "64 bit long mode not supported. System halted."
+	.asciz "Error: 64-bit long mode not supported. System halted."
 noexecute_msg:
-	.asciz "No-execute pages not supported. System halted."
+	.asciz "Error: No-execute pages not supported. System halted."
 fx_msg:
-	.asciz "FXSAVE/FXRESTORE instructions not supported. System halted."
+	.asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
 sse2_msg:
-	.asciz "SSE2 instructions not supported. System halted."
+	.asciz "Error: SSE2 instructions not supported. System halted."
Index: kernel/arch/amd64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/amd64/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/amd64/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup amd64
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+#define FRAME_OFFSET_FP_PREV	0
+#define FRAME_OFFSET_RA		1
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return fp != 0;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	uint64_t *stack = (void *) fp;
+	*prev = stack[FRAME_OFFSET_FP_PREV];
+	return true;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	uint64_t *stack = (void *) fp;
+	*ra = stack[FRAME_OFFSET_RA];
+	return true;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return fp != 0;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return !copy_from_uspace((void *) prev,
+	    (uint64_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return !copy_from_uspace((void *) ra, (uint64_t *) fp + FRAME_OFFSET_RA,
+	    sizeof(*ra));
+}
+
+/** @}
+ */
Index: kernel/arch/amd64/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/amd64/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/amd64/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	movq %rbp, %rax
+	ret
+
+program_counter_get:
+	movq (%rsp), %rax
+	ret
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/src/interrupt.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -53,4 +53,5 @@
 #include <ddi/irq.h>
 #include <symtab.h>
+#include <stacktrace.h>
 
 /*
@@ -80,4 +81,6 @@
 	    istate->r10, istate->r11);
 	printf("%%rsp=%#llx\n", &istate->stack[0]);
+	
+	stack_trace_istate(istate);
 }
 
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/src/mm/page.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -203,5 +203,6 @@
 {
 	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%d bytes).", physaddr, size)
+		panic("Unable to map physical memory %p (%d bytes).", physaddr,
+		    size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
Index: kernel/arch/amd64/src/smp/ap.S
===================================================================
--- kernel/arch/amd64/src/smp/ap.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/amd64/src/smp/ap.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -99,4 +99,6 @@
 start64:
 	movq (ctx), %rsp
+	pushq $0
+	movq %rsp, %rbp
 	call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET   # never returns
 
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/arm32/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -57,4 +57,6 @@
 	arch/$(KARCH)/src/exception.c \
 	arch/$(KARCH)/src/userspace.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/mm/as.c \
 	arch/$(KARCH)/src/mm/frame.c \
Index: kernel/arch/arm32/_link.ld.in
===================================================================
--- kernel/arch/arm32/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/arm32/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -34,4 +34,5 @@
 		*(.sdata);
 		*(.reginfo);
+		. = ALIGN(8);
 		symbol_table = .;
 		*(symtab.*);
Index: kernel/arch/arm32/include/exception.h
===================================================================
--- kernel/arch/arm32/include/exception.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/arm32/include/exception.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -86,5 +86,5 @@
 
 /** Struct representing CPU state saved when an exception occurs. */
-typedef struct {
+typedef struct istate {
 	uint32_t spsr;
 	uint32_t sp;
@@ -133,4 +133,9 @@
 }
 
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return istate->r11;
+}
+
 
 extern void install_exception_handlers(void);
Index: kernel/arch/arm32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/arm32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/arm32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup arm32
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/arm32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/arm32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	mov pc, lr
+
+program_counter_get:
+	mov pc, lr
Index: kernel/arch/arm32/src/mm/page.c
===================================================================
--- kernel/arch/arm32/src/mm/page.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/arm32/src/mm/page.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -88,5 +88,5 @@
 	    KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) {
 		panic("Unable to map physical memory %p (%d bytes).",
-		    physaddr, size)
+		    physaddr, size);
 	}
 	
Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -78,4 +78,6 @@
 	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/debug/panic.s \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/delay.s \
 	arch/$(KARCH)/src/asm.S \
Index: kernel/arch/ia32/_link.ld.in
===================================================================
--- kernel/arch/ia32/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -42,4 +42,5 @@
 		hardcoded_unmapped_kdata_size = .;
 		LONG(unmapped_kdata_end - unmapped_kdata_start);
+		. = ALIGN(8);
 		symbol_table = .;
 		*(symtab.*);            /* Symbol table, must be LAST symbol! */
Index: kernel/arch/ia32/include/context.h
===================================================================
--- kernel/arch/ia32/include/context.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/include/context.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -49,4 +49,11 @@
 #define SP_DELTA	(8 + STACK_ITEM_SIZE)
 
+#define context_set(c, _pc, stack, size) \
+	do { \
+		(c)->pc = (uintptr_t) (_pc); \
+		(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
+		(c)->ebp = 0; \
+	} while (0)
+
 #endif /* KERNEL */
 
Index: kernel/arch/ia32/include/interrupt.h
===================================================================
--- kernel/arch/ia32/include/interrupt.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/include/interrupt.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -69,8 +69,9 @@
 #define VECTOR_DEBUG_IPI		(IVT_FREEBASE + 2)
 
-typedef struct {
+typedef struct istate {
 	uint32_t eax;
 	uint32_t ecx;
 	uint32_t edx;
+	uint32_t ebp;
 
 	uint32_t gs;
@@ -102,4 +103,9 @@
 }
 
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return istate->ebp;
+}
+
 extern void (* disable_irqs_function)(uint16_t irqmask);
 extern void (* enable_irqs_function)(uint16_t irqmask);
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/src/asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -269,4 +269,5 @@
 	pushl %gs
 
+	pushl %ebp
 	pushl %edx
 	pushl %ecx
@@ -278,5 +279,6 @@
 	movw %ax, %es
 
-	cld
+	# stop stack traces here
+	xorl %ebp, %ebp
 
 	pushl %esp          # *istate
@@ -290,4 +292,5 @@
 	popl %ecx
 	popl %edx
+	popl %ebp
 	
 	popl %gs
Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/src/boot/boot.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -94,4 +94,8 @@
 	pushl grub_eax
 	call arch_pre_main
+
+	# Create the first stack frame
+	pushl $0
+	movl %esp, %ebp
 	
 	call main_bsp
Index: kernel/arch/ia32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/ia32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup ia32
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+#define FRAME_OFFSET_FP_PREV	0
+#define FRAME_OFFSET_RA		1
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return fp != 0;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	uint32_t *stack = (void *) fp;
+	*prev = stack[FRAME_OFFSET_FP_PREV];
+	return true;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	uint32_t *stack = (void *) fp;
+	*ra = stack[FRAME_OFFSET_RA];
+	return true;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return fp != 0;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return !copy_from_uspace((void *) prev,
+	    (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA,
+	    sizeof(*ra));
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/ia32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	movl %ebp, %eax
+	ret
+
+program_counter_get:
+	movl (%esp), %eax
+	ret
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/src/interrupt.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -53,4 +53,5 @@
 #include <ddi/irq.h>
 #include <symtab.h>
+#include <stacktrace.h>
 
 /*
@@ -79,4 +80,6 @@
 	printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
 	printf("       %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
+
+	stack_trace_istate(istate);
 }
 
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/src/mm/page.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -80,5 +80,5 @@
 {
 	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%d bytes).", physaddr, size)
+		panic("Unable to map physical memory %p (%d bytes).", physaddr, size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
Index: kernel/arch/ia32/src/smp/ap.S
===================================================================
--- kernel/arch/ia32/src/smp/ap.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia32/src/smp/ap.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -78,4 +78,7 @@
 	addl $0x80000000, %esp			# PA2KA(ctx.sp)
 	
+	pushl $0				# create the first stack frame
+	movl %esp, %ebp
+
 	jmpl $KTEXT, $main_ap
 
Index: kernel/arch/ia64/Makefile.inc
===================================================================
--- kernel/arch/ia64/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia64/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -53,4 +53,6 @@
 	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/ivt.S \
 	arch/$(KARCH)/src/interrupt.c \
Index: kernel/arch/ia64/_link.ld.in
===================================================================
--- kernel/arch/ia64/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia64/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -37,4 +37,5 @@
 		*(COMMON);
 
+		. = ALIGN(8);
                 symbol_table = .;
                 *(symtab.*);            /* Symbol table, must be LAST symbol!*/
Index: kernel/arch/ia64/include/interrupt.h
===================================================================
--- kernel/arch/ia64/include/interrupt.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia64/include/interrupt.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -72,5 +72,5 @@
 #define EOI  0  /**< The actual value doesn't matter. */
 
-typedef struct {
+typedef struct istate {
 	uint128_t f2;
 	uint128_t f3;
@@ -143,4 +143,9 @@
 }
 
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return 0;	/* FIXME */
+}
+
 static inline int istate_from_uspace(istate_t *istate)
 {
Index: kernel/arch/ia64/include/mm/asid.h
===================================================================
--- kernel/arch/ia64/include/mm/asid.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia64/include/mm/asid.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -50,14 +50,16 @@
  * but those extra bits are not used by the kernel. 
  */
-#define RIDS_PER_ASID		7
+#define RIDS_PER_ASID		8
 
 #define RID_MAX			262143		/* 2^18 - 1 */
-#define RID_KERNEL		0
-#define RID_INVALID		1
+#define RID_KERNEL7		7
 
-#define ASID2RID(asid, vrn)	(((asid)>RIDS_PER_ASID)?(((asid)*RIDS_PER_ASID)+(vrn)):(asid))
-#define RID2ASID(rid)		((rid)/RIDS_PER_ASID)
+#define ASID2RID(asid, vrn) \
+	((asid) * RIDS_PER_ASID + (vrn))
 
-#define ASID_MAX_ARCH		(RID_MAX/RIDS_PER_ASID)
+#define RID2ASID(rid) \
+	((rid) / RIDS_PER_ASID)
+
+#define ASID_MAX_ARCH		(RID_MAX / RIDS_PER_ASID)
 
 #endif
Index: kernel/arch/ia64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia64/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/ia64/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup ia64
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+/** @}
+ */
Index: kernel/arch/ia64/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/ia64/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/ia64/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	mov r8 = r0
+	br.ret.sptk.many b0
+
+program_counter_get:
+	mov r8 = r0
+	br.ret.sptk.many b0
Index: kernel/arch/ia64/src/mm/page.c
===================================================================
--- kernel/arch/ia64/src/mm/page.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia64/src/mm/page.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -71,26 +71,12 @@
 
 	/*
-	 * First set up kernel region register.
-	 * This is redundant (see start.S) but we keep it here just for sure.
-	 */
-	rr.word = rr_read(VRN_KERNEL);
-	rr.map.ve = 0;                  /* disable VHPT walker */
-	rr.map.ps = PAGE_WIDTH;
-	rr.map.rid = ASID2RID(ASID_KERNEL, VRN_KERNEL);
-	rr_write(VRN_KERNEL, rr.word);
-	srlz_i();
-	srlz_d();
-
-	/*
-	 * And setup the rest of region register.
+	 * Set up kernel region registers.
+	 * VRN_KERNEL has already been set in start.S.
+	 * For paranoia reasons, we set it again.
 	 */
 	for(i = 0; i < REGION_REGISTERS; i++) {
-		/* skip kernel rr */
-		if (i == VRN_KERNEL)
-			continue;
-	
 		rr.word = rr_read(i);
 		rr.map.ve = 0;		/* disable VHPT walker */
-		rr.map.rid = RID_KERNEL;
+		rr.map.rid = ASID2RID(ASID_KERNEL, i);
 		rr.map.ps = PAGE_WIDTH;
 		rr_write(i, rr.word);
Index: kernel/arch/ia64/src/start.S
===================================================================
--- kernel/arch/ia64/src/start.S	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ia64/src/start.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -74,5 +74,5 @@
 	movl r10 = (RR_MASK)
 	and r9 = r10, r9
-	movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
+	movl r10 = (((RID_KERNEL7) << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
 	or r9 = r10, r9
 	
Index: kernel/arch/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/mips32/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -70,4 +70,6 @@
 	arch/$(KARCH)/src/debugger.c \
 	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/mm/frame.c \
 	arch/$(KARCH)/src/mm/page.c \
Index: kernel/arch/mips32/_link.ld.in
===================================================================
--- kernel/arch/mips32/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/mips32/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -38,4 +38,5 @@
 		*(.bss);                        /* uninitialized static variables */
 		*(COMMON);                      /* global variables */
+		. = ALIGN(8);
 		symbol_table = .;
 		*(symtab.*);
Index: kernel/arch/mips32/include/exception.h
===================================================================
--- kernel/arch/mips32/include/exception.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/mips32/include/exception.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -58,5 +58,5 @@
 #define EXC_VCED	31
 
-typedef struct {
+typedef struct istate {
 	uint32_t at;
 	uint32_t v0;
@@ -102,4 +102,8 @@
 	return istate->epc;
 }
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return 0;	/* FIXME */
+}
 
 extern void exception(istate_t *istate);
Index: kernel/arch/mips32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/mips32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup mips32
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+/** @}
+ */
Index: kernel/arch/mips32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	j $ra
+	xor $v0, $v0
+
+program_counter_get:
+	j $ra
+	xor $v0, $v0
Index: kernel/arch/ppc32/Makefile.inc
===================================================================
--- kernel/arch/ppc32/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ppc32/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -46,4 +46,6 @@
 	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/debug/panic.s \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/fpu_context.S \
 	arch/$(KARCH)/src/boot/boot.S \
Index: kernel/arch/ppc32/_link.ld.in
===================================================================
--- kernel/arch/ppc32/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ppc32/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -51,4 +51,5 @@
 		*(COMMON);      /* global variables */
 		
+		. = ALIGN(8);
 		symbol_table = .;
 		*(symtab.*);    /* Symbol table, must be LAST symbol!*/
Index: kernel/arch/ppc32/include/exception.h
===================================================================
--- kernel/arch/ppc32/include/exception.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ppc32/include/exception.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -39,5 +39,5 @@
 #include <arch/regutils.h>
 
-typedef struct {
+typedef struct istate {
 	uint32_t r0;
 	uint32_t r2;
@@ -98,4 +98,9 @@
 }
 
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return istate->sp;
+}
+
 #endif
 
Index: kernel/arch/ppc32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ppc32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/ppc32/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup ppc32
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+/** @}
+ */
Index: kernel/arch/ppc32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/ppc32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/ppc32/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	blr
+
+program_counter_get:
+	blr
Index: kernel/arch/ppc32/src/mm/page.c
===================================================================
--- kernel/arch/ppc32/src/mm/page.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/ppc32/src/mm/page.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -51,5 +51,5 @@
 	    KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
 		panic("Unable to map physical memory %p (%" PRIs " bytes).",
-		    physaddr, size)
+		    physaddr, size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/sparc64/Makefile.inc	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -54,4 +54,6 @@
 ARCH_SOURCES = \
 	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/asm.S \
 	arch/$(KARCH)/src/panic.S \
Index: kernel/arch/sparc64/_link.ld.in
===================================================================
--- kernel/arch/sparc64/_link.ld.in	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/sparc64/_link.ld.in	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -36,4 +36,5 @@
 		*(COMMON);                  /* global variables */
 		
+		. = ALIGN(8);
 		symbol_table = .;
 		*(symtab.*);                /* Symbol table, must be LAST symbol!*/
Index: kernel/arch/sparc64/include/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/interrupt.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/arch/sparc64/include/interrupt.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -50,5 +50,5 @@
 };		
 
-typedef struct {
+typedef struct istate {
 	uint64_t	tnpc;
 	uint64_t	tpc;
@@ -71,4 +71,9 @@
 }
 
+static inline unative_t istate_get_fp(istate_t *istate)
+{
+	return 0;	/* TODO */
+}
+
 #endif
 
Index: kernel/arch/sparc64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup sparc64
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+bool kernel_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_validate(uintptr_t fp)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+{
+	return false;
+}
+
+bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+{
+	return false;
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/arch/sparc64/src/debug/stacktrace_asm.S	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2010 Jakub Jermar
+# 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.
+#
+
+.text
+
+.global frame_pointer_get
+.global program_counter_get
+
+frame_pointer_get:
+	retl
+	nop
+
+program_counter_get:
+	retl
+	nop
+
Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/generic/include/debug.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -75,5 +75,5 @@
 #	define LOG(format, ...) \
 		printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \
-			__LINE__, ##__VA_ARGS__);
+		    __LINE__, ##__VA_ARGS__);
 #else
 #	define LOG(format, ...)
@@ -92,5 +92,5 @@
 		{ \
 			printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \
-			__LINE__); \
+			    __LINE__); \
 			fnc; \
 		}
Index: kernel/generic/include/interrupt.h
===================================================================
--- kernel/generic/include/interrupt.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/generic/include/interrupt.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -42,4 +42,5 @@
 #include <arch.h>
 #include <ddi/irq.h>
+#include <stacktrace.h>
 
 typedef void (* iroutine)(int n, istate_t *istate);
@@ -49,6 +50,8 @@
 	if (istate_from_uspace(istate)) { \
 		task_t *task = TASK; \
-		printf("Task %s (%" PRIu64 ") killed due to an exception at %p: ", task->name, task->taskid, istate_get_pc(istate)); \
-		printf(fmt "\n", ##__VA_ARGS__); \
+		printf("Task %s (%" PRIu64 ") killed due to an exception at " \
+		    "program counter %p.\n", task->name, task->taskid, istate_get_pc(istate)); \
+		stack_trace_istate(istate); \
+		printf("Kill message: " fmt "\n", ##__VA_ARGS__); \
 		task_kill(task->taskid); \
 		thread_exit(); \
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/generic/include/panic.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -36,8 +36,16 @@
 #define KERN_PANIC_H_
 
+#include <stacktrace.h>
+#include <print.h>
+
 #ifdef CONFIG_DEBUG
 #	define panic(format, ...) \
-		panic_printf("Kernel panic in %s() at %s:%u: " format "\n", \
-		__func__, __FILE__, __LINE__, ##__VA_ARGS__);
+		do { \
+			printf("Kernel panic in %s() at %s:%u.\n", \
+			    __func__, __FILE__, __LINE__); \
+			stack_trace(); \
+			panic_printf("Panic message: " format "\n", \
+			    ##__VA_ARGS__);\
+		} while (0)
 #else
 #	define panic(format, ...) \
Index: kernel/generic/include/stacktrace.h
===================================================================
--- kernel/generic/include/stacktrace.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/generic/include/stacktrace.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup genericdebug 
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_STACKTRACE_H_
+#define KERN_STACKTRACE_H_
+
+#include <arch/types.h>
+#include <typedefs.h>
+
+/* Forward declarations. */
+struct istate;
+
+typedef struct {
+	bool (* frame_pointer_validate)(uintptr_t);
+	bool (* frame_pointer_prev)(uintptr_t, uintptr_t *);
+	bool (* return_address_get)(uintptr_t, uintptr_t *);
+	bool (* symbol_resolve)(uintptr_t, char **, uintptr_t *);
+} stack_trace_ops_t;
+
+extern stack_trace_ops_t kst_ops;
+extern stack_trace_ops_t ust_ops;
+
+extern void stack_trace(void);
+extern void stack_trace_istate(struct istate *);
+extern void stack_trace_fp_pc(stack_trace_ops_t *, uintptr_t, uintptr_t);
+
+/*
+ * The following interface is to be implemented by each architecture.
+ */
+extern uintptr_t frame_pointer_get(void);
+extern uintptr_t program_counter_get();
+
+extern bool kernel_frame_pointer_validate(uintptr_t);
+extern bool kernel_frame_pointer_prev(uintptr_t, uintptr_t *);
+extern bool kernel_return_address_get(uintptr_t, uintptr_t *);
+
+extern bool uspace_frame_pointer_validate(uintptr_t);
+extern bool uspace_frame_pointer_prev(uintptr_t, uintptr_t *);
+extern bool uspace_return_address_get(uintptr_t, uintptr_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/symtab.h
===================================================================
--- kernel/generic/include/symtab.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/generic/include/symtab.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -45,9 +45,9 @@
 };
 
-extern int symtab_name_lookup(unative_t addr, char **name);
-extern char *symtab_fmt_name_lookup(unative_t addr);
-extern int symtab_addr_lookup(const char *name, uintptr_t *addr);
-extern void symtab_print_search(const char *name);
-extern int symtab_compl(char *input, size_t size);
+extern int symtab_name_lookup(uintptr_t, char **, uintptr_t *);
+extern char *symtab_fmt_name_lookup(uintptr_t);
+extern int symtab_addr_lookup(const char *, uintptr_t *);
+extern void symtab_print_search(const char *);
+extern int symtab_compl(char *, size_t);
 
 #ifdef CONFIG_SYMTAB
Index: kernel/generic/src/debug/stacktrace.c
===================================================================
--- kernel/generic/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ kernel/generic/src/debug/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup genericdebug 
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <interrupt.h>
+#include <arch/types.h>
+#include <symtab.h>
+
+#define STACK_FRAMES_MAX	20
+
+void
+stack_trace_fp_pc(stack_trace_ops_t *ops, uintptr_t fp, uintptr_t pc)
+{
+	int cnt = 0;
+	char *symbol;
+	uintptr_t offset;
+
+	while (cnt++ < STACK_FRAMES_MAX && ops->frame_pointer_validate(fp)) {
+		if (ops->symbol_resolve &&
+		    ops->symbol_resolve(pc, &symbol, &offset)) {
+		    	if (offset)
+				printf("%p: %s+%p()\n", fp, symbol, offset);
+			else
+				printf("%p: %s()\n", fp, symbol);
+		} else {
+			printf("%p: %p()\n", fp, pc);
+		}
+		if (!ops->return_address_get(fp, &pc))
+			break;
+		if (!ops->frame_pointer_prev(fp, &fp))
+			break;
+	}
+}
+
+void stack_trace(void)
+{
+	stack_trace_fp_pc(&kst_ops, frame_pointer_get(), program_counter_get());
+
+	/*
+	 * Prevent the tail call optimization of the previous call by
+	 * making it a non-tail call.
+	 */
+	(void) frame_pointer_get();
+}
+
+void stack_trace_istate(istate_t *istate)
+{
+	if (istate_from_uspace(istate))
+		stack_trace_fp_pc(&ust_ops, istate_get_fp(istate),
+		    istate_get_pc(istate));
+	else
+		stack_trace_fp_pc(&kst_ops, istate_get_fp(istate),
+		    istate_get_pc(istate));
+}
+
+static bool kernel_symbol_resolve(uintptr_t addr, char **sp, uintptr_t *op)
+{
+	return (symtab_name_lookup(addr, sp, op) == 0);
+}
+
+stack_trace_ops_t kst_ops = {
+	.frame_pointer_validate = kernel_frame_pointer_validate,
+	.frame_pointer_prev = kernel_frame_pointer_prev,
+	.return_address_get = kernel_return_address_get,
+	.symbol_resolve = kernel_symbol_resolve
+};
+
+stack_trace_ops_t ust_ops = {
+	.frame_pointer_validate = uspace_frame_pointer_validate,
+	.frame_pointer_prev = uspace_frame_pointer_prev,
+	.return_address_get = uspace_return_address_get,
+	.symbol_resolve = NULL
+};
+
+/** @}
+ */
Index: kernel/generic/src/debug/symtab.c
===================================================================
--- kernel/generic/src/debug/symtab.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ kernel/generic/src/debug/symtab.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -46,6 +46,7 @@
 /** Get name of a symbol that seems most likely to correspond to address.
  *
- * @param addr Address.
- * @param name Place to store pointer to the symbol name.
+ * @param addr		Address.
+ * @param name		Place to store pointer to the symbol name.
+ * @param offset	Place to store offset from the symbol address.
  *
  * @return Zero on success or negative error code, ENOENT if not found,
@@ -53,5 +54,5 @@
  *
  */
-int symtab_name_lookup(unative_t addr, char **name)
+int symtab_name_lookup(uintptr_t addr, char **name, uintptr_t *offset)
 {
 #ifdef CONFIG_SYMTAB
@@ -65,4 +66,7 @@
 	if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) {
 		*name = symbol_table[i - 1].symbol_name;
+		if (offset)
+			*offset = addr -
+			    uint64_t_le2host(symbol_table[i - 1].address_le);
 		return EOK;
 	}
@@ -88,8 +92,8 @@
  *
  */
-char *symtab_fmt_name_lookup(unative_t addr)
+char *symtab_fmt_name_lookup(uintptr_t addr)
 {
 	char *name;
-	int rc = symtab_name_lookup(addr, &name);
+	int rc = symtab_name_lookup(addr, &name, NULL);
 	
 	switch (rc) {
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/Makefile	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -38,4 +38,5 @@
 	app/init \
 	app/klog \
+	app/mkfat \
 	app/redir \
 	app/tester \
Index: uspace/app/bdsh/Makefile.build
===================================================================
--- uspace/app/bdsh/Makefile.build	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/app/bdsh/Makefile.build	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -42,4 +42,5 @@
 	cmds/modules/help/help.c \
 	cmds/modules/mkdir/mkdir.c \
+	cmds/modules/mkfile/mkfile.c \
 	cmds/modules/rm/rm.c \
 	cmds/modules/bdd/bdd.c \
Index: uspace/app/bdsh/cmds/modules/mkfile/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mkfile/entry.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/bdsh/cmds/modules/mkfile/entry.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,9 @@
+#ifndef MKFILE_ENTRY_H
+#define MKFILE_ENTRY_H
+
+/* Entry points for the mkfile command */
+extern int cmd_mkfile(char **);
+extern void help_cmd_mkfile(unsigned int);
+
+#endif /* MKFILE_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/mkfile/mkfile.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mkfile/mkfile.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/bdsh/cmds/modules/mkfile/mkfile.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2009 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 <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <macros.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "config.h"
+#include "errors.h"
+#include "util.h"
+#include "entry.h"
+#include "mkfile.h"
+#include "cmds.h"
+
+/** Number of bytes to write at a time */
+#define BUFFER_SIZE 16384
+
+static char *cmdname = "mkfile";
+
+static struct option const long_options[] = {
+	{"size", required_argument, 0, 's'},
+	{"help", no_argument, 0, 'h'},
+	{0, 0, 0, 0}
+};
+
+void help_cmd_mkfile(unsigned int level)
+{
+	if (level == HELP_SHORT) {
+		printf("`%s' creates a new zero-filled file\n", cmdname);
+	} else {
+		help_cmd_mkfile(HELP_SHORT);
+		printf(
+		"Usage:  %s [options] <path>\n"
+		"Options:\n"
+		"  -h, --help       A short option summary\n"
+		"  -s, --size sz    Size of the file\n"
+		"\n"
+		"Size is a number followed by 'k', 'm' or 'g' for kB, MB, GB.\n"
+		"E.g. 100k, 2m, 1g.\n",
+		cmdname);
+	}
+
+	return;
+}
+
+/** Parse size specification.
+ *
+ * Size specification is in the form <decimal_number><unit> where
+ * <unit> is 'k', 'm' or 'g' for kB, MB, GB.
+ *
+ * @param str	String containing the size specification.
+ * @return	Non-negative size in bytes on success, -1 on failure.
+ */
+static ssize_t read_size(const char *str)
+{
+	ssize_t number, unit;
+	char *ep;
+
+	number = strtol(str, &ep, 10);
+	if (ep[0] == '\0')
+		return number;
+
+	if (ep[1] != '\0')
+		    return -1;
+
+	switch (tolower(ep[0])) {
+	case 'k': unit = 1024; break;
+	case 'm': unit = 1024*1024; break;
+	case 'g': unit = 1024*1024*1024; break;
+	default: return -1;
+	}
+
+	return number * unit;
+}
+
+int cmd_mkfile(char **argv)
+{
+	unsigned int argc;
+	int c, opt_ind;
+	int fd;
+	ssize_t file_size;
+	ssize_t total_written;
+	ssize_t to_write, rc;
+	char *file_name;
+	void *buffer;
+
+	file_size = 0;
+
+	argc = cli_count_args(argv);
+
+	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
+		c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind);
+		switch (c) {
+		case 'h':
+			help_cmd_mkfile(HELP_LONG);
+			return CMD_SUCCESS;
+		case 's':
+			file_size = read_size(optarg);
+			if (file_size < 0) {
+				printf("%s: Invalid file size specification.\n",
+				    cmdname);
+				return CMD_FAILURE;
+			}
+			break;
+		}
+	}
+
+	argc -= optind;
+
+	if (argc != 1) {
+		printf("%s: incorrect number of arguments. Try `%s --help'\n",
+			cmdname, cmdname);
+		return CMD_FAILURE;
+	}
+
+	file_name = argv[optind];
+
+	fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
+	if (fd < 0) {
+		printf("%s: failed to create file %s.\n", cmdname, file_name);
+		return CMD_FAILURE;
+	}
+
+	buffer = calloc(BUFFER_SIZE, 1);
+	if (buffer == NULL) {
+		printf("%s: Error, out of memory.\n", cmdname);
+		return CMD_FAILURE;
+	}
+
+	total_written = 0;
+	while (total_written < file_size) {
+		to_write = min(file_size - total_written, BUFFER_SIZE);
+		rc = write(fd, buffer, to_write);
+		if (rc <= 0) {
+			printf("%s: Error writing file (%d).\n", cmdname, rc);
+			close(fd);
+			return CMD_FAILURE;
+		}
+		total_written += rc;
+	}
+
+	rc = close(fd);
+	if (rc != 0) {
+		printf("%s: Error writing file (%d).\n", cmdname, rc);
+		return CMD_FAILURE;
+	}
+
+	free(buffer);
+
+	return CMD_SUCCESS;
+}
Index: uspace/app/bdsh/cmds/modules/mkfile/mkfile.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mkfile/mkfile.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/bdsh/cmds/modules/mkfile/mkfile.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,8 @@
+#ifndef MKFILE_H
+#define MKFILE_H
+
+/* Prototypes for the mkfile command, excluding entry points */
+
+
+#endif /* MKFILE_H */
+
Index: uspace/app/bdsh/cmds/modules/mkfile/mkfile_def.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mkfile/mkfile_def.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/bdsh/cmds/modules/mkfile/mkfile_def.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,8 @@
+{
+	"mkfile",
+	"Create new file",
+	&cmd_mkfile,
+	&help_cmd_mkfile,
+},
+
+
Index: uspace/app/bdsh/cmds/modules/modules.h
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/app/bdsh/cmds/modules/modules.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -20,4 +20,5 @@
 #include "help/entry.h"
 #include "mkdir/entry.h"
+#include "mkfile/entry.h"
 #include "rm/entry.h"
 #include "bdd/entry.h"
@@ -39,4 +40,5 @@
 #include "help/help_def.h"
 #include "mkdir/mkdir_def.h"
+#include "mkfile/mkfile_def.h"
 #include "rm/rm_def.h"
 #include "bdd/bdd_def.h"
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/app/edit/edit.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -98,4 +98,5 @@
 static bool done;
 static pane_t pane;
+static bool cursor_visible;
 
 static int scr_rows, scr_columns;
@@ -108,4 +109,8 @@
 /** Maximum filename length that can be entered. */
 #define INFNAME_MAX_LEN 128
+
+static void cursor_show(void);
+static void cursor_hide(void);
+static void cursor_setvis(bool visible);
 
 static void key_handle_unmod(console_event_t const *ev);
@@ -199,4 +204,7 @@
 
 	/* Initial display */
+	cursor_visible = true;
+
+	cursor_hide();
 	console_clear(con);
 	pane_text_display();
@@ -205,5 +213,5 @@
 		status_display("File not found. Starting empty file.");
 	pane_caret_display();
-
+	cursor_show();
 
 	done = false;
@@ -230,4 +238,6 @@
 		/* Redraw as necessary. */
 
+		cursor_hide();
+
 		if (pane.rflags & REDRAW_TEXT)
 			pane_text_display();
@@ -238,4 +248,6 @@
 		if (pane.rflags & REDRAW_CARET)
 			pane_caret_display();
+
+		cursor_show();
 	}
 
@@ -243,4 +255,22 @@
 
 	return 0;
+}
+
+static void cursor_show(void)
+{
+	cursor_setvis(true);
+}
+
+static void cursor_hide(void)
+{
+	cursor_setvis(false);
+}
+
+static void cursor_setvis(bool visible)
+{
+	if (cursor_visible != visible) {
+		console_cursor_visibility(con, visible);
+		cursor_visible = visible;
+	}
 }
 
Index: uspace/app/mkfat/Makefile
===================================================================
--- uspace/app/mkfat/Makefile	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/mkfat/Makefile	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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 Makefile.common
+
+.PHONY: all clean
+
+all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS)
+	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
+	$(MAKE) -f Makefile.build PRECHECK=$(PRECHECK)
+
+clean:
+	rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm
+	find . -name '*.o' -follow -exec rm \{\} \;
Index: uspace/app/mkfat/Makefile.build
===================================================================
--- uspace/app/mkfat/Makefile.build	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/mkfat/Makefile.build	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# 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.
+#
+
+## Setup toolchain
+#
+
+include Makefile.common
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I$(LIBBLOCK_PREFIX)
+
+## Sources
+#
+
+SOURCES = \
+	mkfat.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all
+
+all: $(OUTPUT) $(OUTPUT).disasm
+
+-include $(DEPEND)
+
+$(OUTPUT).disasm: $(OUTPUT)
+	$(OBJDUMP) -d $< > $@
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+%.o: %.c $(DEPEND)
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS)
+endif
+
+$(DEPEND):
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
+	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: uspace/app/mkfat/Makefile.common
===================================================================
--- uspace/app/mkfat/Makefile.common	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/mkfat/Makefile.common	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005 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.
+#
+
+
+## Common names
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+LIBBLOCK_PREFIX = ../../lib/libblock
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
+
+DEPEND = Makefile.depend
+DEPEND_PREV = $(DEPEND).prev
+OUTPUT = mkfat
Index: uspace/app/mkfat/fat.h
===================================================================
--- uspace/app/mkfat/fat.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/mkfat/fat.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar
+ * 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.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+
+#ifndef FAT_FAT_H_
+#define FAT_FAT_H_
+
+#include <sys/types.h>
+
+#define BS_BLOCK		0
+#define BS_SIZE			512
+
+#define DIRENT_SIZE		32
+
+typedef struct fat_bs {
+	uint8_t		ji[3];		/**< Jump instruction. */
+	uint8_t		oem_name[8];
+	/* BIOS Parameter Block */
+	uint16_t	bps;		/**< Bytes per sector. */
+	uint8_t		spc;		/**< Sectors per cluster. */
+	uint16_t	rscnt;		/**< Reserved sector count. */
+	uint8_t		fatcnt;		/**< Number of FATs. */
+	uint16_t	root_ent_max;	/**< Maximum number of root directory
+					     entries. */
+	uint16_t	totsec16;	/**< Total sectors. 16-bit version. */
+	uint8_t		mdesc;		/**< Media descriptor. */
+	uint16_t	sec_per_fat;	/**< Sectors per FAT12/FAT16. */
+	uint16_t	sec_per_track;	/**< Sectors per track. */
+	uint16_t	headcnt;	/**< Number of heads. */
+	uint32_t	hidden_sec;	/**< Hidden sectors. */
+	uint32_t	totsec32;	/**< Total sectors. 32-bit version. */
+
+	union {
+		struct {
+			/* FAT12/FAT16 only: Extended BIOS Parameter Block */
+			/** Physical drive number. */
+			uint8_t		pdn;
+			uint8_t		reserved;
+			/** Extended boot signature. */
+			uint8_t		ebs;
+			/** Serial number. */
+			uint32_t	id;
+			/** Volume label. */
+			uint8_t		label[11];
+			/** FAT type. */
+			uint8_t		type[8];
+			/** Boot code. */
+			uint8_t		boot_code[448];
+			/** Boot sector signature. */
+			uint16_t	signature;
+		} __attribute__ ((packed));
+		struct fat32 {
+			/* FAT32 only */
+			/** Sectors per FAT. */
+			uint32_t	sectors_per_fat;
+			/** FAT flags. */
+			uint16_t	flags;
+			/** Version. */
+			uint16_t	version;
+			/** Cluster number of root directory. */
+			uint32_t	root_cluster;
+			/** Sector number of file system information sector. */
+			uint16_t	fsinfo_sec;
+			/** Sector number of boot sector copy. */
+			uint16_t	bscopy_sec;
+			uint8_t		reserved1[12];
+			/** Physical drive number. */
+			uint8_t		pdn;
+			uint8_t		reserved2;
+			/** Extended boot signature. */
+			uint8_t		ebs;
+			/** Serial number. */
+			uint32_t	id;
+			/** Volume label. */
+			uint8_t		label[11];
+			/** FAT type. */
+			uint8_t		type[8];
+			/** Boot code. */
+			uint8_t		boot_code[420];
+			/** Signature. */
+			uint16_t	signature;
+		} __attribute__ ((packed));
+	};
+} __attribute__ ((packed)) fat_bs_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/app/mkfat/mkfat.c
===================================================================
--- uspace/app/mkfat/mkfat.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
+++ uspace/app/mkfat/mkfat.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2010 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.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+
+/**
+ * @file	mkfat.c
+ * @brief	Tool for creating new FAT file systems.
+ *
+ * Currently we can only create 16-bit FAT.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libblock.h>
+#include <mem.h>
+#include <devmap.h>
+#include <byteorder.h>
+#include <errno.h>
+#include "fat.h"
+
+#define NAME	"mkfat"
+
+/** Divide and round up. */
+#define div_round_up(a, b) (((a) + (b) - 1) / (b))
+
+/** Predefined file-system parameters */
+enum {
+	sector_size		= 512,
+	sectors_per_cluster	= 8,
+	fat_count		= 2,
+	reserved_clusters	= 2,
+	media_descriptor	= 0xF8 /**< fixed disk */
+};
+
+/** Configurable file-system parameters */
+typedef struct fat_cfg {
+	uint32_t total_sectors;
+	uint16_t root_ent_max;
+	uint16_t addt_res_sectors;
+} fat_cfg_t;
+
+/** Derived file-system parameters */
+typedef struct fat_params {
+	struct fat_cfg cfg;
+	uint16_t reserved_sectors;
+	uint16_t rootdir_sectors;
+	uint32_t fat_sectors;
+	uint16_t total_clusters;
+} fat_params_t;
+
+static void syntax_print(void);
+
+static int fat_params_compute(struct fat_cfg const *cfg,
+    struct fat_params *par);
+static int fat_blocks_write(struct fat_params const *par,
+    dev_handle_t handle);
+static void fat_bootsec_create(struct fat_params const *par, struct fat_bs *bs);
+
+int main(int argc, char **argv)
+{
+	struct fat_params par;
+	struct fat_cfg cfg;
+
+	int rc;
+	char *dev_path;
+	dev_handle_t handle;
+	size_t block_size;
+	char *endptr;
+	bn_t dev_nblocks;
+
+	cfg.total_sectors = 0;
+	cfg.addt_res_sectors = 0;
+	cfg.root_ent_max = 128;
+
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+
+	--argc; ++argv;
+
+	if (str_cmp(*argv, "--size") == 0) {
+		--argc; ++argv;
+		if (*argv == NULL) {
+			printf(NAME ": Error, argument missing.\n");
+			syntax_print();
+			return 1;
+		}
+
+		cfg.total_sectors = strtol(*argv, &endptr, 10);
+		if (*endptr != '\0') {
+			printf(NAME ": Error, invalid argument.\n");
+			syntax_print();
+			return 1;
+		}
+
+		--argc; ++argv;
+	}
+
+	if (argc != 1) {
+		printf(NAME ": Error, unexpected argument.\n");
+		syntax_print();
+		return 1;
+	}
+
+	dev_path = *argv;
+
+	rc = devmap_device_get_handle(dev_path, &handle, 0);
+	if (rc != EOK) {
+		printf(NAME ": Error resolving device `%s'.\n", dev_path);
+		return 2;
+	}
+
+	rc = block_init(handle, 2048);
+	if (rc != EOK)  {
+		printf(NAME ": Error initializing libblock.\n");
+		return 2;
+	}
+
+	rc = block_get_bsize(handle, &block_size);
+	if (rc != EOK) {
+		printf(NAME ": Error determining device block size.\n");
+		return 2;
+	}
+
+	rc = block_get_nblocks(handle, &dev_nblocks);
+	if (rc != EOK) {
+		printf(NAME ": Warning, failed to obtain block device size.\n");
+	} else {
+		printf(NAME ": Block device has %llu blocks.\n", dev_nblocks);
+		cfg.total_sectors = dev_nblocks;
+	}
+
+	if (block_size != 512) {
+		printf(NAME ": Error. Device block size is not 512 bytes.\n");
+		return 2;
+	}
+
+	if (cfg.total_sectors == 0) {
+		printf(NAME ": Error. You must specify filesystem size.\n");
+		return 1;
+	}
+
+	printf(NAME ": Creating FAT filesystem on device %s.\n", dev_path);
+
+	rc = fat_params_compute(&cfg, &par);
+	if (rc != EOK) {
+		printf(NAME ": Invalid file-system parameters.\n");
+		return 2;
+	}
+
+	rc = fat_blocks_write(&par, handle);
+	if (rc != EOK) {
+		printf(NAME ": Error writing device.\n");
+		return 2;
+	}
+
+	block_fini(handle);
+	printf("Success.\n");
+
+	return 0;
+}
+
+static void syntax_print(void)
+{
+	printf("syntax: mkfat [--size <num_blocks>] <device_name>\n");
+}
+
+/** Derive sizes of different filesystem structures.
+ *
+ * This function concentrates all the different computations of FAT
+ * file system params.
+ */
+static int fat_params_compute(struct fat_cfg const *cfg, struct fat_params *par)
+{
+	uint32_t fat_bytes;
+	uint32_t non_data_sectors_lb;
+
+	/*
+         * Make a conservative guess on the FAT size needed for the file
+         * system. The optimum could be potentially smaller since we
+         * do not subtract size of the FAT itself when computing the
+         * size of the data region.
+         */
+
+	par->reserved_sectors = 1 + cfg->addt_res_sectors;
+	par->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
+	    sector_size);
+	non_data_sectors_lb = par->reserved_sectors + par->rootdir_sectors;
+
+	par->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
+	    sectors_per_cluster);
+
+	fat_bytes = (par->total_clusters + 2) * 2;
+	par->fat_sectors = div_round_up(fat_bytes, sector_size);
+
+	par->cfg = *cfg;
+
+	return EOK;
+}
+
+/** Create file system with the given parameters. */
+static int fat_blocks_write(struct fat_params const *par, dev_handle_t handle)
+{
+	bn_t addr;
+	uint8_t *buffer;
+	int i;
+	uint32_t j;
+	int rc;
+	struct fat_bs bs;
+
+	fat_bootsec_create(par, &bs);
+
+	rc = block_write_direct(handle, BS_BLOCK, 1, &bs);
+	if (rc != EOK)
+		return EIO;
+
+	addr = BS_BLOCK + 1;
+
+	buffer = calloc(sector_size, 1);
+	if (buffer == NULL)
+		return ENOMEM;
+
+	/* Reserved sectors */
+	for (i = 0; i < par->reserved_sectors - 1; ++i) {
+		rc = block_write_direct(handle, addr, 1, buffer);
+		if (rc != EOK)
+			return EIO;
+
+		++addr;
+	}
+
+	/* File allocation tables */
+	for (i = 0; i < fat_count; ++i) {
+		printf("Writing allocation table %d.\n", i + 1);
+
+		for (j = 0; j < par->fat_sectors; ++j) {
+			memset(buffer, 0, sector_size);
+			if (j == 0) {
+				buffer[0] = media_descriptor;
+				buffer[1] = 0xFF;
+				buffer[2] = 0xFF;
+				buffer[3] = 0xFF;
+			}
+
+			rc = block_write_direct(handle, addr, 1, buffer);
+			if (rc != EOK)
+				return EIO;
+
+			++addr;
+		}
+	}
+
+	printf("Writing root directory.\n");
+
+	memset(buffer, 0, sector_size);
+
+	/* Root directory */
+	for (i = 0; i < par->rootdir_sectors; ++i) {
+		rc = block_write_direct(handle, addr, 1, buffer);
+		if (rc != EOK)
+			return EIO;
+
+		++addr;
+	}
+
+	free(buffer);
+
+	return EOK;
+}
+
+/** Construct boot sector with the given parameters. */
+static void fat_bootsec_create(struct fat_params const *par, struct fat_bs *bs)
+{
+	memset(bs, 0, sizeof(*bs));
+
+	bs->ji[0] = 0xEB;
+	bs->ji[1] = 0x3C;
+	bs->ji[2] = 0x90;
+
+	memcpy(bs->oem_name, "HELENOS ", 8);
+
+	/* BIOS Parameter Block */
+	bs->bps = host2uint16_t_le(sector_size);
+	bs->spc = sectors_per_cluster;
+	bs->rscnt = host2uint16_t_le(par->reserved_sectors);
+	bs->fatcnt = fat_count;
+	bs->root_ent_max = host2uint16_t_le(par->cfg.root_ent_max);
+
+	if (par->cfg.total_sectors < 0x10000)
+		bs->totsec16 = host2uint16_t_le(par->cfg.total_sectors);
+	else
+		bs->totsec16 = host2uint16_t_le(0);
+
+	bs->mdesc = media_descriptor;
+	bs->sec_per_fat = host2uint16_t_le(par->fat_sectors);
+	bs->sec_per_track = host2uint16_t_le(63);
+	bs->headcnt = host2uint16_t_le(6);
+	bs->hidden_sec = host2uint32_t_le(0);
+
+	if (par->cfg.total_sectors >= 0x10000)
+		bs->totsec32 = host2uint32_t_le(par->cfg.total_sectors);
+	else
+		bs->totsec32 = host2uint32_t_le(0);
+
+	/* Extended BPB */
+	bs->pdn = 0x80;
+	bs->ebs = 0x29;
+	bs->id = host2uint32_t_be(0x12345678);
+
+	memcpy(bs->label, "HELENOS_NEW", 11);
+	memcpy(bs->type, "FAT16   ", 8);
+	bs->signature = host2uint16_t_be(0x55AA);
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libblock/libblock.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -87,4 +87,5 @@
 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
 static int get_block_size(int dev_phone, size_t *bsize);
+static int get_num_blocks(int dev_phone, bn_t *nblocks);
 
 static devcon_t *devcon_search(dev_handle_t dev_handle)
@@ -714,5 +715,5 @@
 
 	memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
-	rc = read_blocks(devcon, ba, cnt);
+	rc = write_blocks(devcon, ba, cnt);
 
 	fibril_mutex_unlock(&devcon->comm_area_lock);
@@ -736,4 +737,21 @@
 	
 	return get_block_size(devcon->dev_phone, bsize);
+}
+
+/** Get number of blocks on device.
+ *
+ * @param dev_handle	Device handle of the block device.
+ * @param nblocks	Output number of blocks.
+ *
+ * @return		EOK on success or negative error code on failure.
+ */
+int block_get_nblocks(dev_handle_t dev_handle, bn_t *nblocks)
+{
+	devcon_t *devcon;
+
+	devcon = devcon_search(dev_handle);
+	assert(devcon);
+	
+	return get_num_blocks(devcon->dev_phone, nblocks);
 }
 
@@ -789,4 +807,18 @@
 }
 
+/** Get total number of blocks on block device. */
+static int get_num_blocks(int dev_phone, bn_t *nblocks)
+{
+	ipcarg_t nb_l, nb_h;
+	int rc;
+
+	rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
+	if (rc == EOK) {
+		*nblocks = (bn_t) MERGE_LOUP32(nb_l, nb_h);
+	}
+
+	return rc;
+}
+
 /** @}
  */
Index: uspace/lib/libblock/libblock.h
===================================================================
--- uspace/lib/libblock/libblock.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libblock/libblock.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -60,6 +60,4 @@
 #define BLOCK_FLAGS_NOREAD	1
 
-typedef uint64_t bn_t;	/**< Block number type. */
-
 typedef struct block {
 	/** Mutex protecting the reference count. */
@@ -110,4 +108,5 @@
 
 extern int block_get_bsize(dev_handle_t, size_t *);
+extern int block_get_nblocks(dev_handle_t, bn_t *);
 extern int block_read_direct(dev_handle_t, bn_t, size_t, void *);
 extern int block_write_direct(dev_handle_t, bn_t, size_t, const void *);
Index: uspace/lib/libc/generic/io/io.c
===================================================================
--- uspace/lib/libc/generic/io/io.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libc/generic/io/io.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -554,4 +554,15 @@
 }
 
+int ftell(FILE *stream)
+{
+	off_t rc = lseek(stream->fd, 0, SEEK_CUR);
+	if (rc == (off_t) (-1)) {
+		/* errno has been set by lseek. */
+		return -1;
+	}
+
+	return rc;
+}
+
 void rewind(FILE *stream)
 {
@@ -584,4 +595,10 @@
 }
 
+void clearerr(FILE *stream)
+{
+	stream->eof = false;
+	stream->error = false;
+}
+
 int fphone(FILE *stream)
 {
Index: uspace/lib/libc/generic/stacktrace.c
===================================================================
--- uspace/lib/libc/generic/stacktrace.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libc/generic/stacktrace.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -39,6 +39,4 @@
 void stack_trace_fp_pc(uintptr_t fp, uintptr_t pc)
 {
-	printf("Printing stack trace:\n");
-	printf("=====================\n");
 	while (frame_pointer_validate(fp)) {
 		printf("%p: %p()\n", fp, pc);
@@ -46,5 +44,4 @@
 		fp = frame_pointer_prev(fp);
 	}
-	printf("=====================\n");
 }
 
Index: uspace/lib/libc/include/assert.h
===================================================================
--- uspace/lib/libc/include/assert.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libc/include/assert.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -51,5 +51,12 @@
 
 #ifndef NDEBUG
-#	define assert(expr) if (!(expr)) { printf("Assertion failed (%s) at file '%s', line %d.\n", #expr, __FILE__, __LINE__); abort();}
+#	define assert(expr) \
+		do { \
+			if (!(expr)) { \
+				printf("Assertion failed (%s) at file '%s', " \
+				    "line %d.\n", #expr, __FILE__, __LINE__); \
+				abort(); \
+			} \
+		} while (0)
 #else
 #	define assert(expr)
Index: uspace/lib/libc/include/ipc/bd.h
===================================================================
--- uspace/lib/libc/include/ipc/bd.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libc/include/ipc/bd.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -40,4 +40,5 @@
 typedef enum {
 	BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD,
+	BD_GET_NUM_BLOCKS,
 	BD_READ_BLOCKS,
 	BD_WRITE_BLOCKS
Index: uspace/lib/libc/include/sys/types.h
===================================================================
--- uspace/lib/libc/include/sys/types.h	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/lib/libc/include/sys/types.h	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -40,4 +40,5 @@
 typedef long off_t;
 typedef int mode_t;
+typedef uint64_t bn_t;	/**< Block number type. */
 
 typedef int32_t wchar_t;
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -296,4 +296,8 @@
 			ipc_answer_1(callid, EOK, block_size);
 			continue;
+		case BD_GET_NUM_BLOCKS:
+			ipc_answer_2(callid, EOK, LOWER32(disk[disk_id].blocks),
+			    UPPER32(disk[disk_id].blocks));
+			continue;
 		default:
 			retval = EINVAL;
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -56,4 +56,5 @@
 
 static const size_t block_size = 512;
+static bn_t num_blocks;
 static FILE *img;
 
@@ -99,4 +100,5 @@
 {
 	int rc;
+	long img_size;
 
 	rc = devmap_driver_register(NAME, file_bd_connection);
@@ -109,4 +111,17 @@
 	if (img == NULL)
 		return EINVAL;
+
+	if (fseek(img, 0, SEEK_END) != 0) {
+		fclose(img);
+		return EIO;
+	}
+
+	img_size = ftell(img);
+	if (img_size < 0) {
+		fclose(img);
+		return EIO;
+	}
+
+	num_blocks = img_size / block_size;
 
 	fibril_mutex_initialize(&dev_lock);
@@ -174,4 +189,8 @@
 			ipc_answer_1(callid, EOK, block_size);
 			continue;
+		case BD_GET_NUM_BLOCKS:
+			ipc_answer_2(callid, EOK, LOWER32(num_blocks),
+			    UPPER32(num_blocks));
+			continue;
 		default:
 			retval = EINVAL;
@@ -186,8 +205,15 @@
 {
 	size_t n_rd;
+	int rc;
 
 	fibril_mutex_lock(&dev_lock);
 
-	fseek(img, ba * block_size, SEEK_SET);
+	clearerr(img);
+	rc = fseek(img, ba * block_size, SEEK_SET);
+	if (rc < 0) {
+		fibril_mutex_unlock(&dev_lock);
+		return EIO;
+	}
+
 	n_rd = fread(buf, block_size, cnt, img);
 
@@ -209,13 +235,25 @@
 {
 	size_t n_wr;
+	int rc;
 
 	fibril_mutex_lock(&dev_lock);
 
-	fseek(img, ba * block_size, SEEK_SET);
-	n_wr = fread(buf, block_size, cnt, img);
+	clearerr(img);
+	rc = fseek(img, ba * block_size, SEEK_SET);
+	if (rc < 0) {
+		fibril_mutex_unlock(&dev_lock);
+		return EIO;
+	}
+
+	n_wr = fwrite(buf, block_size, cnt, img);
 
 	if (ferror(img) || n_wr < cnt) {
 		fibril_mutex_unlock(&dev_lock);
 		return EIO;	/* Write error */
+	}
+
+	if (fflush(img) != 0) {
+		fibril_mutex_unlock(&dev_lock);
+		return EIO;
 	}
 
Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -234,4 +234,7 @@
 			ipc_answer_1(callid, EOK, block_size);
 			continue;
+		case BD_GET_NUM_BLOCKS:
+			retval = ENOTSUP;
+			break;
 		default:
 			retval = EINVAL;
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -463,5 +463,8 @@
 			ipc_answer_1(callid, EOK, block_size);
 			continue;
-
+		case BD_GET_NUM_BLOCKS:
+			ipc_answer_2(callid, EOK, LOWER32(part->length),
+			    UPPER32(part->length));
+			continue;
 		default:
 			retval = EINVAL;
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/srv/bd/rd/rd.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -153,4 +153,8 @@
 			ipc_answer_1(callid, EOK, block_size);
 			continue;
+		case BD_GET_NUM_BLOCKS:
+			ipc_answer_2(callid, EOK, LOWER32(rd_size / block_size),
+			    UPPER32(rd_size / block_size));
+			continue;
 		default:
 			/*
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision ed212f723416c47b9cec06720f133c26c1fb3e0a)
+++ uspace/srv/vfs/vfs_ops.c	(revision 52cdcbcb92cae7de860c5d62e64b13d7743a1ba9)
@@ -900,4 +900,5 @@
 		}
 		newpos = size + off;
+		file->pos = newpos;
 		fibril_mutex_unlock(&file->lock);
 		ipc_answer_1(rid, EOK, newpos);
