Skip to contentSkip to conversation

serial: make early_uart to use early_prarm instead of console_initcall

PATCH In review Yinghai Lu 6 participants 15 messages May 19, 2007 – May 21, 2007

Subsystems (3)
lore
Share & tools
lore

Yinghai Lu

author
#0 lore raw

PATCH 1/1 serial: make early_uart to use early_prarm instead of console_initcall

[PATCH]serial: make early_uart to use early_prarm instead of console_initcall

Make early_uart to use early_param, so uart console can be used earlier. Make it to be bootconsole with CON_BOOT flag, so can use console handover feature. and it will switch to corresponding normal serial console automatically. new command line will be

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0

it will print in very early stage
Early serial console at I/O port 0x3f8 (options '9600n8') later for console it will print
console handover: boot [uart0] -> real [ttyS0]

Signed-off-by <[email protected]>
drivers/serial/8250.c +2 -21
index c84dab0..75459e8 100644
@@ -2367,6 +2367,7 @@ static struct uart_ops serial8250_pops = {
 	.request_port	= serial8250_request_port,
 	.config_port	= serial8250_config_port,
 	.verify_port	= serial8250_verify_port,
+	.find_port_for_earlycon = serial8250_find_port_for_earlycon,
 };
 
 static struct uart_8250_port serial8250_ports[UART_NR];
@@ -2533,7 +2534,7 @@ static int __init serial8250_console_init(void)
 }
 console_initcall(serial8250_console_init);
 
-static int __init find_port(struct uart_port *p)
+int __init find_port_serial8250(struct uart_port *p)
 {
 	int line;
 	struct uart_port *port;
@@ -2546,26 +2547,6 @@ static int __init find_port(struct uart_port *p)
 	return -ENODEV;
 }
 
-int __init serial8250_start_console(struct uart_port *port, char *options)
-{
-	int line;
-
-	line = find_port(port);
-	if (line < 0)
-		return -ENODEV;
-
-	add_preferred_console("ttyS", line, options);
-	printk("Adding console on ttyS%d at %s 0x%lx (options '%s')\n",
-		line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port",
-		port->iotype == UPIO_MEM ? (unsigned long) port->mapbase :
-		    (unsigned long) port->iobase, options);
-	if (!(serial8250_console.flags & CON_ENABLED)) {
-		serial8250_console.flags &= ~CON_PRINTBUFFER;
-		register_console(&serial8250_console);
-	}
-	return line;
-}
-
 #define SERIAL8250_CONSOLE	&serial8250_console
 #else
 #define SERIAL8250_CONSOLE	NULL
drivers/serial/8250_early.c +44 -42

137 lines not on this page · raw message

drivers/serial/Kconfig +6 -0
index 315ea99..fc58473 100644
@@ -62,6 +62,12 @@ config SERIAL_8250_CONSOLE
 	  kernel will automatically use the first serial line, /dev/ttyS0, as
 	  system console.
 
+	  you can set that using a kernel command line option such as
+	  "earlycon=uart,io,0x3f8,9600n8" or 
+	  "earlycon=uart,mem,0xfe000008,115200n8". 
+	  and it will switch to normal serial console when correponding port is 
+	  ready.
+
 	  If unsure, say N.
 
 config SERIAL_8250_GSC
drivers/serial/Makefile +0 -0
drivers/serial/serial_core.c +4 -1
index 326020f..956d435 100644
@@ -2303,8 +2303,11 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
 	 * It may be that the port was not available.
 	 */
 	if (port->type != PORT_UNKNOWN &&
-	    port->cons && !(port->cons->flags & CON_ENABLED))
+	    port->cons && !(port->cons->flags & CON_ENABLED)) {
+		if(port->ops && port->ops->find_port_for_earlycon) 
+			port->ops->find_port_for_earlycon();
 		register_console(port->cons);
+	}
 
 	/*
 	 * Ensure UPF_DEAD is not set.
include/linux/console.h +1 -0
index 62ef6e1..4cb7749 100644
@@ -107,6 +107,7 @@ struct console {
 };
 
 extern int add_preferred_console(char *name, int idx, char *options);
+extern int update_console_cmdline_console_index(char *name, int idx_old, int idx_new);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern struct console *console_drivers;
include/linux/serial.h +0 -6
index 33fc8cb..deb7143 100644
@@ -177,11 +177,5 @@ struct serial_icounter_struct {
 #ifdef __KERNEL__
 #include <linux/compiler.h>
 
-/* Allow architectures to override entries in serial8250_ports[] at run time: */
-struct uart_port;	/* forward declaration */
-extern int early_serial_setup(struct uart_port *port);
-extern int early_serial_console_init(char *options);
-extern int serial8250_start_console(struct uart_port *port, char *options);
-
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SERIAL_H */
include/linux/serial_8250.h +3 -0
index 71310d8..0d79fc5 100644
@@ -60,4 +60,7 @@ void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
 void serial8250_resume_port(int line);
 
