Skip to contentSkip to conversation

early printk for x86

PATCH In review Dave Hansen 6 participants 12 messages Nov 14, 2002 – Nov 18, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 early printk for x86

I copied the x86_64 early printk support for plain x86. Is anyone opposed to me sending this on to Linus?

Signature · 2 lines
Dave Hansen
[email protected]
arch/i386/Kconfig +20 -0
diff -urN linux-2.5.47-clean/arch/i386/Kconfig linux-2.5.47/arch/i386/Kconfig
@@ -1574,6 +1574,26 @@
 	  that can still be used by old drivers that are being ported from
 	  2.0/2.2.
 
+config EARLY_PRINTK
+	bool "Early console support"
+	default n
+	depends on DEBUG_KERNEL
+	help
+	  Write kernel log output directly into the VGA buffer or serial port. 
+	  This is useful for kernel debugging when your machine crashes very 
+	  early before the console code is initialized. For normal operation 
+	  it is not recommended because it looks ugly and doesn't cooperate 
+	  with klogd/syslogd or the X server.You should normally N here, 
+	  unless you want to debug such a crash.
+
+	  Syntax: earlyprintk=vga
+		  earlyprintk=serial[,ttySn[,baudrate]] 
+	  Append ,keep to not disable it when the real console takes over.
+	  Only vga or serial at a time, not both.
+	  Currently only ttyS0 and ttyS1 are supported. 
+	  Interaction with the standard serial driver is not very good. 
+	  The VGA output is eventually overwritten by the real console.
+
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
 	depends on DEBUG_KERNEL
arch/i386/kernel/Makefile +1 -0
diff -urN linux-2.5.47-clean/arch/i386/kernel/Makefile linux-2.5.47/arch/i386/kernel/Makefile
@@ -28,6 +28,7 @@
 obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
 obj-$(CONFIG_PROFILING)		+= profile.o
 obj-$(CONFIG_EDD)             	+= edd.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 EXTRA_AFLAGS   := -traditional
 
arch/i386/kernel/early_printk.c +220 -0

220 lines not on this page · raw message

arch/i386/kernel/setup.c +6 -0
diff -urN linux-2.5.47-clean/arch/i386/kernel/setup.c linux-2.5.47/arch/i386/kernel/setup.c
@@ -84,6 +84,7 @@
 
 extern void early_cpu_init(void);
 extern void dmi_scan_machine(void);
+extern void setup_early_printk(char *);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 extern int blk_nohighio;
@@ -836,7 +837,12 @@
 void __init setup_arch(char **cmdline_p)
 {
 	unsigned long max_low_pfn;
+	char* s;
 
+	s = strstr(saved_command_line, "earlyprintk=");
+	if (s != NULL)
+		setup_early_printk(s+12);
+	
 	pre_setup_arch_hook();
 	early_cpu_init();
 
#1 lore raw
Quoted 2 lines · Dave Hansen

I copied the x86_64 early printk support for plain x86. Is anyone opposed to me sending this on to Linus?

No problem from my side.

although it may make sense to just put in the #ifdef __i386__ for vgabase and then #include it.

-Andi

#2 lore raw
In reply to Dave Hansen

VGA and serial are certainly not hammer+ia32-specific. Make the generic parts generic... the arch-specific components would need to change early-foo base addresses perhaps, but otherwise, it's pretty generic.

Jeff

#7 lore raw
In reply to Dave Hansen

VGA and serial are certainly not hammer+ia32-specific. Make the generic parts generic... the arch-specific components would need to change early-foo base addresses perhaps, but otherwise, it's pretty generic.

Jeff

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

#3 lore raw
In reply to Jeff Garzik
Quoted 1 line · Jeff Garzik

VGA and serial are certainly not hammer+ia32-specific. Make the generic parts generic... the arch-specific components would need to change early-foo base addresses perhaps, but otherwise, it's pretty generic.

Take 2.

- Move the x86_64 early_printk.c into kernel/
- move some of the basic defines into linux/early_printk.h and asm-{i386,x86_64}/early_printk.h
- run the setup in start_kernel() before setup_arch()

arch/i386/Kconfig                 |   20 +++
arch/x86_64/kernel/early_printk.c |  218 -----------------------------
arch/x86_64/kernel/head64.c       |    5
include/asm-i386/early_printk.h   |    8 +
include/asm-x86_64/early_printk.h |    8 +
include/linux/early_printk.h      |   47 ++++++++
init/main.c                       |    1
kernel/Makefile                   |    1
kernel/early_printk.c             |  209 +++++++++++++++++++++++++++++
 9 files changed, 295 insertions(+), 222 deletions(-)
Signature · 2 lines
Dave Hansen
[email protected]
arch/i386/Kconfig +20 -0
diff -urN linux-2.5.47-clean/arch/i386/Kconfig linux-2.5.47/arch/i386/Kconfig
@@ -1588,6 +1588,26 @@
 	  keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
 	  unless you really know what this hack does.
 
+config EARLY_PRINTK
+	bool "Early console support"
+	default n
+	depends on DEBUG_KERNEL
+	help
+	  Write kernel log output directly into the VGA buffer or serial port. 
+	  This is useful for kernel debugging when your machine crashes very 
+	  early before the console code is initialized. For normal operation 
+	  it is not recommended because it looks ugly and doesn't cooperate 
+	  with klogd/syslogd or the X server.You should normally N here, 
+	  unless you want to debug such a crash.
+
+	  Syntax: earlyprintk=vga
+		  earlyprintk=serial[,ttySn[,baudrate]] 
+	  Append ,keep to not disable it when the real console takes over.
+	  Only vga or serial at a time, not both.
+	  Currently only ttyS0 and ttyS1 are supported. 
+	  Interaction with the standard serial driver is not very good. 
+	  The VGA output is eventually overwritten by the real console.
+
 config DEBUG_SPINLOCK
 	bool "Spinlock debugging"
 	depends on DEBUG_KERNEL
arch/x86_64/kernel/early_printk.c +0 -218

218 lines not on this page · raw message

arch/x86_64/kernel/head64.c +1 -4
diff -urN linux-2.5.47-clean/arch/x86_64/kernel/head64.c linux-2.5.47/arch/x86_64/kernel/head64.c
@@ -70,7 +70,7 @@
 	boot_cpu_data.x86_mask = eax & 0xf;
 }
 
