Yes, the kernel produces log messages about its progress and features during boot. If something were to go wrong, then those log messages are quite useful. That function was 2-way, and you could have logged in and worked on the system with serial console as a very simple text-only interface. It is in fact one of the most useful debug tools you will find in the embedded world. This is what owned the UART, and your program was intruding on it, basically typing whatever it did into a login prompt. Now the serial console program no longer owns this UART so it is free to use (you might still get a boot hang if your program outputs to the UART at just the wrong moment during boot since boot stages likely still see input).
Most any UART can be used as serial console. The topic of
ttyTHS# is almost unrelated. The
ttyS# designation is the original legacy driver, and this does not use DMA. The
ttyTHS# driver is the “
Tegra High Speed” driver, a version of the
ttyS# legacy driver. Both drivers often run on the same
UART, although you should not (but could) use both simultaneously. The hardware is compatible with both drivers, but the
THS driver might be more efficient. The reason why the
THS driver is not used in serial console is because the boot stages are not Linux, and they do not have the
THS driver; those stages have been around a very very long time and use the legacy driver. One would lose boot message content if the transition from boot to Linux kernel required resetting the UART/driver. Using the
ttyS# driver even after boot implies continuity of service for serial console. Still, both a legacy device and
THS device are the same device, they just use different drivers at the same time (serial console only uses one at a time, this is good; mixing a second application at the same time is bad regardless of whether or not they both use legacy or
THS, but not knowing
THS is the same physical device tricks people into thinking they can do it).
You could just do a Google search for “
linux serial console”. This is in general quite common in the embedded world, although it can be used in a PC as well. Since all it does is take a series of bytes and write them or read them it is far simpler than installing a graphics driver or networking; when all else crashes and burns a serial console tends to work. An excellent way to debug broken hardware or software.
nvgetty.service is just the modern way of enabling serial console. When the kernel loads it is process ID
0 (PID 0). The kernel runs only one program, and that program is
init (PID 1).
init used to just be a series of shell programs and drivers not arranged in any particular way except by custom.
systemd is a daemon replacing old style
init. The tool for interacting with
sysemctl. Systemd organizes a more modular way of specifying services and conditions used in boot or shutdown. One can specify some synthetic boot stage, and what prerequisites are needed, plus what is to run in that boot stage, followed by telling
systemd to go to that state. Example:
mutli-user.target is multiple user login, text-mode only, while
graphical.target is multiple user login, but using the GUI. If you kill the system and shut it down via “
sudo killall -HUP init”, then this is essentially
systemd being told to go to the shutdown stage.
To see customization of the
init process via
systemd examine the human readable files at “
/etc/systemd”. Some of these are just symbolic links into unmodified system files somewhere under “
/lib/systemd/system”. As an example, the system will boot to a default target, and for a Jetson this is “
graphical.target”. If you go to “
/etc/systemd/system” you will find a symbolic link named “
default.target”, and this points to the real file “
/lib/systemd/system/graphical.target”. Looking under this you will find a set of specifications. Those specifications work with other
systemd files to produce a chain of what services or targets produce the required chain of boot events. It is basically a solver of dependencies something like a Makefile, but it boots instead of compiling.
nvgetty.service is optional and can be told to work or not work, and becomes a dependency in a chain when enabled.