+extern int find_port_serial8250(struct uart_port *p);
+extern int serial8250_find_port_for_earlycon(void);
+
 #endif
include/linux/serial_core.h +5 -0
index a3ac4c8..b74fa4a 100644
@@ -199,6 +199,11 @@ struct uart_ops {
 	void		(*config_port)(struct uart_port *, int);
 	int		(*verify_port)(struct uart_port *, struct serial_struct *);
 	int		(*ioctl)(struct uart_port *, unsigned int, unsigned long);
+	
+	/*
+	 * for earlycon to console switch
+	 */
+	int		(*find_port_for_earlycon)(void);
 };
 
 #define UART_CONFIG_TYPE	(1 << 0)
init/main.c +0 -0
kernel/printk.c +15 -0
index 0bbdeac..253c0f7 100644
@@ -726,6 +726,21 @@ int __init add_preferred_console(char *name, int idx, char *options)
 	return 0;
 }
 
+int __init update_console_cmdline_console_index(char *name, int idx_old, int idx_new)
+{
+	int i;
+
+	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+		if (strcmp(console_cmdline[i].name, name) == 0 &&
+			  console_cmdline[i].index == idx_old) {
+			  	console_cmdline[i].index = idx_new;
+				return 0;
+		}
+
+	return 0;
+}
+	
+
 #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
 /**
  * suspend_console - suspend the console subsystem
#1 lore raw
Quoted 7 lines · On Fri, 18 May 2007 19:00:16 -0700 Yinghai Lu <[email protected]> wrote:

[PATCH]serial: make early_uart to use early_prarm instead of console_initcall

Make early_uart to use early_param, so uart console can be used earlier. Make it to be bootconsole with CON_BOOT flag, so can use console handover feature. and it will switch to corresponding normal serial console automatically. new command line will be

Quoted 7 lines

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0

it will print in very early stage
Early serial console at I/O port 0x3f8 (options '9600n8') later for console it will print
console handover: boot [uart0] -> real [ttyS0]

I'll queue this up for some testing, but I'd be a bit reluctant to send it into Linus due to my poor understanding of what it actually does. What _is_ an early console, and how does it differ from a non-early one?

Someone help, please.

Coudl you please provide a patch against
Documentation/kernel-parameters.txt as well?

#2 lore raw
Quoted 9 lines · Andrew Morton

I'll queue this up for some testing, but I'd be a bit reluctant to send it into Linus due to my poor understanding of what it actually does. What _is_ an early console, and how does it differ from a non-early one?

Someone help, please.

Coudl you please provide a patch against
Documentation/kernel-parameters.txt as well?

the story:
Bjorn refer to andi's early_printk to create one early_uart. it took console=uart,io,0x3f8,9600n8
or console=uart,mem,0xfxxx,115200n8.
and it is called via console_init. --- it is not really early uart for platform other than ia64.
ia64 call early_serial_console_init explicitly, so it is some early. but it needs to late_initcall to do console switch.

Gerd's patch (console handover) was merged into mainline. it will switch from early_printk to normal console in register_console via CON_BOOT flags.. ===> only for x86

I produced one patch to change early_uart calling from console_init to early_param. So to make early_uart to real early_uart for all other platform in addition to ia64.
it will take
earlycon=uart,io,0x3f8,9600n8 console=ttyS0,9600n8

but Bjorn said that don't let the customer to key two times about console command line.
Then come this patch. will take earlycon=uart,io,0x3f8,9600n8
and it will switch to console ttyS0 automatically. ---- by calling add_preferred_console.

Still need Bjorn to:
1. remove early_serial_console_init call in ia64 setup_arch.
2. verify mem io 8250 compatiable card.

for 2, in x86 platform we need to use fix_to_virt and fix map to give it one fixed virtual address. == like Eric did for usb debug port console.

I will send out another in email about updated early dbgp console with current tree.

YH

#3 lore raw
Quoted 40 lines · On Sun, 20 May 2007 21:29:20 -0700 "Yinghai Lu" <[email protected]> wrote:
Quoted 9 lines · Andrew Morton

I'll queue this up for some testing, but I'd be a bit reluctant to send it into Linus due to my poor understanding of what it actually does. What _is_ an early console, and how does it differ from a non-early one?

Someone help, please.

Coudl you please provide a patch against
Documentation/kernel-parameters.txt as well?

the story:
Bjorn refer to andi's early_printk to create one early_uart. it took console=uart,io,0x3f8,9600n8
or console=uart,mem,0xfxxx,115200n8.
and it is called via console_init. --- it is not really early uart for platform other than ia64.
ia64 call early_serial_console_init explicitly, so it is some early. but it needs to late_initcall to do console switch.

Gerd's patch (console handover) was merged into mainline. it will switch from early_printk to normal console in register_console via CON_BOOT flags.. ===> only for x86

I produced one patch to change early_uart calling from console_init to early_param. So to make early_uart to real early_uart for all other platform in addition to ia64.
it will take
earlycon=uart,io,0x3f8,9600n8 console=ttyS0,9600n8

but Bjorn said that don't let the customer to key two times about console command line.
Then come this patch. will take earlycon=uart,io,0x3f8,9600n8
and it will switch to console ttyS0 automatically. ---- by calling add_preferred_console.

Still need Bjorn to:
1. remove early_serial_console_init call in ia64 setup_arch.
2. verify mem io 8250 compatiable card.

Quoted 6 lines

for 2, in x86 platform we need to use fix_to_virt and fix map to give it one fixed virtual address. == like Eric did for usb debug port console.

I will send out another in email about updated early dbgp console with current tree.

hm, OK. I hope you guys have it under control ;)

With http://userweb.kernel.org/~akpm/config-vmm.txt I get

drivers/built-in.o:(.data+0x5790): undefined reference to `serial8250_find_port_for_earlycon'

#4 lore raw
Quoted 7 lines · Andrew Morton

hm, OK. I hope you guys have it under control ;)

With http://userweb.kernel.org/~akpm/config-vmm.txt I get

drivers/built-in.o:(.data+0x5790): undefined reference to `serial8250_find_port_for_earlycon'

please check this one

Bjorn,
I can not find fixmap.h for ia64.....hope you can use ioremap instead, then we can create one dummy fixmap.h in include/asm-ia64

[PATCH]serial: make early_uart to use early_prarm instead of console_initcall

Make early_uart to use early_param, so uart console can be used earlier. Make it to be bootconsole with CON_BOOT flag, so can use console handover feature. and it will switch to corresponding normal serial console automatically.
new command line will be

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0
earlycon=uart,mmio,0xff5e0000,115200n8

it will print in very early stage
Early serial console at I/O port 0x3f8 (options '9600n8') later for console it will print
console handover: boot [uart0] -> real [ttyS0]

Signed-off-by <[email protected]>
arch/i386/kernel/head.S +8 -0
index f74dfc4..2d37850 100644
@@ -168,6 +168,12 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
 .section .init.text,"ax",@progbits
 #endif
 
+	/* Do an early initialization of the fixmap area */
+	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
+	movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
+	addl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
+	movl %eax, 4092(%edx)
+
 #ifdef CONFIG_SMP
 ENTRY(startup_32_smp)
 	cld
