Index: .gitignore
===================================================================
--- .gitignore	(revision 5e93bed562402974d8be35a223ade5b6e85d80ee)
+++ .gitignore	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
@@ -67,2 +67,3 @@
 freebsd-userspace/lib/libc/net/nsparser.c
 freebsd-userspace/lib/libc/net/nsparser.i
+freebsd-userspace/rtems/rtems-kvm-symbols.c
Index: freebsd-userspace/Makefile
===================================================================
--- freebsd-userspace/Makefile	(revision 5e93bed562402974d8be35a223ade5b6e85d80ee)
+++ freebsd-userspace/Makefile	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
@@ -164,4 +164,6 @@
 # C_FILES += rtems/rtems-net-setup.c
 C_FILES += rtems/syslog.c
+C_FILES += rtems/rtems-kvm.c
+C_FILES += rtems/rtems-kvm-symbols.c
 C_FILES += rtems/rtems-syslog-initialize.c
 C_FILES += rtems/rtems-getprogname.c
@@ -271,5 +273,6 @@
 COMMAND_RELS = $(NETSTAT) $(IFCONFIG)
 
-GEN_FILES = include/rpc/rpcb_prot.h
+GEN_FILES = rtems/rtems-kvm-symbols.c
+GEN_FILES += include/rpc/rpcb_prot.h
 GEN_FILES += commands/sbin/route/keywords.h
 # lib/libc/net
@@ -295,4 +298,7 @@
 $(NETSTAT): $(NETSTAT_C_O_FILES)
 	$(LD) -r -o $@ $^
+
+rtems/rtems-kvm-symbols.c: rtems/generate_kvm_symbols
+	./rtems/generate_kvm_symbols >rtems/rtems-kvm-symbols.c
 
 include/rpc/rpcb_prot.h: include/rpc/rpcb_prot.x
