got the bootloader->main handoff working
diff --git a/bbb_cape/src/cape/Makefile b/bbb_cape/src/cape/Makefile
index 5046615..d74e700 100644
--- a/bbb_cape/src/cape/Makefile
+++ b/bbb_cape/src/cape/Makefile
@@ -45,6 +45,7 @@
 OBJECTS_bootloader := bootloader \
 	uart_common \
 	uart_byte \
+	led \
 
 OBJECTS_main_test := $(OBJECTS_main_common) \
 	robot_test \
diff --git a/bbb_cape/src/cape/analog.c b/bbb_cape/src/cape/analog.c
index 0ccd2f0..58a1563 100644
--- a/bbb_cape/src/cape/analog.c
+++ b/bbb_cape/src/cape/analog.c
@@ -28,7 +28,7 @@
   // (100ns+8ns)*120MHz = 12.96
 
   // Clear the CSEL pin to select it.
-  for (int i = 0; i < 9; ++i) CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
+  for (int i = 0; i < 9; ++i) CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
   current_channel = channel;
   uint16_t data = 1 << 8 /* start bit */ |
       0 << 7 /* not differential */ |
@@ -43,7 +43,7 @@
     // Masking off the high bits is important because there's nothing driving
     // the MISO line during the time the MCU receives them.
     analog_readings[current_channel] = value & 0x3FF;
-    CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
+    CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
 
     TIM->CR1 = TIM_CR1_UDIS;
     TIM->CCR1 = 1;
@@ -66,7 +66,7 @@
   RCC->APB1ENR |= RCC_APB1ENR_TIMEN;
 
   gpio_setup_out(CSEL_GPIO, CSEL_NUM, 3);
-  CSEL_GPIO->BSRRL = 1 << CSEL_NUM;  // make sure it's deselected
+  CSEL_GPIO->BSRRH = 1 << CSEL_NUM;  // make sure it's deselected
 
   gpio_setup_alt(GPIOB, 13, 5);  // SCK
   gpio_setup_alt(GPIOB, 14, 5);  // MISO
diff --git a/bbb_cape/src/cape/bootloader.c b/bbb_cape/src/cape/bootloader.c
index 1ed6218..3ff86af 100644
--- a/bbb_cape/src/cape/bootloader.c
+++ b/bbb_cape/src/cape/bootloader.c
@@ -3,6 +3,7 @@
 #include <STM32F2XX.h>
 
 #include "cape/bootloader_handoff.h"
+#include "cape/led.h"
 
 // Sets everything up and then jumps to the main code.
 static void jump_to_main(void) __attribute__((noreturn));
@@ -15,12 +16,58 @@
   __builtin_unreachable();
 }
 
-void _start(void) {
-  SYSCFG->CMPCR = SYSCFG_CMPCR_CMP_PD;  // enable IO compensation cell
-  while (!(SYSCFG->CMPCR & SYSCFG_CMPCR_READY)) {}  // wait for it to be ready
+static void setup_main_clock(void) {
+  // We set up a couple of registers here separately from the actual register to
+  // avoid having to think about what happens when the value is in some
+  // intermediate state.
 
+  RCC->CR |= RCC_CR_HSEON;  // get the HSE oscillator going
+
+  FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN |
+               FLASH_ACR_LATENCY_3WS;
+
+  uint32_t rcc_pllcfgr = 0;
+  rcc_pllcfgr |= RCC_PLLCFGR_PLLSRC;  // use the external oscillator
+  // 8MHz * 120 / 4 / 2 = 120MHz
+  rcc_pllcfgr |= 120 << 6;  // multiplier
+  rcc_pllcfgr |= 4;  // divider
+  rcc_pllcfgr |= 5 << 24;  // other stuff divider = 5, just in case
+  RCC->PLLCFGR = rcc_pllcfgr;
+
+  uint32_t rcc_cfgr = 0;
+  rcc_cfgr |= 4 << 13;  // APB2 divider = 2
+  rcc_cfgr |= 5 << 10;  // APB1 divider = 4
+  rcc_cfgr |= 2;  // use the PLL
+
+  // Wait for the HSE oscillator to be stable.
+  while (!(RCC->CR & RCC_CR_HSERDY)) {}
+
+  RCC->CR |= RCC_CR_PLLON;
+  // Wait for the main PLL to be stable.
+  while (!(RCC->CR & RCC_CR_PLLRDY)) {}
+  // Wait until the flash is using 3 wait states.
+  while ((FLASH->ACR & 7) != 3) {}
+  RCC->CFGR = rcc_cfgr;
+  // Wait until we are using the PLL as our main clock source.
+  while ((RCC->CFGR & (3 << 2)) != (2 << 2)) {}
+}
+
+void _start(void) {
+  // Enable the GPIO pin clocks.
   // We don't have anything on the 1 port D pin, so don't bother enabling it.
-  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
+  RCC->AHB1ENR |=
+      RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
+  led_init();
+  led_set(LED_ERR, 1);
+
+  setup_main_clock();
+
+#if 0
+  SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD;  // enable IO compensation cell
+  while (!(SYSCFG->CMPCR & SYSCFG_CMPCR_READY)) {}  // wait for it to be ready
+  TODO(brians): Figure out what the story with this is.
+#endif
+  led_set(LED_DB, 1);
 
   jump_to_main();
 }
diff --git a/bbb_cape/src/cape/bootloader.ld b/bbb_cape/src/cape/bootloader.ld
index 21aaa00..6751529 100644
--- a/bbb_cape/src/cape/bootloader.ld
+++ b/bbb_cape/src/cape/bootloader.ld
@@ -1,7 +1,7 @@
 MEMORY
 {
-  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x08000   /*  32k */
-  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 0x20000   /* 128k */
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16k
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 128k
 }
 
 SECTIONS
diff --git a/bbb_cape/src/cape/bootloader_handoff.h b/bbb_cape/src/cape/bootloader_handoff.h
index d0fcde8..1e48e90 100644
--- a/bbb_cape/src/cape/bootloader_handoff.h
+++ b/bbb_cape/src/cape/bootloader_handoff.h
@@ -5,7 +5,7 @@
 // the bootloader and the main code.
 
 // How much flash the bootloader has (starting at address 0).
-#define BOOTLOADER_FLASH_SIZE 0x8000
+#define BOOTLOADER_FLASH_SIZE 0x4000
 // Where the main code's flash starts.
 #define MAIN_FLASH_START BOOTLOADER_FLASH_SIZE
 
diff --git a/bbb_cape/src/cape/fill_packet.c b/bbb_cape/src/cape/fill_packet.c
index 700df1d..ad7396e 100644
--- a/bbb_cape/src/cape/fill_packet.c
+++ b/bbb_cape/src/cape/fill_packet.c
@@ -11,7 +11,6 @@
 #include "cape/crc.h"
 #include "cape/bootloader_handoff.h"
 #include "cape/gyro.h"
-#include "cape/led.h"
 #include "cape/analog.h"
 #include "cape/robot.h"
 #include "cape/digital.h"
@@ -73,7 +72,6 @@
   TIMESTAMP_TIM->CR1 |= TIM_CR1_CEN;
 
   crc_init();
-  led_init();
   analog_init();
   encoder_init();
   gyro_init();
diff --git a/bbb_cape/src/cape/gyro.c b/bbb_cape/src/cape/gyro.c
index 80accb9..43006fd 100644
--- a/bbb_cape/src/cape/gyro.c
+++ b/bbb_cape/src/cape/gyro.c
@@ -97,7 +97,7 @@
   // Do it 8 times (9 cycles) to wait for the amount of time the gyro datasheet
   // says we need to.
   // (1/2/(7.5MHz)+8ns)*120MHz = 8.96
-  for (int i = 0; i < 8; ++i) CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
+  for (int i = 0; i < 8; ++i) CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
 }
 
 // Blocks until there is space to enqueue data.
