diff --git a/lisp/NetBSD-os.c b/lisp/NetBSD-os.c
new file mode 100644
index 0000000000000000000000000000000000000000..57722a6b23d5104e2a6b3f814d6b2befecc0551a
--- /dev/null
+++ b/lisp/NetBSD-os.c
@@ -0,0 +1,238 @@
+/*
+ * NetBSD-os.c.
+ * From OpenBSD-os.c 1.1 2001/12/06 19:15:44 pmai Exp
+ * From FreeBSD-os.c 1.6 2000/10/24 13:32:30 dtc Exp
+ *
+ * OS-dependent routines.  This file (along with os.h) exports an
+ * OS-independent interface to the operating system VM facilities.
+ * Suprisingly, this interface looks a lot like the Mach interface
+ * (but simpler in some places).  For some operating systems, a subset
+ * of these functions will have to be emulated.
+ *
+ * This is the OSF1 version.  By Sean Hallgren.
+ * Much hacked by Paul Werkowski
+ * GENCGC support by Douglas Crosher, 1996, 1997.
+ * Frobbed for OpenBSD by Pierre R. Mai, 2001.
+ * Frobbed for NetBSD by Pierre R. Mai, 2002.
+ *
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/NetBSD-os.c,v 1.1 2002/01/28 20:19:39 pmai Exp $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <errno.h>
+#include "./signal.h"
+#include "os.h"
+#include "arch.h"
+#include "globals.h"
+#include "interrupt.h"
+#include "lispregs.h"
+#include "internals.h"
+
+#include <sys/types.h>
+#include <signal.h>
+/* #include <sys/sysinfo.h> */
+#include <sys/proc.h>
+#include "validate.h"
+size_t os_vm_page_size;
+
+#define DPRINTF(t,a) {if (t) fprintf a;}
+
+#if defined GENCGC
+#include "gencgc.h"
+#endif
+
+
+void os_init(void)
+{
+  os_vm_page_size = OS_VM_DEFAULT_PAGESIZE;
+}
+
+int sc_reg(struct sigcontext *c, int offset)
+{
+  switch(offset)
+    {
+    case  0: return c->sc_eax;
+    case  2: return c->sc_ecx;
+    case  4: return c->sc_edx;
+    case  6: return c->sc_ebx;
+    case  8: return c->sc_esp;
+    case 10: return c->sc_ebp;
+    case 12: return c->sc_esi;
+    case 14: return c->sc_edi;
+    }
+  return 0;
+}
+
+void os_save_context(void)
+{
+  /*
+   * Called from interrupt handlers so C stuff knows things set in Lisp.
+   */
+}
+
+void os_set_context(void)
+{
+}
+
+os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
+{
+  int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+
+  /*
+   * NetBSD 1.5.2 seems to insist on each mmap being less than 128MB.
+   * So we mmap in 64MB steps.  This is probably inefficient, but the
+   * missing CR2 reporting in signal handlers already ensures that
+   * NetBSD/x86 is not a suitable platform for CMU CL as it stands.
+   */
+  
+  if (addr)
+    flags |= MAP_FIXED;
+  else
+    flags |= MAP_VARIABLE;
+
+  DPRINTF(0, (stderr, "os_validate %x %d =>", addr, len));
+
+  if (addr)
+    {
+      os_vm_address_t curaddr=addr;
+
+      while (len>0)
+	{
+	  os_vm_address_t resaddr;
+	  int curlen=MIN(64*1024*1024,len);
+	  
+	  resaddr = mmap(curaddr, curlen, OS_VM_PROT_ALL, flags, -1, 0);
+	  
+	  if (resaddr == (os_vm_address_t) -1)
+	    {
+	      perror("mmap");
+	      
+	      while (curaddr>addr)
+		{
+		  curaddr-=64*1024*1024;
+		  munmap(curaddr,64*1024*1024);
+		}
+	      
+	      return NULL;
+	    }
+
+	  DPRINTF(0, (stderr, " %x", resaddr));
+	  
+	  curaddr+=curlen;
+	  len-=curlen;
+	}
+      
+      DPRINTF(0, (stderr, "\n"));
+    }
+  else
+    {
+      addr = mmap(0, len, OS_VM_PROT_ALL, flags, -1, 0);
+
+      if (addr == (os_vm_address_t) -1)
+	{
+	  perror("mmap");
+	  return NULL;
+	}
+      
+      DPRINTF(0, (stderr, " %x\n", addr));
+    }
+
+  return addr;
+}
+
+void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
+{
+  DPRINTF(0, (stderr, "os_invalidate %x %d\n", addr, len));
+
+  if (munmap(addr, len) == -1)
+    perror("munmap");
+}
+
+os_vm_address_t os_map(int fd, int offset, os_vm_address_t addr,
+		       os_vm_size_t len)
+{
+  addr = mmap(addr, len,
+	      OS_VM_PROT_ALL,
+	      MAP_PRIVATE | MAP_FILE | MAP_FIXED,
+	      fd, (off_t) offset);
+
+  if (addr == (os_vm_address_t) -1)
+    perror("mmap");
+
+  return addr;
+}
+
+void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
+{
+}
+
+void os_protect(os_vm_address_t address, os_vm_size_t length,
+		os_vm_prot_t prot)
+{
+  if (mprotect(address, length, prot) == -1)
+    perror("mprotect");
+}
+
+
+
+static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
+{
+  char* beg = (char*) sbeg;
+  char* end = (char*) sbeg + slen;
+  char* adr = (char*) a;
+  return (adr >= beg && adr < end);
+}
+
+boolean valid_addr(os_vm_address_t addr)
+{
+  int ret;
+  os_vm_address_t newaddr;
+  newaddr = os_trunc_to_page(addr);
+
+  if (   in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
+      || in_range_p(addr, STATIC_SPACE_START   , STATIC_SPACE_SIZE   )
+      || in_range_p(addr, DYNAMIC_0_SPACE_START, dynamic_space_size  )
+      || in_range_p(addr, DYNAMIC_1_SPACE_START, dynamic_space_size  )
+      || in_range_p(addr, CONTROL_STACK_START  , CONTROL_STACK_SIZE  )
+      || in_range_p(addr, BINDING_STACK_START  , BINDING_STACK_SIZE  ))
+    return TRUE;
+  return FALSE;
+}
+
+
+static void sigsegv_handler(HANDLER_ARGS)
+{
+
+  /*
+   * Since NetBSD on x86 currently provides no way to get the faulting
+   * memory address (i.e. the contents of the CR2 register), the page
+   * protection mechanism of the generational GC currently can't be
+   * used (see gengc.c), hence we don't neet to do anything here.
+   *
+   * See OpenBSD-os.c for details of what should be here, once NetBSD
+   * provides siginfo_t.
+   */
+
+  SAVE_CONTEXT();
+
+  DPRINTF(0, (stderr, "sigsegv:\n"));
+  interrupt_handle_now(signal, code, context);
+}
+
+static void sigbus_handler(HANDLER_ARGS)
+{
+  SAVE_CONTEXT();
+
+  DPRINTF(0, (stderr, "sigbus:\n"));
+  interrupt_handle_now(signal, code, context);
+}
+
+void os_install_interrupt_handlers(void)
+{
+  interrupt_install_low_level_handler(SIGSEGV, sigsegv_handler);
+  interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
+}
diff --git a/lisp/gencgc.c b/lisp/gencgc.c
index 3e03314c843766bab3c22a4aeef15585d294ee63..14bfb59133c4fe430fa30e22620aad19e81d1a5c 100644
--- a/lisp/gencgc.c
+++ b/lisp/gencgc.c
@@ -7,7 +7,7 @@
  *
  * Douglas Crosher, 1996, 1997, 1998, 1999.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.25 2001/12/06 19:15:44 pmai Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.26 2002/01/28 20:19:39 pmai Exp $
  *
  */
 
@@ -53,7 +53,13 @@ unsigned gencgc_verbose = 0;
  * To enable the use of page protection to help avoid the scavenging
  * of pages that don't have pointers to younger generations.
  */
+#ifdef __NetBSD__
+/* NetBSD on x86 has no way to retrieve the faulting address in the
+ * SIGSEGV handler, so for the moment we can't use page protection. */
+boolean  enable_page_protection = FALSE;
+#else
 boolean  enable_page_protection = TRUE;
+#endif
 
 /*
  * Hunt for pointers to old-space, when GCing generations >= verify_gen.
@@ -85,9 +91,10 @@ boolean check_code_fixups = FALSE;
 
 /*
  * To enable unmapping of a page and re-mmaping it to have it zero filled.
- * Note: this can waste a lot of swap on FreeBSD and OpenBSD(?) so don't unmap.
+ * Note: this can waste a lot of swap on FreeBSD and Open/NetBSD(?) so
+ * don't unmap.
  */
-#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
 boolean gencgc_unmap_zero = FALSE;
 #else
 boolean gencgc_unmap_zero = TRUE;