2020-03-19 23:51:28

by ron minnich

[permalink] [raw]
Subject: [PATCH 1/1] x86 support for the initrd= command line option

In LinuxBoot systems, a kernel and initramfs are loaded into FLASH
to replace proprietary firmware/BIOS code. Space being at a premium
on some systems, the kernel and initramfs must be place in whatever
open corners of the FLASH exist. These corners are not always
easily used.

For example, on Intel-based UEFI systems, the Management Engine
(ME) is given half the FLASH, though it uses very little, as little
as 1.25MiB. Not only is 2.75MiB of an 8MiB part unused; but
10.75MiB of a 16MiB part is unused. This space can be recovered by
a number of tools, e.g. utk and its tighten_me command, and if
Linux can be told where the space is Linux can load an initrd from
it.

In an ideal case, we would take the space from the ME and add it to
a FLASH-based filesystem. While UEFI does have filesystem-like
structures, this recovered space can only be added to its "file
system" by rebuilding UEFI from source or writing a UEFI device
driver. Both these options are impractical in most cases. The space
can only be referenced as a physical address.

There is code in the core that allows specification of the initrd
as a physical address and size, but it is not supported on all
architectures. This patch adds support for initrd= to the x86.

For debugging and recovery purposes, if initrd= is present in the
command line, other existing initrd sources should still have
higher priority. The initramfs in flash might be damaged or
broken. Hence, it must still be possible to load a kernel and
initramfs with a conventional bootloader, or even load the
FLASH-based kernel with a different initramfs; or boot a
kernel and let it use the initrd in FLASH.

In support of that priority ordering, this patch sets the ramdisk
image pointer to phys_initrd_start only if it is not already set;
and sets ramdisk_size to phys_initrd_size only if it is not already
set.

It has been tested extensively in LinuxBoot environments.

Signed-off-by: Ronald G. Minnich <[email protected]>
---
arch/x86/kernel/setup.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a74262c71484..1b04ef8ea12d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)

ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;

+ if (ramdisk_image == 0) {
+ ramdisk_image = phys_initrd_start;
+ }
return ramdisk_image;
}
static u64 __init get_ramdisk_size(void)
@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)

ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;

+ if (ramdisk_size == 0) {
+ ramdisk_size = phys_initrd_size;
+ }
return ramdisk_size;
}

--
2.17.1


2020-03-19 23:58:59

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 19, 2020 4:49:05 PM PDT, ron minnich <[email protected]> wrote:
>In LinuxBoot systems, a kernel and initramfs are loaded into FLASH
>to replace proprietary firmware/BIOS code. Space being at a premium
>on some systems, the kernel and initramfs must be place in whatever
>open corners of the FLASH exist. These corners are not always
>easily used.
>
>For example, on Intel-based UEFI systems, the Management Engine
>(ME) is given half the FLASH, though it uses very little, as little
>as 1.25MiB. Not only is 2.75MiB of an 8MiB part unused; but
>10.75MiB of a 16MiB part is unused. This space can be recovered by
>a number of tools, e.g. utk and its tighten_me command, and if
>Linux can be told where the space is Linux can load an initrd from
>it.
>
>In an ideal case, we would take the space from the ME and add it to
>a FLASH-based filesystem. While UEFI does have filesystem-like
>structures, this recovered space can only be added to its "file
>system" by rebuilding UEFI from source or writing a UEFI device
>driver. Both these options are impractical in most cases. The space
>can only be referenced as a physical address.
>
>There is code in the core that allows specification of the initrd
>as a physical address and size, but it is not supported on all
>architectures. This patch adds support for initrd= to the x86.
>
>For debugging and recovery purposes, if initrd= is present in the
>command line, other existing initrd sources should still have
>higher priority. The initramfs in flash might be damaged or
>broken. Hence, it must still be possible to load a kernel and
>initramfs with a conventional bootloader, or even load the
>FLASH-based kernel with a different initramfs; or boot a
>kernel and let it use the initrd in FLASH.
>
>In support of that priority ordering, this patch sets the ramdisk
>image pointer to phys_initrd_start only if it is not already set;
>and sets ramdisk_size to phys_initrd_size only if it is not already
>set.
>
>It has been tested extensively in LinuxBoot environments.
>
>Signed-off-by: Ronald G. Minnich <[email protected]>
>---
> arch/x86/kernel/setup.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
>diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>index a74262c71484..1b04ef8ea12d 100644
>--- a/arch/x86/kernel/setup.c
>+++ b/arch/x86/kernel/setup.c
>@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
>
> ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
>
>+ if (ramdisk_image == 0) {
>+ ramdisk_image = phys_initrd_start;
>+ }
> return ramdisk_image;
> }
> static u64 __init get_ramdisk_size(void)
>@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)
>
> ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
>
>+ if (ramdisk_size == 0) {
>+ ramdisk_size = phys_initrd_size;
>+ }
> return ramdisk_size;
> }

The initrd= option is reserved namespace for the bootloader. It is also worth noting that the x86 boot protocol now allows the bootloader to point to arbitrary chunks of memory for the initrd.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-20 00:52:27

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

Thanks for looking, but I'm not entirely sure how to parse your answer :-)

In LinuxBoot, we compile Linux into a UEFI driver and load it in
FLASH. It's started by the UEFI driver scheduler, a.k.a DxeCore. In
this case, Linux is both a bootloader (for the Linux or other kernel
it will boot) and Linux is also the thing booted by UEFI. As I
mentioned, we want to avoid writing a UEFI driver just to tell Linux
where to find the initramfs. Further, we want to be able to boot this
kernel and have it use an initramfs provided by a different bootloader
(pxeboot, for example). This flexibility is proving very useful for
companies deploying LinuxBoot today.

I got the idea of using initrd= because u-boot is able to pass that
option to the ARM kernel and the ARM kernel will process it: see,
e.g., the usage in arch/arm/configs/acs5k_defconfig.

Are you saying initrd is reserved for a bootloader to produce it or
consume it? It's certainly not either on ARM: it is in some cases
included in a compiled-in command line, and used by the kernel, just
as we are doing in this patch. The kernel build process produces it,
and the kernel consumes it. All this functionality is there, and all
this patch does it bring it into the x86 kernel with this 6 line
patch.

If, in spite of this usage on ARM, you'd still not rather see a
corresponding usage on x86, how do we get the effect we need here?
Again, we don't want to write UEFI drivers, but we would like some
minimal way to communicate to the kernel where an initramfs is in
memory; and, further, we want it to be the lowest priority option, so
we easily override it. Suggestions on how to do this are welcome.

