diff --git a/arm/fdt.c b/arm/fdt.c
index cb4f00d..381d48f 100644
--- a/arm/fdt.c
+++ b/arm/fdt.c
@@ -9,14 +9,11 @@
 
 #include <stdbool.h>
 
-#include <asm/setup.h>
 #include <linux/byteorder.h>
 #include <linux/kernel.h>
 #include <linux/sizes.h>
 #include <linux/psci.h>
 
-static char kern_cmdline[COMMAND_LINE_SIZE];
-
 bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
 {
 	return false;
@@ -145,7 +142,7 @@ static int setup_fdt(struct kvm *kvm)
 	/* /chosen */
 	_FDT(fdt_begin_node(fdt, "chosen"));
 	_FDT(fdt_property_cell(fdt, "linux,pci-probe-only", 1));
-	_FDT(fdt_property_string(fdt, "bootargs", kern_cmdline));
+	_FDT(fdt_property_string(fdt, "bootargs", kvm->cfg.real_cmdline));
 
 	/* Initrd */
 	if (kvm->arch.initrd_size != 0) {
@@ -223,94 +220,3 @@ static int setup_fdt(struct kvm *kvm)
 	return 0;
 }
 late_init(setup_fdt);
-
-static int read_image(int fd, void **pos, void *limit)
-{
-	int count;
-
-	while (((count = xread(fd, *pos, SZ_64K)) > 0) && *pos <= limit)
-		*pos += count;
-
-	if (pos < 0)
-		die_perror("xread");
-
-	return *pos < limit ? 0 : -ENOMEM;
-}
-
-#define FDT_ALIGN	SZ_2M
-#define INITRD_ALIGN	4
-bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
-				 const char *kernel_cmdline)
-{
-	void *pos, *kernel_end, *limit;
-	unsigned long guest_addr;
-
-	/*
-	 * Linux requires the initrd and dtb to be mapped inside lowmem,
-	 * so we can't just place them at the top of memory.
-	 */
-	limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1;
-
-	pos = kvm->ram_start + ARM_KERN_OFFSET(kvm);
-	kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos);
-	if (read_image(fd_kernel, &pos, limit) == -ENOMEM)
-		die("kernel image too big to contain in guest memory.");
-
-	kernel_end = pos;
-	pr_info("Loaded kernel to 0x%llx (%llu bytes)",
-		kvm->arch.kern_guest_start,
-		host_to_guest_flat(kvm, pos) - kvm->arch.kern_guest_start);
-
-	/*
-	 * Now load backwards from the end of memory so the kernel
-	 * decompressor has plenty of space to work with. First up is
-	 * the device tree blob...
-	 */
-	pos = limit;
-	pos -= (FDT_MAX_SIZE + FDT_ALIGN);
-	guest_addr = ALIGN(host_to_guest_flat(kvm, pos), FDT_ALIGN);
-	pos = guest_flat_to_host(kvm, guest_addr);
-	if (pos < kernel_end)
-		die("fdt overlaps with kernel image.");
-
-	kvm->arch.dtb_guest_start = guest_addr;
-	pr_info("Placing fdt at 0x%llx - 0x%llx",
-		kvm->arch.dtb_guest_start,
-		host_to_guest_flat(kvm, limit));
-	limit = pos;
-
-	/* ... and finally the initrd, if we have one. */
-	if (fd_initrd != -1) {
-		struct stat sb;
-		unsigned long initrd_start;
-
-		if (lseek(fd_initrd, 0, SEEK_SET) < 0)
-			die_perror("lseek");
-
-		if (fstat(fd_initrd, &sb))
-			die_perror("fstat");
-
-		pos -= (sb.st_size + INITRD_ALIGN);
-		guest_addr = ALIGN(host_to_guest_flat(kvm, pos), INITRD_ALIGN);
-		pos = guest_flat_to_host(kvm, guest_addr);
-		if (pos < kernel_end)
-			die("initrd overlaps with kernel image.");
-
-		initrd_start = guest_addr;
-		if (read_image(fd_initrd, &pos, limit) == -ENOMEM)
-			die("initrd too big to contain in guest memory.");
-
-		kvm->arch.initrd_guest_start = initrd_start;
-		kvm->arch.initrd_size = host_to_guest_flat(kvm, pos) - initrd_start;
-		pr_info("Loaded initrd to 0x%llx (%llu bytes)",
-			kvm->arch.initrd_guest_start,
-			kvm->arch.initrd_size);
-	} else {
-		kvm->arch.initrd_size = 0;
-	}
-
-	strncpy(kern_cmdline, kernel_cmdline, COMMAND_LINE_SIZE);
-	kern_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
-
-	return true;
-}
diff --git a/arm/kvm.c b/arm/kvm.c
index d0e4a20..6e3f80e 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -3,6 +3,7 @@
 #include "kvm/util.h"
 #include "kvm/8250-serial.h"
 #include "kvm/virtio-console.h"
