Index: lib/libkvm/kvm_arm.c
===================================================================
--- lib/libkvm/kvm_arm.c
+++ lib/libkvm/kvm_arm.c
@@ -132,8 +132,10 @@
 	u_long kernbase, physaddr, pa;
 	pd_entry_t *l1pt;
 	Elf32_Ehdr *ehdr;
+	Elf32_Phdr *phdr;
 	size_t hdrsz;
 	char minihdr[8];
+	int found, i;
 
 	if (!kd->rawdump) {
 		if (pread(kd->pmfd, &minihdr, 8, 0) == 8) {
@@ -158,19 +160,33 @@
 	hdrsz = ehdr->e_phoff + ehdr->e_phentsize * ehdr->e_phnum;
 	if (_kvm_maphdrs(kd, hdrsz) == -1)
 		return (-1);
-	nl[0].n_name = "kernbase";
+
+	phdr = (Elf32_Phdr *)((uint8_t *)ehdr + ehdr->e_phoff);
+	found = 0;
+	for (i = 0; i < ehdr->e_phnum; i++) {
+		if (phdr[i].p_type == PT_LOOS) {
+			kernbase = phdr[i].p_vaddr;
+			physaddr = phdr[i].p_paddr;
+			found = 1;
+			break;
+		}
+	}
+
 	nl[1].n_name = NULL;
-	if (kvm_nlist(kd, nl) != 0)
-		kernbase = KERNBASE;
-	else
-		kernbase = nl[0].n_value;
+	if (!found) {
+		nl[0].n_name = "kernbase";
+		if (kvm_nlist(kd, nl) != 0)
+			kernbase = KERNBASE;
+		else
+			kernbase = nl[0].n_value;
 
-	nl[0].n_name = "physaddr";
-	if (kvm_nlist(kd, nl) != 0) {
-		_kvm_err(kd, kd->program, "couldn't get phys addr");
-		return (-1);
+		nl[0].n_name = "physaddr";
+		if (kvm_nlist(kd, nl) != 0) {
+			_kvm_err(kd, kd->program, "couldn't get phys addr");
+			return (-1);
+		}
+		physaddr = nl[0].n_value;
 	}
-	physaddr = nl[0].n_value;
 	nl[0].n_name = "kernel_l1pa";
 	if (kvm_nlist(kd, nl) != 0) {
 		_kvm_err(kd, kd->program, "bad namelist");
Index: sys/arm/arm/dump_machdep.c
===================================================================
--- sys/arm/arm/dump_machdep.c
+++ sys/arm/arm/dump_machdep.c
@@ -245,6 +245,30 @@
 	return (error);
 }
 
+/*
+ * Add a header to be used by libkvm to get the va to pa delta
+ */
+static int
+dump_os_header(struct dumperinfo *di)
+{
+	Elf_Phdr phdr;
+	int error;
+
+	bzero(&phdr, sizeof(phdr));
+	phdr.p_type = PT_LOOS;
+	phdr.p_flags = PF_R;			/* XXX */
+	phdr.p_offset = fileofs;
+	phdr.p_vaddr = KERNVIRTADDR;
+	phdr.p_paddr = pmap_kextract(KERNVIRTADDR);
+	phdr.p_filesz = 0;
+	phdr.p_memsz = 0;
+	phdr.p_align = PAGE_SIZE;
+
+	error = buf_write(di, (char*)&phdr, sizeof(phdr));
+	fileofs += phdr.p_filesz;
+	return (error);
+}
+
 static int
 cb_size(struct md_pa *mdp, int seqnr, void *arg)
 {
@@ -308,7 +332,7 @@
 
 	/* Calculate dump size. */
 	dumpsize = 0L;
-	ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize);
+	ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize) + 1;
 	hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
 	fileofs = MD_ALIGN(hdrsz);
 	dumpsize += fileofs;
@@ -325,7 +349,7 @@
 	mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize, di->blocksize);
 
 	printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
-	    ehdr.e_phnum);
+	    ehdr.e_phnum - 1);
 
 	/* Dump leader */
 	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
@@ -340,6 +364,8 @@
 
 	/* Dump program headers */
 	error = foreach_chunk(cb_dumphdr, di);
+	if (error >= 0)
+		error = dump_os_header(di);
 	if (error < 0)
 		goto fail;
 	buf_flush(di);