Index: boot/Makefile
===================================================================
--- boot/Makefile	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/Makefile	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -72,5 +72,5 @@
 
 clean_dist:
-	rm -f $(INITRD).fs $(INITRD).img $(COMPS_H) $(COMPS_C) $(LINK) *.co
+	rm -f $(INITRD).fs $(INITRD).img $(COMPS_H) $(COMPS_C) $(LINK) $(LINK).comp *.co
 	rm -f $(USPACE_PATH)/dist/srv/*
 	rm -f $(USPACE_PATH)/dist/app/*
Index: boot/Makefile.build
===================================================================
--- boot/Makefile.build	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/Makefile.build	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -106,4 +106,7 @@
 	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@ $(COMPONENT_OBJECTS) $(OBJECTS)
 
+$(LINK): $(LINK).comp $(DEPEND)
+	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $(LINK).comp | grep -v "^\#" > $(LINK)
+
 %.o: %.S $(DEPEND)
 	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/Makefile.common	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -55,4 +55,5 @@
 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
 MKFAT = $(TOOLS_PATH)/mkfat.py
+MKUIMAGE = $(TOOLS_PATH)/mkuimage.py
 
 JOBFILE = $(ROOT_PATH)/tools/jobfile.py
Index: boot/Makefile.uboot
===================================================================
--- boot/Makefile.uboot	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
+++ boot/Makefile.uboot	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -0,0 +1,46 @@
+#
+# 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.
+#
+
+.PHONY: all clean
+
+include Makefile.common
+
+IMAGE_NAME=HelenOS-$(RELEASE)
+BIN_OUTPUT=image.bin
+
+all: $(POST_OUTPUT)
+
+$(BIN_OUTPUT): $(BOOT_OUTPUT)
+	$(OBJCOPY) -O binary $< $@
+
+$(POST_OUTPUT): $(BIN_OUTPUT)
+	$(MKUIMAGE) -name "$(IMAGE_NAME)" -laddr 0x30008000 -saddr 0x30008000 \
+    $< $@
+
+clean:
+	rm -f $(BIN_OUTPUT)
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/arch/arm32/Makefile.inc	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -27,4 +27,10 @@
 #
 
+ifeq ($(MACHINE), gta02)
+	BOOT_OUTPUT = image.boot
+	POST_OUTPUT = $(ROOT_PATH)/uImage.bin
+	POSTBUILD = Makefile.uboot
+endif
+
 BFD_NAME = elf32-littlearm
 BFD_OUTPUT = $(BFD_NAME)
Index: boot/arch/arm32/_link.ld.in
===================================================================
--- boot/arch/arm32/_link.ld.in	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/arch/arm32/_link.ld.in	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -1,11 +1,13 @@
+#include <arch/arch.h>
+
 ENTRY(start)
 
 SECTIONS {
-	. = 0x0000;
+	. = BOOT_BASE;
 	.text : {
 		*(BOOTSTRAP);
 		*(.text);
 	}
-	. = 0x8000;
+	. = BOOT_BASE + 0x8000;
 	.data : {
 		*(BOOTPT);      /* bootstrap page table */
Index: boot/arch/arm32/include/arch.h
===================================================================
--- boot/arch/arm32/include/arch.h	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/arch/arm32/include/arch.h	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -36,5 +36,15 @@
 #define PTL0_ENTRY_SIZE  4
 
-#define BOOT_OFFSET  0xa00000
+/*
+ * Address where the boot stage image starts (beginning of usable physical
+ * memory).
+ */
+#ifdef MACHINE_gta02
+#define BOOT_BASE	0x30008000
+#else
+#define BOOT_BASE	0x00000000
+#endif
+
+#define BOOT_OFFSET	(BOOT_BASE + 0xa00000)
 
 #ifndef __ASM__
Index: boot/arch/arm32/include/main.h
===================================================================
--- boot/arch/arm32/include/main.h	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/arch/arm32/include/main.h	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
  *
@@ -38,11 +39,21 @@
 
 /** Address where characters to be printed are expected. */
-#ifdef MACHINE_testarm
-	#define VIDEORAM_ADDRESS  0x10000000
-#endif
 
-#ifdef MACHINE_integratorcp
-	#define VIDEORAM_ADDRESS  0x16000000
-#endif
+/** GTA02 serial console UART register addresses.
+ *
+ * This is UART channel 2 of the S3C24xx CPU
+ */
+#define GTA02_SCONS_UTRSTAT	0x50008010
+#define GTA02_SCONS_UTXH	0x50008020
+
+/* Bits in UTXH register */
+#define S3C24XX_UTXH_TX_EMPTY	0x00000004
+
+
+/** GXemul testarm serial console output register */
+#define TESTARM_SCONS_ADDR 	0x10000000
+
+/** IntegratorCP serial console output register */
+#define ICP_SCONS_ADDR 		0x16000000
 
 extern void bootstrap(void);
Index: boot/arch/arm32/src/putchar.c
===================================================================
--- boot/arch/arm32/src/putchar.c	(revision fc14438a8dd4f64269a9db0d8db45f35450495dd)
+++ boot/arch/arm32/src/putchar.c	(revision 99b2564010a554f44b9d4abdeda4d41b63dfd1ae)
@@ -2,4 +2,5 @@
  * Copyright (c) 2007 Michal Kebrt
  * Copyright (c) 2009 Vineeth Pillai
+ * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,13 +41,84 @@
 #include <str.h>
 
+#ifdef MACHINE_gta02
+
+/** Send a byte to the gta02 serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb_gta02(uint8_t byte)
+{
+	volatile uint32_t *utrstat;
+	volatile uint32_t *utxh;
+
+	utrstat = (volatile uint32_t *) GTA02_SCONS_UTRSTAT;
+	utxh    = (volatile uint32_t *) GTA02_SCONS_UTXH;
+
+	/* Wait until transmitter is empty. */
+	while ((*utrstat & S3C24XX_UTXH_TX_EMPTY) == 0)
+		;
+
+	/* Transmit byte. */
+	*utxh = (uint32_t) byte;
+}
+
+#endif
+
+#ifdef MACHINE_testarm
+
+/** Send a byte to the GXemul testarm serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb_testarm(uint8_t byte)
+{
+	*((volatile uint8_t *) TESTARM_SCONS_ADDR) = byte;
+}
+
+#endif
+
+#ifdef MACHINE_integratorcp
+
+/** Send a byte to the IntegratorCP serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb_icp(uint8_t byte)
+{
+	*((volatile uint8_t *) ICP_SCONS_ADDR) = byte;
+}
+
+#endif
+
+/** Send a byte to the serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb(uint8_t byte)
+{
+#ifdef MACHINE_gta02
+	scons_sendb_gta02(byte);
+#endif
+#ifdef MACHINE_testarm
+	scons_sendb_testarm(byte);
+#endif
+#ifdef MACHINE_integratorcp
+	scons_sendb_icp(byte);
+#endif
+}
+
+/** Display a character
+ *
+ * @param ch	Character to display
+ */
 void putchar(const wchar_t ch)
 {
 	if (ch == '\n')
-		*((volatile char *) VIDEORAM_ADDRESS) = '\r';
-	
+		scons_sendb('\r');
+
 	if (ascii_check(ch))
-		*((volatile char *) VIDEORAM_ADDRESS) = ch;
+		scons_sendb((uint8_t) ch);
 	else
-		*((volatile char *) VIDEORAM_ADDRESS) = U_SPECIAL;
+		scons_sendb(U_SPECIAL);
 }
 