ron

On Thu, Mar 19, 2020 at 4:57 PM <[email protected]> wrote:
>
> On March 19, 2020 4:49:05 PM PDT, ron minnich <[email protected]> wrote:
> >In LinuxBoot systems, a kernel and initramfs are loaded into FLASH
> >to replace proprietary firmware/BIOS code. Space being at a premium
> >on some systems, the kernel and initramfs must be place in whatever
> >open corners of the FLASH exist. These corners are not always
> >easily used.
> >
> >For example, on Intel-based UEFI systems, the Management Engine
> >(ME) is given half the FLASH, though it uses very little, as little
> >as 1.25MiB. Not only is 2.75MiB of an 8MiB part unused; but
> >10.75MiB of a 16MiB part is unused. This space can be recovered by
> >a number of tools, e.g. utk and its tighten_me command, and if
> >Linux can be told where the space is Linux can load an initrd from
> >it.
> >
> >In an ideal case, we would take the space from the ME and add it to
> >a FLASH-based filesystem. While UEFI does have filesystem-like
> >structures, this recovered space can only be added to its "file
> >system" by rebuilding UEFI from source or writing a UEFI device
> >driver. Both these options are impractical in most cases. The space
> >can only be referenced as a physical address.
> >
> >There is code in the core that allows specification of the initrd
> >as a physical address and size, but it is not supported on all
> >architectures. This patch adds support for initrd= to the x86.
> >
> >For debugging and recovery purposes, if initrd= is present in the
> >command line, other existing initrd sources should still have
> >higher priority. The initramfs in flash might be damaged or
> >broken. Hence, it must still be possible to load a kernel and
> >initramfs with a conventional bootloader, or even load the
> >FLASH-based kernel with a different initramfs; or boot a
> >kernel and let it use the initrd in FLASH.
> >
> >In support of that priority ordering, this patch sets the ramdisk
> >image pointer to phys_initrd_start only if it is not already set;
> >and sets ramdisk_size to phys_initrd_size only if it is not already
> >set.
> >
> >It has been tested extensively in LinuxBoot environments.
> >
> >Signed-off-by: Ronald G. Minnich <[email protected]>
> >---
> > arch/x86/kernel/setup.c | 6 ++++++
> > 1 file changed, 6 insertions(+)
> >
> >diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> >index a74262c71484..1b04ef8ea12d 100644
> >--- a/arch/x86/kernel/setup.c
> >+++ b/arch/x86/kernel/setup.c
> >@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
> >
> > ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
> >
> >+ if (ramdisk_image == 0) {
> >+ ramdisk_image = phys_initrd_start;
> >+ }
> > return ramdisk_image;
> > }
> > static u64 __init get_ramdisk_size(void)
> >@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)
> >
> > ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
> >
> >+ if (ramdisk_size == 0) {
> >+ ramdisk_size = phys_initrd_size;
> >+ }
> > return ramdisk_size;
> > }
>
> The initrd= option is reserved namespace for the bootloader. It is also worth noting that the x86 boot protocol now allows the bootloader to point to arbitrary chunks of memory for the initrd.
> --
> Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-20 01:00:50

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 19, 2020 5:50:52 PM PDT, ron minnich <[email protected]> wrote:
>Thanks for looking, but I'm not entirely sure how to parse your answer
>:-)
>
>In LinuxBoot, we compile Linux into a UEFI driver and load it in
>FLASH. It's started by the UEFI driver scheduler, a.k.a DxeCore. In
>this case, Linux is both a bootloader (for the Linux or other kernel
>it will boot) and Linux is also the thing booted by UEFI. As I
>mentioned, we want to avoid writing a UEFI driver just to tell Linux
>where to find the initramfs. Further, we want to be able to boot this
>kernel and have it use an initramfs provided by a different bootloader
>(pxeboot, for example). This flexibility is proving very useful for
>companies deploying LinuxBoot today.
>
>I got the idea of using initrd= because u-boot is able to pass that
>option to the ARM kernel and the ARM kernel will process it: see,
>e.g., the usage in arch/arm/configs/acs5k_defconfig.
>
>Are you saying initrd is reserved for a bootloader to produce it or
>consume it? It's certainly not either on ARM: it is in some cases
>included in a compiled-in command line, and used by the kernel, just
>as we are doing in this patch. The kernel build process produces it,
>and the kernel consumes it. All this functionality is there, and all
>this patch does it bring it into the x86 kernel with this 6 line
>patch.
>
>If, in spite of this usage on ARM, you'd still not rather see a
>corresponding usage on x86, how do we get the effect we need here?
>Again, we don't want to write UEFI drivers, but we would like some
>minimal way to communicate to the kernel where an initramfs is in
>memory; and, further, we want it to be the lowest priority option, so
>we easily override it. Suggestions on how to do this are welcome.
>
>ron
>
>On Thu, Mar 19, 2020 at 4:57 PM <[email protected]> wrote:
>>
>> On March 19, 2020 4:49:05 PM PDT, ron minnich <[email protected]>
>wrote:
>> >In LinuxBoot systems, a kernel and initramfs are loaded into FLASH
>> >to replace proprietary firmware/BIOS code. Space being at a premium
>> >on some systems, the kernel and initramfs must be place in whatever
>> >open corners of the FLASH exist. These corners are not always
>> >easily used.
>> >
>> >For example, on Intel-based UEFI systems, the Management Engine
>> >(ME) is given half the FLASH, though it uses very little, as little
>> >as 1.25MiB. Not only is 2.75MiB of an 8MiB part unused; but
>> >10.75MiB of a 16MiB part is unused. This space can be recovered by
>> >a number of tools, e.g. utk and its tighten_me command, and if
>> >Linux can be told where the space is Linux can load an initrd from
>> >it.
>> >
>> >In an ideal case, we would take the space from the ME and add it to
>> >a FLASH-based filesystem. While UEFI does have filesystem-like
>> >structures, this recovered space can only be added to its "file
>> >system" by rebuilding UEFI from source or writing a UEFI device
>> >driver. Both these options are impractical in most cases. The space
>> >can only be referenced as a physical address.
>> >
>> >There is code in the core that allows specification of the initrd
>> >as a physical address and size, but it is not supported on all
>> >architectures. This patch adds support for initrd= to the x86.
>> >
>> >For debugging and recovery purposes, if initrd= is present in the
>> >command line, other existing initrd sources should still have
>> >higher priority. The initramfs in flash might be damaged or
>> >broken. Hence, it must still be possible to load a kernel and
>> >initramfs with a conventional bootloader, or even load the
>> >FLASH-based kernel with a different initramfs; or boot a
>> >kernel and let it use the initrd in FLASH.
>> >
>> >In support of that priority ordering, this patch sets the ramdisk
>> >image pointer to phys_initrd_start only if it is not already set;
>> >and sets ramdisk_size to phys_initrd_size only if it is not already
>> >set.
>> >
>> >It has been tested extensively in LinuxBoot environments.
>> >
>> >Signed-off-by: Ronald G. Minnich <[email protected]>
>> >---
>> > arch/x86/kernel/setup.c | 6 ++++++
>> > 1 file changed, 6 insertions(+)
>> >
>> >diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> >index a74262c71484..1b04ef8ea12d 100644
>> >--- a/arch/x86/kernel/setup.c
>> >+++ b/arch/x86/kernel/setup.c
>> >@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
>> >
>> > ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
>> >
>> >+ if (ramdisk_image == 0) {
>> >+ ramdisk_image = phys_initrd_start;
>> >+ }
>> > return ramdisk_image;
>> > }
>> > static u64 __init get_ramdisk_size(void)
>> >@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)
>> >
>> > ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
>> >
>> >+ if (ramdisk_size == 0) {
>> >+ ramdisk_size = phys_initrd_size;
>> >+ }
>> > return ramdisk_size;
>> > }
>>
>> The initrd= option is reserved namespace for the bootloader. It is
>also worth noting that the x86 boot protocol now allows the bootloader
>to point to arbitrary chunks of memory for the initrd.
>> --
>> Sent from my Android device with K-9 Mail. Please excuse my brevity.

