diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/Makefile linux-cb26/arch/arm/Makefile
--- linux-cb26.orig/arch/arm/Makefile	Mon Aug  7 15:28:10 2000
+++ linux-cb26/arch/arm/Makefile	Tue Aug 22 18:38:09 2000
@@ -153,6 +153,13 @@
 CFLAGS		+= -g
 endif
 
+ifeq ($(CONFIG_KGDB),y)
+# If configured for kgdb support, don't mix function prologue code
+# with body code so gdb's arm-tdep.c:arm_scan_prologue function
+# can find frame pointers correctly...
+CFLAGS		+= -fno-schedule-insns -fno-schedule-insns2
+endif
+
 HEAD		:= arch/arm/kernel/head-$(PROCESSOR).o arch/arm/kernel/init_task.o
 SUBDIRS		:= arch/arm/special $(SUBDIRS) arch/arm/lib arch/arm/kernel arch/arm/mm
 CORE_FILES	:= arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/config.in linux-cb26/arch/arm/config.in
--- linux-cb26.orig/arch/arm/config.in	Mon Aug  7 15:28:10 2000
+++ linux-cb26/arch/arm/config.in	Mon Aug 14 15:55:18 2000
@@ -253,10 +253,16 @@
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
-bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POINTER
+bool 'Remote debugging support' CONFIG_KGDB
+if [ "$CONFIG_KGDB" = "y" ]; then
+  define_bool CONFIG_FRAME_POINTER y
+  define_bool CONFIG_DEBUG_INFO y
+else
+  bool 'Compile kernel with frame pointer (for useful debugging)' CONFIG_FRAME_POINTER
+  bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
+fi
 bool 'Verbose kernel error messages' CONFIG_DEBUG_ERRORS
 bool 'Verbose user fault messages' CONFIG_DEBUG_USER
-bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 if [ "$CONFIG_CPU_26" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/kernel/Makefile linux-cb26/arch/arm/kernel/Makefile
--- linux-cb26.orig/arch/arm/kernel/Makefile	Mon Aug  7 15:28:10 2000
+++ linux-cb26/arch/arm/kernel/Makefile	Mon Aug 14 15:59:19 2000
@@ -84,6 +84,10 @@
   endif
 endif
 
+ifeq ($(CONFIG_KGDB),y)
+  O_OBJS += arm32-stub.o
+endif
+
 $(HEAD_OBJ): $(HEAD_OBJ:.o=.S)
 	$(CC) -D__ASSEMBLY__ -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@
 
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/kernel/arm32-stub.c linux-cb26/arch/arm/kernel/arm32-stub.c
--- linux-cb26.orig/arch/arm/kernel/arm32-stub.c	Wed Dec 31 16:00:00 1969
+++ linux-cb26/arch/arm/kernel/arm32-stub.c	Mon Aug 28 19:55:17 2000
@@ -0,0 +1,667 @@
+/*
+ * arch/arm/kernel/arm32-stub.c -- stub for GDB remote debugging protocol
+ *
+ * Originally written by Glenn Engel, Lake Stevens Instrumental Division, HP
+ * Contributed by HP Systems
+ *
+ * Modified for usermode ARM debugging by Steve Longerbeam, Communica Inc.
+ *
+ * Modified for ARMlinux on Psion Series 5 machines by Noel Cragg
+ * <noel@red-bean.com>
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL  Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   (signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: <two hex digits computed as mod 256 sum of <packet info>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#if 0
+#include <asm/assembler.h>	/* for I_BIT -- wrong somehow? */
+#else
+#undef I_BIT
+#define I_BIT (1 << 27)
+#undef F_BIT
+#define F_BIT (1 << 26)
+#endif
+
+/* write and read single characters (this code currently lives in
+   drivers/char/serial_7110.c) */
+extern int putDebugChar (char c);
+extern int getDebugChar (void);
+
+/* BUFMAX defines the maximum number of characters in inbound/outbound
+   buffers -- at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized;	/* nonzero means we've been initialized */
+
+static int remote_debug = 0;	/* nonzero shows protocol debug messages */
+
+static int check_fault = 0;	/* flag to check for a memory fault */
+
+static volatile int mem_err = 0; /* indicate mem error for mem2hex/hex2mem */
+
+static const char hexchars[] = "0123456789abcdef";
+
+/* saved user-mode registers, in the order GDB expects them */
+struct
+{
+  int r0;
+  int r1;
+  int r2;
+  int r3;
+  int r4;
+  int r5;
+  int r6;
+  int r7;
+  int r8;
+  int r9;
+  int sl;
+  int fp;
+  int ip;
+  int sp;
+  int lr;
+  int pc;
+  unsigned char f[8][12];
+  int fps;
+  int ps;
+}
+__attribute__ ((packed)) user_regs;
+
+#define NUMREGBYTES sizeof(user_regs)
+
+#define flush_i_cache() asm(" mcr p15, 0, r0, c7, c5, 0")
+#define BREAKPOINT()    asm(" .word 0xe7ffdefe")
+
+
+/**********************************************************************/
+/**********************************************************************/
+
+
+/* return the int value of a hex character */
+
+int
+hex (char ch)
+{
+  if ((ch >= 'a') && (ch <= 'f'))
+    return (ch - 'a' + 10);
+  if ((ch >= '0') && (ch <= '9'))
+    return (ch - '0');
+  if ((ch >= 'A') && (ch <= 'F'))
+    return (ch - 'A' + 10);
+  return (-1);
+}
+
+
+/* get a packet */
+
+void
+getpacket (char *buffer)
+{
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int i;
+  int count;
+  char ch;
+
+  if (remote_debug)
+    printk ("getpacket");
+
+  do
+    {
+      /* scan for the sequence $<data>#<checksum> */
+
+      if (remote_debug)
+	printk (":");
+      /* wait around for the start character, ignore all other characters */
+      while ((ch = (getDebugChar () & 0x7f)) != '$');
+      checksum = 0;
+      xmitcsum = -1;
+
+      count = 0;
+
+      /* now, read until a # or end of buffer is found */
+      while (count < BUFMAX)
+	{
+	  ch = getDebugChar () & 0x7f;
+	  if (ch == '#')
+	    break;
+	  checksum = checksum + ch;
+	  buffer[count] = ch;
+	  count = count + 1;
+	}
+      buffer[count] = 0;
+
+      if (ch == '#')
+	{
+	  xmitcsum = hex (getDebugChar () & 0x7f) << 4;
+	  xmitcsum += hex (getDebugChar () & 0x7f);
+#if 0
+	  if (remote_debug && (checksum != xmitcsum))
+	    {
+	      printk ("bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
+		      checksum, xmitcsum, buffer);
+	    }
+#endif
+
+	  if (checksum != xmitcsum)
+	    putDebugChar ('-');	/* failed checksum */
+	  else
+	    {
+	      putDebugChar ('+');	/* successful transfer */
+	      /* if a sequence char is present, reply the sequence ID */
+	      if (buffer[2] == ':')
+		{
+		  putDebugChar (buffer[0]);
+		  putDebugChar (buffer[1]);
+		  /* remove sequence chars from buffer */
+		  count = strlen (buffer);
+		  for (i = 3; i <= count; i++)
+		    buffer[i - 3] = buffer[i];
+		}
+	    }
+	}
+    }
+  while (checksum != xmitcsum);
+
+  if (remote_debug)
+    printk (" $%s#%c%c\n",
+	    buffer, hexchars[checksum >> 4], hexchars[checksum % 16]);
+}
+
+
+/* send a packet */
+
+void
+putpacket (char *buffer)
+{
+  unsigned char checksum;
+  int count;
+  char ch;
+
+  /* $<packet info>#<checksum> */
+  do
+    {
+      putDebugChar ('$');
+      checksum = 0;
+      count = 0;
+
+      while ((ch = buffer[count]))
+	{
+	  putDebugChar (ch);
+	  checksum += ch;
+	  count += 1;
+	}
+
+      putDebugChar ('#');
+      putDebugChar (hexchars[checksum >> 4]);
+      putDebugChar (hexchars[checksum % 16]);
+
+      if (remote_debug)
+	printk ("putpacket: $%s#%c%c\n",
+		buffer, hexchars[checksum >> 4], hexchars[checksum % 16]);
+
+    }
+  while ((getDebugChar () & 0x7f) != '+');
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+static short error;
+
+
+/* Convert the memory pointed to by mem into hex, placing result in
+   buf.  Return a pointer to the last char put in buf (null).  If
+   MAY_FAULT is non-zero, then we should set mem_err in response to a
+   fault; if zero treat a fault like any other fault in the stub.  */
+
+char *
+mem2hex (char *mem, char *buf, int count, int may_fault)
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    check_fault = 1;
+  for (i = 0; i < count; i++)
+    {
+      ch = *mem++;		/* this may cause a fault */
+      if (may_fault && mem_err)
+	return (buf);
+      *buf++ = hexchars[ch >> 4];
+      *buf++ = hexchars[ch % 16];
+    }
+  *buf = 0;
+  if (may_fault)
+    check_fault = 0;
+  return (buf);
+}
+
+
+/* Convert the hex array pointed to by buf into binary to be placed in
+   mem.  Return a pointer to the character AFTER the last byte
+   written.  */
+
+char *
+hex2mem (char *buf, char *mem, int count, int may_fault)
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    check_fault = 1;
+  for (i = 0; i < count; i++)
+    {
+      ch = hex (*buf++) << 4;
+      ch = ch + hex (*buf++);
+      *mem++ = ch;		/* this may cause a fault */
+      if (may_fault && mem_err)
+	return (mem);
+    }
+  if (may_fault)
+    check_fault = 0;
+  return (mem);
+}
+
+
+/* convert an ascii hex representation to an int */
+
+int
+hexToInt (char **ptr, int *intValue)
+{
+  int numChars = 0;
+  int hexValue;
+
+  *intValue = 0;
+
+  while (**ptr)
+    {
+      hexValue = hex (**ptr);
+      if (hexValue >= 0)
+	{
+	  *intValue = (*intValue << 4) | hexValue;
+	  numChars++;
+	}
+      else
+	break;
+
+      (*ptr)++;
+    }
+
+  return (numChars);
+}
+
+
+/* Functions to tweak the SPSR. */
+
+static inline int
+get_psr (void)
+{
+  int psr;
+  asm volatile ("mrs %0, cpsr"
+		: "=r" (psr)
+		: /* no inputs */ );
+  return psr;
+}
+
+static inline void
+set_psr (int psr)
+{
+  asm volatile ("msr cpsr, %0"
+		: /* no outputs */
+		: "r" (psr));
+}
+
+
+/* This function does all command processing for interfacing to gdb. */
+
+void
+handle_exception (int sigval, struct pt_regs *regs)
+{
+  static int in_gdb = 0;
+  int addr, length;
+  unsigned long psr;
+  char *ptr;
+
+  if (remote_debug)
+    printk ("handle_exception(%d)\n", sigval);
+
+  if (check_fault)
+    {
+      /* We must have tried to set or get a memory location that
+         triggered a fault.  Set the error flag, increment the PC past
+         the bad instruction, and return to the stub. */
+
+      mem_err = 1;
+
+      /* Speaking of incrementing the PC here, I'm not quite sure why
+         I should have to do it, since the processor is supposed to
+         set the R14_svc to the bad instruction + 4.  I guess there's
+         something going on here which I haven't tracked down yet.
+
+         For example, if I examine a memory location which isn't
+         mapped by the MMU, a data access exception is raised and this
+         function gets called.  The PC is at the instruction which is
+         trying to dereference the memory location.  I expect that
+         there's some other code somewhere which munges the PC before
+         we see it, because in most cases you'll want to get the
+         fault, swap in the memory, and try again, no?  */
+
+      regs->ARM_pc += 4;
+      return;
+    }
+
+  if (in_gdb++)
+    {
+      printk ("handle_exception called recursively -- returning...\n");
+      return;
+    }
+
+  /* By default, the processor will increment the PC by 4 when an
+     exception occurs.  Most of the time we don't want that, since we
+     want the PC to point to the location of the breakpoint (or we'll
+     confuse GDB). */
+  regs->ARM_pc -= 4;
+
+  if (remote_debug)
+    show_regs (regs);
+
+  /* disable interrupts */
+  psr = get_psr ();
+  set_psr (psr | I_BIT | F_BIT);
+
+  if (remote_debug)
+    printk ("psr before=%08lx after=%08lx\n", psr, psr | I_BIT | F_BIT);
+
+  /* Copy the stuff in REGS to USER_REGS (that is, the registers
+     stored in the order in which GDB expects for the 'g' command).
+     (In supervisor mode we don't care about floating point registers
+     since the kernel doesn't use floating point math.  We're skipping
+     those registers, therefore.) */
+
+  user_regs.r0 = (int) regs->ARM_r0;
+  user_regs.r1 = (int) regs->ARM_r1;
+  user_regs.r2 = (int) regs->ARM_r2;
+  user_regs.r3 = (int) regs->ARM_r3;
+  user_regs.r4 = (int) regs->ARM_r4;
+  user_regs.r5 = (int) regs->ARM_r5;
+  user_regs.r6 = (int) regs->ARM_r6;
+  user_regs.r7 = (int) regs->ARM_r7;
+  user_regs.r8 = (int) regs->ARM_r8;
+  user_regs.r9 = (int) regs->ARM_r9;
+  user_regs.sl = (int) regs->ARM_r10;
+  user_regs.fp = (int) regs->ARM_fp;
+  user_regs.ip = (int) regs->ARM_ip;
+  user_regs.sp = (int) regs->ARM_sp;
+  user_regs.lr = (int) regs->ARM_lr;
+  user_regs.pc = (int) regs->ARM_pc;
+  user_regs.ps = (int) regs->ARM_cpsr;
+
+  /* reply to host that an exception has occurred */
+#if 0
+  /* old style */
+  remcomOutBuffer[0] = 'S';
+  remcomOutBuffer[1] = hexchars[sigval >> 4];
+  remcomOutBuffer[2] = hexchars[sigval % 16];
+  remcomOutBuffer[3] = 0;
+  putpacket (remcomOutBuffer);
+#else
+  /* new style -- faster because GDB doesn't have to ask for
+     additional registers when stepping */
+  ptr = remcomOutBuffer;
+
+  /* Send trap type (converted to signal) */
+  *ptr++ = 'T';
+  *ptr++ = hexchars[sigval >> 4];
+  *ptr++ = hexchars[sigval & 0xf];
+
+  /* order of registers sent to GDB... */
+#define GDBREG_FP (11)
+#define GDBREG_IP (12)
+#define GDBREG_SP (13)
+#define GDBREG_LR (14)
+#define GDBREG_PC (15)
+#define GDBREG_PS (25)
+
+  /* PC */
+  *ptr++ = hexchars[GDBREG_PC >> 4];
+  *ptr++ = hexchars[GDBREG_PC & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((char *) &user_regs.pc, ptr, 4, 0);
+  *ptr++ = ';';
+
+  /* FP */
+  *ptr++ = hexchars[GDBREG_FP >> 4];
+  *ptr++ = hexchars[GDBREG_FP & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((char *) &user_regs.fp, ptr, 4, 0);
+  *ptr++ = ';';
+
+  /* SP */
+  *ptr++ = hexchars[GDBREG_SP >> 4];
+  *ptr++ = hexchars[GDBREG_SP & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((char *) &user_regs.sp, ptr, 4, 0);
+  *ptr++ = ';';
+
+  /* PS */
+  *ptr++ = hexchars[GDBREG_PS >> 4];
+  *ptr++ = hexchars[GDBREG_PS & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((char *) &user_regs.ps, ptr, 4, 0);
+  *ptr++ = ';';
+
+  *ptr++ = 0;
+
+  putpacket (remcomOutBuffer);	/* send it off... */
+#endif
+
+  while (1)
+    {
+      error = 0;
+      remcomOutBuffer[0] = 0;
+      getpacket (remcomInBuffer);
+
+      switch (remcomInBuffer[0])
+	{
+	case '?':
+	  /* print last signal */
+	  remcomOutBuffer[0] = 'S';
+	  remcomOutBuffer[1] = hexchars[sigval >> 4];
+	  remcomOutBuffer[2] = hexchars[sigval % 16];
+	  remcomOutBuffer[3] = 0;
+	  break;
+
+	case 'd':
+	  /* toggle debug */
+	  remote_debug = !(remote_debug);
+	  break;
+
+	case 'g':
+	  /* read registers */
+	  mem2hex ((char *) &user_regs, remcomOutBuffer, NUMREGBYTES, 0);
+	  break;
+
+	case 'G':
+	  /* set registers */
+	  hex2mem (&remcomInBuffer[1], (char *) &user_regs, NUMREGBYTES, 0);
+
+	  regs->ARM_r0 = (unsigned long) user_regs.r0;
+	  regs->ARM_r1 = (unsigned long) user_regs.r1;
+	  regs->ARM_r2 = (unsigned long) user_regs.r2;
+	  regs->ARM_r3 = (unsigned long) user_regs.r3;
+	  regs->ARM_r4 = (unsigned long) user_regs.r4;
+	  regs->ARM_r5 = (unsigned long) user_regs.r5;
+	  regs->ARM_r6 = (unsigned long) user_regs.r6;
+	  regs->ARM_r7 = (unsigned long) user_regs.r7;
+	  regs->ARM_r8 = (unsigned long) user_regs.r8;
+	  regs->ARM_r9 = (unsigned long) user_regs.r9;
+	  regs->ARM_r10 = (unsigned long) user_regs.sl;
+	  regs->ARM_fp = (unsigned long) user_regs.fp;
+	  regs->ARM_ip = (unsigned long) user_regs.ip;
+	  regs->ARM_sp = (unsigned long) user_regs.sp;
+	  regs->ARM_lr = (unsigned long) user_regs.lr;
+	  regs->ARM_pc = (unsigned long) user_regs.pc;
+	  regs->ARM_cpsr = (unsigned long) user_regs.ps;
+
+	  strcpy (remcomOutBuffer, "OK");
+	  break;
+
+	case 'm':
+	  /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+	  /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
+	  ptr = &remcomInBuffer[1];
+	  if (hexToInt (&ptr, &addr))
+	    if (*(ptr++) == ',')
+	      if (hexToInt (&ptr, &length))
+		{
+		  ptr = 0;
+		  mem_err = 0;
+		  mem2hex ((char *) addr, remcomOutBuffer, length, 1);
+		  if (mem_err)
+		    {
+		      strcpy (remcomOutBuffer, "E03");
+		      if (remote_debug)
+			printk ("memory fault");
+		    }
+		}
+
+	  if (ptr)
+	    {
+	      strcpy (remcomOutBuffer, "E01");
+	      if (remote_debug)
+		printk ("malformed read memory command: %s", remcomInBuffer);
+	    }
+	  break;
+
+	case 'M':
+	  /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+	  /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
+	  ptr = &remcomInBuffer[1];
+	  if (hexToInt (&ptr, &addr))
+	    if (*(ptr++) == ',')
+	      if (hexToInt (&ptr, &length))
+		if (*(ptr++) == ':')
+		  {
+		    mem_err = 0;
+		    hex2mem (ptr, (char *) addr, length, 1);
+
+		    if (mem_err)
+		      {
+			strcpy (remcomOutBuffer, "E03");
+			if (remote_debug)
+			  printk ("memory fault");
+		      }
+		    else
+		      {
+			strcpy (remcomOutBuffer, "OK");
+		      }
+
+		    ptr = 0;
+		  }
+	  if (ptr)
+	    {
+	      strcpy (remcomOutBuffer, "E02");
+	      if (remote_debug)
+		printk ("malformed write memory command: %s", remcomInBuffer);
+	    }
+	  break;
+
+	case 'k':		/* 'kill' just makes the program continue */
+	case 'c':
+	  /* cAA..AA    Continue from address AA..AA(optional) */
+	  /* try to read optional parameter, pc unchanged if no parm */
+	  ptr = &remcomInBuffer[1];
+	  if (hexToInt (&ptr, &addr))
+	    user_regs.pc = addr;
+
+	  /* Need to flush the instruction cache here, as we may
+	     have deposited a breakpoint, and the icache probably
+	     has no way of knowing that a data ref to some location
+	     may have changed something that is in the instruction
+	     cache.  */
+	  asm (" mcr p15, 0, r0, c7, c5, 0");
+
+	  /* re-enable interrupts (possibly) */
+	  set_psr (psr);
+
+	  in_gdb--;
+	  return;
+	  break;
+
+	default:
+	  /* all other commands are unrecognized and return an empty
+	     packet as per the protocol */
+	  break;
+
+	}			/* switch */
+
+      /* reply to the request */
+      putpacket (remcomOutBuffer);
+    }
+}
+
+
+/* This function is used to set up exception handlers for tracing and
+   breakpoints.  In this version of the stub, there's not much here,
+   since alternate code has been compiled in when the CONFIG_KGDB
+   symbol is defined.  */
+
+void
+set_debug_traps (void)
+{
+  if (initialized)
+    return;
+
+  /* In case GDB is started before us, ack any packets (presumably
+     "$?#xx") sitting there.  */
+  putDebugChar ('+');
+
+  initialized = 1;
+}
+
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+
+void
+breakpoint (void)
+{
+  if (initialized)
+    BREAKPOINT ();
+}
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/kernel/entry-armv.S linux-cb26/arch/arm/kernel/entry-armv.S
--- linux-cb26.orig/arch/arm/kernel/entry-armv.S	Mon Aug  7 15:28:10 2000
+++ linux-cb26/arch/arm/kernel/entry-armv.S	Mon Aug 28 19:02:03 2000
@@ -506,8 +506,12 @@
 		add	r4, sp, #S_SP
 		stmia	r4, {r5 - r9}			@ save sp_SVC, lr_SVC, pc, cpsr, old_ro
 
+/* I don't believe that the kernel can use the floating point emulator. */
+#if 0
 		adrsvc	al, r9, 1f			@ r9  = normal FP return
+/* expands to:	adral   r9, 1f */
 		bl	call_fpe			@ lr  = undefined instr return
+#endif
 
 		mov	r0, r5				@ unsigned long pc
 		mov	r1, sp				@ struct pt_regs *regs
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/kernel/process.c linux-cb26/arch/arm/kernel/process.c
--- linux-cb26.orig/arch/arm/kernel/process.c	Mon Aug  7 15:27:52 2000
+++ linux-cb26/arch/arm/kernel/process.c	Sat Aug 19 00:37:14 2000
@@ -102,21 +102,16 @@
 
 	flags = condition_codes(regs);
 
-	printk( "pc : [<%08lx>]    lr : [<%08lx>]\n"
-		"sp : %08lx  ip : %08lx  fp : %08lx\n",
-		instruction_pointer(regs),
-		regs->ARM_lr, regs->ARM_sp,
-		regs->ARM_ip, regs->ARM_fp);
-	printk( "r10: %08lx  r9 : %08lx  r8 : %08lx\n",
-		regs->ARM_r10, regs->ARM_r9,
-		regs->ARM_r8);
-	printk( "r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
-		regs->ARM_r7, regs->ARM_r6,
+	printk( "pc:%08lx lr:%08lx sp:%08lx ip:%08lx fp:%08lx r10:%08lx\n",
+		instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp,
+		regs->ARM_ip, regs->ARM_fp, regs->ARM_r10);
+	printk( "r9:%08lx r8:%08lx r7:%08lx r6:%08lx r5:%08lx r4:%08lx\n",
+		regs->ARM_r9, regs->ARM_r8, regs->ARM_r7, regs->ARM_r6,
 		regs->ARM_r5, regs->ARM_r4);
-	printk( "r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
-		regs->ARM_r3, regs->ARM_r2,
-		regs->ARM_r1, regs->ARM_r0);
-	printk("Flags: %c%c%c%c",
+	printk( "r3:%08lx r2:%08lx r1:%08lx r0:%08lx\n",
+		regs->ARM_r3, regs->ARM_r2, regs->ARM_r1,
+		regs->ARM_r0);
+	printk("Flags %c%c%c%c",
 		flags & CC_N_BIT ? 'N' : 'n',
 		flags & CC_Z_BIT ? 'Z' : 'z',
 		flags & CC_C_BIT ? 'C' : 'c',
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/kernel/traps.c linux-cb26/arch/arm/kernel/traps.c
--- linux-cb26.orig/arch/arm/kernel/traps.c	Mon Aug  7 15:27:52 2000
+++ linux-cb26/arch/arm/kernel/traps.c	Mon Aug 28 17:13:26 2000
@@ -24,6 +24,10 @@
 #include <asm/atomic.h>
 #include <asm/pgtable.h>
 
+#ifdef CONFIG_KGDB
+extern void handle_exception(int sigval, struct pt_regs *regs);
+#endif
+
 extern void die_if_kernel(char *str, struct pt_regs *regs, int err, int ret);
 extern void c_backtrace (unsigned long fp, int pmode);
 extern int ptrace_cancel_bpt (struct task_struct *);
@@ -193,7 +197,11 @@
 		do_exit (ret);
 	else {
 		cli ();
+#ifdef CONFIG_KGDB
+		handle_exception (err, regs);
+#else
 		while (1);
+#endif
 	}
 }
 
@@ -209,6 +217,15 @@
 
 asmlinkage void do_undefinstr (int address, struct pt_regs *regs, int mode)
 {
+#ifdef CONFIG_KGDB
+  /* If we're here in supervisor mode, we've hit a breakpoint --
+     invoke the debugging stub */
+  if (! user_mode (regs))
+    {
+      handle_exception (SIGTRAP, regs);
+      return;
+    }
+#endif
 #ifdef CONFIG_DEBUG_USER
 	printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
 		current->comm, current->pid, instruction_pointer(regs));
@@ -225,6 +242,13 @@
 	printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
 		current->comm, current->pid, instruction_pointer(regs));
 #endif
+#ifdef CONFIG_KGDB
+	if (! user_mode (regs))
+	  {
+	    printk ("do_excpt ()\n");
+	    handle_exception (SIGBUS, regs);
+	  }
+#endif
 	current->tss.error_code = 0;
 	current->tss.trap_no = 11;
 	force_sig (SIGBUS, current);
@@ -244,6 +268,13 @@
 	printk (KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
 		handler[reason],
 		processor_modes[proc_mode]);
+#ifdef CONFIG_KGDB
+	if (! user_mode (regs))
+	  {
+	    printk ("bad_mode ()\n");
+	    handle_exception (-1, regs);
+	  }
+#endif
 	die_if_kernel ("Oops", regs, 0, -1);
 }
 
@@ -263,6 +294,13 @@
 {
 	switch (no) {
 	case 0: /* branch through 0 */
+#ifdef CONFIG_KGDB
+	       if (! user_mode (regs))
+		 {
+		   printk ("arm_syscall (0)\n");
+		   handle_exception (-1, regs);
+		 }
+#endif
 		force_sig(SIGSEGV, current);
 		die_if_kernel ("branch through zero", regs, 0, SIGSEGV);
 		break;
@@ -299,6 +337,13 @@
 			c_backtrace (regs->ARM_fp, processor_mode(regs));
 		}
 #endif
+#ifdef CONFIG_KGDB
+	       if (! user_mode (regs))
+		 {
+		   printk ("arm_syscall (%d)\n", no);
+		   handle_exception (SIGILL, regs);
+		 }
+#endif
 		force_sig (SIGILL, current);
 		die_if_kernel ("Oops", regs, no, SIGILL);
 		break;
@@ -308,6 +353,15 @@
 
 asmlinkage void deferred(int n, struct pt_regs *regs)
 {
+#ifdef CONFIG_KGDB
+  if (! user_mode (regs))
+    {
+      printk ("deferred (%d)\n", n);
+      handle_exception (SIGSTOP, regs);
+    }
+  else
+#endif
+    {
 	/* You might think just testing `handler' would be enough, but PER_LINUX
 	   points it to no_lcall7 to catch undercover SVr4 binaries.  Gutted. */
 	if (current->personality != PER_LINUX && current->exec_domain->handler) {
@@ -322,6 +376,7 @@
 	       current->comm);
 #endif
 	force_sig (SIGILL, current);
+    }
 }
 
 asmlinkage void arm_malalignedptr(const char *str, void *pc, volatile void *ptr)
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/mm/fault-common.c linux-cb26/arch/arm/mm/fault-common.c
--- linux-cb26.orig/arch/arm/mm/fault-common.c	Mon Aug  7 15:28:03 2000
+++ linux-cb26/arch/arm/mm/fault-common.c	Mon Aug 28 17:14:08 2000
@@ -131,6 +131,10 @@
 	}
 
 no_context:
+#ifdef CONFIG_KGDB
+	handle_exception (SIGSEGV, regs);
+	up(&mm->mmap_sem);
+#else
 	/* Are we prepared to handle this kernel fault?  */
 	if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
 #ifdef DEBUG
@@ -142,6 +146,7 @@
 	}
 
 	kernel_page_fault(addr, mode, regs, tsk, mm);
+#endif
 	return;
 
 do_sigbus:
diff -rbuN -X exclude-list linux-cb26.orig/arch/arm/nwfpe/fpa11_cprt.c linux-cb26/arch/arm/nwfpe/fpa11_cprt.c
--- linux-cb26.orig/arch/arm/nwfpe/fpa11_cprt.c	Mon Aug  7 15:27:52 2000
+++ linux-cb26/arch/arm/nwfpe/fpa11_cprt.c	Thu Aug 17 14:34:22 2000
@@ -72,7 +72,7 @@
     case  WFC_CODE >> 20:
     {
        int mode = 0;
-       __asm__ volatile ("mrs %0, cpsr; and %0, %0, #0x1f;" : : "g" (mode));
+       __asm__ volatile ("mrs %0, cpsr; and %0, %0, #0x1f;" : : "r" (mode));
        nRc = (0x13 == mode) ? 1 : 0;	/* in SVC processor mode? */
        if (nRc) writeFPCR(readRegister(getRd(opcode)));
     }
@@ -81,7 +81,7 @@
     case  RFC_CODE >> 20:
     {
        int mode = 0;
-       __asm__ volatile ("mrs %0, cpsr; and %0, %0, #0x1f;" : : "g" (mode));
+       __asm__ volatile ("mrs %0, cpsr; and %0, %0, #0x1f;" : : "r" (mode));
        nRc = (0x13 == mode) ? 1 : 0;	/* in SVC processor mode? */
        if (nRc) writeRegister(getRd(opcode),readFPCR()); break;
     }
diff -rbuN -X exclude-list linux-cb26.orig/drivers/char/serial_7110.c linux-cb26/drivers/char/serial_7110.c
--- linux-cb26.orig/drivers/char/serial_7110.c	Mon Aug  7 15:28:10 2000
+++ linux-cb26/drivers/char/serial_7110.c	Mon Aug 28 19:12:57 2000
@@ -370,9 +370,52 @@
 		printk(KERN_ERR "Couldn't register CL-PS7110 serial driver\n");
 		return -1;
 	}
+
+#ifdef CONFIG_KGDB
+	/* @@NJC */
+	set_debug_traps ();
+	printk ("connect GDB now...\n");
+	breakpoint ();
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_KGDB
+int putDebugChar (char c)
+{
+#if 0
+  printk ("put ");
+#endif
+  udelay (5);
+  disable_irq(IRQ_UTXINT);
+  while(IO_SYSFLG & UTXFF)
+    ;
+  IO_UARTDR=c;
+  enable_irq(IRQ_UTXINT);
+#if 0
+  printk ("`%c'     (%d)\n", c, (int) c);
+#endif
 	return 0;
 }
 
+int getDebugChar (void)
+{
+  int c;
+#if 0
+  printk ("get ");
+#endif
+  disable_irq(IRQ_URXINT);
+  while(IO_SYSFLG & URXFE)
+    pm_change(&rs_pm_dev,1);
+  c=IO_UARTDR;
+  enable_irq(IRQ_URXINT);
+#if 0
+  printk ("    `%c' (%d)\n", (char) c, (c & (int) 0xFF));
+#endif
+  return c;
+}
+#endif
+
 #ifdef CONFIG_SERIAL_7110_CONSOLE
 /************** console driver *****************/
 
diff -rbuN -X exclude-list linux-cb26.orig/gdbconfig linux-cb26/gdbconfig
--- linux-cb26.orig/gdbconfig	Wed Dec 31 16:00:00 1969
+++ linux-cb26/gdbconfig	Mon Aug 28 19:22:26 2000
@@ -0,0 +1,333 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+
+#
+# System and processor type
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_FOOTBRIDGE is not set
+CONFIG_ARCH_CLPS7110=y
+CONFIG_ARCH_PSION=y
+# CONFIG_ARCH_GEOFOX is not set
+CONFIG_CPU_ARM7=y
+CONFIG_KERNEL_PCMCIA=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ALIGNMENT_TRAP is not set
+# CONFIG_TEXT_SECTIONS is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SMART_SLOCK=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_STALDRV is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_ESPSERIAL is not set
+CONFIG_SERIAL_7110=y
+CONFIG_SERIAL_7110_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_AUDIO_7110=y
+CONFIG_PSION_KBD_US=y
+CONFIG_TOUCH_PSION=y
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_CLPS7110=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+CONFIG_FBCON_MFB=y
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
+# CONFIG_FBCON_CFB16 is not set
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_NET_ALIAS is not set
+# CONFIG_FILTER is not set
+# CONFIG_UNIX is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_INET_RARP is not set
+# CONFIG_IP_NOSR is not set
+# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+# CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA subsystem support
+#
+# CONFIG_IRDA is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_DLCI is not set
+CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+# CONFIG_RCPCI is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+
+#
+# Kernel hacking
+#
+CONFIG_KGDB=y
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_ARTHUR is not set
