Index: trunk/src/kern_head.c
===================================================================
--- trunk/src/kern_head.c	(revision 40)
+++ trunk/src/kern_head.c	(revision 41)
@@ -46,4 +46,5 @@
 #include <limits.h>
 #include <sys/utsname.h>
+#include <sys/mman.h>
 
 /* number of system calls */
@@ -72,4 +73,61 @@
 static unsigned char system_call_code[SYS_CODE_SIZE];
 
+static int kmem_read (int fd, unsigned long addr, unsigned char * buf, int len)
+{
+  if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
+    {
+      if (verbose)
+	perror("kmem_read: lseek");
+      return -1;
+    }
+  if (read(fd, buf, len) < 0)
+    {
+      if (verbose)
+	perror("kmem_read: read");
+      return -1;
+    }
+  return 0;
+}
+
+static int kmem_mmap (int fd, unsigned long addr, unsigned char * buf, int len)
+{
+  size_t    moff, roff;
+  size_t    sz;
+  char    * kmap;
+
+
+  /* first, try read()
+   */
+  int  ret_old = kmem_read (fd, addr, buf, len); 
+
+  if (ret_old == 0)
+    return ret_old;
+
+  if (verbose)
+    fprintf(stderr, 
+	    "kmem_mmap: read() from /dev/kmem failed, now trying mmap()\n");
+
+  sz = getpagesize(); /* unistd.h */
+
+  moff = ((size_t)(addr/sz)) * sz;                 /* lower page boundary */
+  roff = addr - moff;    /* off relative to lower address of mmapped area */
+  kmap = mmap(0, len+sz, PROT_READ, MAP_PRIVATE, fd, moff);/* sys/mman.h */
+
+  if (kmap == MAP_FAILED)
+    {
+      perror("kmem_mmap: mmap");
+      return -1;
+    }
+  memcpy (buf, &kmap[roff], len);
+      
+  if (munmap(kmap, len+sz) != 0)
+    {
+      perror("kmem_mmap: munmap");
+      return -1;
+    }
+
+  return 0;
+}
+
 int read_kcode (unsigned long addr, unsigned char * buf, int len)
 {
@@ -88,14 +146,10 @@
       return -1;
     }
-  if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
-    {
-      perror("read_kcode: lseek");
-      return -1;
-    }
-  if (read(fd, buf, len) < 0)
-    {
-      perror("read_kcode: read");
-      return -1;
-    }
+  if (kmem_mmap(fd, addr, buf, len) < 0)
+    {
+      close (fd);
+      return -1;
+    }
+  close (fd);
   return 0;
 }
Index: trunk/src/sh_kern.c
===================================================================
--- trunk/src/sh_kern.c	(revision 40)
+++ trunk/src/sh_kern.c	(revision 41)
@@ -39,4 +39,5 @@
 #include <sys/wait.h>
 #include <signal.h>
+#include <sys/mman.h>
 
 
@@ -475,4 +476,47 @@
 #endif
 
+static int sh_kern_kmem_read (int fd, unsigned long addr, 
+			      unsigned char * buf, int len)
+{
+  if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
+    {
+      return -1;
+    }
+  if (read(fd, buf, len) < 0)
+    {
+      return -1;
+    }
+  return 0;
+}
+
+static int sh_kern_read_data (int fd, unsigned long addr, 
+			      unsigned char * buf, size_t len)
+{
+  size_t    moff, roff;
+  size_t    sz;
+  char    * kmap;
+
+  /* first, try read()
+   */
+  if (0 == sh_kern_kmem_read (fd, addr, buf, len))
+    return 0;
+
+  /* next, try mmap()
+   */
+  sz = getpagesize(); /* unistd.h */
+
+  moff = ((size_t)(addr/sz)) * sz;                 /* lower page boundary */
+  roff = addr - moff;    /* off relative to lower address of mmapped area */
+
+  kmap = mmap(0, len+sz, PROT_READ, MAP_PRIVATE, fd, moff);/* sys/mman.h */
+
+  if (kmap == MAP_FAILED)
+    {
+      return -1;
+    }
+  memcpy (buf, &kmap[roff], len);
+  return munmap(kmap, len+sz);
+}
+
 int sh_kern_check_internal ()
 {
@@ -617,16 +661,11 @@
 	  if(status == 0)
 	    {
-	      if(lseek(kd, (off_t)kaddr, SEEK_SET) == -1)
+	      retry_msleep (0, ShKernDelay); /* milliseconds */
+	      
+	      if (sh_kern_read_data (kd, kaddr, 
+				     (unsigned char *) &kmem_call_table, 
+				     sizeof(kmem_call_table)))
 		{
 		  status = -2;
-		}
-	    }
-	  if(status == 0)
-	    {
-	      retry_msleep (0, ShKernDelay); /* milliseconds */
-	      if (sizeof(kmem_call_table) != 
-		  read(kd, &kmem_call_table, sizeof(kmem_call_table)))
-		{
-		  status = -3;
 		}
 	    }
@@ -655,12 +694,14 @@
 		      (sh.flag.update == S_TRUE))
 		    {
-		      lseek (kd, kmem_call_table[j], SEEK_SET);
+		      sh_kern_read_data (kd, kmem_call_table[j], 
+					 (unsigned char *) &(kmem_code_table[j][0]),
+					 2 * sizeof(unsigned int));
 		    }
 		  else
 		    {
-		      lseek (kd, sh_syscalls[j].addr, SEEK_SET);
+		      sh_kern_read_data (kd, sh_syscalls[j].addr, 
+					 (unsigned char *) &(kmem_code_table[j][0]),
+					 2 * sizeof(unsigned int));
 		    }
-		  read  (kd, &(kmem_code_table[j][0]), 
-			 2 * sizeof(unsigned int));
 		}
 	    }
@@ -683,6 +724,6 @@
 
 	      memset(sh_idt_table, '\0', SH_MAXIDT*8);
-	      lseek (kd, idt_addr, SEEK_SET);
-	      read  (kd, sh_idt_table, idt_size*8);
+	      sh_kern_read_data (kd, idt_addr, 
+				 (unsigned char *) sh_idt_table, idt_size*8);
 	    }
 #endif
@@ -696,6 +737,6 @@
 	  if(status == 0)
 	    {
-	      lseek (kd, system_call_addr, SEEK_SET);
-	      read  (kd, new_system_call_code, 256);
+	      sh_kern_read_data (kd, system_call_addr, 
+				 (unsigned char *) new_system_call_code, 256);
 	    }
 
@@ -708,8 +749,10 @@
 	  if(status == 0)
 	    {
-	      lseek (kd, proc_root, SEEK_SET);
-	      read  (kd, &proc_root_dir, sizeof(proc_root_dir));
-	      lseek (kd, proc_root_iops, SEEK_SET);
-	      read  (kd, &proc_root_inode, sizeof(proc_root_inode));
+	      sh_kern_read_data (kd, proc_root, 
+				 (unsigned char *) &proc_root_dir, 
+				 sizeof(proc_root_dir));
+	      sh_kern_read_data (kd, proc_root_iops, 
+				 (unsigned char *) &proc_root_inode, 
+				 sizeof(proc_root_inode));
 	    }
 #endif