It has been designated consumed by the bootloader on x86 since at least 1995. So ARM broke it.

How is this information passed to any version of Linux in the first place, and how do you then start up Linux? I suspect this is probably rather simple in the end...

Note that when Linux is run as an UEFI binary the kernel UEFI stub can load an initrd file via the UEFI file I/O interface.

In some ways, arguably the Right Thing for the firmware to expose this would be to have a resource exposed via ACPI .


--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-20 15:42:48

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On Thu, Mar 19, 2020 at 5:59 PM <[email protected]> wrote:
>
> On March 19, 2020 5:50:52 PM PDT, ron minnich <[email protected]> wrote:
> >Thanks for looking, but I'm not entirely sure how to parse your answer
> >:-)
> >
> >In LinuxBoot, we compile Linux into a UEFI driver and load it in
> >FLASH. It's started by the UEFI driver scheduler, a.k.a DxeCore. In
> >this case, Linux is both a bootloader (for the Linux or other kernel
> >it will boot) and Linux is also the thing booted by UEFI. As I
> >mentioned, we want to avoid writing a UEFI driver just to tell Linux
> >where to find the initramfs. Further, we want to be able to boot this
> >kernel and have it use an initramfs provided by a different bootloader
> >(pxeboot, for example). This flexibility is proving very useful for
> >companies deploying LinuxBoot today.
> >
> >I got the idea of using initrd= because u-boot is able to pass that
> >option to the ARM kernel and the ARM kernel will process it: see,
> >e.g., the usage in arch/arm/configs/acs5k_defconfig.
> >
> >Are you saying initrd is reserved for a bootloader to produce it or
> >consume it? It's certainly not either on ARM: it is in some cases
> >included in a compiled-in command line, and used by the kernel, just
> >as we are doing in this patch. The kernel build process produces it,
> >and the kernel consumes it. All this functionality is there, and all
> >this patch does it bring it into the x86 kernel with this 6 line
> >patch.
> >
> >If, in spite of this usage on ARM, you'd still not rather see a
> >corresponding usage on x86, how do we get the effect we need here?
> >Again, we don't want to write UEFI drivers, but we would like some
> >minimal way to communicate to the kernel where an initramfs is in
> >memory; and, further, we want it to be the lowest priority option, so
> >we easily override it. Suggestions on how to do this are welcome.
> >
> >ron
> >
> >On Thu, Mar 19, 2020 at 4:57 PM <[email protected]> wrote:
> >>
> >> On March 19, 2020 4:49:05 PM PDT, ron minnich <[email protected]>
> >wrote:
> >> >In LinuxBoot systems, a kernel and initramfs are loaded into FLASH
> >> >to replace proprietary firmware/BIOS code. Space being at a premium
> >> >on some systems, the kernel and initramfs must be place in whatever
> >> >open corners of the FLASH exist. These corners are not always
> >> >easily used.
> >> >
> >> >For example, on Intel-based UEFI systems, the Management Engine
> >> >(ME) is given half the FLASH, though it uses very little, as little
> >> >as 1.25MiB. Not only is 2.75MiB of an 8MiB part unused; but
> >> >10.75MiB of a 16MiB part is unused. This space can be recovered by
> >> >a number of tools, e.g. utk and its tighten_me command, and if
> >> >Linux can be told where the space is Linux can load an initrd from
> >> >it.
> >> >
> >> >In an ideal case, we would take the space from the ME and add it to
> >> >a FLASH-based filesystem. While UEFI does have filesystem-like
> >> >structures, this recovered space can only be added to its "file
> >> >system" by rebuilding UEFI from source or writing a UEFI device
> >> >driver. Both these options are impractical in most cases. The space
> >> >can only be referenced as a physical address.
> >> >
> >> >There is code in the core that allows specification of the initrd
> >> >as a physical address and size, but it is not supported on all
> >> >architectures. This patch adds support for initrd= to the x86.
> >> >
> >> >For debugging and recovery purposes, if initrd= is present in the
> >> >command line, other existing initrd sources should still have
> >> >higher priority. The initramfs in flash might be damaged or
> >> >broken. Hence, it must still be possible to load a kernel and
> >> >initramfs with a conventional bootloader, or even load the
> >> >FLASH-based kernel with a different initramfs; or boot a
> >> >kernel and let it use the initrd in FLASH.
> >> >
> >> >In support of that priority ordering, this patch sets the ramdisk
> >> >image pointer to phys_initrd_start only if it is not already set;
> >> >and sets ramdisk_size to phys_initrd_size only if it is not already
> >> >set.
> >> >
> >> >It has been tested extensively in LinuxBoot environments.
> >> >
> >> >Signed-off-by: Ronald G. Minnich <[email protected]>
> >> >---
> >> > arch/x86/kernel/setup.c | 6 ++++++
> >> > 1 file changed, 6 insertions(+)
> >> >
> >> >diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> >> >index a74262c71484..1b04ef8ea12d 100644
> >> >--- a/arch/x86/kernel/setup.c
> >> >+++ b/arch/x86/kernel/setup.c
> >> >@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
> >> >
> >> > ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
> >> >
> >> >+ if (ramdisk_image == 0) {
> >> >+ ramdisk_image = phys_initrd_start;
> >> >+ }
> >> > return ramdisk_image;
> >> > }
> >> > static u64 __init get_ramdisk_size(void)
> >> >@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)
> >> >
> >> > ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
> >> >
> >> >+ if (ramdisk_size == 0) {
> >> >+ ramdisk_size = phys_initrd_size;
> >> >+ }
> >> > return ramdisk_size;
> >> > }
> >>
> >> The initrd= option is reserved namespace for the bootloader. It is
> >also worth noting that the x86 boot protocol now allows the bootloader
> >to point to arbitrary chunks of memory for the initrd.
> >> --
> >> Sent from my Android device with K-9 Mail. Please excuse my brevity.
>
> It has been designated consumed by the bootloader on x86 since at least 1995. So ARM broke it.