-extern void start_kernel(void), pda_init(int), setup_early_printk(char *); 
+extern void start_kernel(void), pda_init(int); 
 extern int disable_apic;
 
 void __init x86_64_start_kernel(char * real_mode_data)
@@ -80,9 +80,6 @@
 	clear_bss();
 	pda_init(0);
 	copy_bootdata(real_mode_data);
-	s = strstr(saved_command_line, "earlyprintk="); 
-	if (s != NULL)
-		setup_early_printk(s+12); 
 #ifdef CONFIG_X86_IO_APIC
 	if (strstr(saved_command_line, "disableapic"))
 		disable_apic = 1;
include/asm-i386/early_printk.h +8 -0
diff -urN linux-2.5.47-clean/include/asm-i386/early_printk.h linux-2.5.47/include/asm-i386/early_printk.h
@@ -0,0 +1,8 @@
+#ifndef __EARLY_PRINTK_H_I386_
+#define __EARLY_PRINTK_H_i386_
+
+#define VGABASE  0xB8000
+#define SERIAL_BASES { 0x3f8, 0x2f8 }
+#define SERIAL_BASES_LEN 2
+
+#endif
include/asm-x86_64/early_printk.h +8 -0
diff -urN linux-2.5.47-clean/include/asm-x86_64/early_printk.h linux-2.5.47/include/asm-x86_64/early_printk.h
@@ -0,0 +1,8 @@
+#ifdef __EARLY_PRINTK_H_X86_64_
+#define __EARLY_PRINTK_H_X86_64_
+
+#define VGABASE	0xffffffff800b8000UL
+#define SERIAL_BASES { 0x3f8, 0x2f8 }
+#define SERIAL_BASES_LEN 2
+
+#endif

Binary files linux-2.5.47-clean/include/linux/.early_printk.h.swp and linux-2.5.47/include/linux/.early_printk.h.swp differ

include/linux/early_printk.h +47 -0

47 lines not on this page · raw message

init/main.c +2 -0
diff -urN linux-2.5.47-clean/init/main.c linux-2.5.47/init/main.c
@@ -33,6 +33,7 @@
 #include <linux/workqueue.h>
 #include <linux/profile.h>
 #include <linux/rcupdate.h>
+#include <linux/early_printk.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -387,6 +388,7 @@
  */
 	lock_kernel();
 	printk(linux_banner);
+	setup_early_printk(&command_line);
 	setup_arch(&command_line);
 	setup_per_cpu_areas();
 	build_all_zonelists();
kernel/Makefile +1 -0
diff -urN linux-2.5.47-clean/kernel/Makefile linux-2.5.47/kernel/Makefile
@@ -21,6 +21,7 @@
 obj-$(CONFIG_CPU_FREQ) += cpufreq.o
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/early_printk.c +209 -0

209 lines not on this page · raw message

#8 lore raw
In reply to Dave Hansen

Looks pretty decent to me... minor comments:

* might be a good idea to match defaults with the defaults of the normal serial console. IIRC that's 38400,N,8,1. which brings up a tangent, 57600 or 115200 is probably preferred these days, but that requires a later patch to update serial console and early serial console to be faster

* VGA base might want to be a variable, though I have not convinced myself that such is useful

#4 lore raw
In reply to Dave Hansen
Quoted 11 lines · Dave Hansen
Quoted 3 lines · Jeff Garzik

VGA and serial are certainly not hammer+ia32-specific. Make the generic
parts generic... the arch-specific components would need to change
early-foo base addresses perhaps, but otherwise, it's pretty generic.

Take 2.

- Move the x86_64 early_printk.c into kernel/
- move some of the basic defines into linux/early_printk.h and asm-{i386,x86_64}/early_printk.h
- run the setup in start_kernel() before setup_arch()

That's overkill. Most architectures have an early_printk equivalent in firmware. Only i386 and x86-64 are not lucky enough to have one that is usable from the CPU mode linux uses.

-Andi

#5 lore raw
Quoted 3 lines · Jeff Garzik
Quoted 3 lines
Quoted 3 lines

VGA and serial are certainly not hammer+ia32-specific. Make the generic
parts generic... the arch-specific components would need to change
early-foo base addresses perhaps, but otherwise, it's pretty generic.

Quoted 5 lines · Dave Hansen
Quoted 5 lines

Take 2.
- Move the x86_64 early_printk.c into kernel/
- move some of the basic defines into linux/early_printk.h and asm-{i386,x86_64}/early_printk.h
- run the setup in start_kernel() before setup_arch()

Quoted 3 lines · Andi Kleen

That's overkill. Most architectures have an early_printk equivalent in firmware. Only i386 and x86-64 are not lucky enough to have one that is usable from the CPU mode linux uses.

Perhaps s/early_printk/prom_printf/ would pick up a few arches for free.

Bill

#6 lore raw
In reply to Andi Kleen
Followup to:  <[email protected]>
By author:    Andi Kleen <[email protected]>
In newsgroup: linux.dev.kernel
Quoted 5 lines

That's overkill. Most architectures have an early_printk equivalent in firmware. Only i386 and x86-64 are not lucky enough to have one that is usable from the CPU mode linux uses.

That's a pretty big assumption. I wouldn't hold that to be necessarily true.

-hpa

Signature · 3 lines
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt	<[email protected]>
#9 lore raw
In reply to Dave Hansen
Quoted 2 lines · [email protected] said:

1. I copied the x86_64 early printk support for plain x86. Is
anyone opposed to me sending this on to Linus?

Why is it necessary to reimplement serial console for each arch rather than just registering the generic serial console as early as possible from arch-specific code?

There's no _reason_ to wait for console_init(), for most consoles.

--
dwmw2

#10 lore raw
Quoted 10 lines · David Woodhouse
Quoted 2 lines · [email protected] said:

1. I copied the x86_64 early printk support for plain x86. Is
anyone opposed to me sending this on to Linus?

Why is it necessary to reimplement serial console for each arch rather than just registering the generic serial console as early as possible from arch-specific code?

There's no _reason_ to wait for console_init(), for most consoles.

The generic serial driver needs lots of infrastructure that is not present in early boot. Also the early_printk serial driver is polled, not interrupt driven. The whole point of early_printk is that you can debug from line one of your code, so it is essential that it is self contained as far as possible.

-Andi

#11 lore raw
Quoted 3 lines · [email protected] said:

The generic serial driver needs lots of infrastructure that is not
present in early boot. Also the early_printk serial driver is polled, not interrupt driven.

No, the generic serial _console_ is polled and should require no more infrastructure than the early_console version which it strongly resembles.

After all, it's generally called from console_init(), at which point there's little more infrastructure available than in setup_arch() _anyway_.

You should happily be able to call serial8250_console_init() earlier then console_init() currently does.

(Btw, if you're playing with this code I posted a cleanup to all the horrible #ifdefs in console_init, converting it to the __initcall mechanism.
http://marc.theaimsgroup.com/?l=linux-kernel&m=103660078206270&w=2 )

--
dwmw2