@@ -507,6 +513,8 @@ ENTRY(_stext)
 .section ".bss.page_aligned","w"
 ENTRY(swapper_pg_dir)
 	.fill 1024,4,0
+ENTRY(swapper_pg_pmd)
+	.fill 1024,4,0	
 ENTRY(empty_zero_page)
 	.fill 4096,1,0
 
arch/x86_64/kernel/head.S +14 -1
index 1fab487..2da30ad 100644
@@ -73,7 +73,11 @@ startup_64:
 	addq	%rbp, init_level4_pgt + (511*8)(%rip)
 
 	addq	%rbp, level3_ident_pgt + 0(%rip)
+	
 	addq	%rbp, level3_kernel_pgt + (510*8)(%rip)
+	addq	%rbp, level3_kernel_pgt + (511*8)(%rip)
+
+	addq	%rbp, level2_fixmap_pgt + (506*8)(%rip)
 
 	/* Add an Identity mapping if I am above 1G */
 	leaq	_text(%rip), %rdi
@@ -314,7 +318,16 @@ NEXT_PAGE(level3_kernel_pgt)
 	.fill	510,8,0
 	/* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
 	.quad	level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
-	.fill	1,8,0
+ 	.quad	level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
+
+NEXT_PAGE(level2_fixmap_pgt)
+	.fill	506,8,0
+	.quad	level1_fixmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
+	/* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
+	.fill	5,8,0
+
+NEXT_PAGE(level1_fixmap_pgt)
+	.fill	512,8,0
 
 NEXT_PAGE(level2_ident_pgt)
 	/* Since I easily can, map the first 1G.
drivers/serial/8250.c +4 -21
index c84dab0..5a91ac5 100644
@@ -2367,6 +2367,9 @@ static struct uart_ops serial8250_pops = {
 	.request_port	= serial8250_request_port,
 	.config_port	= serial8250_config_port,
 	.verify_port	= serial8250_verify_port,
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	.find_port_for_earlycon = serial8250_find_port_for_earlycon,
+#endif
 };
 
 static struct uart_8250_port serial8250_ports[UART_NR];
@@ -2533,7 +2536,7 @@ static int __init serial8250_console_init(void)
 }
 console_initcall(serial8250_console_init);
 
-static int __init find_port(struct uart_port *p)
+int __init find_port_serial8250(struct uart_port *p)
 {
 	int line;
 	struct uart_port *port;
@@ -2546,26 +2549,6 @@ static int __init find_port(struct uart_port *p)
 	return -ENODEV;
 }
 
-int __init serial8250_start_console(struct uart_port *port, char *options)
-{
-	int line;
-
-	line = find_port(port);
-	if (line < 0)
-		return -ENODEV;
-
-	add_preferred_console("ttyS", line, options);
-	printk("Adding console on ttyS%d at %s 0x%lx (options '%s')\n",
-		line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port",
-		port->iotype == UPIO_MEM ? (unsigned long) port->mapbase :
-		    (unsigned long) port->iobase, options);
-	if (!(serial8250_console.flags & CON_ENABLED)) {
-		serial8250_console.flags &= ~CON_PRINTBUFFER;
-		register_console(&serial8250_console);
-	}
-	return line;
-}
-
 #define SERIAL8250_CONSOLE	&serial8250_console
 #else
 #define SERIAL8250_CONSOLE	NULL
drivers/serial/8250_early.c +34 -51

148 lines not on this page · raw message

drivers/serial/Kconfig +6 -0
index 315ea99..b1de60d 100644
@@ -62,6 +62,12 @@ config SERIAL_8250_CONSOLE
 	  kernel will automatically use the first serial line, /dev/ttyS0, as
 	  system console.
 
+	  you can set that using a kernel command line option such as
+	  "earlycon=uart,io,0x3f8,9600n8" or 
+	  "earlycon=uart,mmio,0xfe000008,115200n8". 
+	  and it will switch to normal serial console when correponding port is 
+	  ready.
+
 	  If unsure, say N.
 
 config SERIAL_8250_GSC
drivers/serial/serial_core.c +4 -1
index 326020f..956d435 100644
@@ -2303,8 +2303,11 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
 	 * It may be that the port was not available.
 	 */
 	if (port->type != PORT_UNKNOWN &&
-	    port->cons && !(port->cons->flags & CON_ENABLED))
+	    port->cons && !(port->cons->flags & CON_ENABLED)) {
+		if(port->ops && port->ops->find_port_for_earlycon) 
+			port->ops->find_port_for_earlycon();
 		register_console(port->cons);
+	}
 
 	/*
 	 * Ensure UPF_DEAD is not set.
include/asm-i386/fixmap.h +2 -0
index 80ea052..249e753 100644
@@ -54,6 +54,8 @@ extern unsigned long __FIXADDR_TOP;
 enum fixed_addresses {
 	FIX_HOLE,
 	FIX_VDSO,
+	FIX_DBGP_BASE,
+	FIX_EARLYCON_MEM_BASE,
 #ifdef CONFIG_X86_LOCAL_APIC
 	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
 #endif
include/asm-x86_64/fixmap.h +3 -1
index e90e167..2acb9b7 100644
@@ -35,6 +35,8 @@ enum fixed_addresses {
 	VSYSCALL_LAST_PAGE,
 	VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
 	VSYSCALL_HPET,
+	FIX_DBGP_BASE,
+	FIX_EARLYCON_MEM_BASE,
 	FIX_HPET_BASE,
 	FIX_APIC_BASE,	/* local (CPU) APIC) -- required for SMP or not */
 	FIX_IO_APIC_BASE_0,