No argument, but at the same time, it is now used in arch, mips, and
powerpc. I suspect there is no going back.

> How is this information passed to any version of Linux in the first place, and how do you then start up Linux? I suspect this is probably rather simple in the end...

Right now, it is an early_param in init/do_mounts_initrd.c, hence part
of core. It came in with b1ab95c6 in 11/2018, which is what drew us to
it initially.

On some systems, we now have LInuxBoot running on the ARM board
controller (BMC) AND on the x86 as well, and keeping some conformance
of booting and command line structure has a high value. There's a
reason this patch is so small: all the bits I needed are in the kernel
already. If I use initrd= on the kernel command line, and
CONFIG_BLK_DEV_INITRD is set, the kernel variables are set, on all
architectures.

Google, facebook, and others are now deploying LinuxBoot into their
data centers; IoT companies are building on it; manufacturers are
using it; aerospace companies too. We have need of this kind of
capability. We chose this way of doing it after looking at a lot of
options, including ACPI. Many of the smaller companies we work with
also use ARM, and prefer this method to using ACPI, because then it's
one less point of difference.

> Note that when Linux is run as an UEFI binary the kernel UEFI stub can load an initrd file via the UEFI file I/O interface.

As part of our deployment of LinuxBoot, we are removing all UEFI
components we can, including those that implement file system and disk
I/O. They represent attack surface. So that's not an option.

Besides, the initrd is in reclaimed flash anyway, not a disk. UEFI can
only load components from a firmware volume and, as mentioned, to make
the reclaimed space available for UEFI to use we have to recompile
from source or write a UEFI driver to add that reclaimed space to the
firmware volume at startup -- undesirable and, for most places,
impossible.

Further, some companies (e.g. facebook) are looking to deploy
FSP/coreboot on x86, so using UEFI components to load initrd is a
short-term, dead-end effort.

>
> In some ways, arguably the Right Thing for the firmware to expose this would be to have a resource exposed via ACPI .

Arguably true, but we've found a real reluctance among our partners to
get involved with ACPI. Further, many of them work with ARM, and feel
that given this works today on ARM, it would be nice to have it work
on x86. While it is true that the bootloaders such as syslinux, grub,
etc. have initrd in their namespace, in LinuxBoot systems we don't
have those bootloaders. Linux is our bootloader.

I don't expect ARM/powerpc/MIPS communities to give initrd= up; it's
already in core; I can put it on a command line for a FLASH-installed
x86 Linux kernel and it will be processed, and those variables will be
set. It's ubiquity is what makes it so attractive. It's wonderfully
convenient, especially in test situations, where I might netboot a
kernel but tell it to use the initramfs in flash.

So, how do we move forward? If it's just not possible to have initrd=
mean something to the x86 kernel, as it does to other architectures,
is a different name OK? That's a bit less attractive, as it puts us in
"when on x86, do this; on all others, the standard initrd= parameter
works" mode. But if that's what it takes, we'll do it. physinitrd?
initrdaddr? something else?

We do need this. We're rolling systems into datacenters and at some
point the need for this is a blocker. So I'd like to get this figured
out.

Thanks for anything you can do.

ron

2020-03-20 18:20:25

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On Thu, Mar 19, 2020 at 5:59 PM <[email protected]> wrote:

> It has been designated consumed by the bootloader on x86 since at least 1995. So ARM broke it.

Eh. This feels like a matter of semantics - booting the kernel via EFI
results in it being parsed by the boot stub, so in that case we're
left arguing that the boot stub isn't the kernel. I can just about buy
that, but it's a stretch. For this change to actually break something,
we'd need the bootloader to be passing something that the kernel
parses, but not actually populating the initrd fields in bootparams.
That seems unlikely?

2020-03-23 18:22:14

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 20, 2020 11:19:19 AM PDT, Matthew Garrett <[email protected]> wrote:
>On Thu, Mar 19, 2020 at 5:59 PM <[email protected]> wrote:
>
>> It has been designated consumed by the bootloader on x86 since at
>least 1995. So ARM broke it.
>
>Eh. This feels like a matter of semantics - booting the kernel via EFI
>results in it being parsed by the boot stub, so in that case we're
>left arguing that the boot stub isn't the kernel. I can just about buy
>that, but it's a stretch. For this change to actually break something,
>we'd need the bootloader to be passing something that the kernel
>parses, but not actually populating the initrd fields in bootparams.
>That seems unlikely?

