diff --git a/.gdbinit.tmpl b/.gdbinit.tmpl
index 4c4e7349921458b3d35028257a71c0ed4ae41ef7..f71681a10a796325b7b6278959ef00a3f64bcfe4 100644
--- a/.gdbinit.tmpl
+++ b/.gdbinit.tmpl
@@ -1,9 +1,5 @@
 set $lastcs = -1
 
-# This fails on Darwin because the default gdb has no ELF support
-# echo + symbol-file obj/kern/kernel\n
-# symbol-file obj/kern/kernel
-
 define hook-stop
   # There doesn't seem to be a good way to detect if we're in 16- or
   # 32-bit mode, but in 32-bit mode we always run with CS == 8 in the
@@ -26,3 +22,6 @@ end
 
 echo + target remote localhost:1234\n
 target remote localhost:1234
+
+echo + symbol-file kernel\n
+symbol-file kernel
diff --git a/Makefile b/Makefile
index 1e73ee1c0e79a7c7aece0f8b7c9f17b29c6bf7bc..24ba05e67edcd79932686fcb980672e924d4c9e4 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ OBJCOPY = $(TOOLPREFIX)objcopy
 OBJDUMP = $(TOOLPREFIX)objdump
 CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32
 CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
-ASFLAGS = -m32
+ASFLAGS = -m32 -gdwarf-2
 # FreeBSD ld wants ``elf_i386_fbsd''
 LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null)
 
@@ -143,9 +143,9 @@ GDBPORT = $(shell expr `id -u` % 5000 + 25000)
 QEMUOPTS = -smp 2 -hdb fs.img xv6.img
 
 qemu: fs.img xv6.img
-	qemu -parallel mon:stdio $(QEMUOPTS)
+	qemu -serial mon:stdio $(QEMUOPTS)
 
-qemutty: fs.img xv6.img
+qemu-nox: fs.img xv6.img
 	qemu -nographic $(QEMUOPTS)
 
 .gdbinit: .gdbinit.tmpl
@@ -153,7 +153,11 @@ qemutty: fs.img xv6.img
 
 qemu-gdb: fs.img xv6.img .gdbinit
 	@echo "*** Now run 'gdb'." 1>&2
-	qemu -parallel mon:stdio $(QEMUOPTS) -s -S -p $(GDBPORT)
+	qemu -serial mon:stdio $(QEMUOPTS) -s -S -p $(GDBPORT)
+
+qemu-gdb-nox: fs.img xv6.img .gdbinit
+	@echo "*** Now run 'gdb'." 1>&2
+	qemu -nographic $(QEMUOPTS) -s -S -p $(GDBPORT)
 
 # CUT HERE
 # prepare dist for students
diff --git a/console.c b/console.c
index 0613a471d7abb5acc61f71ad4e7509ead44b4ad1..16d0e7a1b0e0c8dad1afa9bddd9847e64d08a8e0 100644
--- a/console.c
+++ b/console.c
@@ -163,7 +163,12 @@ consputc(int c)
       ;
   }
 
-  uartputc(c);
+  if (c == BACKSPACE) {
+    uartputc('\b');
+    uartputc(' ');
+    uartputc('\b');
+  } else
+    uartputc(c);
   cgaputc(c);
 }
 
@@ -198,6 +203,7 @@ consoleintr(int (*getc)(void))
       }
       break;
     case C('H'):  // Backspace
+    case '\x7f':
       if(input.e != input.w){
         input.e--;
         consputc(BACKSPACE);
@@ -205,6 +211,9 @@ consoleintr(int (*getc)(void))
       break;
     default:
       if(c != 0 && input.e-input.r < INPUT_BUF){
+        // The serial port produces 0x13, not 0x10
+        if(c == '\r')
+          c = '\n';
         input.buf[input.e++ % INPUT_BUF] = c;
         consputc(c);
         if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){
diff --git a/string.c b/string.c
index cb890eebf08db9a604e5f58cadebdd5553584970..a557dc5dee5bc6aa04135c5501f6119a59d75609 100644
--- a/string.c
+++ b/string.c
@@ -44,6 +44,13 @@ memmove(void *dst, const void *src, uint n)
   return dst;
 }
 
+// memcpy exists to placate GCC.  Use memmove.
+void*
+memcpy(void *dst, const void *src, uint n)
+{
+  return memmove(dst, src, n);
+}
+
 int
 strncmp(const char *p, const char *q, uint n)
 {