@@ -84,7 +86,7 @@ static __always_inline unsigned long fix_to_virt(const unsigned int idx)
 	if (idx >= __end_of_fixed_addresses)
 		__this_fixmap_does_not_exist();
 
-        return __fix_to_virt(idx);
+	return __fix_to_virt(idx);
 }
 
 #endif
include/linux/console.h +1 -0
index 62ef6e1..4cb7749 100644
@@ -107,6 +107,7 @@ struct console {
 };
 
 extern int add_preferred_console(char *name, int idx, char *options);
+extern int update_console_cmdline_console_index(char *name, int idx_old, int idx_new);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern struct console *console_drivers;
include/linux/serial.h +0 -6
index 33fc8cb..deb7143 100644
@@ -177,11 +177,5 @@ struct serial_icounter_struct {
 #ifdef __KERNEL__
 #include <linux/compiler.h>
 
-/* Allow architectures to override entries in serial8250_ports[] at run time: */
-struct uart_port;	/* forward declaration */
-extern int early_serial_setup(struct uart_port *port);
-extern int early_serial_console_init(char *options);
-extern int serial8250_start_console(struct uart_port *port, char *options);
-
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SERIAL_H */
include/linux/serial_8250.h +3 -0
index 71310d8..0d79fc5 100644
@@ -60,4 +60,7 @@ void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
 void serial8250_resume_port(int line);
 
+extern int find_port_serial8250(struct uart_port *p);
+extern int serial8250_find_port_for_earlycon(void);
+
 #endif
include/linux/serial_core.h +5 -0
index a3ac4c8..b74fa4a 100644
@@ -199,6 +199,11 @@ struct uart_ops {
 	void		(*config_port)(struct uart_port *, int);
 	int		(*verify_port)(struct uart_port *, struct serial_struct *);
 	int		(*ioctl)(struct uart_port *, unsigned int, unsigned long);
+	
+	/*
+	 * for earlycon to console switch
+	 */
+	int		(*find_port_for_earlycon)(void);
 };
 
 #define UART_CONFIG_TYPE	(1 << 0)
kernel/printk.c +15 -0
index 0bbdeac..253c0f7 100644
@@ -726,6 +726,21 @@ int __init add_preferred_console(char *name, int idx, char *options)
 	return 0;
 }
 
