What is the purpose of earlycon?

I tried to understand the purpose of the earlycon kernel command-line argument, but failed so far. Of course I know that in theory it should enable early boot logs on serial console, but with all SBCs I use, including the VisionFive 2, the serial console via UART pins give logs from including SPL, long before the kernel command-line arguments are even parsed.

In case of VisionFive 2 it’s SPL, DDR blob, OpenSBI, U-Boot, how it reads environment and extlinux and then how the kernel starts, until the enabled serial getty prompts. I carefully compared the output with:

  • earlycon=sbi
  • earlycon
  • removing it entirely

defined in extlinux.conf and there is absolutely no difference. So what is this argument aiming to change?

The same question applies to all ARM SBCs I tested this with, but asking it here as the official Debian image contains the argument as well, so someone had a reason to add it, I hope.


in my experience you get kernel output already before the console is enabled - iirc the messages are buffered anyway, so the output is the same with or without, but the timing is different, i.e. you should get output earlier with earlycon - this is helpful for debugging problems where the kernel dies even before the console is up … but i might be completely wrong with this.


But the console is already enabled before the kernel image is even loaded, as OpenSBI and U-Boot successfully use it for output already.

But I think I understand now: Even that OpenSBI and U-Boot are able to print to the console, the kernel needs to load its own driver for its own output. Thanks to the buffer, one sees the same kernel logs, but with earlycon they appear some milliseconds earlier. And if the kernel crashes before its common console driver is loaded, one might not see kernel logs at all (even that U-Boot logs are there) without earlycon.

I had another look:

  • earlycon=sbi:
    [    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
  • earlycon:
    [    0.000000] earlycon: uart0 at MMIO32 0x0000000010000000 (options '115200')

Not sure about the practical difference, but seems like on RISC-V one should use the SBI option: Early console using RISC-V SBI - CONFIG_SERIAL_EARLYCON_RISCV_SBI - earlycon-riscv-sbi.ko - kernelconfig.io