Commit 694cfd87 authored by Ronald G. Minnich's avatar Ronald G. Minnich Committed by Borislav Petkov

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

[akpm@linux-foundation.org: coding style fixes]
Signed-off-by: default avatarRonald G. Minnich <rminnich@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarH. Peter Anvin (Intel) <hpa@zytor.com>
Link: http://lkml.kernel.org/r/CAP6exYLK11rhreX=6QPyDQmW7wPHsKNEFtXE47pjx41xS6O7-A@mail.gmail.com
Link: https://lkml.kernel.org/r/20200426011021.1cskg0AGd%akpm@linux-foundation.org
parent 6a8b55ed
...@@ -1748,6 +1748,13 @@ ...@@ -1748,6 +1748,13 @@
initrd= [BOOT] Specify the location of the initial ramdisk 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 init_on_alloc= [MM] Fill newly allocated pages and heap objects with
zeroes. zeroes.
Format: 0 | 1 Format: 0 | 1
......
...@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void) ...@@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32; ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
if (ramdisk_image == 0)
ramdisk_image = phys_initrd_start;
return ramdisk_image; return ramdisk_image;
} }
static u64 __init get_ramdisk_size(void) static u64 __init get_ramdisk_size(void)
...@@ -245,6 +248,9 @@ 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; ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
if (ramdisk_size == 0)
ramdisk_size = phys_initrd_size;
return ramdisk_size; return ramdisk_size;
} }
......
...@@ -28,7 +28,7 @@ static int __init no_initrd(char *str) ...@@ -28,7 +28,7 @@ static int __init no_initrd(char *str)
__setup("noinitrd", no_initrd); __setup("noinitrd", no_initrd);
static int __init early_initrd(char *p) static int __init early_initrdmem(char *p)
{ {
phys_addr_t start; phys_addr_t start;
unsigned long size; unsigned long size;
...@@ -43,6 +43,17 @@ static int __init early_initrd(char *p) ...@@ -43,6 +43,17 @@ static int __init early_initrd(char *p)
} }
return 0; 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); early_param("initrd", early_initrd);
static int init_linuxrc(struct subprocess_info *info, struct cred *new) static int init_linuxrc(struct subprocess_info *info, struct cred *new)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment