1

I am currently using uboot to boot linux kernel. I have not mentioned ttyS0 or anything in the console parameter. I get to see the output only when there is not console parameter while if I specify the console parameter the log stops after "Starting Kernel...". So I was trying to find if the linux kernel uses the u-boot serial driver to print and get characters. But when I make a small change or add a print statement in the driver I can see that change till the u-boot command line while I cannot see these when Linux is started. I am wondering which driver is being used to print data and get data from the console.

Edit(1) : After some working with the TTY Driver I am now getting print statements on console. See log below :

[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x84000000
[    0.000000] Linux version 5.5.0-rc1-00032-g264b43306b8c-dirty (venkatakrishnan@venkatakrishnan-ubuntu) (gcc version 10.2.0 (GCC)) #22 Tue Jul 27 15:02:20 IST 2021
[    0.000000] initrd not found or empty - disabling initrd
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000084000000-0x000000008fffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000084000000-0x000000008fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000084000000-0x000000008fffffff]
[    0.000000] software IO TLB: mapped [mem 0x8bd5b000-0x8fd5b000] (64MB)
[    0.000000] elf_hwcap is 0x1105
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 48480
[    0.000000] Kernel command line: console=ttySHAKTI0,19200n8 earlycon root=/dev/mmcblk1p1 rw rootfs=ext4 noinitrd selinux=0
[    0.000000] Dentry cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[    0.000000] Inode-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.000000] Sorting __ex_table...
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 112684K/196608K available (3868K kernel code, 199K rwdata, 702K rodata, 9856K init, 233K bss, 83924K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
[    0.000000] plic: mapped 29 interrupts with 1 handlers for 2 contexts.
[    0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
[    0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1ef4687b1, max_idle_ns: 112843571739654 ns
[    0.001342] sched_clock: 64 bits at 32kHz, resolution 30517ns, wraps every 70368744171142ns
[    0.011474] Calibrating delay loop (skipped), value calculated using timer frequency.. 0.06 BogoMIPS (lpj=131)
[    0.016326] pid_max: default: 32768 minimum: 301
[    0.077301] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.082397] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[    0.482940] devtmpfs: initialized
[    1.069976] random: get_random_bytes called from setup_net+0x54/0x1dc with crng_init=0
[    1.123840] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    1.129333] futex hash table entries: 256 (order: 0, 6144 bytes, linear)
[    1.213317] NET: Registered protocol family 16
[    1.639770] Shakti UART Probing started...
[    1.669952] 11300.uart: ttySHAKTI0 at MMIO 0x11300 (irq = 0, base_baud = 0) is a Shakti UART 0
[  234.333038] printk: console [ttySHAKTI0] enabled
[  235.845855] clocksource: Switched to clocksource riscv_clocksource
[  236.541534] NET: Registered protocol family 2
[  236.840209] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear)
[  237.152709] TCP established hash table entries: 2048 (order: 2, 16384 bytes, linear)
[  237.442626] TCP bind hash table entries: 2048 (order: 2, 16384 bytes, linear)
[  237.703186] TCP: Hash tables configured (established 2048 bind 2048)
[  237.953887] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[  238.188140] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[  238.492340] NET: Registered protocol family 1
[  268.344238] workingset: timestamp_bits=62 max_order=15 bucket_order=0
[  281.773803] ntfs: driver 2.1.32 [Flags: R/W DEBUG].
[  282.271209] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[  282.536315] io scheduler mq-deadline registered
[  282.675445] io scheduler kyber registered
[  282.983062] io scheduler bfq registered
[  304.778137] Error: Driver 'shakti-uart' is already registered, aborting...
[  305.379852] shakti_spi 20100.spi: Shakti SPI Driver initialized
[  306.020507] libphy: Fixed MDIO Bus: probed
[  306.185424] xilinx_emaclite 44000.ethernet: Device Tree Probing
[  306.439025] libphy: Xilinx Emaclite MDIO: probed
[  306.686065] xilinx_emaclite 44000.ethernet: MAC address is now 00:0a:35:00:00:00
[  307.191101] xilinx_emaclite 44000.ethernet: Xilinx EmacLite at 0x00044000 mapped to 0x04010000, irq=29
[  307.796661] mmc_spi spi0.0: SD/MMC host mmc0, no DMA, no WP, no poweroff, cd polling
[  308.229644] NET: Registered protocol family 17
[  311.828765] Freeing unused kernel memory: 9856K
[  311.968719] This architecture does not have kernel memory protection.
[  312.218292] Run /init as init process
[  313.042419] mmc0: host does not support reading read-only switch, assuming write-enable
[  313.339843] mmc0: new SDHC card on SPI
[  314.152679] mmcblk0: mmc0:0000 SS08G 7.40 GiB 
[  315.783752]  mmcblk0: p1