Index: freebsd-userspace/rtems/generate_kvm_symbols
===================================================================
--- freebsd-userspace/rtems/generate_kvm_symbols	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
+++ freebsd-userspace/rtems/generate_kvm_symbols	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
@@ -0,0 +1,108 @@
+#! /bin/sh
+#
+# This file generates the symbol table for the kvm subsystem. The
+# table is limited to the ones we believe are needed.
+
+symbols=""
+while read sym
+do
+  symbols="${symbols} ${sym}"
+done <<EOF
+_ifnet
+_rtstat
+_rt_tables
+_mrtstat
+_mfchashtbl
+_viftable
+_ipxpcb_list
+_ipxstat
+_spx_istat
+_ddpstat
+_ddpcb
+_ngsocklist
+_ip6stat
+_icmp6stat
+_ipsec4stat
+_ipsec6stat
+_pim6stat
+_mrt6stat
+_mf6ctable
+_mif6table
+_pfkeystat
+_mbstat
+_mbtypes
+_nmbclusters
+_nmbufs
+_mbuf_hiwm
+_clust_hiwm
+_smp_cpus
+_pagesize
+_mb_statpcpu
+_rttrash
+_mbuf_lowm
+_clust_lowm
+_carpstats
+_pfsyncstats
+_ahstat
+_espstat
+_ipcompstat
+_tcpstat
+_udpstat
+_ipstat
+_icmpstat
+_igmpstat
+_pimstat
+_tcbinfo
+_udbinfo
+_divcbinfo
+_ripcbinfo
+_unp_count
+_unp_gencnt
+_unp_dhead
+_unp_shead
+_rip6stat
+_sctpstat
+_mfctablesize
+_arpstat
+EOF
+
+cat <<EOF
+/**** THIS FILE IS GENERATED BY A SCRIPT ****/
+
+/*
+ * This file contains the known list of symbols for the kvm subsystem.
+ */
+
+#include "kvm_private.h"
+#include "stdio.h"
+
+/*
+ *  The following is the known list of symbols that may be passed
+ *  to the kvm family of calls.
+ */
+
+EOF
+for sym in ${symbols}
+do
+  no_underscore=`echo $sym | sed -e 's/^_//' `
+  echo "extern int ${no_underscore} __attribute((weak));"
+done
+
+cat <<EOF
+/*
+ *  The following is the known list of symbols that may be passed
+ *  to the kvm family of calls.
+ */
+
+kvm_symval_t rtems_kvm_symbols[] = {
+EOF
+for sym in ${symbols}
+do
+  no_underscore=`echo $sym | sed -e 's/^_//' `
+  echo "  { \"${sym}\", &${no_underscore} },"
+done
+
+cat <<EOF
+  { "", NULL }
+};
+EOF
Index: freebsd-userspace/rtems/kvm_private.h
===================================================================
--- freebsd-userspace/rtems/kvm_private.h	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
+++ freebsd-userspace/rtems/kvm_private.h	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
@@ -0,0 +1,13 @@
+#ifndef __KVM_PRIVATE_h
+#define __KVM_PRIVATE_h
+
+#include <stdint.h>
+
+typedef struct {
+  const char *symbol;
+  uintptr_t   value;
+} kvm_symval_t;
+
+kvm_symval_t rtems_kvm_symbols[];
+
+#endif
Index: freebsd-userspace/rtems/rtems-kvm.c
===================================================================
--- freebsd-userspace/rtems/rtems-kvm.c	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
+++ freebsd-userspace/rtems/rtems-kvm.c	(revision 34e1fb2c5a0141161dcd1b5fb419e43cae20681e)
@@ -0,0 +1,107 @@
+#include "port_before.h"
+#include <sys/cdefs.h>
+#include <kvm.h>
+#include <nlist.h>
+#include <assert.h>
+
+#include "kvm_private.h"
+
+char *
+kvm_geterr(
+	kvm_t *kd
+)
+{
+	return "KVM error";
+	// return (kd->errbuf);
+}
+
+kvm_t *
+kvm_openfiles(
+	const char *uf,
+	const char *mf,
+	const char *sf __unused,
+	int flag,
+	char *errout
+)
+{
+  return (kvm_t *)kvm_openfiles;
+}
+
+int
+kvm_nlist(kvm_t *kd, struct nlist *nl)
+{
+	struct nlist *p;
+	int nvalid;
+	int error;
+	kvm_symval_t *kvm;
+
+	assert( kd != NULL );
+	assert( nl != NULL );
+
+	nvalid = 0;
+again:
+	for (p = nl; p->n_name && p->n_name[0]; ++p) {
+		if (p->n_type != N_UNDF)
+			continue;
+		if (p->n_name[0] != '_')
+			continue;
+             
+		for (kvm=rtems_kvm_symbols; kvm->symbol[0]; ++kvm) {
+			if (!strcmp(p->n_name, kvm->symbol)) {
+				p->n_type = N_TEXT;
+				p->n_other = 0;
+				p->n_desc = 0;
+				p->n_value = kvm->value;
+				if (kvm->value) {
+					++nvalid;
+			printf("kvm: %s = %p\n", p->n_name, (void*)kvm->value);
+				}
+				break;
+			}
+		}
+		if (! kvm->symbol[0]) {
+			printf("kvm: did not know about %s\n", p->n_name);
+		}
+	}
+
+	error = ((p - nl) - nvalid);
+	return (error);
+
+}
+
+
+ssize_t
+kvm_read(kd, kva, buf, len)
+	kvm_t *kd;
+	u_long kva;
+	void *buf;
+	size_t len;
+{
+	assert( kd != NULL );
+	assert( buf != NULL );
+
+	if ( kva == 0 )
+		return (-1);
+
+#ifdef __rtems__
+	// printf( "%d from %p to %p\n", len, (void*)kva, buf);
+#endif
+#if 0
+	/*
+	 * Use a byte-wide copy to avoid alignment issues.
+	 */
+	{
+		unsigned char *s;
+		unsigned char *d;
+		size_t c;
+
+		s = (void *)kva;
+		d = buf;
+		for (c=0; c<len ; c++)
+			*d++ = *s++;
+	}
+#else
+	memcpy(buf, (void *)kva, len);
+#endif
+	return len;
+}
