diff --git a/xen/Rules.mk b/xen/Rules.mk
index 41a1c26..67bedce 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -60,6 +60,12 @@ CFLAGS += -nostdinc -fno-builtin -fno-common
 CFLAGS += -Werror -Wredundant-decls -Wno-pointer-arith
 $(call cc-option-add,CFLAGS,CC,-Wvla)
 CFLAGS += -pipe -D__XEN__ -include $(BASEDIR)/include/xen/config.h
+
+ifeq ($(armds),y)
+CFLAGS += -nostdlibinc -nostdlib -Wno-unused-command-line-argument
+CFLAGS += -include $(BASEDIR)/include/asm/armds.h
+endif
+
 CFLAGS-$(CONFIG_DEBUG_INFO) += -g
 CFLAGS += '-D__OBJECT_FILE__="$@"'
 
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 70f532e..a5a3479 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -83,11 +83,16 @@ else
 all_symbols =
 endif
 
+ifeq ($(armds),y)
+$(TARGET): $(TARGET)-syms
+	fromelf --bin $< --output $@
+else
 $(TARGET): $(TARGET)-syms
 	$(OBJCOPY) -O binary -S $< $@
 ifeq ($(CONFIG_ARM_64),y)
 	ln -sf $(notdir $@)  ../../$(notdir $@).efi
 endif
+endif
 
 ifeq ($(CONFIG_LTO),y)
 # Gather all LTO objects together
@@ -102,6 +107,19 @@ prelink.o: $(ALL_OBJS)
 	$(LD) $(LDFLAGS) -r -o $@ $^
 endif
 