You are right as long as this is the very last priority *and* neither boot loaders nor the kernel will croak on unexpected input (I really object to Ron calling the non-x86 version "standard", but that's a whole other ball of wax.)

Pointing to any number of memory chunks via setup_data works and doesn't need to be exposed to the user, but I guess the above is reasonable.

*However*, I would also suggest adding "initrdmem=" across architectures that doesn't have the ambiguity.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-23 18:55:48

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On Mon, Mar 23, 2020 at 11:19 AM <[email protected]> wrote:
> Pointing to any number of memory chunks via setup_data works and doesn't need to be exposed to the user, but I guess the above is reasonable.

so, good to go?

>
> *However*, I would also suggest adding "initrdmem=" across architectures that doesn't have the ambiguity.

agreed. I can look at doing that next.

ron

2020-03-23 19:06:58

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 23, 2020 11:54:28 AM PDT, ron minnich <[email protected]> wrote:
>On Mon, Mar 23, 2020 at 11:19 AM <[email protected]> wrote:
>> Pointing to any number of memory chunks via setup_data works and
>doesn't need to be exposed to the user, but I guess the above is
>reasonable.
>
>so, good to go?
>
>>
>> *However*, I would also suggest adding "initrdmem=" across
>architectures that doesn't have the ambiguity.
>
>agreed. I can look at doing that next.
>
>ron

I would prefer if we could put both into the same patchset.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-23 19:42:32

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

I'm wondering -- adding initrdmem= is easy, do you think we'll ever be
able to end uses of initrd= in the ARM and MIPS world? Is it ok to
have these two identical command line parameters? I'm guessing just
changing initrd= would be hard.

Do we just accept initrd= from this day forward, as well as initrdmem=?

On Mon, Mar 23, 2020 at 12:06 PM <[email protected]> wrote:
>
> On March 23, 2020 11:54:28 AM PDT, ron minnich <[email protected]> wrote:
> >On Mon, Mar 23, 2020 at 11:19 AM <[email protected]> wrote:
> >> Pointing to any number of memory chunks via setup_data works and
> >doesn't need to be exposed to the user, but I guess the above is
> >reasonable.
> >
> >so, good to go?
> >
> >>
> >> *However*, I would also suggest adding "initrdmem=" across
> >architectures that doesn't have the ambiguity.
> >
> >agreed. I can look at doing that next.
> >
> >ron
>
> I would prefer if we could put both into the same patchset.
> --
> Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-23 21:43:21

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 23, 2020 12:40:15 PM PDT, ron minnich <[email protected]> wrote:
>I'm wondering -- adding initrdmem= is easy, do you think we'll ever be
>able to end uses of initrd= in the ARM and MIPS world? Is it ok to
>have these two identical command line parameters? I'm guessing just
>changing initrd= would be hard.
>
>Do we just accept initrd= from this day forward, as well as initrdmem=?
>
>On Mon, Mar 23, 2020 at 12:06 PM <[email protected]> wrote:
>>
>> On March 23, 2020 11:54:28 AM PDT, ron minnich <[email protected]>
>wrote:
>> >On Mon, Mar 23, 2020 at 11:19 AM <[email protected]> wrote:
>> >> Pointing to any number of memory chunks via setup_data works and
>> >doesn't need to be exposed to the user, but I guess the above is
>> >reasonable.
>> >
>> >so, good to go?
>> >
>> >>
>> >> *However*, I would also suggest adding "initrdmem=" across
>> >architectures that doesn't have the ambiguity.
>> >
>> >agreed. I can look at doing that next.
>> >
>> >ron
>>
>> I would prefer if we could put both into the same patchset.
>> --
>> Sent from my Android device with K-9 Mail. Please excuse my brevity.

Yes, accept both.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-23 22:31:57

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

sounds good, I'm inclined to want to mention only initrdmem= in
Documentation? or just say initrd is discouraged or deprecated?

On Mon, Mar 23, 2020 at 2:41 PM <[email protected]> wrote:
>
> On March 23, 2020 12:40:15 PM PDT, ron minnich <[email protected]> wrote:
> >I'm wondering -- adding initrdmem= is easy, do you think we'll ever be
> >able to end uses of initrd= in the ARM and MIPS world? Is it ok to
> >have these two identical command line parameters? I'm guessing just
> >changing initrd= would be hard.
> >
> >Do we just accept initrd= from this day forward, as well as initrdmem=?
> >
> >On Mon, Mar 23, 2020 at 12:06 PM <[email protected]> wrote:
> >>
> >> On March 23, 2020 11:54:28 AM PDT, ron minnich <[email protected]>
> >wrote:
> >> >On Mon, Mar 23, 2020 at 11:19 AM <[email protected]> wrote:
> >> >> Pointing to any number of memory chunks via setup_data works and
> >> >doesn't need to be exposed to the user, but I guess the above is
> >> >reasonable.
> >> >
> >> >so, good to go?
> >> >
> >> >>
> >> >> *However*, I would also suggest adding "initrdmem=" across
> >> >architectures that doesn't have the ambiguity.
> >> >
> >> >agreed. I can look at doing that next.
> >> >
> >> >ron
> >>
> >> I would prefer if we could put both into the same patchset.
> >> --
> >> Sent from my Android device with K-9 Mail. Please excuse my brevity.
>
> Yes, accept both.
> --
> Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-23 22:39:15

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

nvm, it's only mentioned as a parameter for bootloaders.

Testing this change now.

On Mon, Mar 23, 2020 at 3:29 PM ron minnich <[email protected]> wrote:
>
> sounds good, I'm inclined to want to mention only initrdmem= in
> Documentation? or just say initrd is discouraged or deprecated?
>
> On Mon, Mar 23, 2020 at 2:41 PM <[email protected]> wrote:
> >
> > On March 23, 2020 12:40:15 PM PDT, ron minnich <[email protected]> wrote:
> > >I'm wondering -- adding initrdmem= is easy, do you think we'll ever be
> > >able to end uses of initrd= in the ARM and MIPS world? Is it ok to
> > >have these two identical command line parameters? I'm guessing just
> > >changing initrd= would be hard.
> > >
> > >Do we just accept initrd= from this day forward, as well as initrdmem=?
> > >
> > >On Mon, Mar 23, 2020 at 12:06 PM <[email protected]> wrote:
> > >>
> > >> On March 23, 2020 11:54:28 AM PDT, ron minnich <[email protected]>
> > >wrote:
> > >> >On Mon, Mar 23, 2020 at 11:19 AM <[email protected]> wrote:
> > >> >> Pointing to any number of memory chunks via setup_data works and
> > >> >doesn't need to be exposed to the user, but I guess the above is
> > >> >reasonable.
> > >> >
> > >> >so, good to go?
> > >> >
> > >> >>
> > >> >> *However*, I would also suggest adding "initrdmem=" across
> > >> >architectures that doesn't have the ambiguity.
> > >> >
> > >> >agreed. I can look at doing that next.
> > >> >
> > >> >ron
> > >>
> > >> I would prefer if we could put both into the same patchset.
> > >> --
> > >> Sent from my Android device with K-9 Mail. Please excuse my brevity.
> >
> > Yes, accept both.
> > --
> > Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-24 16:08:43

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

Here is the version that I think does what you asked.

I'd like to change the patch title but left it on this email thread.


Subject: [PATCH 1/1] initrdmem= option to specify initrd physical address

This patch adds the initrdmem option:
initrdmem=ss[KMG],nn[KMG]
which is used to specify the physical address of the initrd,
almost always an address in FLASH. It also adds code for
x86 to use the existing phys_init_start and
phys_init_size variables in the kernel.
This is useful in cases where we wish to place a kernel
and initrd in FLASH, but there is no firmware file
system structure in the FLASH.

One such situation occurs when we have reclaimed unused FLASH
space on UEFI systems by, e.g., taking it from the Management
Engine. For example, on many systems, the ME is given half the
FLASH part; not only is 2.75M of an 8M part unused; but 10.75M
of a 16M part is unused. We can use this space to contain
an initrd, but need to tell Linux where it is.

This space is "raw": due to, e.g., UEFI limitations:
it can not be added to UEFI firmware volumes without rebuilding
UEFI from source or writing a UEFI device driver. We can reference it
only as a physical address and size.

At the same time, should we netboot a kernel or load it from
GRUB or syslinux, we want to have the option of not using
the physical address specification. Then, should we wish, it
is easy to boot the kernel and provide an initrd; or boot the
the kernel and let it use the initrd in FLASH. In practice this
has proven to be very helpful as we integrate Linux into FLASH
on x86.

Hence, the most flexible and convenient path is to enable the
initrdmem command line flag in a way that it is the last choice tried.

For example, on the DigitalLoggers Atomic Pi, we burn an image into
FLASH with a built-in command line which includes:
initrdmem=0xff968000,0x200000
which specifies a location and size.

Signed-off-by: Ronald G. Minnich <[email protected]>
---
Documentation/admin-guide/kernel-parameters.txt | 7 +++++++
arch/x86/kernel/setup.c | 6 ++++++
init/do_mounts_initrd.c | 13 ++++++++++++-
3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt
b/Documentation/admin-guide/kernel-parameters.txt
index c07815d230bc..9cd356958a7f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1714,6 +1714,13 @@

initrd= [BOOT] Specify the location of the initial ramdisk

+ initrdmem= [KNL] Specify a physical adddress and size from which
+ to load the inird. If an initrd is compiled in or
+ specified in the bootparams, it takes priority
+ over this setting.
+ Format: ss[KMG],nn[KMG]
+ Defaut is 0, 0
+
init_on_alloc= [MM] Fill newly allocated pages and heap objects with
zeroes.
Format: 0 | 1
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a74262c71484..1b04ef8ea12d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)

ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;

