I want to program a small bare metal hello world application on an Intel Galileo board. Using UEFI to print text (for UART-1) works well, of course, but I want to access UART “manually” without the help of UEFI.
In QEMU, my code works well:
.h file
#define COM1_PORT (0x03F8) #define UART_PORT (COM1_PORT) enum uart_port_offs_t {
.c file
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; }
Main
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); }
Speculation didn't help me much. I believe that UARTs on Intel Galileo motherboards do not use / emulate regular / legacy COM ports 3F8h, 2F8h, 3E8h or 2E8h.
Can someone tell me what I'm doing wrong, or even post an example with a minimal bare metal greeting?
source share