Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932558AbbDKIb4 (ORCPT ); Sat, 11 Apr 2015 04:31:56 -0400 Received: from mail-la0-f51.google.com ([209.85.215.51]:35407 "EHLO mail-la0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751861AbbDKIbv (ORCPT ); Sat, 11 Apr 2015 04:31:51 -0400 From: Alexander Kuleshov To: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Greg Kroah-Hartman Cc: Yinghai Lu , Peter Hurley , linux-kernel@vger.kernel.org, Alexander Kuleshov Subject: [PATCH 2/2 v5] x86/earlyprintk: setup earlyprintk as early as possible Date: Sat, 11 Apr 2015 14:31:44 +0600 Message-Id: <1428741104-4394-1-git-send-email-kuleshovmail@gmail.com> X-Mailer: git-send-email 2.3.3.611.g09038fc.dirty In-Reply-To: <1428567524-17386-1-git-send-email-kuleshovmail@gmail.com> References: <1428567524-17386-1-git-send-email-kuleshovmail@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6241 Lines: 196 As setup_early_printk passed to the early_param, it will be usable only after 'parse_early_param' function will be called from the 'setup_arch'. So we have earlyprintk during early boot and decompression. Next point after decompression of the kernel where we can use early_printk is after call of the 'parse_early_param'. This patch makes setup_early_printk visible for head{32,64}.c So 'early_printk' function will be usabable after decompression of the kernel and before parse_early_param will be called. It also must be safe if CONFIG_CMDLINE_BOOL and CONFIG_CMDLINE_OVERRIDE are set, because setup_cmdline function will be called before setup_early_printk. Tested it with qemu, so early_printk() is usable and prints to serial console right after setup_early_printk function called from arch/x86/kerne/head64.c Changes v1->v2: * Comment added before the setup_early_printk call; * Added information about testing to the commit message. Changes v2->v3: * Call setup_cmdline before setup_early_printk; * setup_early_printk call wrapped with the setup_early_serial_console which checks that 'serial' given to the earlyprintk command line option. This prevents call of the setup_early_printk with the given pciserial/dbgp/efi, because they are using early_ioremap. Changes v3->v4: * Move setup_early_serial_console from the include/linux/printk.h to the arch/x86/include/asm/serial.h, because this function is only for x86 now. Changes v4->v5: * Add check for console_log_level before call of the early_printk() Signed-off-by: Alexander Kuleshov --- arch/x86/include/asm/serial.h | 7 +++++++ arch/x86/kernel/early_printk.c | 31 +++++++++++++++++++++++++++++-- arch/x86/kernel/head32.c | 5 +++++ arch/x86/kernel/head64.c | 9 ++++++++- include/linux/init.h | 4 ---- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/serial.h b/arch/x86/include/asm/serial.h index 460b84f..789e123 100644 --- a/arch/x86/include/asm/serial.h +++ b/arch/x86/include/asm/serial.h @@ -26,4 +26,11 @@ { .uart = 0, BASE_BAUD, 0x3E8, 4, STD_COMX_FLAGS }, /* ttyS2 */ \ { .uart = 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ + +#ifdef CONFIG_EARLY_PRINTK +int setup_early_serial_console(void); +#else +static void setup_early_serial_console(void) {}; +#endif + #endif /* _ASM_X86_SERIAL_H */ diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index a62536a..6052eba 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -342,14 +343,16 @@ static int __init setup_early_printk(char *buf) keep = (strstr(buf, "keep") != NULL); while (*buf != '\0') { - if (!strncmp(buf, "serial", 6)) { + if (!strncmp(buf, "serial", 6) && + early_serial_console.index == -1) { buf += 6; early_serial_init(buf); early_console_register(&early_serial_console, keep); if (!strncmp(buf, ",ttyS", 5)) buf += 5; } - if (!strncmp(buf, "ttyS", 4)) { + if (!strncmp(buf, "ttyS", 4) && + early_serial_console.index == -1) { early_serial_init(buf + 4); early_console_register(&early_serial_console, keep); } @@ -391,4 +394,28 @@ static int __init setup_early_printk(char *buf) return 0; } +int setup_early_serial_console() { +#ifdef CONFIG_EARLY_PRINTK + char *arg; + + /* + * make sure that we have: + * "serial,0x3f8,115200" + * "serial,ttyS0,115200" + * "ttyS0,115200" + */ + arg = strstr(boot_command_line, "earlyprintk=serial"); + if (!arg) + arg = strstr(boot_command_line, "earlyprintk=ttyS"); + if (!arg) + return -1; + + arg = strstr(boot_command_line, "earlyprintk="); + /* += strlen("earlyprintk"); */ + arg += 12; + + return setup_early_printk(arg); +#endif +} + early_param("earlyprintk", setup_early_printk); diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 7ad0ad0..c59afe4 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -19,6 +19,7 @@ #include #include #include +#include static void __init i386_default_early_setup(void) { @@ -32,6 +33,11 @@ static void __init i386_default_early_setup(void) asmlinkage __visible void __init i386_start_kernel(void) { setup_cmdline(); + /* setup serial console as early as possible */ + setup_early_serial_console(); + if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) + early_printk("Early serial console is active\n"); + cr4_init_shadow(); sanitize_boot_params(&boot_params); diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 6eea2de..129acc3 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -28,6 +28,7 @@ #include #include #include +#include /* * Manage page tables very early on. @@ -172,12 +173,17 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) copy_bootdata(__va(real_mode_data)); setup_cmdline(); + /* setup serial console as early as possible */ + setup_early_serial_console(); + if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) + early_printk("Early serial console is active\n"); /* * Load microcode early on BSP. */ load_ucode_bsp(); + if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) early_printk("Kernel alive\n"); @@ -193,8 +198,10 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) void __init x86_64_start_reservations(char *real_mode_data) { /* version is always not zero if it is copied */ - if (!boot_params.hdr.version) + if (!boot_params.hdr.version) { copy_bootdata(__va(real_mode_data)); + setup_early_serial_console(); + } reserve_ebda_region(); -- 2.3.3.611.g09038fc.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/