+int __init update_console_cmdline_console_index(char *name, int idx_old, int idx_new)
+{
+	int i;
+
+	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+		if (strcmp(console_cmdline[i].name, name) == 0 &&
+			  console_cmdline[i].index == idx_old) {
+			  	console_cmdline[i].index = idx_new;
+				return 0;
+		}
+
+	return 0;
+}
+	
+
 #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
 /**
  * suspend_console - suspend the console subsystem
#5 lore raw
Quoted 3 lines · Yinghai Lu

Bjorn,
I can not find fixmap.h for ia64.....hope you can use ioremap instead, then we can create one dummy fixmap.h in include/asm-ia64

ia64 ioremap should work early enough, so it doesn't have fixmap. Seems like in this case, maybe bt_ioremap() would be more appropriate than fixmap, since there's no requirement that virtual address be known at compile-time.

Quoted 1 line

[PATCH]serial: make early_uart to use early_prarm instead of console_initcall

s/prarm/param/

Quoted 5 lines

new command line will be

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0
earlycon=uart,mmio,0xff5e0000,115200n8

Why do we have to have a new "earlycon" argument? Why can't we just parse "console=uart" early?

BTW, if you want to convert it from "console=uart" to "console=8250", as part of this cleanup, I think that would be OK. Just make it a separate patch and don't forget to change drivers/firmware/pcdp.c and Documentation/kernel-parameters.txt at the same time.

Bjorn

#6 lore raw
Quoted 6 lines · Bjorn Helgaas
Quoted 3 lines

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0
earlycon=uart,mmio,0xff5e0000,115200n8

Why do we have to have a new "earlycon" argument? Why can't we just parse "console=uart" early?

with console=uart, you need to call early_serial_console_init explictly in your arch setup_arch to get early console.

with console_initcall(early_uart_console_init), the early_uart_console will be called via console_init in start_kernel, init/main.c that is not real early console.

YH

#7 lore raw
Quoted 10 lines · Yinghai Lu
Quoted 6 lines · Bjorn Helgaas
Quoted 3 lines

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0
earlycon=uart,mmio,0xff5e0000,115200n8

Why do we have to have a new "earlycon" argument? Why can't we just parse "console=uart" early?

with console=uart, you need to call early_serial_console_init explictly in your arch setup_arch to get early console.

Can't we just do:

  early_param("console", setup_early_console);

and have setup_early_console() ignore everything except "uart"?

Quoted 3 lines

with console_initcall(early_uart_console_init), the early_uart_console will be called via console_init in start_kernel, init/main.c that is not real early console.

I agree that's too late.

Bjorn

#8 lore raw
Quoted 3 lines · Bjorn Helgaas
  early_param("console", setup_early_console);

and have setup_early_console() ignore everything except "uart"?

console= is used
__setup("console=", console_setup);
early_param doesn't have chance to see it.

YH

#9 lore raw
In reply to Yinghai Lu
Quoted 3 lines · Yinghai Lu

Gerd's patch (console handover) was merged into mainline. it will switch from early_printk to normal console in register_console via CON_BOOT flags.. ===> only for x86

Tagging boot consoles (aka early_printk) with CON_BOOT certainly makes sense. Just doing that doesn't work for ia64?

What is the point in making that work on x86 additionally to serial support in early_printk? It might make sense to split away the serial bits from early_printk.c and move them out of arch/ into -- say -- drivers/serial/, so other architectures can use that too and we have only one serial earlyprintk implementation in the kernel. Not sure it is worth the effort given the code size.

cheers,
Gerd

#10 lore raw
Quoted 6 lines · Gerd Hoffmann

What is the point in making that work on x86 additionally to serial support in early_printk? It might make sense to split away the serial bits from early_printk.c and move them out of arch/ into -- say -- drivers/serial/, so other architectures can use that too and we have only one serial earlyprintk implementation in the kernel. Not sure it is worth the effort given the code size.

yes, we can drop serial bits from early_printk.c, and use drivers/serial/8250_early.c and
with "earlycon=uart,io,0x3f8,9600n8", "early=ueart,mmio,0xfe000000,9600n8"

and we can extend other non 8250 compatitable uart to some *_early.c in the same dir.
So other platform and other uart could be happy to get early console.

YH

#11 lore raw
In reply to Andrew Morton
Quoted 12 lines · Andrew Morton
Quoted 10 lines · On Fri, 18 May 2007 19:00:16 -0700 Yinghai Lu <[email protected]> wrote:

[PATCH]serial: make early_uart to use early_prarm instead of console_initcall

Make early_uart to use early_param, so uart console can be used earlier. Make it to be bootconsole with CON_BOOT flag, so can use console handover feature. and it will switch to corresponding normal serial console automatically. new command line will be

earlycon=uart,io,0x3f8,9600n8
earlycon=uart,io,0x3f8,9600n8 console=tty0

Quoted 8 lines
Quoted 4 lines

it will print in very early stage
Early serial console at I/O port 0x3f8 (options '9600n8') later for console it will print
console handover: boot [uart0] -> real [ttyS0]

I'll queue this up for some testing, but I'd be a bit reluctant to send it into Linus due to my poor understanding of what it actually does. What _is_ an early console, and how does it differ from a non-early one?

It is someone's reimplemention of earlyprintk= for another architecture that happens to mostly work on x86 too because the code is not ifdeffed. I don't think it makes much sense on x86 though because earlyprintk exists.

-Andi

#12 lore raw
Quoted 6 lines · Andi Kleen
Quoted 3 lines · Andrew Morton

I'll queue this up for some testing, but I'd be a bit reluctant to send it into Linus due to my poor understanding of what it actually does. What _is_ an early console, and how does it differ from a non-early one?

It is someone's reimplemention of earlyprintk= for another architecture

I implemented 8250_early for ia64. It is based on early_printk and is quite similar to it.

One important difference is that early_printk has the "ttyS0 is at 0x3f8" knowledge compiled into it. That doesn't work for ia64 because ttyS0 may be anywhere.

Since 8250_early doesn't assume the ttyS locations, you have to tell it the device address, not the name. Some ia64 firmware tells the OS the address of the console device. With 8250_early, if the user wants the OS to use the same console as the firmware, he doesn't need any "console=" argument at all.

The other important difference is that 8250_early tries to coordinate with the normal 8250 console driver. For example, if you use "console=uart,io,0x3f8", 8250_early works like early_printk does, and then automatically switches to the normal 8250 driver later. With early_printk, I think you would have to use "earlyprintk=serial,ttyS0 console=ttyS0" to do the same thing.

Quoted 1 line

that happens to mostly work on x86 too because the code is not ifdeffed.

8250_early has no arch dependency, so there's no reason to ifdef it. It only depends on ioremap/inb/outb/readb/writeb.

Quoted 1 line

I don't think it makes much sense on x86 though because earlyprintk exists.

There are two reasons 8250_early might make sense on x86:

- x86 firmware might someday tell the OS where the console is (e.g., via drivers/firmware/pcdp.c). That requires a way to locate the device by its address, not by the name.

- You only have to specify the console device once, not twice.

On the other hand, maybe you *want* the earlyprintk device to be a different device than the regular console. 8250_early wouldn't handle that very well.

Bjorn

#13 lore raw
In reply to Andi Kleen
Quoted 6 lines · Andi Kleen
Quoted 3 lines · Andrew Morton

I'll queue this up for some testing, but I'd be a bit reluctant to send it into Linus due to my poor understanding of what it actually does. What _is_ an early console, and how does it differ from a non-early one?

It is someone's reimplemention of earlyprintk= for another architecture

I implemented 8250_early for ia64. It is based on early_printk and is quite similar to it.

One important difference is that early_printk has the "ttyS0 is at 0x3f8" knowledge compiled into it. That doesn't work for ia64 because ttyS0 may be anywhere.

Since 8250_early doesn't assume the ttyS locations, you have to tell it the device address, not the name. Some ia64 firmware tells the OS the address of the console device. With 8250_early, if the user wants the OS to use the same console as the firmware, he doesn't need any "console=" argument at all.

The other important difference is that 8250_early tries to coordinate with the normal 8250 console driver. For example, if you use "console=uart,io,0x3f8", 8250_early works like early_printk does, and then automatically switches to the normal 8250 driver later. With early_printk, I think you would have to use "earlyprintk=serial,ttyS0 console=ttyS0" to do the same thing.

Quoted 1 line

that happens to mostly work on x86 too because the code is not ifdeffed.

8250_early has no arch dependency, so there's no reason to ifdef it. It only depends on ioremap/inb/outb/readb/writeb.

Quoted 1 line

I don't think it makes much sense on x86 though because earlyprintk exists.

There are two reasons 8250_early might make sense on x86:

- x86 firmware might someday tell the OS where the console is (e.g., via drivers/firmware/pcdp.c). That requires a way to locate the device by its address, not by the name.

- You only have to specify the console device once, not twice.

On the other hand, maybe you *want* the earlyprintk device to be a different device than the regular console. 8250_early wouldn't handle that very well.

Bjorn

author
#14 lore raw
In reply to Andi Kleen
Quoted 2 lines · Andi Kleen

It is someone's reimplemention of earlyprintk= for another architecture
that happens to mostly work on x86 too because the code is not ifdeffed. I don't think it makes much sense on x86 though because earlyprintk exists.

Andi,

Bjorn refer to your early_printk to implement early_uart for ia64 platform. code is almost identical, but it could take mmio,0xfe00000,9600n8 etc. or say mmio type serial card.

YH