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 removes 'earlyprintk' from the early_param and setup it right after
boot data copying. So 'early_printk' function will be usabable after
decompression of the kernel and before parse_early_param will be called.
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.
Signed-off-by: Alexander Kuleshov <[email protected]>
---
arch/x86/kernel/early_printk.c | 4 +---
arch/x86/kernel/head64.c | 3 +++
include/linux/printk.h | 1 +
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index a62536a..4b0577b 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -329,7 +329,7 @@ static inline void early_console_register(struct console *con, int keep_early)
register_console(early_console);
}
-static int __init setup_early_printk(char *buf)
+int __init setup_early_printk(char *buf)
{
int keep;
@@ -390,5 +390,3 @@ static int __init setup_early_printk(char *buf)
}
return 0;
}
-
-early_param("earlyprintk", setup_early_printk);
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index c4f8d46..4034ea6 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -172,6 +172,9 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
copy_bootdata(__va(real_mode_data));
+ /* setup earlyprintk as early as possible */
+ setup_early_printk(boot_command_line);
+
/*
* Load microcode early on BSP.
*/
diff --git a/include/linux/printk.h b/include/linux/printk.h
index baa3f97..47e3919 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -115,6 +115,7 @@ int no_printk(const char *fmt, ...)
#ifdef CONFIG_EARLY_PRINTK
extern asmlinkage __printf(1, 2)
void early_printk(const char *fmt, ...);
+int setup_early_printk(char *buf);
#else
static inline __printf(1, 2) __cold
void early_printk(const char *s, ...) { }
--
2.3.3.611.g09038fc.dirty
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 removes 'earlyprintk' from the early_param and setup it right after
boot data copying. So 'early_printk' function will be usabable after
decompression of kernel and before parse_early_param will be called.
Kernel with this patch was tested with qemu-i386. early_printk function works
after early_printk initialization.
Signed-off-by: Alexander Kuleshov <[email protected]>
---
arch/x86/kernel/head32.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 2911ef3..dd0aadc 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -34,6 +34,9 @@ asmlinkage __visible void __init i386_start_kernel(void)
cr4_init_shadow();
sanitize_boot_params(&boot_params);
+ /* setup earlyprintk as early as possible */
+ setup_early_printk(boot_command_line);
+
/* Call the subarch specific early setup function */
switch (boot_params.hdr.hardware_subarch) {
case X86_SUBARCH_INTEL_MID:
--
2.3.3.611.g09038fc.dirty
* Alexander Kuleshov <[email protected]> wrote:
> 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 removes 'earlyprintk' from the early_param and setup it right after
> boot data copying. So 'early_printk' function will be usabable after
> decompression of kernel and before parse_early_param will be called.
>
> Kernel with this patch was tested with qemu-i386. early_printk function works
> after early_printk initialization.
>
> Signed-off-by: Alexander Kuleshov <[email protected]>
> ---
> arch/x86/kernel/head32.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
> index 2911ef3..dd0aadc 100644
> --- a/arch/x86/kernel/head32.c
> +++ b/arch/x86/kernel/head32.c
> @@ -34,6 +34,9 @@ asmlinkage __visible void __init i386_start_kernel(void)
> cr4_init_shadow();
> sanitize_boot_params(&boot_params);
>
> + /* setup earlyprintk as early as possible */
> + setup_early_printk(boot_command_line);
So why not at the beginning of the function?
Thanks,
Ingo
* Alexander Kuleshov <[email protected]> wrote:
> 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 removes 'earlyprintk' from the early_param and setup it right after
> boot data copying. So 'early_printk' function will be usabable after
> decompression of the kernel and before parse_early_param will be called.
>
> 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.
>
> Signed-off-by: Alexander Kuleshov <[email protected]>
> ---
> arch/x86/kernel/early_printk.c | 4 +---
> arch/x86/kernel/head64.c | 3 +++
> include/linux/printk.h | 1 +
> 3 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
> index a62536a..4b0577b 100644
> --- a/arch/x86/kernel/early_printk.c
> +++ b/arch/x86/kernel/early_printk.c
> @@ -329,7 +329,7 @@ static inline void early_console_register(struct console *con, int keep_early)
> register_console(early_console);
> }
>
> -static int __init setup_early_printk(char *buf)
> +int __init setup_early_printk(char *buf)
> {
> int keep;
>
> @@ -390,5 +390,3 @@ static int __init setup_early_printk(char *buf)
> }
> return 0;
> }
> -
> -early_param("earlyprintk", setup_early_printk);
> diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
> index c4f8d46..4034ea6 100644
> --- a/arch/x86/kernel/head64.c
> +++ b/arch/x86/kernel/head64.c
> @@ -172,6 +172,9 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
>
> copy_bootdata(__va(real_mode_data));
>
> + /* setup earlyprintk as early as possible */
> + setup_early_printk(boot_command_line);
> +
So does this work with CONFIG_CMDLINE_BOOL + CONFIG_CMDLINE_OVERRIDE?
Thanks,
Ingo
>2015-04-07 17:09 GMT+06:00 Ingo Molnar <[email protected]>:
>
> So does this work with CONFIG_CMDLINE_BOOL + CONFIG_CMDLINE_OVERRIDE?
>
Yes, i just tested both patch for x86 and x86_64 and they work with
CONFIG_CMDLINE_BOOL + CONFIG_CMDLINE_OVERRIDE and with given
CONFIG_CMDLINE string.
Will move setup_early_printk to the beginnig of the i386_start_kernel
and resend the patch.
Thank you.
As setup_earlyprintk 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 removes 'earlyprintk' from the early_param and setup it right after
boot data copying. So 'early_printk' function will be usabable after
decompression of kernel and before parse_early_param will be called.
Kernel with this patch was tested with qemu-i386. early_printk function works
after early_printk initialization. This patch also tested and works with enabled
CONFIG_CMDLINE_BOOL and CONFIG_CMDLINE_OVERRIDE.
Changes v1->v2:
* Call of the setup_early_printk moved to the top of the i386_start_kernel
Signed-off-by: Alexander Kuleshov <[email protected]>
---
arch/x86/kernel/head32.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 2911ef3..cd8527c 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -31,6 +31,9 @@ static void __init i386_default_early_setup(void)
asmlinkage __visible void __init i386_start_kernel(void)
{
+ /* setup earlyprintk as early as possible */
+ setup_early_printk(boot_command_line);
+
cr4_init_shadow();
sanitize_boot_params(&boot_params);
--
2.3.3.611.g09038fc.dirty
* Alexander Kuleshov <[email protected]> wrote:
> >2015-04-07 17:09 GMT+06:00 Ingo Molnar <[email protected]>:
> >
> > So does this work with CONFIG_CMDLINE_BOOL + CONFIG_CMDLINE_OVERRIDE?
> >
>
> Yes, i just tested both patch for x86 and x86_64 and they work with
> CONFIG_CMDLINE_BOOL + CONFIG_CMDLINE_OVERRIDE and with given
> CONFIG_CMDLINE string.
So if you set up earlyprintk via CONFIG_CMDLINE_OVERRIDE it just
works?
Thanks,
Ingo
2015-04-07 17:35 GMT+06:00 Ingo Molnar <[email protected]>:
>
>
> So if you set up earlyprintk via CONFIG_CMDLINE_OVERRIDE it just
> works?
>
Look, how i did it. I set:
CONFIG_CMDLINE_BOOL =y
CONFIG_CMDLINE_OVERRIDE =y
and passed following string:
[=root=/dev/sdb earlyprintk=ttyS0 loglevel=7 debug rdinit=/sbin/init
root=/dev/ram memblock=debug]
to the CONFIG_CMDLINE.
Now i put two early_printk calls before and after earlyprintk initialization:
early_printk("before setup_early_printk \n");
setup_early_printk(boot_command_line);
early_printk("after setup_early_printk \n");
And i don't see first string, but see last.
Did i make something wrong?
* Alexander Kuleshov <[email protected]> wrote:
> 2015-04-07 17:35 GMT+06:00 Ingo Molnar <[email protected]>:
> >
> >
> > So if you set up earlyprintk via CONFIG_CMDLINE_OVERRIDE it just
> > works?
> >
>
> Look, how i did it. I set:
>
> CONFIG_CMDLINE_BOOL =y
> CONFIG_CMDLINE_OVERRIDE =y
>
> and passed following string:
>
> [=root=/dev/sdb earlyprintk=ttyS0 loglevel=7 debug rdinit=/sbin/init
> root=/dev/ram memblock=debug]
>
> to the CONFIG_CMDLINE.
>
> Now i put two early_printk calls before and after earlyprintk initialization:
>
> early_printk("before setup_early_printk \n");
> setup_early_printk(boot_command_line);
> early_printk("after setup_early_printk \n");
>
> And i don't see first string, but see last.
>
> Did i make something wrong?
Yes, you need to check how and where in the arch init code
boot_command_line is set up in the CONFIG_CMDLINE_OVERRIDE=y case.
Thanks,
Ingo
* 2015-04-07 20:03 GMT+06:00 Ingo Molnar <[email protected]>:
>
> Yes, you need to check how and where in the arch init code
> boot_command_line is set up in the CONFIG_CMDLINE_OVERRIDE=y case.
>
arch setup code defines builtin_cmdline and initalizes it with
CONFIG_CMDLINE, which
is 'root=/dev/sdb earlyprintk=ttyS0 loglevel=7 debug rdinit=/sbin/init
root=/dev/ram memblock=debug' string in my test. During kernel
initialization (int setup_arch),
builtin_cmdline copying to the boot_command_line if CONFIG_CMDLINE_OVERRIDE and
CONFIG_CMDLINE_BOOL are set.
I think that it is not correct to pass boot_command_line to the
setup_early_printk in
CONFIG_CMDLINE_OVERRIDE=y case. As boot_command_line will be overwritten with
builtin_cmdline.
What do you think if we'll builtin_cmdline from the
arch/x86/kernel/setup.c to the init.h to
make it visible for head_{32,64}.c and pass builtin_cmdline or
boot_command_line to
the setup_early_printk depend on CONFIG_CMDLINE_OVERRIDE?
2015-04-07 22:49 GMT+06:00 Alexander Kuleshov <[email protected]>:
> * 2015-04-07 20:03 GMT+06:00 Ingo Molnar <[email protected]>:
>>
>> Yes, you need to check how and where in the arch init code
>> boot_command_line is set up in the CONFIG_CMDLINE_OVERRIDE=y case.
>>
>
> arch setup code defines builtin_cmdline and initalizes it with
> CONFIG_CMDLINE, which
> is 'root=/dev/sdb earlyprintk=ttyS0 loglevel=7 debug rdinit=/sbin/init
> root=/dev/ram memblock=debug' string in my test. During kernel
> initialization (int setup_arch),
> builtin_cmdline copying to the boot_command_line if CONFIG_CMDLINE_OVERRIDE and
> CONFIG_CMDLINE_BOOL are set.
>
> I think that it is not correct to pass boot_command_line to the
> setup_early_printk in
> CONFIG_CMDLINE_OVERRIDE=y case. As boot_command_line will be overwritten with
> builtin_cmdline.
>
> What do you think if we'll builtin_cmdline from the
> arch/x86/kernel/setup.c to the init.h to
> make it visible for head_{32,64}.c and pass builtin_cmdline or
> boot_command_line to
> the setup_early_printk depend on CONFIG_CMDLINE_OVERRIDE?
No, it's the wrong way. CONFIG_CMDLINE_BOOL can be 'y', but
CONFIG_CMDLINE_OVERRIDE
will be 'n', and boot_command_line will be appended, but not overwritten
What do you think about following way to solve this:
1. To move this code: -
https://github.com/torvalds/linux/blob/master/arch/x86/kernel/setup.c#L971-L982
to the separate function, something like setup_cmdline().
2. Call setup_cmdline in head{32,64}.c and call
setup_early_printk(boot_command_line)
right after this.
After execution of the setup_cmdline, boot_command_line will be in
actual state. It will contain
command line which we passed to the kernel directly, or overwriten
with CONFIG_CMDLINE_OVERRIDE,
or appended with CONFIG_CMDLINE_OVERRIDE.
What do you think about this?
I already did it and tested on my local machine and it works, but
maybe I have missed something important.