Skip to content

Commit

Permalink
Fixes and cleanups for earlyprintk aka boot console
Browse files Browse the repository at this point in the history
The console subsystem already has an idea of a boot console, using the
CON_BOOT flag.  The implementation has some flaws though.  The major
problem is that presence of a boot console makes register_console() ignore
any other console devices (unless explicitly specified on the kernel
command line).

This patch fixes the console selection code to *not* consider a boot
console a full-featured one, so the first non-boot console registering will
become the default console instead.  This way the unregister call for the
boot console in the register_console() function actually triggers and the
handover from the boot console to the real console device works smoothly.
Added a printk for the handover, so you know which console device the
output goes to when the boot console stops printing messages.

The disable_early_printk() call is obsolete with that patch, explicitly
disabling the early console isn't needed any more as it works automagically
with that patch.

I've walked through the tree, dropped all disable_early_printk() instances
found below arch/ and tagged the consoles with CON_BOOT if needed.  The
code is tested on x86, sh (thanks to Paul) and mips (thanks to Ralf).

Changes to last version: Rediffed against -rc3, adapted to mips cleanups by
Ralf, fixed "udbg-immortal" cmd line arg on powerpc.

Signed-off-by: Gerd Hoffmann <[email protected]>
Acked-by: Paul Mundt <[email protected]>
Acked-by: Ralf Baechle <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Alan Cox <[email protected]>
Cc: Richard Henderson <[email protected]>
Cc: Ivan Kokshaysky <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Jeremy Fitzhardinge <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Gerd Hoffmann authored and Linus Torvalds committed May 8, 2007
1 parent 6ae9200 commit 69331af
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 77 deletions.
9 changes: 0 additions & 9 deletions arch/alpha/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,15 +744,6 @@ setup_arch(char **cmdline_p)
paging_init();
}

void __init
disable_early_printk(void)
{
if (alpha_using_srm && srmcons_output) {
unregister_srm_console();
srmcons_output = 0;
}
}

static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
"0",
Expand Down
2 changes: 1 addition & 1 deletion arch/alpha/kernel/srmcons.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ static struct console srmcons = {
.write = srm_console_write,
.device = srm_console_device,
.setup = srm_console_setup,
.flags = CON_PRINTBUFFER,
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};

Expand Down
5 changes: 0 additions & 5 deletions arch/mips/kernel/early_printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,3 @@ void __init setup_early_printk(void)
{
register_console(&early_console);
}

void __init disable_early_printk(void)
{
unregister_console(&early_console);
}
19 changes: 6 additions & 13 deletions arch/powerpc/kernel/udbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,29 +142,22 @@ static void udbg_console_write(struct console *con, const char *s,
static struct console udbg_console = {
.name = "udbg",
.write = udbg_console_write,
.flags = CON_PRINTBUFFER | CON_ENABLED,
.flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT,
.index = -1,
};

static int early_console_initialized;

void __init disable_early_printk(void)
{
if (!early_console_initialized)
return;
if (strstr(boot_command_line, "udbg-immortal")) {
printk(KERN_INFO "early console immortal !\n");
return;
}
unregister_console(&udbg_console);
early_console_initialized = 0;
}

/* called by setup_system */
void register_early_udbg_console(void)
{
if (early_console_initialized)
return;

if (strstr(boot_command_line, "udbg-immortal")) {
printk(KERN_INFO "early console immortal !\n");
udbg_console.flags &= ~CON_BOOT;
}
early_console_initialized = 1;
register_console(&udbg_console);
}
Expand Down
18 changes: 6 additions & 12 deletions arch/sh/kernel/early_printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,20 +192,14 @@ int __init setup_early_printk(char *buf)
}
#endif

if (likely(early_console))
if (likely(early_console)) {
if (keep_early)
early_console->flags &= ~CON_BOOT;
else
early_console->flags |= CON_BOOT;
register_console(early_console);
}

return 0;
}
early_param("earlyprintk", setup_early_printk);

void __init disable_early_printk(void)
{
if (!early_console_initialized || !early_console)
return;
if (!keep_early) {
printk("disabling early console\n");
unregister_console(early_console);
} else
printk("keeping early console\n");
}
8 changes: 1 addition & 7 deletions arch/sh64/kernel/early_printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static struct console sh_console = {
.name = "scifcon",
.write = sh_console_write,
.setup = sh_console_setup,
.flags = CON_PRINTBUFFER,
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};

Expand All @@ -97,9 +97,3 @@ void __init enable_early_printk(void)

register_console(&sh_console);
}

void disable_early_printk(void)
{
unregister_console(&sh_console);
}

20 changes: 5 additions & 15 deletions arch/x86_64/kernel/early_printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,22 +243,12 @@ static int __init setup_early_printk(char *buf)
early_console = &simnow_console;
keep_early = 1;
}

if (keep_early)
early_console->flags &= ~CON_BOOT;
else
early_console->flags |= CON_BOOT;
register_console(early_console);
return 0;
}

early_param("earlyprintk", setup_early_printk);

void __init disable_early_printk(void)
{
if (!early_console_initialized || !early_console)
return;
if (!keep_early) {
printk("disabling early console\n");
unregister_console(early_console);
early_console_initialized = 0;
} else {
printk("keeping early console\n");
}
}

5 changes: 0 additions & 5 deletions drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ static DECLARE_MUTEX(allocated_ptys_lock);
static int ptmx_open(struct inode *, struct file *);
#endif

extern void disable_early_printk(void);

static void initialize_tty_struct(struct tty_struct *tty);

static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
Expand Down Expand Up @@ -3897,9 +3895,6 @@ void __init console_init(void)
* set up the console device so that later boot sequences can
* inform about problems etc..
*/
#ifdef CONFIG_EARLY_PRINTK
disable_early_printk();
#endif
call = __con_initcall_start;
while (call < __con_initcall_end) {
(*call)();
Expand Down
26 changes: 16 additions & 10 deletions kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,8 +931,16 @@ void register_console(struct console *console)
{
int i;
unsigned long flags;
struct console *bootconsole = NULL;

if (preferred_console < 0)
if (console_drivers) {
if (console->flags & CON_BOOT)
return;
if (console_drivers->flags & CON_BOOT)
bootconsole = console_drivers;
}

if (preferred_console < 0 || bootconsole || !console_drivers)
preferred_console = selected_console;

/*
Expand Down Expand Up @@ -978,8 +986,11 @@ void register_console(struct console *console)
if (!(console->flags & CON_ENABLED))
return;

if (console_drivers && (console_drivers->flags & CON_BOOT)) {
unregister_console(console_drivers);
if (bootconsole) {
printk(KERN_INFO "console handover: boot [%s%d] -> real [%s%d]\n",
bootconsole->name, bootconsole->index,
console->name, console->index);
unregister_console(bootconsole);
console->flags &= ~CON_PRINTBUFFER;
}

Expand Down Expand Up @@ -1030,16 +1041,11 @@ int unregister_console(struct console *console)
}
}

/* If last console is removed, we re-enable picking the first
* one that gets registered. Without that, pmac early boot console
* would prevent fbcon from taking over.
*
/*
* If this isn't the last console and it has CON_CONSDEV set, we
* need to set it on the next preferred console.
*/
if (console_drivers == NULL)
preferred_console = selected_console;
else if (console->flags & CON_CONSDEV)
if (console_drivers != NULL && console->flags & CON_CONSDEV)
console_drivers->flags |= CON_CONSDEV;

release_console_sem();
Expand Down

0 comments on commit 69331af

Please sign in to comment.