+ if (ramdisk_image == 0) {
+ ramdisk_image = phys_initrd_start;
+ }
return ramdisk_image;
}
static u64 __init get_ramdisk_size(void)
@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)

ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;

+ if (ramdisk_size == 0) {
+ ramdisk_size = phys_initrd_size;
+ }
return ramdisk_size;
}

diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index dab8b1151b56..d72beda824aa 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -28,7 +28,7 @@ static int __init no_initrd(char *str)

__setup("noinitrd", no_initrd);

-static int __init early_initrd(char *p)
+static int __init early_initrdmem(char *p)
{
phys_addr_t start;
unsigned long size;
@@ -43,6 +43,17 @@ static int __init early_initrd(char *p)
}
return 0;
}
+early_param("initrdmem", early_initrdmem);
+
+/*
+ * This is here as the initrd keyword has been in use since 11/2018
+ * on ARM, PowerPC, and MIPS.
+ * It should not be; it is reserved for bootloaders.
+ */
+static int __init early_initrd(char *p)
+{
+ return early_initrdmem(p);
+}
early_param("initrd", early_initrd);

static int init_linuxrc(struct subprocess_info *info, struct cred *new)
--
2.17.1

2020-03-24 16:14:11

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On 3/24/20 9:05 AM, ron minnich wrote:
> diff --git a/Documentation/admin-guide/kernel-parameters.txt
> b/Documentation/admin-guide/kernel-parameters.txt
> index c07815d230bc..9cd356958a7f 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1714,6 +1714,13 @@
>
> initrd= [BOOT] Specify the location of the initial ramdisk
>
> + initrdmem= [KNL] Specify a physical adddress and size from which
> + to load the inird. If an initrd is compiled in or

initrd.

> + specified in the bootparams, it takes priority
> + over this setting.
> + Format: ss[KMG],nn[KMG]
> + Defaut is 0, 0

Default

> +
> init_on_alloc= [MM] Fill newly allocated pages and heap objects with
> zeroes.
> Format: 0 | 1


--
~Randy

2020-03-24 16:20:29

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

Subject: [PATCH 1/1] initrdmem= option to specify initrd physical address

This patch adds the initrdmem option:
initrdmem=ss[KMG],nn[KMG]
which is used to specify the physical address of the initrd,
almost always an address in FLASH. It also adds code for
x86 to use the existing phys_init_start and
phys_init_size variables in the kernel.
This is useful in cases where we wish to place a kernel
and initrd in FLASH, but there is no firmware file
system structure in the FLASH.

One such situation occurs when we have reclaimed unused FLASH
space on UEFI systems by, e.g., taking it from the Management
Engine. For example, on many systems, the ME is given half the
FLASH part; not only is 2.75M of an 8M part unused; but 10.75M
of a 16M part is unused. We can use this space to contain
an initrd, but need to tell Linux where it is.

This space is "raw": due to, e.g., UEFI limitations:
it can not be added to UEFI firmware volumes without rebuilding
UEFI from source or writing a UEFI device driver. We can reference it
only as a physical address and size.

At the same time, should we netboot a kernel or load it from
GRUB or syslinux, we want to have the option of not using
the physical address specification. Then, should we wish, it
is easy to boot the kernel and provide an initrd; or boot the
the kernel and let it use the initrd in FLASH. In practice this
has proven to be very helpful as we integrate Linux into FLASH
on x86.

Hence, the most flexible and convenient path is to enable the
initrdmem command line flag in a way that it is the last choice tried.

For example, on the DigitalLoggers Atomic Pi, we burn an image into
FLASH with a built-in command line which includes:
initrdmem=0xff968000,0x200000
which specifies a location and size.