+#include "kvm/fdt.h"
 
 #include "arm-common/gic.h"
 
@@ -85,3 +86,91 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
 }
+
+static int read_image(int fd, void **pos, void *limit)
+{
+	int count;
+
+	while (((count = xread(fd, *pos, SZ_64K)) > 0) && *pos <= limit)
+		*pos += count;
+
+	if (pos < 0)
+		die_perror("xread");
+
+	return *pos < limit ? 0 : -ENOMEM;
+}
+
+#define FDT_ALIGN	SZ_2M
+#define INITRD_ALIGN	4
+bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
+				 const char *kernel_cmdline)
+{
+	void *pos, *kernel_end, *limit;
+	unsigned long guest_addr;
+
+	/*
+	 * Linux requires the initrd and dtb to be mapped inside lowmem,
+	 * so we can't just place them at the top of memory.
+	 */
+	limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1;
+
+	pos = kvm->ram_start + ARM_KERN_OFFSET(kvm);
+	kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos);
+	if (read_image(fd_kernel, &pos, limit) == -ENOMEM)
+		die("kernel image too big to contain in guest memory.");
+
+	kernel_end = pos;
+	pr_info("Loaded kernel to 0x%llx (%llu bytes)",
+		kvm->arch.kern_guest_start,
+		host_to_guest_flat(kvm, pos) - kvm->arch.kern_guest_start);
+
+	/*
+	 * Now load backwards from the end of memory so the kernel
+	 * decompressor has plenty of space to work with. First up is
+	 * the device tree blob...
+	 */
+	pos = limit;
+	pos -= (FDT_MAX_SIZE + FDT_ALIGN);
+	guest_addr = ALIGN(host_to_guest_flat(kvm, pos), FDT_ALIGN);
+	pos = guest_flat_to_host(kvm, guest_addr);
+	if (pos < kernel_end)
+		die("fdt overlaps with kernel image.");
+
+	kvm->arch.dtb_guest_start = guest_addr;
+	pr_info("Placing fdt at 0x%llx - 0x%llx",
+		kvm->arch.dtb_guest_start,
+		host_to_guest_flat(kvm, limit));
+	limit = pos;
+
+	/* ... and finally the initrd, if we have one. */
+	if (fd_initrd != -1) {
+		struct stat sb;
+		unsigned long initrd_start;
+
+		if (lseek(fd_initrd, 0, SEEK_SET) < 0)
+			die_perror("lseek");
+
+		if (fstat(fd_initrd, &sb))
+			die_perror("fstat");
+
+		pos -= (sb.st_size + INITRD_ALIGN);
+		guest_addr = ALIGN(host_to_guest_flat(kvm, pos), INITRD_ALIGN);
+		pos = guest_flat_to_host(kvm, guest_addr);
+		if (pos < kernel_end)
+			die("initrd overlaps with kernel image.");
+
+		initrd_start = guest_addr;
+		if (read_image(fd_initrd, &pos, limit) == -ENOMEM)
+			die("initrd too big to contain in guest memory.");
+
+		kvm->arch.initrd_guest_start = initrd_start;
+		kvm->arch.initrd_size = host_to_guest_flat(kvm, pos) - initrd_start;
+		pr_info("Loaded initrd to 0x%llx (%llu bytes)",
+			kvm->arch.initrd_guest_start,
+			kvm->arch.initrd_size);
+	} else {
+		kvm->arch.initrd_size = 0;
+	}
+
+	return true;
+}
