PRINTK printed information is not printed until the console is registered, but before the console is registered in Start_kernel
There are already printk movements. This information is stored in the PRINTK buf, which can be configured as a BUF size:
General Setup
Kernel Log buffer size (+ 64KB, + = 128KB)
14=2^14=16KB, 16=2^16=64kb ...
Printk->vprintk_emit->
->log_store Saving print information to BUF in PRINTK
->console_unlock->call_console_drivers->console->write Printing Information
Registry of the console:
static struct Console cdns_uart_console = {
. Name = Cdns_uart_tty_name,
. Write = Cdns_uart_console_write,
. device = Uart_console_device,
. Setup = Cdns_uart_console_setup,
. Flags = Con_printbuffer, Print out the PRINTK information of BUF
. Index =-1,/* Specified on the cmdline (e.g. console=ttyps) */
. Data = &cdns_uart_uart_driver,
};
static int __init cdns_uart_console_init (void)
{
Register_console (&cdns_uart_console);
return 0;
}
Console_initcall (Cdns_uart_console_init);
#define Console_initcall (FN) \
static initcall_t __initcall_# #fn \
__used __section (. Con_initcall.init) = fn
CONSOLE_INITCALL macro definition put Cdns_uart_console_init in the. Con_initcall.init segment, which can be found from Vmlinux.lds.
__con_initcall_start =.; * (. con_initcall.init) __con_initcall_end =.;
The starting address of the segment is __con_initcall_start, and all functions in that segment are called in the Driver\tty\tty_io.c\console_init function.
Console_init is called in the Start_kernel function. The registry and driver of the console are irrelevant, and it has its own setup,write function,
After the Register_console, the console can output information.
for (i = 0, c = console_cmdline;
I < Max_cmdlineconsoles && c->name[0];
i++, C + +) {
if (strcmp (C->name, newcon->name)! = 0)/* Console->name defined in the driver to be consistent with the command line */
Continue
if (newcon->index >= 0 &&
Newcon->index! = c->index)
Continue
if (Newcon->index < 0)
Newcon->index = c->index;
if (_braille_register_console (Newcon, C))
Return
if (Newcon->setup &&
Newcon->setup (Newcon, console_cmdline[i].options)! = 0)/* Call the Console->setup function, options are parameters such as 115200n81 */
Break
Newcon->flags |= con_enabled;
Newcon->index = c->index;
if (i = = Selected_console) {
Newcon->flags |= Con_consdev;
Preferred_console = Selected_console;
}
Break
}
if (Newcon->flags & Con_printbuffer) {//The BUF information is printed only if Con_printbuffer is set
/*
* Console_unlock (); Would print out the buffered messages
* For us.
*/
Raw_spin_lock_irqsave (&logbuf_lock, flags);
Console_seq = Syslog_seq;
Console_idx = Syslog_idx;
Console_prev = Syslog_prev;
Raw_spin_unlock_irqrestore (&logbuf_lock, flags);
/*
* We ' re about to replay the log buffer. Only does this
* Just-registered Console to avoid excessive message spam to
* The already-registered consoles.
*/
Exclusive_console = Newcon;
}
Console_unlock (); The function prints the information into the UART.
Linux Serial Console Registration