[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

U-Boot, d-i and selecting the console device



Hello everybody,

in Jessie many of the supported armhf platforms require a serial
console to be able to use d-i, because there is simply no support
for a framebuffer console.

In Stretch, which introduced u-boot v2015.04, things are getting
a bit different.  U-Boot v2015.04 offers simplefb support for a
number of platforms, and the upcoming u-boot v2015.07 brings
improvements in the USB support layer that allows for easier use
of USB keyboards with u-boot.  U-boot nowadays actually supports
having framebuffer console with a USB keyboard and serial console
at the same time, with both mirroring each other.

As long as we are within u-boot, that works reasonably well, but
when we boot the kernel, we need to define a primary console
device, as the kernel can AFAIK only have one primary console
device, and d-i uses that to display itself.  The problem we have
now is how to automatically select that in way that works easily
for users who have only a serial console or who have only
framebuffer console.

The kernel default console device can be determined by different
mechanisms:

The oldest one, which we have been using in Jessie, is passing a
"console" kernel parameter, such as "console=ttyS0,115200" for a
serial console.  Different systems have different names for their
primary serial console device (e.g. ttyS0, ttymxc0, ttyAMA0), so
we currently pass the contents of the u-boot console variable to
the kernel.  The u-boot console variable is predefined in the
u-boot sources for each platform and - unless changed by the
user - points to the primary serial console for the current
platform.

The second way to define a default console device for the kernel
is by setting the stdout-path property in the device-tree.  This
is a feature that has been introduced rather recently, and most
armhf platforms which actually set this property in their
device-tree define a serial console as their default stdout-path.
As far as I have been able to determine, the console kernel
parameter has precedence over the stdout-path property in case
both are defined.

With the current way of things, i.e. passing the u-boot console
variable to the kernel, d-i by default always starts on a serial
console.  This is not particularly nice for people who do not
have a proper serial console cable for their board.  The user can
of course change the u-boot console variable from e.g. ttyS0
(serial console) to tty0 (framebuffer console), but that requires
manually stopping the d-i boot process, changing the u-boot
console variable and restarting the boot process, which makes a
not-so-nice out-of-the-box experience for novice users.

If we don't pass a console variable to the kernel, d-i starts
on the console device defined by the platform's stdout-path
property, i.e. usually on a serial console - again bad luck
for people having only a framebuffer console.

If we set the console variable to tty0, d-i starts on the
framebuffer console if it is available, or on a dummy console,
if no framebuffer console is available. The dummy console is
invisible, i.e. a serial-console-only user doesn't get any
output, so bad luck for the people using a serial console
in this case.

AFAICS there is no way to determine the "active" console in
u-boot and set either the u-boot console variable or the
stdout-path property accordingly.  Even if there was such a
mechanism, the question remains: what is the "active" console? 
With our d-i SD-card images, the system autoboots directly into
d-i without any user interaction required, to there is no way for
u-boot to determine which console the user is intending to use.

During my experiments, I also stumbled over the fact that there
appears to be a difference between setting the primary console
device to a serial port by setting the stdout-path property and
by passing a console=ttyS0 kernel parameter.  Running a number of
experiments with an already installed systems gave the follwing
results:

With console=tty0 passed to the kernel:
- no kernel and no systemd output on the serial port
- no getty on the serial port
- kernel and systemd output on tty0 (framebuffer console)
- getty on tty0

With console=ttyS0,115200 passed to the kernel:
- no kernel and no systemd output on tty0 (framebuffer
  console)
- kernel and systemd output on the serial port
- getty on both the serial port and on tty0

With no console parameter at all passed to the kernel, i.e.
the primary console device determined by the stdout-path
property, which points to the serial console:
- kernel output on tty0
- kernel und systemd output on the serial port
- getty on both the serial port and on tty0   

Explanations, ideas and comments welcome :-).

Regards,
Karsten
-- 
Gem. Par. 28 Abs. 4 Bundesdatenschutzgesetz widerspreche ich der Nutzung
sowie der Weitergabe meiner personenbezogenen Daten für Zwecke der
Werbung sowie der Markt- oder Meinungsforschung.


Reply to: