UART bare metal Intel Galileo

Eu quero programar um pouco de "olá mundo"metal nu aplicação noIntel Galileo borda. Usar o UEFI para imprimir texto (para o UART-1) funciona bem, é claro, mas quero acessar o UART "manualmente", sem a ajuda da UEFI.

No QEMU, meu código funciona bem:

arquivo .h
#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
};
arquivo .c
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 < len) {
        while (!is_output_empty()) {
            asm volatile ("pause");
        }
        outb(UART_PORT + THR, buf[written]);
        ++written;
    }
    return written;
}
a Principal
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Exiting EFI boot services ...\r\n");
SystemTable->BootServices->ExitBootServices(ImageHandle, map_key);

uart_init();

while (1) {
    const char s[] = "UART\r\n";
    uart_write(s, sizeof (s) - 1);
}

As especificações não me ajudaram muito. Eu acho que os UARTs na placa Intel Galileo não usam / emulam as portas COM normais / herdadas 3F8h, 2F8h, 3E8h ou 2E8h.

Alguém pode me dizer o que estou fazendo de errado, ou até mesmo postar um exemplo mínimo do mundo olá bare metal?

questionAnswers(1)

yourAnswerToTheQuestion