Index: boot/arch/arm64/Makefile.inc
===================================================================
--- boot/arch/arm64/Makefile.inc	(revision 5b586b9a32f80302879788263b29cffd509a776a)
+++ boot/arch/arm64/Makefile.inc	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
@@ -27,45 +27,4 @@
 #
 
-BOOT_OUTPUT = image.boot
-POST_OUTPUT = $(ROOT_PATH)/image.iso
-POSTBUILD = Makefile.grub
-GRUB_LOADER = chainloader
-
-BFD_NAME = elf64-littleaarch64
-# Request binary BFD output. The ARM64 port manually prepares the .text
-# section to look as a PE file than can be loaded on EFI systems.
-BFD_OUTPUT = binary
-
-BITS = 64
-ENDIANESS = LE
-
-# UEFI binaries should be relocatable, the EFI boot service LoadImage() will
-# rebase the boot file using the .reloc information in the image if it cannot
-# load the binary at its preferred address. The ARM64 port does not provide this
-# information in its PE file (that would require manually creating it) but
-# instead the boot code is compiled with the -fpic option and the bootloader
-# relocates itself at runtime.
-#
-# N.B. The UEFI guarantees for AArch64 that during boot time the primary
-# processor is in the execution mode that has unaligned access enabled. The
-# -mstrict-align option is therefore not needed.
-EXTRA_CFLAGS = -fpic -fvisibility=hidden
-EXTRA_LDFLAGS = -Wl,-shared
-
-SOURCES = \
-	arch/$(BARCH)/src/asm.S \
-	arch/$(BARCH)/src/main.c \
-	arch/$(BARCH)/src/relocate.c \
-	$(COMPS).o \
-	genarch/src/efi.c \
-	generic/src/gzip.c \
-	generic/src/inflate.c \
-	generic/src/kernel.c \
-	generic/src/memstr.c \
-	generic/src/payload.c \
-	generic/src/printf.c \
-	generic/src/printf_core.c \
-	generic/src/str.c \
-	generic/src/tar.c \
-	generic/src/version.c \
-	generic/src/vprintf.c
+BUILD = Makefile.empty
+POSTBUILD = Makefile.empty
Index: boot/arch/arm64/meson.build
===================================================================
--- boot/arch/arm64/meson.build	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
+++ boot/arch/arm64/meson.build	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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.
+#
+
+BUILD = true
+
+POST_OUTPUT = 'image.iso'
+POSTBUILD = 'grub'
+GRUB_LOADER = 'chainloader'
+
+# Request binary output. The ARM64 port manually prepares the .text
+# section to look as a PE file than can be loaded on EFI systems.
+boot_image_format = 'binary'
+
+boot_src = files(
+	'src/asm.S',
+	'src/main.c',
+	'src/relocate.c',
+	'../../genarch/src/efi.c',
+	'../../generic/src/gzip.c',
+	'../../generic/src/inflate.c',
+	'../../generic/src/kernel.c',
+	'../../generic/src/memstr.c',
+	'../../generic/src/payload.c',
+	'../../generic/src/printf.c',
+	'../../generic/src/printf_core.c',
+	'../../generic/src/str.c',
+	'../../generic/src/tar.c',
+	'../../generic/src/version.c',
+	'../../generic/src/vprintf.c',
+)
Index: boot/grub/meson.build
===================================================================
--- boot/grub/meson.build	(revision 5b586b9a32f80302879788263b29cffd509a776a)
+++ boot/grub/meson.build	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
@@ -5,12 +5,37 @@
 dist_dirname = 'grub_dist'
 
-build_dist_text = []
-build_dist_deps = []
-foreach init : rd_init_binaries
-	target = 'boot/' + run_command(basename, init[1], check: true).stdout().strip()
+if GRUB_LOADER == 'multiboot'
+	build_dist_text = []
+	build_dist_deps = []
+	foreach init : rd_init_binaries
+		target = 'boot/' + run_command(basename, init[1], check: true).stdout().strip()
 
-	build_dist_text += install_snippet.format(init[0].full_path(), target)
-	build_dist_deps += init[0]
-endforeach
+		build_dist_text += install_snippet.format(init[0].full_path(), target)
+		build_dist_deps += init[0]
+	endforeach
+
+	LOADS = [ 'echo \'Loading kernel\'' ]
+	LOADS += [ MULTIBOOT_CMD + ' /boot/kernel.elf' ]
+
+	MODULES = rd_init + [ 'boot/initrd.img' ]
+
+	foreach module : MODULES
+		module = '/boot/' + run_command(basename, module, check: true).stdout().strip()
+		LOADS += 'echo \'Loading @0@\''.format(module)
+		LOADS += '@0@ @1@ @1@'.format(MODULE_CMD, module)
+	endforeach
+endif
+
+if GRUB_LOADER == 'chainloader'
+	# init binaries are already part of the chainloaded boot image.
+	build_dist_text = [ install_snippet.format(boot_image.full_path(), 'boot/' + boot_image_name) ]
+	build_dist_deps = [ boot_image ]
+
+	LOADS = [
+		'echo \'Loading ' + boot_image_name + '\'',
+		'chainloader /boot/' + boot_image_name,
+		'boot',
+	]
+endif
 
 build_dist_sh = configure_file(
@@ -20,6 +45,4 @@
 )
 
-
-MODULES = rd_init + [ 'boot/initrd.img' ]
 
 if GRUB_ARCH == 'pc'
@@ -31,23 +54,4 @@
 	MODULE_CMD = 'module2'
 	INSMODS = [ 'insmod efi_gop', 'insmod efi_uga' ]
-endif
-
-if GRUB_LOADER == 'multiboot'
-	LOADS = [ 'echo \'Loading kernel\'' ]
-	LOADS += [ MULTIBOOT_CMD + ' /boot/kernel.elf' ]
-
-	foreach module : MODULES
-		module = '/boot/' + run_command(basename, module, check: true).stdout().strip()
-		LOADS += 'echo \'Loading @0@\''.format(module)
-		LOADS += '@0@ @1@ @1@'.format(MODULE_CMD, module)
-	endforeach
-endif
-
-if GRUB_LOADER == 'chainloader'
-	LOADS = [
-		'echo \'Loading ' + BOOT_OUTPUT + '\'',
-		'chainloader /boot/' + BOOT_OUTPUT,
-		'boot',
-	]
 endif
 
Index: meson.build
===================================================================
--- meson.build	(revision 5b586b9a32f80302879788263b29cffd509a776a)
+++ meson.build	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
@@ -49,4 +49,10 @@
 	arguments: [ '@INPUT@' ],
 	output: '@PLAINNAME@.check.c',
+	capture: true,
+)
+
+gzip = generator(find_program('gzip',
+	arguments: [ '--no-name', '-9', '--stdout', '@INPUT@' ]
+	output: '@PLAINNAME@.gz',
 	capture: true,
 )
Index: meson/arch/arm64/meson.build
===================================================================
--- meson/arch/arm64/meson.build	(revision 5b586b9a32f80302879788263b29cffd509a776a)
+++ meson/arch/arm64/meson.build	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
@@ -1,6 +1,48 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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.
+#
+
 arch_uspace_c_args = [ '-D__LE__', '-fno-omit-frame-pointer' ]
 arch_kernel_c_args = arch_uspace_c_args + [ '-march=armv8-a+nofp+nosimd', '-mgeneral-regs-only' ]
 arch_kernel_link_args = [ '-nostdlib' ]
 arch_uspace_link_args = [ '-nostdlib', '-lgcc' ]
+
+
+# UEFI binaries should be relocatable, the EFI boot service LoadImage() will
+# rebase the boot file using the .reloc information in the image if it cannot
+# load the binary at its preferred address. The ARM64 port does not provide this
+# information in its PE file (that would require manually creating it) but
+# instead the boot code is compiled with the -fpic option and the bootloader
+# relocates itself at runtime.
+#
+# N.B. The UEFI guarantees for AArch64 that during boot time the primary
+# processor is in the execution mode that has unaligned access enabled. The
+# -mstrict-align option is therefore not needed.
+arch_boot_c_args = arch_uspace_c_args + [ '-fpic', '-fvisibility=hidden', '-fno-function-sections' ]
+arch_boot_link_args = [ '-Wl,-shared', '-Wl,--no-gc-sections' ]
 
 
Index: tools/ew.py
===================================================================
--- tools/ew.py	(revision 5b586b9a32f80302879788263b29cffd509a776a)
+++ tools/ew.py	(revision a73a1453b2b32910e3e981c2942288e99e7df640)
@@ -273,5 +273,5 @@
 	elif cfg['image'] == 'image.iso@arm64':
 		# Define image.iso cdrom backend.
-		cmdline += ' -drive if=none,file=image.iso,id=cdrom,media=cdrom'
+		cmdline += ' -drive if=none,file=build/image.iso,id=cdrom,media=cdrom'
 		# Define scsi bus.
 		cmdline += ' -device virtio-scsi-device'