Signed-off-by: Ronald G. Minnich <[email protected]>
---
Documentation/admin-guide/kernel-parameters.txt | 7 +++++++
arch/x86/kernel/setup.c | 6 ++++++
init/do_mounts_initrd.c | 13 ++++++++++++-
3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt
b/Documentation/admin-guide/kernel-parameters.txt
index c07815d230bc..9cd356958a7f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1714,6 +1714,13 @@

initrd= [BOOT] Specify the location of the initial ramdisk

+ initrdmem= [KNL] Specify a physical adddress and size from which
+ to load the initrd. If an initrd is compiled in or
+ specified in the bootparams, it takes priority
+ over this setting.
+ Format: ss[KMG],nn[KMG]
+ Default is 0, 0
+
init_on_alloc= [MM] Fill newly allocated pages and heap objects with
zeroes.
Format: 0 | 1
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a74262c71484..1b04ef8ea12d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)

ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;

+ if (ramdisk_image == 0) {
+ ramdisk_image = phys_initrd_start;
+ }
return ramdisk_image;
}
static u64 __init get_ramdisk_size(void)
@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)

ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;

+ if (ramdisk_size == 0) {
+ ramdisk_size = phys_initrd_size;
+ }
return ramdisk_size;
}

diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index dab8b1151b56..d72beda824aa 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -28,7 +28,7 @@ static int __init no_initrd(char *str)

__setup("noinitrd", no_initrd);

-static int __init early_initrd(char *p)
+static int __init early_initrdmem(char *p)
{
phys_addr_t start;
unsigned long size;
@@ -43,6 +43,17 @@ static int __init early_initrd(char *p)
}
return 0;
}
+early_param("initrdmem", early_initrdmem);
+
+/*
+ * This is here as the initrd keyword has been in use since 11/2018
+ * on ARM, PowerPC, and MIPS.
+ * It should not be; it is reserved for bootloaders.
+ */
+static int __init early_initrd(char *p)
+{
+ return early_initrdmem(p);
+}
early_param("initrd", early_initrd);

static int init_linuxrc(struct subprocess_info *info, struct cred *new)
--
2.17.1

2020-03-25 03:32:16

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On 2020-03-23 15:29, ron minnich wrote:
> sounds good, I'm inclined to want to mention only initrdmem= in
> Documentation? or just say initrd is discouraged or deprecated?

Deprecated, yes.

-hpa

2020-03-25 16:20:17

by ron minnich

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

I think it may be fine at this point. The only reference to initrd= is
in some of the platform-specific docs and I'm reluctant to change
those. wdyt?

thanks again

On Tue, Mar 24, 2020 at 8:31 PM H. Peter Anvin <[email protected]> wrote:
>
> On 2020-03-23 15:29, ron minnich wrote:
> > sounds good, I'm inclined to want to mention only initrdmem= in
> > Documentation? or just say initrd is discouraged or deprecated?
>
> Deprecated, yes.
>
> -hpa
>

2020-03-25 17:23:53

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 24, 2020 9:19:01 AM PDT, ron minnich <[email protected]> wrote:
>Subject: [PATCH 1/1] initrdmem= option to specify initrd physical
>address
>
>This patch adds the initrdmem option:
>initrdmem=ss[KMG],nn[KMG]
>which is used to specify the physical address of the initrd,
>almost always an address in FLASH. It also adds code for
>x86 to use the existing phys_init_start and
>phys_init_size variables in the kernel.
>This is useful in cases where we wish to place a kernel
>and initrd in FLASH, but there is no firmware file
>system structure in the FLASH.
>
>One such situation occurs when we have reclaimed unused FLASH
>space on UEFI systems by, e.g., taking it from the Management
>Engine. For example, on many systems, the ME is given half the
>FLASH part; not only is 2.75M of an 8M part unused; but 10.75M
>of a 16M part is unused. We can use this space to contain
>an initrd, but need to tell Linux where it is.
>
>This space is "raw": due to, e.g., UEFI limitations:
>it can not be added to UEFI firmware volumes without rebuilding
>UEFI from source or writing a UEFI device driver. We can reference it
>only as a physical address and size.
>
>At the same time, should we netboot a kernel or load it from
>GRUB or syslinux, we want to have the option of not using
>the physical address specification. Then, should we wish, it
>is easy to boot the kernel and provide an initrd; or boot the
>the kernel and let it use the initrd in FLASH. In practice this
>has proven to be very helpful as we integrate Linux into FLASH
>on x86.
>
>Hence, the most flexible and convenient path is to enable the
>initrdmem command line flag in a way that it is the last choice tried.
>
>For example, on the DigitalLoggers Atomic Pi, we burn an image into
>FLASH with a built-in command line which includes:
>initrdmem=0xff968000,0x200000
>which specifies a location and size.
>
>Signed-off-by: Ronald G. Minnich <[email protected]>
>---
> Documentation/admin-guide/kernel-parameters.txt | 7 +++++++
> arch/x86/kernel/setup.c | 6 ++++++
> init/do_mounts_initrd.c | 13 ++++++++++++-
> 3 files changed, 25 insertions(+), 1 deletion(-)
>
>diff --git a/Documentation/admin-guide/kernel-parameters.txt
>b/Documentation/admin-guide/kernel-parameters.txt
>index c07815d230bc..9cd356958a7f 100644
>--- a/Documentation/admin-guide/kernel-parameters.txt
>+++ b/Documentation/admin-guide/kernel-parameters.txt
>@@ -1714,6 +1714,13 @@
>
> initrd= [BOOT] Specify the location of the initial ramdisk
>
>+ initrdmem= [KNL] Specify a physical adddress and size from
>which
>+ to load the initrd. If an initrd is compiled in or
>+ specified in the bootparams, it takes priority
>+ over this setting.
>+ Format: ss[KMG],nn[KMG]
>+ Default is 0, 0
>+
>init_on_alloc= [MM] Fill newly allocated pages and heap objects with
> zeroes.
> Format: 0 | 1
>diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>index a74262c71484..1b04ef8ea12d 100644
>--- a/arch/x86/kernel/setup.c
>+++ b/arch/x86/kernel/setup.c
>@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
>
> ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
>
>+ if (ramdisk_image == 0) {
>+ ramdisk_image = phys_initrd_start;
>+ }
> return ramdisk_image;
> }
> static u64 __init get_ramdisk_size(void)
>@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)
>
> ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
>
>+ if (ramdisk_size == 0) {
>+ ramdisk_size = phys_initrd_size;
>+ }
> return ramdisk_size;
> }
>
>diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
>index dab8b1151b56..d72beda824aa 100644
>--- a/init/do_mounts_initrd.c
>+++ b/init/do_mounts_initrd.c
>@@ -28,7 +28,7 @@ static int __init no_initrd(char *str)
>
> __setup("noinitrd", no_initrd);
>
>-static int __init early_initrd(char *p)
>+static int __init early_initrdmem(char *p)
> {
> phys_addr_t start;
> unsigned long size;
>@@ -43,6 +43,17 @@ static int __init early_initrd(char *p)
> }
> return 0;
> }
>+early_param("initrdmem", early_initrdmem);
>+
>+/*
>+ * This is here as the initrd keyword has been in use since 11/2018
>+ * on ARM, PowerPC, and MIPS.
>+ * It should not be; it is reserved for bootloaders.
>+ */
>+static int __init early_initrd(char *p)
>+{
>+ return early_initrdmem(p);
>+}
> early_param("initrd", early_initrd);
>
>static int init_linuxrc(struct subprocess_info *info, struct cred *new)