+ifeq ($(armds),y)
+$(TARGET)-syms: prelink.o xen.scat
+	armlink --scatter="xen.scat" --edit="xen.steer" --no_scanlib $(LDFLAGS) prelink.o $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0
+	$(NM) -pa --format=sysv $(@D)/.$(@F).0 \
+		| $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).0.S
+	$(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0.o
+	armlink --scatter="xen.scat" --edit="xen.steer" --no_scanlib $(LDFLAGS) prelink.o $(@D)/.$(@F).0.o -o $(@D)/.$(@F).1
+	$(NM) -pa --format=sysv $(@D)/.$(@F).1 \
+		| $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1.S
+	$(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1.o
+	armlink --scatter="xen.scat" --edit="xen.steer" --no_scanlib --symdefs="$(@D)/$(@F).map" $(LDFLAGS) prelink.o $(build_id_linker) $(@D)/.$(@F).1.o -o $@
+	rm -f $(@D)/.$(@F).[0-9]*
+else
 $(TARGET)-syms: prelink.o xen.lds
 	$(LD) $(LDFLAGS) -T xen.lds -N prelink.o \
 	    $(BASEDIR)/common/symbols-dummy.o -o $(@D)/.$(@F).0
@@ -119,14 +137,20 @@ $(TARGET)-syms: prelink.o xen.lds
 		| $(BASEDIR)/tools/symbols --xensyms --sysv --sort \
 		>$(@D)/$(@F).map
 	rm -f $(@D)/.$(@F).[0-9]*
+endif
 
 asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c
 	$(CC) $(filter-out -flto,$(CFLAGS)) -S -o $@ $<
 
+ifeq ($(armds),y)
+xen.scat: xen.scat.S
+	$(CC) -P -E --target=aarch64-arm-none-eabi -o $@ $<
+else
 xen.lds: xen.lds.S
 	$(CC) -P -E -Ui386 $(AFLAGS) -o $@ $<
 	sed -e 's/xen\.lds\.o:/xen\.lds:/g' <.xen.lds.d >.xen.lds.d.new
 	mv -f .xen.lds.d.new .xen.lds.d
+endif
 
 dtb.o: $(CONFIG_DTB_FILE)
 
diff --git a/xen/arch/arm/xen.scat.S b/xen/arch/arm/xen.scat.S
new file mode 100644
index 0000000..3bb405f
--- /dev/null
+++ b/xen/arch/arm/xen.scat.S
@@ -0,0 +1,266 @@
+#if 0 
+/*
+ * armlink does not understand shifts in scat file expressions
+ * so hardcode needed values
+ */
+#include <xen/cache.h>
+#include <asm/page.h>
+#include <asm/percpu.h>
+#undef ENTRY
+#undef ALIGN
+#else
+ #define PAGE_SIZE 4096
+ #define POINTER_ALIGN 8
+ #define SMP_CACHE_BYTES 128
+ #define STACK_SIZE 32768
+ #define XEN_VIRT_START 0x00200000
+#endif
+
+LOAD XEN_VIRT_START
+{
+;_start
+;_stext
+  _text AlignExpr(+0, PAGE_SIZE) PADVALUE 0x9090
+  {
+    *(.text*)
+    *(.text.cold)
+    *(.text.unlikely)
+    *(.fixup)
+    *(.gnu.warning)
+  }
+;_etext
+
+;_srodata
+;__start_bug_frames
+  _rodata_bug_frames_0 AlignExpr(+0, PAGE_SIZE) FIXED ZEROPAD
+  {
+    *(.bug_frames.0)
+  }
+;__stop_bug_frames_0
+
+  _rodata_bug_frames_1 +0 FIXED ZEROPAD
+  {
+    *(.bug_frames.1)
+  }
+;__stop_bug_frames_1
+
+  _rodata_bug_frames_2 +0 FIXED ZEROPAD
+  {
+    *(.bug_frames.2)
+  }
+;__stop_bug_frames_2
+
+  _rodata_data +0
+  {
+    *(.rodata)
+    *(.rodata.*)
+    *(.data.rel.ro)
+    *(.data.rel.ro.*)
+  }
+
+#ifdef CONFIG_LOCK_PROFILE
+;__lock_profile_start
+  _rodata_lockprofile_data AlignExpr(+0, POINTER_ALIGN) FIXED ZEROPAD
+  {
+    *(.lockprofile.data)
+  }
+;__lock_profile_end
+#endif
+
+;__param_start
+  _rodata_data_param AlignExpr(+0, POINTER_ALIGN) FIXED ZEROPAD
+  {
+    *(.data.param)
+  }
+;__param_end
+
+;__proc_info_start
+  _rodata_proc_info +0 FIXED ZEROPAD
+  {
+    *(.proc.info)
+  }
+;__proc_info_end
+
+#if defined(CONFIG_HAS_VPCI) && defined(CONFIG_LATE_HWDOM)
+;__start_vpci_array
+  _rodata_data_vpci AlignExpr(+0, POINTER_ALIGN) SORTTYPE Lexical FIXED ZEROPAD
+  {
+    *(SORT(.data.vpci.*))
+  }
+;__end_vpci_array
+#endif
+
+#if defined(BUILD_ID)
+;__note_gnu_build_id_start
+  _note_gnu_build_id +0 FIXED ZEROPAD
+  {
+    *(.note.gnu.build-id)
+  }
+;__note_gnu_build_id_end
+#endif
+
+;_erodata
+
+  _data AlignExpr(+0, PAGE_SIZE) FIXED ZEROPAD
+  {
+    *(.data.page_aligned.*)
+    *(.data.*)
+  }
+
+;__start_schedulers_array
+  _data_schedulers AlignExpr(+0, 8) FIXED ZEROPAD
+  {
+    *(.data.schedulers)
+  }
+;__end_schedulers_array
+
+  _data_rel +0 FIXED ZEROPAD
+  {
+    *(.data.rel)
+    *(.data.rel.*)
+;#CONSTRUCTORS ????
+  }
+
+;__start___ex_table  
+  _data_ex_table AlignExpr(+0, SMP_CACHE_BYTES) FIXED ZEROPAD
+  {
+    *(.ex_table)
+  }
+;__stop___ex_table
+
+;__start___pre_ex_table
+  _data_ex_table_pre +0 FIXED ZEROPAD
+  {
+    *(.ex_table.pre)
+  }
+;__stop___pre_ex_table
+
+  _data_read_mostly +0 FIXED ZEROPAD
+  {
+    *(.data.read_mostly)
+  }
+
+;_splatform
+  _arch_info AlignExpr(+0, 8) FIXED ZEROPAD
+  {
+     *(.arch.info)
+  }
+;_eplatform
+
+;_sdevice
+  _dev_info AlignExpr(+0, 8) FIXED ZEROPAD
+  {
+    *(.dev.info)
+  }
+;_edevice
+
+;_asdevice
+  _adev_info AlignExpr(+0, 8) FIXED ZEROPAD
+  {
+    *(.adev.info)
+  }
+;_aedevice
+
+;__init_begin
+;_sinittext
+  _init_text AlignExpr(+0, PAGE_SIZE) FIXED ZEROPAD
+  {
+    *(.init.text)
+  }
+;_einittext
+
+  _init_rodata AlignExpr(+0, PAGE_SIZE) FIXED ZEROPAD
+  {
+    *(.init.rodata)
+    *(.init.rodata.rel)
+    *(.init.rodata.str*)
+  }
+
+;__setup_start
+  _init_setup AlignExpr(+0, POINTER_ALIGN) FIXED ZEROPAD
+  {
+    *(.init.setup)
+  }
+;__setup_end
+
+;__initcall_start
+  _initcallpresmp_init +0 FIXED ZEROPAD
+  {
+    *(.initcallpresmp.init)
+  }
+;__presmp_initcall_end
+
+  _initcall1_init +0 FIXED ZEROPAD
+  {
+    *(.initcall1.init)
+  }
+;__initcall_end
+
+;__alt_instructions
+  _altinstructions AlignExpr(+0, 4) FIXED ZEROPAD
+  {
+    *(.altinstructions)
+  }
+;__alt_instructions_end
+
+  _altinstr_replacement AlignExpr(+0, 4) FIXED ZEROPAD
+  {
+    *(.altinstr_replacement)
+  }
+
+  _init_data +0 FIXED ZEROPAD
+  {
+    *(.init.data)
+    *(.init.data.rel)
+    *(.init.data.rel.*)
+  }
+
+;__ctors_start
+  _ctors AlignExpr(+0, 8) FIXED ZEROPAD
+  {
+    *(.ctors)
+    *(.init_array)
+  }
+
+  _init_array_sorted AlignExpr(+0, 8) SORTTYPE Lexical FIXED ZEROPAD
+  {
+    *(.init_array.*)
+  }
+;__ctors_end
+
+#if defined(CONFIG_HAS_VPCI) && !defined(CONFIG_LATE_HWDOM)
+  _data_vpci AlignExpr(+0, POINTER_ALIGN) SORTTYPE Lexical FIXED ZEROPAD
+  {
+    *(.data.vpci.*)
+  }
+#endif
+;__init_end_efi
+
+;__init_end
+;__bss_start
+  _bss AlignExpr(+0, STACK_SIZE) FIXED ZEROPAD
+  {
+    *(.bss.stack_aligned*)
+    *(.bss.page_aligned*, OVERALIGN PAGE_SIZE)
+    *(.bss*)
+  }
+
+;__per_cpu_start
+  _bss_percpu AlignExpr(+0, SMP_CACHE_BYTES) FIXED ZEROPAD
+  {
+    *(.bss.percpu)
+    *(.bss.percpu.read_mostly, OVERALIGN SMP_CACHE_BYTES)
+  }
+;__per_cpu_data_end
+;__bss_end
+;_end
+
+#ifdef CONFIG_DTB_FILE
+;_sdtb
+  _dtb FIXED ZEROPAD
+ {
+    *(.dtb)
+ }
+#endif
+
+}
diff --git a/xen/arch/arm/xen.steer b/xen/arch/arm/xen.steer
new file mode 100644
index 0000000..646e912
--- /dev/null
+++ b/xen/arch/arm/xen.steer
@@ -0,0 +1,5 @@
+RESOLVE _srodata AS Load$$_rodata_bug_frames_0$$Base
+RENAME Load$$_text$$Base AS _stext
+RENAME Load$$_text$$Limit AS _etext
+RENAME Load$$_init_text$$Base AS _sinittext
+RENAME Load$$_init_text$$Limit AS _einittext
diff --git a/xen/include/asm-arm/armds.h b/xen/include/asm-arm/armds.h
new file mode 100644
index 0000000..5ee2e5d
--- /dev/null
+++ b/xen/include/asm-arm/armds.h
@@ -0,0 +1,91 @@
+#define _start                      Load$$_text$$Base
+#define _stext                      Load$$_text$$Base
+
+#define _etext                      Load$$_text$$Limit
+
+//#define _srodata                    Load$$_rodata_bug_frames_0$$Base
+#define __start_bug_frames          Load$$_rodata_bug_frames_0$$Base
+
+#define __stop_bug_frames_0         Load$$_rodata_bug_frames_0$$Limit
+#define __stop_bug_frames_1         Load$$_rodata_bug_frames_1$$Limit
+#define __stop_bug_frames_2         Load$$_rodata_bug_frames_2$$Limit
+
+#ifdef CONFIG_LOCK_PROFILE
+#define __lock_profile_start        Load$$_rodata_lockprofile_data$$Base
+#define __lock_profile_end          Load$$_rodata_lockprofile_data$$Limit
+#endif
+
+#define __param_start               Load$$_rodata_data_param$$Base
+#define __param_end                 Load$$_rodata_data_param$$Limit
+
+#define __proc_info_start           Load$$_rodata_proc_info$$Base
+#define __proc_info_end             Load$$_rodata_proc_info$$Limit
+
+#define _erodata                    Load$$_rodata_proc_info$$Limit
+
+#if defined(CONFIG_HAS_VPCI) && defined(CONFIG_LATE_HWDOM)
+#define __start_vpci_array          Load$$_rodata_data_vpci$$Base
+#define __end_vpci_array            Load$$_rodata_data_vpci$$Limit
+
+#undef _erodata
+#define _erodata                    Load$$_rodata_data_vpci$$Limit
+#endif
+
+#if defined(BUILD_ID)
+#define __note_gnu_build_id_start   Load$$_note_gnu_build_id$$Base
+#define __note_gnu_build_id_end     Load$$_note_gnu_build_id$$Limit
+
+#undef _erodata
+#define _erodata                    Load$$_note_gnu_build_id$$Limit
+#endif
+
+#define __start_schedulers_array    Load$$_data_schedulers$$Base
+#define __end_schedulers_array      Load$$_data_schedulers$$Limit
+
+/* Does not exist for ARM
+#define __start___ex_table          Load$$_data_ex_table$$Base
+#define __stop___ex_table           Load$$_data_ex_table$$Limit
+*/
+
+#define __start___pre_ex_table      Load$$_data_ex_table_pre$$Base
+#define __stop___pre_ex_table       Load$$_data_ex_table_pre$$Limit
+
+#define _splatform                  Load$$_arch_info$$Base
+#define _eplatform                  Load$$_arch_info$$Limit
+
+#define _sdevice                    Load$$_dev_info$$Base
+#define _edevice                    Load$$_dev_info$$Limit
+
+#define _asdevice                   Load$$_adev_info$$Base
+#define _aedevice                   Load$$_adev_info$$Limit
+
+#define __init_begin                Load$$_init_text$$Base
+#define _sinittext                  Load$$_init_text$$Base
+#define _einittext                  Load$$_init_text$$Limit
+
+#define __setup_start               Load$$_init_setup$$Base
+#define __setup_end                 Load$$_init_setup$$Limit
+
+#define __initcall_start            Load$$_initcallpresmp_init$$Base
+#define __presmp_initcall_end       Load$$_initcallpresmp_init$$Limit
+#define __initcall_end              Load$$_initcall1_init$$Limit
+
+#define __alt_instructions          Load$$_altinstructions$$Base
+#define __alt_instructions_end      Load$$_altinstructions$$Limit
+
+#define __ctors_start               Load$$_ctors$$Base
+#define __ctors_end                 Load$$_init_array_sorted$$Limit
+#define __init_end_efi              Load$$_init_array_sorted$$Limit
+
+#if defined(CONFIG_HAS_VPCI) && !defined(CONFIG_LATE_HWDOM)
+#undef __init_end_efi
+#define __init_end_efi              Load$$_data_vpci$$Limit
+#endif
+
+#define __init_end                  Load$$_bss$$Base
+#define __bss_start                 Load$$_bss$$Base
+
+#define __per_cpu_start             Load$$_bss_percpu$$Base
+#define __per_cpu_data_end          Load$$_bss_percpu$$Limit
+#define __bss_end                   Load$$_bss_percpu$$Limit
+#define _end                        Load$$_bss_percpu$$Limit
