helloSystem / ISO

helloSystem Live and installation ISO
https://github.com/helloSystem/
BSD 3-Clause "New" or "Revised" License
808 stars 58 forks source link

Serial console over USB to see boot messages #515

Open probonopd opened 1 year ago

probonopd commented 1 year ago

Is your feature request related to a problem? Please describe.

We would like to have a serial console over USB to see boot messages

Describe the solution you'd like

Press Shift-V during early boot, and the output will be directed to a serial console over USB.

The lua code needs to go here:

https://github.com/helloSystem/ISO/blob/ae0880e6889ee568194b8c60135a442787b04bab/overlays/boot/boot/lua/local.lua#L82

Somehow we don't succeed in loading the needed kernel modules in this way yet. Probably it needs to be done differently?

Describe alternatives you've considered

Typing commands at the bootloader prompt

Additional context

Reference:

u20230812 commented 1 year ago

@probonopd I've looked in to this the past several days on different systems. I have not yet single-stepped the code, but it appears that this code is set to use the legacy COM1 port/address for the console. I did not have any luck getting a getty established for uftdi using ttys.

LOADER.EFI

I suspect we will need driver changes to make this use uftdi instead of legacy COM1 UART. Modern hardware does not expose the UART so you'd likely have to solder on to the PCA to get access. I've seen some SBCs get it working, but I suspect they are using the UART pin on the header and not doing a FTDI to FTDI connection.

I did verify that I can see I/O from FTDI to FTDI with two systems connected using cu and minicom so I know the UART/FTDI connection works.

If you have any pointers to how BSD would solve this with modern hardware that would be helpful. Since dumb terminals are no longer in wide use I think a modern default using USB/FTDI makes more sense. Apart from embedded systems (Pinebook Pro, Raspberry Pi, etc.) I don't know of a recent example of a laptop/desktop having a COM1 (DB9) type port exposed so for the goals of helloSystem it makes more sense to pursue the USB/FTDI defaults in the loader.

Thoughts, feedback?

probonopd commented 1 year ago

Fully agree on your analysis regarding what should be achieved, but don't know how to achieve it.

But looking at this, it strikes me that there is no command that tells the system WHICH tty to use:

            printc("Verbose boot with serial console over USB\n\n")
            loader.unsetenv("boot_mute")
            loader.perform("unload")
            loader.setenv("uftdi_load", "YES")
            loader.setenv("umodem_load", "YES")
            loader.setenv("uplcom_load", "YES")
            loader.setenv("uslcom_load", "YES")
            loader.setenv("boot_multicons", "YES")
            loader.setenv("boot_serial", "YES")
            loader.setenv("comconsole_speed", "115200")
            loader.setenv("console", "comconsole")

Possibly we need to set (Source)

     comconsole_port
               Defines the base i/o port used to access console UART (i386 and
               amd64 only).  If the variable is not set, its assumed value is
               0x3F8, which corresponds to PC port COM1, unless overridden by
               BOOT_COMCONSOLE_PORT variable during the compilation of loader.
               Setting the comconsole_port variable automatically set
               hw.uart.console environment variable to provide a hint to
               kernel for location of the console.  Loader console is changed
               immediately after variable comconsole_port is set.

     comconsole_pcidev
               Defines the location of a PCI device of the 'simple
               communication' class to be used as the serial console UART
               (i386 and amd64 only).  The syntax of the variable is
               'bus:device:function[:bar]', where all members must be numeric,
               with possible 0x prefix to indicate a hexadecimal value.  The
               bar member is optional and assumed to be 0x10 if omitted.  The
               bar must decode i/o space.  Setting the variable
               comconsole_pcidev automatically sets the variable
               comconsole_port to the base of the selected bar, and hint
               hw.uart.console.  Loader console is changed immediately after
               variable comconsole_pcidev is set.

https://docs.opnsense.org/troubleshooting/boot.html mentions even more flags that may or may not be relevant:

set hint.uart.0.flags=0x0
set hint.uart.1.flags=0x10
set comconsole_speed=115200
set comconsole_port=0x2F8
set console=comconsole
boot

But what do we need to set it to?

u20230812 commented 1 year ago

The problem I found with UART.0, UART.1 is those are legacy devices mapped to the legacy address of an NS16550 UART. That's the bit I think we need to change to map to a UART that's on uftdi like /dev/ttyU0.

In fact my MacBook with nothing connected shows the COM ports which tells me I can access them on the PCA or through the ballmap on the CPU if I opened it up.

I also looked in to the serial /UART drivers for BSD and usb, ucomm, and ufdi are the only drivers needed. umodem is only needed when talking to an AT type modem.

u20230812 commented 1 year ago

I think "console", "comconsole" is the hardcoded entity we need to figure out how to change to the USB FTDI device even if we have to connect it and use whatever lowest port address that shows up...

probonopd commented 1 year ago

Isn't umodem for USB CDC devices?

u20230812 commented 1 year ago

So one difference is the legacy devices are on the PCIe bus as part of the chipset instead of USB. Of course I could be way off and learn more later :-)

I really need to single-step that code to see what's going on to determine what we can do minimally to get a USB UART working that's not one of the legacy UARTs coming off the CPU.

Do you have any FreeBSD core maintainer connections that you can introduce me to in order to deep-dive and work through this issue? This seems to be a modernization issue with *BSD in general that needs to be worked out - with the understanding that microcontrollers/embedded devices obviously don't have this issue...

probonopd commented 1 year ago

Looking at https://github.com/freebsd/freebsd-src/commits/main/stand/i386/libi386/comconsole.c it seems like @emaste might know about these things (or be able to point us in the right direction). Seeing #include <dev/ic/ns16550.h> there but nothing regarding USB makes me wonder whether it is possible at all to use comconsole with anything else than the legacy 16550 UARTs.

u20230812 commented 1 year ago

Funny thing is simp - appropriately named seems to want this device to be on the PCIe bus...

https://man.freebsd.org/cgi/man.cgi?loader_simp

comconsole_pcidev

bus:device:function[:bar]

u20230812 commented 1 year ago

@probonopd I have no idea how to include you in email. I emailed Ed to see what he knows about the topic. Send me a message with your email and I'll include you on the discussion.

probonopd commented 1 year ago

My mail address is in the LICENSE file of this repo :)