Selecting serial device for console

Hi everyone,
how can I configure which of the available serial devices U-Boot will use for its serial console?
Background: I have a device based on a Raspberry Pi CM4, which has 6 UARTs (UART1 is a mini UART, the others PL011) [1]. In the default configuration (including the mainline Linux broadcom/bcm2711-rpi-cm4-io device tree) the Bluetooth module is attached to UART0. Unless I either completely disable UART0 (status = "disabled" in the device tree) or reconfigure it to be a serial console (e.g. using the RPi disable-bt DTBO) U-Boot fails to boot, I assume (it doesn't get far enough to show messages over netconsole) because it tries and fails to set up a serial console where there's a BT chip listening.
That happens even if another serial console is available: With the RPi bcm2711-rpi-cm4 DTB plus "disable-bt" (disable the Bluetooth module, reconfigure UART0 as a serial console) and "uart1" (set up a serial console on UART1) DTBOs I can see that U-Boot discovers the serial device on UART1 (serial@7e215040):
U-Boot> dm uclass serial uclass 108: serial 0 * serial@7e201000 @ 3af3b200, seq 0 1 serial@7e215040 @ 3af3b2d0, seq 1
However, I can't find a way to make it *use* it instead of UART0 (serial@7e201000). I tried to set CONFIG_CONS_INDEX=1 but didn't see any change (unfortunately the help does not describe exactly how the number is mapped to DT UART definitions). If I completely disable UART0 in the DT as mentioned above U-Boot uses UART1 just fine, so it's not an issue with UART1 as such.
To make matters slightly more complicated, the specific device I have is a RevPi Connect 4, where a vendor overlay [2] describes how to set up an RS485 serial console using UART5. The pins defined there are wired to the outside of the box [3], so eventually I'll actually want to use UART5 for the serial console. Which means I really need a (build-time or preferably DT-based) way to configure which serial device to use.
My goal is to create a single DTS which both U-Boot and Linux can use, and get it upstreamed if possible. If there are configuration options and they're just missing from the documentation, I'd be happy to send a patch to add them once I have a solution.
Best regards, Fiona
[1] https://www.raspberrypi.com/documentation/computers/configuration.html#confi... [2] https://gitlab.com/revolutionpi/linux/-/blob/4ae9a35871799004300f83694a24359... [3] https://revolutionpi.com/en/tutorials/uebersicht-revpi-connect/serielle-gera...

Hi Fiona,
On Thu, 1 Aug 2024 at 08:07, Fiona Klute fiona.klute@gmx.de wrote:
Hi everyone,
how can I configure which of the available serial devices U-Boot will use for its serial console?
Background: I have a device based on a Raspberry Pi CM4, which has 6 UARTs (UART1 is a mini UART, the others PL011) [1]. In the default configuration (including the mainline Linux broadcom/bcm2711-rpi-cm4-io device tree) the Bluetooth module is attached to UART0. Unless I either completely disable UART0 (status = "disabled" in the device tree) or reconfigure it to be a serial console (e.g. using the RPi disable-bt DTBO) U-Boot fails to boot, I assume (it doesn't get far enough to show messages over netconsole) because it tries and fails to set up a serial console where there's a BT chip listening.
That happens even if another serial console is available: With the RPi bcm2711-rpi-cm4 DTB plus "disable-bt" (disable the Bluetooth module, reconfigure UART0 as a serial console) and "uart1" (set up a serial console on UART1) DTBOs I can see that U-Boot discovers the serial device on UART1 (serial@7e215040):
U-Boot> dm uclass serial uclass 108: serial 0 * serial@7e201000 @ 3af3b200, seq 0 1 serial@7e215040 @ 3af3b2d0, seq 1
However, I can't find a way to make it *use* it instead of UART0 (serial@7e201000). I tried to set CONFIG_CONS_INDEX=1 but didn't see any change (unfortunately the help does not describe exactly how the number is mapped to DT UART definitions). If I completely disable UART0 in the DT as mentioned above U-Boot uses UART1 just fine, so it's not an issue with UART1 as such.
To make matters slightly more complicated, the specific device I have is a RevPi Connect 4, where a vendor overlay [2] describes how to set up an RS485 serial console using UART5. The pins defined there are wired to the outside of the box [3], so eventually I'll actually want to use UART5 for the serial console. Which means I really need a (build-time or preferably DT-based) way to configure which serial device to use.
My goal is to create a single DTS which both U-Boot and Linux can use, and get it upstreamed if possible. If there are configuration options and they're just missing from the documentation, I'd be happy to send a patch to add them once I have a solution.
You should be able to update /chosen/stdout-path (in the devicetree) to specify the UART you want, using its alias. So if you have a 'serial1' alias, you can set stdout-path to 'serial1'. This should work in Linux too.
The code in question is serial_find_console_or_panic().
Regards, Simon
Best regards, Fiona
[1] https://www.raspberrypi.com/documentation/computers/configuration.html#confi... [2] https://gitlab.com/revolutionpi/linux/-/blob/4ae9a35871799004300f83694a24359... [3] https://revolutionpi.com/en/tutorials/uebersicht-revpi-connect/serielle-gera...

From: Simon Glass sjg@chromium.org Date: Tue, 6 Aug 2024 15:50:44 -0600
Hi Simon,
Hi Fiona,
On Thu, 1 Aug 2024 at 08:07, Fiona Klute fiona.klute@gmx.de wrote:
Hi everyone,
how can I configure which of the available serial devices U-Boot will use for its serial console?
Background: I have a device based on a Raspberry Pi CM4, which has 6 UARTs (UART1 is a mini UART, the others PL011) [1]. In the default configuration (including the mainline Linux broadcom/bcm2711-rpi-cm4-io device tree) the Bluetooth module is attached to UART0. Unless I either completely disable UART0 (status = "disabled" in the device tree) or reconfigure it to be a serial console (e.g. using the RPi disable-bt DTBO) U-Boot fails to boot, I assume (it doesn't get far enough to show messages over netconsole) because it tries and fails to set up a serial console where there's a BT chip listening.
That happens even if another serial console is available: With the RPi bcm2711-rpi-cm4 DTB plus "disable-bt" (disable the Bluetooth module, reconfigure UART0 as a serial console) and "uart1" (set up a serial console on UART1) DTBOs I can see that U-Boot discovers the serial device on UART1 (serial@7e215040):
U-Boot> dm uclass serial uclass 108: serial 0 * serial@7e201000 @ 3af3b200, seq 0 1 serial@7e215040 @ 3af3b2d0, seq 1
However, I can't find a way to make it *use* it instead of UART0 (serial@7e201000). I tried to set CONFIG_CONS_INDEX=1 but didn't see any change (unfortunately the help does not describe exactly how the number is mapped to DT UART definitions). If I completely disable UART0 in the DT as mentioned above U-Boot uses UART1 just fine, so it's not an issue with UART1 as such.
To make matters slightly more complicated, the specific device I have is a RevPi Connect 4, where a vendor overlay [2] describes how to set up an RS485 serial console using UART5. The pins defined there are wired to the outside of the box [3], so eventually I'll actually want to use UART5 for the serial console. Which means I really need a (build-time or preferably DT-based) way to configure which serial device to use.
My goal is to create a single DTS which both U-Boot and Linux can use, and get it upstreamed if possible. If there are configuration options and they're just missing from the documentation, I'd be happy to send a patch to add them once I have a solution.
You should be able to update /chosen/stdout-path (in the devicetree) to specify the UART you want, using its alias. So if you have a 'serial1' alias, you can set stdout-path to 'serial1'. This should work in Linux too.
The code in question is serial_find_console_or_panic().
While this may reflect how modern Linux handles things, this doesn't actually make a lot of sense to me. And the clue is really in the name of the node under which the stdout-path resides. That property is supposed to communicate to the OS what the firmware/bootloader picked as the console device rather than indicate to the firmware/bootloader what the console device should be. This was how things worked back in the days of OpenFirmware where the firmware would pick an input and an output device based on firmware variables and whether a keyboard was plugged in or not and would set "stdin" and "stdout" properties under /chosen to reflect the choice made by the firmware.
With this in mind it would make total sense to have U-Boot set /chosen/stdout-path based on some environment variable or other information. Of course it might still make sense that the device tree used by U-Boot sets /chosen/stdout-path to indicate the default choice for the console device. But it doesn't make senso to me to tell users that if they want to use a different console device they should go and edit the device tree...
Cheers,
Mark

Hi Mark,
On Tue, 6 Aug 2024 at 16:33, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Tue, 6 Aug 2024 15:50:44 -0600
Hi Simon,
Hi Fiona,
On Thu, 1 Aug 2024 at 08:07, Fiona Klute fiona.klute@gmx.de wrote:
Hi everyone,
how can I configure which of the available serial devices U-Boot will use for its serial console?
Background: I have a device based on a Raspberry Pi CM4, which has 6 UARTs (UART1 is a mini UART, the others PL011) [1]. In the default configuration (including the mainline Linux broadcom/bcm2711-rpi-cm4-io device tree) the Bluetooth module is attached to UART0. Unless I either completely disable UART0 (status = "disabled" in the device tree) or reconfigure it to be a serial console (e.g. using the RPi disable-bt DTBO) U-Boot fails to boot, I assume (it doesn't get far enough to show messages over netconsole) because it tries and fails to set up a serial console where there's a BT chip listening.
That happens even if another serial console is available: With the RPi bcm2711-rpi-cm4 DTB plus "disable-bt" (disable the Bluetooth module, reconfigure UART0 as a serial console) and "uart1" (set up a serial console on UART1) DTBOs I can see that U-Boot discovers the serial device on UART1 (serial@7e215040):
U-Boot> dm uclass serial uclass 108: serial 0 * serial@7e201000 @ 3af3b200, seq 0 1 serial@7e215040 @ 3af3b2d0, seq 1
However, I can't find a way to make it *use* it instead of UART0 (serial@7e201000). I tried to set CONFIG_CONS_INDEX=1 but didn't see any change (unfortunately the help does not describe exactly how the number is mapped to DT UART definitions). If I completely disable UART0 in the DT as mentioned above U-Boot uses UART1 just fine, so it's not an issue with UART1 as such.
To make matters slightly more complicated, the specific device I have is a RevPi Connect 4, where a vendor overlay [2] describes how to set up an RS485 serial console using UART5. The pins defined there are wired to the outside of the box [3], so eventually I'll actually want to use UART5 for the serial console. Which means I really need a (build-time or preferably DT-based) way to configure which serial device to use.
My goal is to create a single DTS which both U-Boot and Linux can use, and get it upstreamed if possible. If there are configuration options and they're just missing from the documentation, I'd be happy to send a patch to add them once I have a solution.
You should be able to update /chosen/stdout-path (in the devicetree) to specify the UART you want, using its alias. So if you have a 'serial1' alias, you can set stdout-path to 'serial1'. This should work in Linux too.
The code in question is serial_find_console_or_panic().
While this may reflect how modern Linux handles things, this doesn't actually make a lot of sense to me. And the clue is really in the name of the node under which the stdout-path resides. That property is supposed to communicate to the OS what the firmware/bootloader picked as the console device rather than indicate to the firmware/bootloader what the console device should be. This was how things worked back in the days of OpenFirmware where the firmware would pick an input and an output device based on firmware variables and whether a keyboard was plugged in or not and would set "stdin" and "stdout" properties under /chosen to reflect the choice made by the firmware.
With this in mind it would make total sense to have U-Boot set /chosen/stdout-path based on some environment variable or other information. Of course it might still make sense that the device tree used by U-Boot sets /chosen/stdout-path to indicate the default choice for the console device. But it doesn't make senso to me to tell users that if they want to use a different console device they should go and edit the device tree...
Yes it is strange. I believe it comes from a time where U-Boot was not allowed its own devicetree properties, so the 'console' alias used by U-Boot back in 2015 was not allowed. The 'console' alias does not support a baud rate as U-Boot's CONFIG_BAUDRATE handles that.
The theory was (if I remember correctly) that U-Boot can just use the Linux information since it is presumably correct. I agree it is odd and a bit backwards. There is code in fdt_support.c to set linux,stdout-path but it seems pretty old and perhaps only used on sunxi.
Would you like to create a series to tidy this up, assuming that we can figure out an acceptable way to specify the UART in U-Boot?
Regards, Simon

Hi Simon, Mark,
thanks for your replies!
Am 08.08.24 um 16:28 schrieb Simon Glass:
Hi Mark,
On Tue, 6 Aug 2024 at 16:33, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Tue, 6 Aug 2024 15:50:44 -0600
Hi Simon,
Hi Fiona,
On Thu, 1 Aug 2024 at 08:07, Fiona Klute fiona.klute@gmx.de wrote:
Hi everyone,
how can I configure which of the available serial devices U-Boot will use for its serial console?
Background: I have a device based on a Raspberry Pi CM4, which has 6 UARTs (UART1 is a mini UART, the others PL011) [1]. In the default configuration (including the mainline Linux broadcom/bcm2711-rpi-cm4-io device tree) the Bluetooth module is attached to UART0. Unless I either completely disable UART0 (status = "disabled" in the device tree) or reconfigure it to be a serial console (e.g. using the RPi disable-bt DTBO) U-Boot fails to boot, I assume (it doesn't get far enough to show messages over netconsole) because it tries and fails to set up a serial console where there's a BT chip listening.
That happens even if another serial console is available: With the RPi bcm2711-rpi-cm4 DTB plus "disable-bt" (disable the Bluetooth module, reconfigure UART0 as a serial console) and "uart1" (set up a serial console on UART1) DTBOs I can see that U-Boot discovers the serial device on UART1 (serial@7e215040):
U-Boot> dm uclass serial uclass 108: serial 0 * serial@7e201000 @ 3af3b200, seq 0 1 serial@7e215040 @ 3af3b2d0, seq 1
However, I can't find a way to make it *use* it instead of UART0 (serial@7e201000). I tried to set CONFIG_CONS_INDEX=1 but didn't see any change (unfortunately the help does not describe exactly how the number is mapped to DT UART definitions). If I completely disable UART0 in the DT as mentioned above U-Boot uses UART1 just fine, so it's not an issue with UART1 as such.
To make matters slightly more complicated, the specific device I have is a RevPi Connect 4, where a vendor overlay [2] describes how to set up an RS485 serial console using UART5. The pins defined there are wired to the outside of the box [3], so eventually I'll actually want to use UART5 for the serial console. Which means I really need a (build-time or preferably DT-based) way to configure which serial device to use.
My goal is to create a single DTS which both U-Boot and Linux can use, and get it upstreamed if possible. If there are configuration options and they're just missing from the documentation, I'd be happy to send a patch to add them once I have a solution.
You should be able to update /chosen/stdout-path (in the devicetree) to specify the UART you want, using its alias. So if you have a 'serial1' alias, you can set stdout-path to 'serial1'. This should work in Linux too.
The code in question is serial_find_console_or_panic().
I can see there that it *should* be using the serial device from /chosen/stdout-path with CONFIG_OF_CONTROL=y (which I have set), but if I set it in the described form (alias to UART5:baudrate, I can share my DTS if that helps) U-Boot doesn't start. Unfortunately without the console it's hard to see *why*, I'll have to see if anything appears if I connect an HDMI display.
In general, should U-Boot be able to use an RS485 output via UART configured via DT (like [1]), or would I need to do board-specific config for that? With the RevPi Connect 4 device I have it's the only serial console that's accessible without opening the box. I have also noticed that both drivers/serial/serial_bcm283x_mu.c and drivers/serial/serial_bcm283x_pl011.c contain some odd checks on whether a serial UART is usable as a console, but I'm not sure if they'd interfere here (because GPIO 15 is part of the RS485 setup).
While this may reflect how modern Linux handles things, this doesn't actually make a lot of sense to me. And the clue is really in the name of the node under which the stdout-path resides. That property is supposed to communicate to the OS what the firmware/bootloader picked as the console device rather than indicate to the firmware/bootloader what the console device should be. This was how things worked back in the days of OpenFirmware where the firmware would pick an input and an output device based on firmware variables and whether a keyboard was plugged in or not and would set "stdin" and "stdout" properties under /chosen to reflect the choice made by the firmware.
With this in mind it would make total sense to have U-Boot set /chosen/stdout-path based on some environment variable or other information. Of course it might still make sense that the device tree used by U-Boot sets /chosen/stdout-path to indicate the default choice for the console device. But it doesn't make senso to me to tell users that if they want to use a different console device they should go and edit the device tree...
In general I agree, on RPi-based devices having the bootloader apply DT overlays is pretty normal though (whether that's a good idea may be up for debate). That said, another issue I see is that U-Boot seems to fail to boot without a valid serial console even though CONFIG_REQUIRE_SERIAL_CONSOLE is not set. If I had a way around that it'd be enough for my immediate issue, even though a working serial console would be very much preferable. ;-)
Best regards, Fiona
[1] https://gitlab.com/revolutionpi/linux/-/blob/4ae9a35871799004300f83694a24359...

Hi Fiona,
On Sat, 10 Aug 2024 at 04:14, Fiona Klute fiona.klute@gmx.de wrote:
Hi Simon, Mark,
thanks for your replies!
Am 08.08.24 um 16:28 schrieb Simon Glass:
Hi Mark,
On Tue, 6 Aug 2024 at 16:33, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Tue, 6 Aug 2024 15:50:44 -0600
Hi Simon,
Hi Fiona,
On Thu, 1 Aug 2024 at 08:07, Fiona Klute fiona.klute@gmx.de wrote:
Hi everyone,
how can I configure which of the available serial devices U-Boot will use for its serial console?
Background: I have a device based on a Raspberry Pi CM4, which has 6 UARTs (UART1 is a mini UART, the others PL011) [1]. In the default configuration (including the mainline Linux broadcom/bcm2711-rpi-cm4-io device tree) the Bluetooth module is attached to UART0. Unless I either completely disable UART0 (status = "disabled" in the device tree) or reconfigure it to be a serial console (e.g. using the RPi disable-bt DTBO) U-Boot fails to boot, I assume (it doesn't get far enough to show messages over netconsole) because it tries and fails to set up a serial console where there's a BT chip listening.
That happens even if another serial console is available: With the RPi bcm2711-rpi-cm4 DTB plus "disable-bt" (disable the Bluetooth module, reconfigure UART0 as a serial console) and "uart1" (set up a serial console on UART1) DTBOs I can see that U-Boot discovers the serial device on UART1 (serial@7e215040):
U-Boot> dm uclass serial uclass 108: serial 0 * serial@7e201000 @ 3af3b200, seq 0 1 serial@7e215040 @ 3af3b2d0, seq 1
However, I can't find a way to make it *use* it instead of UART0 (serial@7e201000). I tried to set CONFIG_CONS_INDEX=1 but didn't see any change (unfortunately the help does not describe exactly how the number is mapped to DT UART definitions). If I completely disable UART0 in the DT as mentioned above U-Boot uses UART1 just fine, so it's not an issue with UART1 as such.
To make matters slightly more complicated, the specific device I have is a RevPi Connect 4, where a vendor overlay [2] describes how to set up an RS485 serial console using UART5. The pins defined there are wired to the outside of the box [3], so eventually I'll actually want to use UART5 for the serial console. Which means I really need a (build-time or preferably DT-based) way to configure which serial device to use.
My goal is to create a single DTS which both U-Boot and Linux can use, and get it upstreamed if possible. If there are configuration options and they're just missing from the documentation, I'd be happy to send a patch to add them once I have a solution.
You should be able to update /chosen/stdout-path (in the devicetree) to specify the UART you want, using its alias. So if you have a 'serial1' alias, you can set stdout-path to 'serial1'. This should work in Linux too.
The code in question is serial_find_console_or_panic().
I can see there that it *should* be using the serial device from /chosen/stdout-path with CONFIG_OF_CONTROL=y (which I have set), but if I set it in the described form (alias to UART5:baudrate, I can share my DTS if that helps) U-Boot doesn't start. Unfortunately without the console it's hard to see *why*, I'll have to see if anything appears if I connect an HDMI display.
Indeed. If you have JTAG access that can help, or you could enable a debug UART and use printch(), etc. to see where it gets to.
If the serial driver dies, U-Boot will stop. I have the same issue on another board and created hacky patch[2] but have not got around to doing it properly.
I suppose you can disable CONFIG_SERIAL_PRESENT but then you will need some other way to test the device.
In general, should U-Boot be able to use an RS485 output via UART configured via DT (like [1]), or would I need to do board-specific config for that?
I don't know...I thought that was a broadcast type of thing. In Linux I believe the UART gets put in a special mode, so U-Boot would need to support that too.
With the RevPi Connect 4 device I have it's the only serial console that's accessible without opening the box. I have also noticed that both drivers/serial/serial_bcm283x_mu.c and drivers/serial/serial_bcm283x_pl011.c contain some odd checks on whether a serial UART is usable as a console, but I'm not sure if they'd interfere here (because GPIO 15 is part of the RS485 setup).
I'm not sure
While this may reflect how modern Linux handles things, this doesn't actually make a lot of sense to me. And the clue is really in the name of the node under which the stdout-path resides. That property is supposed to communicate to the OS what the firmware/bootloader picked as the console device rather than indicate to the firmware/bootloader what the console device should be. This was how things worked back in the days of OpenFirmware where the firmware would pick an input and an output device based on firmware variables and whether a keyboard was plugged in or not and would set "stdin" and "stdout" properties under /chosen to reflect the choice made by the firmware.
With this in mind it would make total sense to have U-Boot set /chosen/stdout-path based on some environment variable or other information. Of course it might still make sense that the device tree used by U-Boot sets /chosen/stdout-path to indicate the default choice for the console device. But it doesn't make senso to me to tell users that if they want to use a different console device they should go and edit the device tree...
In general I agree, on RPi-based devices having the bootloader apply DT overlays is pretty normal though (whether that's a good idea may be up for debate). That said, another issue I see is that U-Boot seems to fail to boot without a valid serial console even though CONFIG_REQUIRE_SERIAL_CONSOLE is not set. If I had a way around that it'd be enough for my immediate issue, even though a working serial console would be very much preferable. ;-)
Enabling DEBUG_UART on rpi would be a worthy goal. It can be a little tricky if there is pinmux, etc. But on another board I figured it out by tracking the register writes done in a normal startup, then writing new code to include those in the board_debug_uart_init()
Regards, Simon
[1] https://gitlab.com/revolutionpi/linux/-/blob/4ae9a35871799004300f83694a24359...
[2] https://patchwork.ozlabs.org/project/uboot/patch/20231101180447.99361-1-sjg@...
participants (3)
-
Fiona Klute
-
Mark Kettenis
-
Simon Glass