@@ -265,7 +265,7 @@
       uint32_t full_value = high_value << 16 | value;
       // Set the CSEL pin high to deselect it.
       // The parity calculation etc took long enough that this is safe now.
-      CSEL_GPIO->BSRRL = 1 << CSEL_NUM;
+      CSEL_GPIO->BSRRH = 1 << CSEL_NUM;
       reading_received(full_value);
     }
   }
@@ -364,7 +364,7 @@
   // It's is just a GPIO pin because we're the master (it would be special if we
   // were a slave).
   gpio_setup_out(CSEL_GPIO, CSEL_NUM, 3);
-  CSEL_GPIO->BSRRL = 1 << CSEL_NUM;  // make sure it's deselected
+  CSEL_GPIO->BSRRH = 1 << CSEL_NUM;  // make sure it's deselected
 
   // Set up SCK, MISO, and MOSI.
   gpio_setup_alt(GPIOC, 10, 6);  // SCK
diff --git a/bbb_cape/src/cape/led.c b/bbb_cape/src/cape/led.c
index 1968f96..97d5a06 100644
--- a/bbb_cape/src/cape/led.c
+++ b/bbb_cape/src/cape/led.c
@@ -13,9 +13,9 @@
 
 static void do_led_set(GPIO_TypeDef *port, int number, int on) {
   if (on) {
-    port->BSRRL = 1 << number;
-  } else {
     port->BSRRH = 1 << number;
+  } else {
+    port->BSRRL = 1 << number;
   }
 }
 
diff --git a/bbb_cape/src/cape/main.c b/bbb_cape/src/cape/main.c
index 411a734..be97171 100644
--- a/bbb_cape/src/cape/main.c
+++ b/bbb_cape/src/cape/main.c
@@ -1,6 +1,7 @@
 #include <STM32F2XX.h>
 
 #include "cape/fill_packet.h"
+#include "cape/led.h"
 
 // The startup asm code defines this to the start of our exception vector table.
 extern uint32_t _vectors;
@@ -11,6 +12,7 @@
   SCB->VTOR = (uint32_t)&_vectors;
   // Data Memory Barrier to make sure it gets the updated vector table.
   __asm__ __volatile__("dmb");
+  led_set(LED_DB, 0);
 
   fill_packet_start();
 
@@ -18,6 +20,9 @@
   // decreses ISR latency a little bit because it doesn't have to stack the
   // registers for the first one.
   SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
+
+  led_set(LED_ERR, 0);
+
   // This seems like the perfect place to use WFI, but Brian on 2013-12-13
   // couldn't find anything verifying that WFI doesn't increase the latency for
   // the first interrupt handled, and we should never actually get here anyways,
diff --git a/bbb_cape/src/cape/main.ld b/bbb_cape/src/cape/main.ld
index ec39b8f..058c2eb 100644
--- a/bbb_cape/src/cape/main.ld
+++ b/bbb_cape/src/cape/main.ld
@@ -1,7 +1,7 @@
 MEMORY
 {
-  FLASH (rx) : ORIGIN = 0x00008000, LENGTH = 0xF8000   /* 1024k - 32k */
-  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 0x20000   /* 128k */
+  FLASH (rx) : ORIGIN = 16k, LENGTH = 1024k - 16k
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 128k
 }
 
 SECTIONS