2015-04-07 11:02:34

by Alexander Kuleshov

[permalink] [raw]
Subject: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible

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


2015-04-07 11:03:08

by Alexander Kuleshov

[permalink] [raw]
Subject: [PATCH 2/2] x86/earlyprintk: setup earlyprintk as possible

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

2015-04-07 11:07:48

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 2/2] x86/earlyprintk: setup earlyprintk as possible


* 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

2015-04-07 11:09:38

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible


* 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 11:24:48

by Alexander Kuleshov

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible

>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.

2015-04-07 11:31:29

by Alexander Kuleshov

[permalink] [raw]
Subject: [PATCH 2/2 v2] x86/earlyprintk: setup earlyprintk as possible

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

2015-04-07 11:35:11

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible


* 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 11:47:04

by Alexander Kuleshov

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible

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?

2015-04-07 14:03:23

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible


* 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 16:49:28

by Alexander Kuleshov

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible

* 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 17:00:46

by Alexander Kuleshov

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible

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

2015-04-07 17:30:43

by Alexander Kuleshov

[permalink] [raw]
Subject: Re: [PATCH 1/2 v2] x86_64/earlyprintk: setup earlyprintk as early as possible

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.