Reviewed-by: H. Peter Anvin (Intel) <[email protected]>
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-03-25 17:24:47

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/1] x86 support for the initrd= command line option

On March 25, 2020 9:19:26 AM PDT, ron minnich <[email protected]> wrote:
>I think it may be fine at this point. The only reference to initrd= is
>in some of the platform-specific docs and I'm reluctant to change
>those. wdyt?
>
>thanks again
>
>On Tue, Mar 24, 2020 at 8:31 PM H. Peter Anvin <[email protected]> wrote:
>>
>> On 2020-03-23 15:29, ron minnich wrote:
>> > sounds good, I'm inclined to want to mention only initrdmem= in
>> > Documentation? or just say initrd is discouraged or deprecated?
>>
>> Deprecated, yes.
>>
>> -hpa
>>

Looks good to me.

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

Subject: [tip: x86/boot] x86/setup: Add an initrdmem= option to specify initrd physical address

The following commit has been merged into the x86/boot branch of tip:

Commit-ID: 694cfd87b0c8a48af2f1afb225563571c0b975c4
Gitweb: https://git.kernel.org/tip/694cfd87b0c8a48af2f1afb225563571c0b975c4
Author: Ronald G. Minnich <[email protected]>
AuthorDate: Sat, 25 Apr 2020 18:10:21 -07:00
Committer: Borislav Petkov <[email protected]>
CommitterDate: Mon, 27 Apr 2020 09:28:16 +02:00

x86/setup: Add an initrdmem= option to specify initrd physical address

Add the initrdmem option:

initrdmem=ss[KMG],nn[KMG]

which is used to specify the physical address of the initrd, almost
always an address in FLASH. Also add code for x86 to use the existing
phys_init_start and phys_init_size variables in the kernel.

This is useful in cases where a kernel and an initrd is placed in FLASH,
but there is no firmware file system structure in the FLASH.

One such situation occurs when unused FLASH space on UEFI systems has
been reclaimed by, e.g., taking it from the Management Engine. For
example, on many systems, the ME is given half the FLASH part; not only
is 2.75M of an 8M part unused; but 10.75M of a 16M part is unused. This
space can be used to contain an initrd, but need to tell Linux where it
is.

This space is "raw": due to, e.g., UEFI limitations: it can not be added
to UEFI firmware volumes without rebuilding UEFI from source or writing
a UEFI device driver. It can be referenced only as a physical address
and size.

At the same time, if a kernel can be "netbooted" or loaded from GRUB or
syslinux, the option of not using the physical address specification
should be available.

Then, it is easy to boot the kernel and provide an initrd; or boot the
the kernel and let it use the initrd in FLASH. In practice, this has
proven to be very helpful when integrating Linux into FLASH on x86.

Hence, the most flexible and convenient path is to enable the initrdmem
command line option in a way that it is the last choice tried.

For example, on the DigitalLoggers Atomic Pi, an image into FLASH can be
burnt in with a built-in command line which includes:

initrdmem=0xff968000,0x200000

which specifies a location and size.

[ bp: Massage commit message, make it passive. ]

[[email protected]: coding style fixes]
Signed-off-by: Ronald G. Minnich <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: H. Peter Anvin (Intel) <[email protected]>
Link: http://lkml.kernel.org/r/CAP6exYLK11rhreX=6QPyDQmW7wPHsKNEFtXE47pjx41xS6O7-A@mail.gmail.com
Link: https://lkml.kernel.org/r/20200426011021.1cskg0AGd%[email protected]
---
Documentation/admin-guide/kernel-parameters.txt | 7 +++++++
arch/x86/kernel/setup.c | 6 ++++++
init/do_mounts_initrd.c | 13 ++++++++++++-
3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 7bc83f3..a441b4f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1748,6 +1748,13 @@

initrd= [BOOT] Specify the location of the initial ramdisk

+ initrdmem= [KNL] Specify a physical address and size from which to
+ load the initrd. If an initrd is compiled in or
+ specified in the bootparams, it takes priority over this
+ setting.
+ Format: ss[KMG],nn[KMG]
+ Default is 0, 0
+
init_on_alloc= [MM] Fill newly allocated pages and heap objects with
zeroes.
Format: 0 | 1
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 4b3fa6c..a3767e7 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)

ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;

+ if (ramdisk_image == 0)
+ ramdisk_image = phys_initrd_start;
+
return ramdisk_image;
}
static u64 __init get_ramdisk_size(void)
@@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)

ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;

+ if (ramdisk_size == 0)
+ ramdisk_size = phys_initrd_size;
+
return ramdisk_size;
}

diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index dab8b11..d72beda 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -28,7 +28,7 @@ static int __init no_initrd(char *str)

__setup("noinitrd", no_initrd);

-static int __init early_initrd(char *p)
+static int __init early_initrdmem(char *p)
{
phys_addr_t start;
unsigned long size;
@@ -43,6 +43,17 @@ static int __init early_initrd(char *p)
}
return 0;
}
+early_param("initrdmem", early_initrdmem);
+
+/*
+ * This is here as the initrd keyword has been in use since 11/2018
+ * on ARM, PowerPC, and MIPS.
+ * It should not be; it is reserved for bootloaders.
+ */
+static int __init early_initrd(char *p)
+{
+ return early_initrdmem(p);
+}
early_param("initrd", early_initrd);

static int init_linuxrc(struct subprocess_info *info, struct cred *new)