I am still wondering that I am not able to see the login prompt and I can see this console being used as log console where the printk statements are only printed(similar to dmesg command). Also for input do we need to register interrupts and use that to being data in or is there any polling method possible?

sawdust
  • 16,103
  • 3
  • 40
  • 50
turbo
  • 87
  • 2
  • 8
  • 1
    Once the boot loader jumps to the kernel's entry point, the boot loader's job is done. The kernel does not call functions in the boot loader. – Ian Abbott Jul 19 '21 at 11:04
  • In that case I have not passed any console parameter through the bootargs but still I get to see the kernel boot log. And when I try to add something like console=ttyS0 then there isnt anything printed in the kernel. I cannot understand from where it is being printed – turbo Jul 19 '21 at 12:18
  • It might be getting kernel command line options from the device tree. Also `console=ttyS0` will default the serial parameters to 9600 baud, no parity, 8 data bits, no flow control unless you append a comma and options after the `ttyS0`. For example, `console=ttyS0,115200n8` specifies 115200 baud, no parity, 8 data bits, no flow control. – Ian Abbott Jul 19 '21 at 14:02
  • It might be compiled with a specific console in mind. – user253751 Jul 19 '21 at 15:24
  • @user253751 I have checked the .config file and found nothing related to console over there. Is there anywhere I need to check again? – turbo Jul 19 '21 at 18:57
  • *"I cannot understand from where it is being printed ... Is there anywhere I need to check again?"* -- Have you inspected the actual kernel command line that is used? It's in the syslog and **/proc/cmdline** – sawdust Jul 19 '21 at 19:10
  • @sawdust I cannot currently login into the system as there is a fault with the busybox. But should I need to write a uart serial driver for my board so that it can display and get chat from the console? This UART IP is a custom one. – turbo Jul 20 '21 at 07:23
  • *"I cannot currently login ..."* -- But you previously wrote that *"I get to see the output only when there is not console parameter ..."*. That output by the kernel is the syslog, and reports the command line as one of the first dozen messages. – sawdust Jul 20 '21 at 19:22
  • Is [this the output that you're *"seeing"*](https://stackoverflow.com/questions/68375894/auto-logout-issue-in-linux-when-booted-through-uboot)? The bootlog that you included in that post shows a kernel command line that invokes the **earlyprintk** feature Therefore the "console" output is from the *temporary* serial console provided by the **earlyprintk** feature. Don't know about the arch you're using, but for Arm see https://falstaff.agner.ch/2015/10/17/linux-earlyprintkearlycon-support-on-arm/ – sawdust Jul 21 '21 at 06:53
  • Yes @sawdust there is an earlyprintk present in the boot options of the kernel. I have the print and all working fine (with extra '\n' at end of each line) but the input through the console is a delayed input by 16 characters. I am wondering where the issue might be so that addressing that will resolve the delayed input problem – turbo Jul 22 '21 at 08:05
  • From the kernel docs I see that `Note that if you boot without a console= option (or with console=/dev/tty0), /dev/console is the same as /dev/tty0. In that case everything will still work.` at [link](https://www.kernel.org/doc/html/latest/admin-guide/serial-console.html) but when I tried to set the console to tty0 and try to boot I get hanged at the "Starting Kernel..." line which seems to be last line from uboot. I tried my serial code and set the console to ttySHAKTI0 (which is the code developed by me) and still saw no characters on the console. removing it starts but with the issue above – turbo Jul 22 '21 at 10:22
  • *"Yes ... there is an earlyprintk present in the boot options of the kernel."* -- Instead of your summation, post the actual boot log, i.e. edit your original post. – sawdust Jul 22 '21 at 20:41
  • `earlyprintk` is a feature of the custom kernel you are using. It is not in upstream and not going to be there, the proper way is to use `earlycon`. – 0andriy Jul 24 '21 at 08:11
  • @0andriy I have changed in the latest build and currently using that. see the log (edited above) – turbo Jul 27 '21 at 11:04
  • You put 19200 baud rate to the kernel console, does _/etc/inittab_ follow that (i.e. is `getty` properly configured)? – 0andriy Jul 27 '21 at 13:44
  • /etc/inittab had the following as the console parameter : ```console::respawn:/sbin/getty -L console 0 vt100``` Is this the one which sets the tty as the primary console? Do we need to change this in order for our custom serial driver to be the primary(display the login prompt)? – turbo Jul 27 '21 at 14:08
  • @sawdust I can only see printk based statements printed on the console. I cannot see printf based statements and the login prompt too. I have also changed the getty as told by @0andriy and it is like this currently ```console::respawn:/sbin/getty -L ttySHAKTI0 19200 vt100``` I am not sure why after configuring the getty the system login is not yet seen. – turbo Jul 29 '21 at 06:26
  • *"do we need to register interrupts..."* -- Yes, and your driver is reporting `irq = 0, base_baud = 0`, which does not seem to be reasonable. *"is there any polling method possible?"* -- No, not practical at all with a multitasking operating system. Learn how to debug your driver by "instrumenting it", i.e. insert **printk()** statements to report internal values or state, or simply to trace what gets executed. – sawdust Jul 29 '21 at 23:36
  • Thanks @sawdust I am currently changing the code to work with interrupts(receive using interrupts). I am also wondering that the kernel log shows ```printk: console [ttySHAKTI0] enabled```thinks that this is a console only to print the kernel log statements? In that case where can I look to change this? – turbo Jul 30 '21 at 06:34
  • That message is from https://elixir.bootlin.com/linux/v5.5/source/kernel/printk/printk.c#L2798, and bothers me. When **earlyprintk** (or **earlycon**) is really activated, there should be a message indicating that it is active, and then there are messages that it is disabled when the regular console takes over. Your log also seems to have an unusual 230+ seconds delay that seems to be consumed by the UART driver. *"In that case where can I look to change this?"* -- What do you mean by *"this"*? Do you want to redefine how the console should function in Linux? Does your driver really work? – sawdust Jul 31 '21 at 01:32
  • I have tried earlycon=sbi for which it worked as you mentioned. The 230 ms delay is due to the fact that the driver is being taking time as there are things like PLIC to be initailized before that. – turbo Jul 31 '21 at 08:29
  • Also what I was meaning by _this?_ is that the kernel log shows `printk: console [ttySHAKTI0] enabled` and I have had a look at imx's log where there wasn't **printk :** before the word _console [...] enabled_ which made me think that kernel specifying that _printk :_ could have caused the kernel to print only kernel logs(printk) statements. I was asking how to make this as a primary console(to login and all) any configuration changes or any changes in the driver code? Thanks @sawdust – turbo Jul 31 '21 at 08:30
  • *"I was asking how to make this as a primary console(to login and all) ..."* -- The `console=` command parameter only specifies devices for kernel messages. It does not setup/configure an interactive terminal. A kernel "console" on UART typically does not even have input capability. The [struct console](https://elixir.bootlin.com/linux/v5.5/source/include/linux/console.h#L145) does allow a read function, but **drivers/tty/serial/** drivers don't implement it. To login on a serial terminal, that is handled by using **getty**; study **Documentation/admin-guide/serial-console.rst**. – sawdust Jul 31 '21 at 10:45
  • Thanks for the info @sawdust. I wasn't aware of this. I have tried to add the serial prefix at the /etc/inittab file so that the getty can handle the login stuff. I have also reconfigured in the busybox menuconfig so that the it gets in the rootfs. But still I am not able to see any change. I will check the code once again. – turbo Aug 02 '21 at 05:35
  • Also @sawdust is there anyother way to get the login prompt or make this as a console(which is used by kernel log and the normal print statements)? – turbo Aug 02 '21 at 07:00
  • *"is there anyother way ..."* -- Study [Documentation/admin-guide/serial-console.rst](https://elixir.bootlin.com/linux/v5.5/source/Documentation/admin-guide/serial-console.rst). See https://stackoverflow.com/questions/68307458/how-to-set-linux-kernel-command-line-on-arm/68340492#68340492 Other arches don't have the ATAGs constraining the choices. Note that *"if no console device is specified, the first device found capable of acting as a system console will be used."* – sawdust Aug 02 '21 at 19:36
  • @sawdust the /dev/console should be the console and all the characters written to it should be printed on the console right? in that sense does this console get goofed up? – turbo Aug 09 '21 at 10:25

1 Answers1

1

I get to see the output only when there is not console parameter while if I specify the console parameter the log stops after "Starting Kernel...".

That implies that
a. when you do specify a console, that device or its driver is not functioning as expected.
and
b. when you do not specify a console, the kernel is defaulting to a serial terminal that it found capable of acting as a system console.
As documented in Documentation/admin-guide/serial-console.rst:

If no console device is specified [in the command line], the first device found capable 
of acting as a system console will be used.  
...  
So if you don't have a VGA card in your system the first serial port will automatically 
become the console.

So I was trying to find if the linux kernel uses the u-boot serial driver to print and get characters.

As already mentioned, the Linux kernel will not execute code outside its own image.
However there is the "low-level kernel debugging" feature (CONFIG_DEBUG_LL and its friends) (that may be architecture dependent) that will utilize a UART already initialized by the bootloader. This feature requires the hardcoding of device addresses so that the kernel is immediately capable of displaying text messages without having to perform any device initialization.
The EARLYPRINTK feature depends on this pre-initialized serial port.


I am wondering which driver is being used to print data and get data from the console.

Displaying kernel messages is a separate functionality from "get data from the console".
The kernel console is essentially an ouput-only device. For example on a PC, Linux can use the VGA display adapter as the console; a display adapter has no input capability. The console is merely a device for the kernel to display its messages.

The console=... kernel parameter does not setup/configure an interactive terminal. A kernel console on UART typically does not even have input capability. The struct console does allow a read function (for input), but drivers/tty/serial/ drivers don't implement it.
The capability to login on a serial terminal is provided by using the getty command (in userspace); study Documentation/admin-guide/serial-console.rst.


As an experiment, I booted a Linux ARM SBC, but edited the bootargs variable so that there was no console=ttyS0... parameter in the command line.
Kernel boot messages were displayed anyway over the serial link, there was a printk: console [tty0] enabled message, and after the UART driver was initialized, the message printk: console [ttyS0] enabled was displayed.

Booting Linux on physical CPU 0x0
Linux version 5.4.81-linux4sam-2020.10 (oe-user@oe-host) (gcc version 9.3.0 (GCC)) #1 Thu Jan 14 12:54:56 UTC 2021
... 
Kernel command line: root=/dev/mmcblk0p1 rw rootfstype=ext4 rootwait atmel.pm_modes=standby,ulp1
...  
Switching to timer-based delay loop, resolution 96ns
Console: colour dummy device 80x30
printk: console [tty0] enabled
Calibrating delay loop (skipped), value calculated using timer frequency.. 20.75 BogoMIPS (lpj=103750)

...  

atmel_usart_serial.0.auto: ttyS0 at MMIO 0xf8020000 (irq = 35, base_baud = 5187500) is a ATMEL_SERIAL
printk: console [ttyS0] enabled 
...

So this kernel defaults to using the first serial terminal for the console as documented: "If no console device is specified, ... the first serial port will automatically become the console."


Your boot log has the following

[    0.000000] Linux version 5.5.0-rc1-00032-g264b43306b8c-dirty (venkatakrishnan@venkatakrishnan-ubuntu) (gcc version 10.2.0 (GCC)) #22 Tue Jul 27 15:02:20 IST 2021

 ...
[    0.000000] Kernel command line: console=ttySHAKTI0,19200n8 earlycon root=/dev/mmcblk1p1 rw rootfs=ext4 noinitrd selinux=0

 ...
[    1.639770] Shakti UART Probing started...
[    1.669952] 11300.uart: ttySHAKTI0 at MMIO 0x11300 (irq = 0, base_baud = 0) is a Shakti UART 0
[  234.333038] printk: console [ttySHAKTI0] enabled

So it appears that the specification of console=ttySHAKTI0... was effective, since the kernel reports that the console is enabled for /dev/ttySHAKTI0.
The specification of earlycon in the command line seems to be ineffective, since that typically generates an appropriate message, and there is not any such message.

If you expect to login using /dev/ttySHAKTI0, then that would depend on a fully-functioning serial terminal driver (i.e. a UART driver that supports termios functions), and a proper /etc/inittab entry that (repeatedly) executes (or respawns) getty (or a variant) on that terminal device.
For example my Linux ARM SBC has:

S0:12345:respawn:/bin/start_getty 115200 ttyS0 vt102

where start_getty is a script used to automatically set up the serial terminal(s) for login on startup.
This login specification is independent of the console=... kernel parameter. But convention is to use the same device for both duties, which can cause confusion as to what a "console" is.

sawdust
  • 16,103
  • 3
  • 40
  • 50
  • Does providing an empty termios function with nothing inside the function make the system work (just asking for testing?) – turbo Aug 10 '21 at 07:58
  • I've answered your original question (and more). Do not try to expand the scope of this post to debug your driver. That is how this site is supposed to work. – sawdust Aug 10 '21 at 20:57