title: Intel Galileo bare metal UART
body: <p>I want to program a little "hello world" <strong>bare metal</strong> application on the <strong>Intel Galileo</strong> board. Using UEFI to print out text (to UART-1) works well, of course, but I want to access the UART "manually", without any help from UEFI.</p>
  
  <p>In QEMU my code works well:</p>
  
  <h3>.h file</h3>
  
  <pre><code>#define COM1_PORT (0x03F8)
  #define UART_PORT (COM1_PORT)
  
  enum uart_port_offs_t
  {   //          DLAB RW
      THR = 0, //   0   W  Transmitter Holding Buffer
      RBR = 0, //   0  R   Receiver Buffer
      DLL = 0, //   1  RW  Divisor Latch Low Byte
      IER = 1, //   0  RW  Interrupt Enable Register
      DLH = 1, //   1  RW  Divisor Latch High Byte
      IIR = 2, //   -  R   Interrupt Identification Register
      FCR = 2, //   -  RW  FIFO Control Register
      LCR = 3, //   -  RW  Line Control Register
      MCR = 4, //   -  RW  Modem Control Register
      LSR = 5, //   -  R   Line Status Register
      MSR = 6, //   -  R   Modem Status Register
      SR  = 7, //   -  RW  Scratch Register
  };
  </code></pre>
  
  <h3>.c file</h3>
  
  <pre><code>void uart_init(void)
  {
      outb(UART_PORT + IER, 0x00); // Disable all interrupts
  
      outb(UART_PORT + LCR, LCR_DLAB);
      outb(UART_PORT + DLL, BAUD_LL); // Set divisor (lo byte)
      outb(UART_PORT + DLH, BAUD_HL); //             (hi byte)
      outb(UART_PORT + LCR, LCR_WORD_BITS_8 | LCR_PAR_NONE | LCR_STOP_BITS_1);
      outb(UART_PORT + FCR, FCR_ENABLE | FCR_CLR_RECV | FCR_CLR_SEND | FCR_TRIGGER_16);
      outb(UART_PORT + MCR, MCR_DSR | MCR_RTS | MCR_AUX2);
  }
  
  ssize_t uart_write(const char *buf, size_t len)
  {
      size_t written = 0;
      while (written &lt; len) {
          while (!is_output_empty()) {
              asm volatile ("pause");
          }
          outb(UART_PORT + THR, buf[written]);
          ++written;
      }
      return written;
  }
  </code></pre>
  
  <h3>main</h3>
  
  <pre><code>SystemTable-&gt;ConOut-&gt;OutputString(SystemTable-&gt;ConOut, L"Exiting EFI boot services ...\r\n");
  SystemTable-&gt;BootServices-&gt;ExitBootServices(ImageHandle, map_key);
  
  uart_init();
  
  while (1) {
      const char s[] = "UART\r\n";
      uart_write(s, sizeof (s) - 1);
  }
  </code></pre>
  
  <p>The specs did not help me very much. I guess that the UARTs on the Intel Galileo board don't use/emulate the normal/legacy COM ports 3F8h, 2F8h, 3E8h, or 2E8h.</p>
  
  <p>Can anyone tell me what I am doing wrong, or even post a minimal bare metal hello world example?</p>