Skip to content

Commit ef12d05

Browse files
committed
Merge patch series "initrd: remove half of classic initrd support"
Askar Safin <safinaskar@gmail.com> says: This patchset will not affect anyone, who showed up in these lists. See [5] for details. Intro ==== This patchset removes half of classic initrd (initial RAM disk) support, i. e. linuxrc code path, which was deprecated in 2020. Initramfs still stays, RAM disk itself (brd) still stays. And other half of initrd stays, too. init/do_mounts* are listed in VFS entry in MAINTAINERS, so I think this patchset should go through VFS tree. I tested the patchset on 8 (!!!) archs in Qemu (see details below). If you still use initrd, see below for workaround. In 2020 deprecation notice was put to linuxrc initrd code path. In v1 I tried to remove initrd fully, but Nicolas Schichan reported that he still uses other code path (root=/dev/ram0 one) on million devices [4]. root=/dev/ram0 code path did not contain deprecation notice. So, in this version of patchset I remove deprecated code path, i. e. linuxrc one, while keeping other, i. e. root=/dev/ram0 one. Also I put deprecation notice to remaining code path, i. e. to root=/dev/ram0 one. I plan to send patches for full removal of initrd after one year, i. e. in January 2027 (of course, initramfs will still work). Also, I tried to make this patchset small to make sure it can be reverted easily. I plan to send cleanups later. Details ==== Other user-visible changes: - Removed kernel command line parameters "load_ramdisk" and "prompt_ramdisk", which did nothing and were deprecated - Removed /proc/sys/kernel/real-root-dev . It was used for initrd only - Command line parameters "noinitrd" and "ramdisk_start=" are deprecated Testing ==== I tested my patchset on many architectures in Qemu using my Rust program, heavily based on mkroot [1]. I used the following cross-compilers: aarch64-linux-musleabi armv4l-linux-musleabihf armv5l-linux-musleabihf armv7l-linux-musleabihf i486-linux-musl i686-linux-musl mips-linux-musl mips64-linux-musl mipsel-linux-musl powerpc-linux-musl powerpc64-linux-musl powerpc64le-linux-musl riscv32-linux-musl riscv64-linux-musl s390x-linux-musl sh4-linux-musl sh4eb-linux-musl x86_64-linux-musl taken from this directory [2]. So, as you can see, there are 18 triplets, which correspond to 8 subdirs in arch/. For every triplet I tested that: - Initramfs still works (both builtin and external) - Direct boot from disk still works - Remaining initrd code path (root=/dev/ram0) still works Workaround ==== If "retain_initrd" is passed to kernel, then initramfs/initrd, passed by bootloader, is retained and becomes available after boot as read-only magic file /sys/firmware/initrd [3]. No copies are involved. I. e. /sys/firmware/initrd is simply a reference to original blob passed by bootloader. This works even if initrd/initramfs is not recognized by kernel in any way, i. e. even if it is not valid cpio archive, nor a fs image supported by classic initrd. This works both with my patchset and without it. This means that you can emulate classic initrd so: link builtin initramfs to kernel; in /init in this initramfs copy /sys/firmware/initrd to some file in / and loop-mount it. This is even better than classic initrd, because: - You can use fs not supported by classic initrd, for example erofs - One copy is involved (from /sys/firmware/initrd to some file in /) as opposed to two when using classic initrd Still, I don't recommend using this workaround, because I want everyone to migrate to proper modern initramfs. But still you can use this workaround if you want. Also: it is not possible to directly loop-mount /sys/firmware/initrd . Theoretically kernel can be changed to allow this (and/or to make it writable), but I think nobody needs this. And I don't want to implement this. On Qemu's -initrd and GRUB's initrd ==== Don't panic, this patchset doesn't remove initramfs (which is used by nearly all Linux distros). And I don't have plans to remove it. Qemu's -initrd option and GRUB's initrd command refer to initrd bootloader mechanism, which is used to load both initrd and (external) initramfs. So, if you use Qemu's -initrd or GRUB's initrd, then you likely use them to pass initramfs, and thus you are safe. v1: https://lore.kernel.org/lkml/20250913003842.41944-1-safinaskar@gmail.com/ v1 -> v2 changes: - A lot. I removed most patches, see cover letter for details v2: https://lore.kernel.org/lkml/20251010094047.3111495-1-safinaskar@gmail.com/ v2 -> v3 changes: - Commit messages - Expanded docs for "noinitrd" - Added link to /sys/firmware/initrd workaround to pr_warn v3: https://lore.kernel.org/lkml/20251017060956.1151347-1-safinaskar@gmail.com/ v3 -> v4 changes: - Changed "September 2026" to "January 2027" (i. e. after 2026 LTS release) [1] https://github.com/landley/toybox/tree/master/mkroot [2] https://landley.net/toybox/downloads/binaries/toolchains/latest [3] https://lore.kernel.org/all/20231207235654.16622-1-graf@amazon.com/ [4] https://lore.kernel.org/lkml/20250918152830.438554-1-nschichan@freebox.fr/ [5] https://lore.kernel.org/lkml/20251022082604.25437-1-safinaskar@gmail.com/ * patches from https://patch.msgid.link/20251119222407.3333257-1-safinaskar@gmail.com: init: remove /proc/sys/kernel/real-root-dev initrd: remove deprecated code path (linuxrc) init: remove deprecated "load_ramdisk" and "prompt_ramdisk" command line parameters Link: https://patch.msgid.link/20251119222407.3333257-1-safinaskar@gmail.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents 8f0b4cc + e6ce36c commit ef12d05

File tree

9 files changed

+23
-160
lines changed

9 files changed

+23
-160
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,8 +3437,6 @@ Kernel parameters
34373437
If there are multiple matching configurations changing
34383438
the same attribute, the last one is used.
34393439

3440-
load_ramdisk= [RAM] [Deprecated]
3441-
34423440
lockd.nlm_grace_period=P [NFS] Assign grace period.
34433441
Format: <integer>
34443442

@@ -4444,8 +4442,10 @@ Kernel parameters
44444442
Note that this argument takes precedence over
44454443
the CONFIG_RCU_NOCB_CPU_DEFAULT_ALL option.
44464444

4447-
noinitrd [RAM] Tells the kernel not to load any configured
4448-
initial RAM disk.
4445+
noinitrd [Deprecated,RAM] Tells the kernel not to load any configured
4446+
initial RAM disk. Currently this parameter applies to
4447+
initrd only, not to initramfs. But it applies to both
4448+
in EFI mode.
44494449

44504450
nointremap [X86-64,Intel-IOMMU,EARLY] Do not enable interrupt
44514451
remapping.
@@ -5402,8 +5402,6 @@ Kernel parameters
54025402
Param: <number> - step/bucket size as a power of 2 for
54035403
statistical time based profiling.
54045404

5405-
prompt_ramdisk= [RAM] [Deprecated]
5406-
54075405
prot_virt= [S390] enable hosting protected virtual machines
54085406
isolated from the hypervisor (if hardware supports
54095407
that). If enabled, the default kernel base address
@@ -5460,7 +5458,7 @@ Kernel parameters
54605458
ramdisk_size= [RAM] Sizes of RAM disks in kilobytes
54615459
See Documentation/admin-guide/blockdev/ramdisk.rst.
54625460

5463-
ramdisk_start= [RAM] RAM disk image start address
5461+
ramdisk_start= [Deprecated,RAM] RAM disk image start address
54645462

54655463
random.trust_cpu=off
54665464
[KNL,EARLY] Disable trusting the use of the CPU's

Documentation/admin-guide/sysctl/kernel.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,12 +1235,6 @@ that support this feature.
12351235
== ===========================================================================
12361236

12371237

1238-
real-root-dev
1239-
=============
1240-
1241-
See Documentation/admin-guide/initrd.rst.
1242-
1243-
12441238
reboot-cmd (SPARC only)
12451239
=======================
12461240

arch/arm/configs/neponset_defconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ CONFIG_ASSABET_NEPONSET=y
99
CONFIG_ZBOOT_ROM_TEXT=0x80000
1010
CONFIG_ZBOOT_ROM_BSS=0xc1000000
1111
CONFIG_ZBOOT_ROM=y
12-
CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
12+
CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) mem=32M noinitrd initrd=0xc0800000,3M"
1313
CONFIG_FPE_NWFPE=y
1414
CONFIG_PM=y
1515
CONFIG_MODULES=y

include/linux/initrd.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
#ifndef __LINUX_INITRD_H
44
#define __LINUX_INITRD_H
55

6-
#define INITRD_MINOR 250 /* shouldn't collide with /dev/ram* too soon ... */
7-
86
/* starting block # of image */
97
extern int rd_image_start;
108

include/uapi/linux/sysctl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ enum
9292
KERN_DOMAINNAME=8, /* string: domainname */
9393

9494
KERN_PANIC=15, /* int: panic timeout */
95-
KERN_REALROOTDEV=16, /* real root device to mount after initrd */
9695

9796
KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
9897
KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */

init/do_mounts.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@ static int root_wait;
3434

3535
dev_t ROOT_DEV;
3636

37-
static int __init load_ramdisk(char *str)
38-
{
39-
pr_warn("ignoring the deprecated load_ramdisk= option\n");
40-
return 1;
41-
}
42-
__setup("load_ramdisk=", load_ramdisk);
43-
4437
static int __init readonly(char *str)
4538
{
4639
if (*str)
@@ -484,13 +477,11 @@ void __init prepare_namespace(void)
484477
if (saved_root_name[0])
485478
ROOT_DEV = parse_root_device(saved_root_name);
486479

487-
if (initrd_load(saved_root_name))
488-
goto out;
480+
initrd_load();
489481

490482
if (root_wait)
491483
wait_for_root(saved_root_name);
492484
mount_root(saved_root_name);
493-
out:
494485
devtmpfs_mount();
495486
init_mount(".", "/", NULL, MS_MOVE, NULL);
496487
init_chroot(".");

init/do_mounts.h

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,15 @@ static inline __init int create_dev(char *name, dev_t dev)
2323
}
2424

2525
#ifdef CONFIG_BLK_DEV_RAM
26-
27-
int __init rd_load_disk(int n);
28-
int __init rd_load_image(char *from);
29-
26+
int __init rd_load_image(void);
3027
#else
31-
32-
static inline int rd_load_disk(int n) { return 0; }
33-
static inline int rd_load_image(char *from) { return 0; }
34-
28+
static inline int rd_load_image(void) { return 0; }
3529
#endif
3630

3731
#ifdef CONFIG_BLK_DEV_INITRD
38-
bool __init initrd_load(char *root_device_name);
32+
void __init initrd_load(void);
3933
#else
40-
static inline bool initrd_load(char *root_device_name)
41-
{
42-
return false;
43-
}
44-
34+
static inline void initrd_load(void) { }
4535
#endif
4636

4737
/* Ensure that async file closing finished to prevent spurious errors. */

init/do_mounts_initrd.c

Lines changed: 8 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,20 @@
22
#include <linux/unistd.h>
33
#include <linux/kernel.h>
44
#include <linux/fs.h>
5-
#include <linux/minix_fs.h>
6-
#include <linux/romfs_fs.h>
75
#include <linux/initrd.h>
8-
#include <linux/sched.h>
9-
#include <linux/freezer.h>
10-
#include <linux/kmod.h>
11-
#include <uapi/linux/mount.h>
126

137
#include "do_mounts.h"
148

159
unsigned long initrd_start, initrd_end;
1610
int initrd_below_start_ok;
17-
static unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
1811
static int __initdata mount_initrd = 1;
1912

2013
phys_addr_t phys_initrd_start __initdata;
2114
unsigned long phys_initrd_size __initdata;
2215

23-
#ifdef CONFIG_SYSCTL
24-
static const struct ctl_table kern_do_mounts_initrd_table[] = {
25-
{
26-
.procname = "real-root-dev",
27-
.data = &real_root_dev,
28-
.maxlen = sizeof(int),
29-
.mode = 0644,
30-
.proc_handler = proc_dointvec,
31-
},
32-
};
33-
34-
static __init int kernel_do_mounts_initrd_sysctls_init(void)
35-
{
36-
register_sysctl_init("kernel", kern_do_mounts_initrd_table);
37-
return 0;
38-
}
39-
late_initcall(kernel_do_mounts_initrd_sysctls_init);
40-
#endif /* CONFIG_SYSCTL */
41-
4216
static int __init no_initrd(char *str)
4317
{
18+
pr_warn("noinitrd option is deprecated and will be removed soon\n");
4419
mount_initrd = 0;
4520
return 1;
4621
}
@@ -70,85 +45,19 @@ static int __init early_initrd(char *p)
7045
}
7146
early_param("initrd", early_initrd);
7247

73-
static int __init init_linuxrc(struct subprocess_info *info, struct cred *new)
74-
{
75-
ksys_unshare(CLONE_FS | CLONE_FILES);
76-
console_on_rootfs();
77-
/* move initrd over / and chdir/chroot in initrd root */
78-
init_chdir("/root");
79-
init_mount(".", "/", NULL, MS_MOVE, NULL);
80-
init_chroot(".");
81-
ksys_setsid();
82-
return 0;
83-
}
84-
85-
static void __init handle_initrd(char *root_device_name)
86-
{
87-
struct subprocess_info *info;
88-
static char *argv[] = { "linuxrc", NULL, };
89-
extern char *envp_init[];
90-
int error;
91-
92-
pr_warn("using deprecated initrd support, will be removed soon.\n");
93-
94-
real_root_dev = new_encode_dev(ROOT_DEV);
95-
create_dev("/dev/root.old", Root_RAM0);
96-
/* mount initrd on rootfs' /root */
97-
mount_root_generic("/dev/root.old", root_device_name,
98-
root_mountflags & ~MS_RDONLY);
99-
init_mkdir("/old", 0700);
100-
init_chdir("/old");
101-
102-
info = call_usermodehelper_setup("/linuxrc", argv, envp_init,
103-
GFP_KERNEL, init_linuxrc, NULL, NULL);
104-
if (!info)
105-
return;
106-
call_usermodehelper_exec(info, UMH_WAIT_PROC|UMH_FREEZABLE);
107-
108-
/* move initrd to rootfs' /old */
109-
init_mount("..", ".", NULL, MS_MOVE, NULL);
110-
/* switch root and cwd back to / of rootfs */
111-
init_chroot("..");
112-
113-
if (new_decode_dev(real_root_dev) == Root_RAM0) {
114-
init_chdir("/old");
115-
return;
116-
}
117-
118-
init_chdir("/");
119-
ROOT_DEV = new_decode_dev(real_root_dev);
120-
mount_root(root_device_name);
121-
122-
printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
123-
error = init_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
124-
if (!error)
125-
printk("okay\n");
126-
else {
127-
if (error == -ENOENT)
128-
printk("/initrd does not exist. Ignored.\n");
129-
else
130-
printk("failed\n");
131-
printk(KERN_NOTICE "Unmounting old root\n");
132-
init_umount("/old", MNT_DETACH);
133-
}
134-
}
135-
136-
bool __init initrd_load(char *root_device_name)
48+
void __init initrd_load(void)
13749
{
13850
if (mount_initrd) {
13951
create_dev("/dev/ram", Root_RAM0);
14052
/*
141-
* Load the initrd data into /dev/ram0. Execute it as initrd
142-
* unless /dev/ram0 is supposed to be our actual root device,
143-
* in that case the ram disk is just set up here, and gets
144-
* mounted in the normal path.
53+
* Load the initrd data into /dev/ram0.
14554
*/
146-
if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
147-
init_unlink("/initrd.image");
148-
handle_initrd(root_device_name);
149-
return true;
55+
if (rd_load_image()) {
56+
pr_warn("using deprecated initrd support, will be removed in January 2027; "
57+
"use initramfs instead or (as a last resort) /sys/firmware/initrd; "
58+
"see section \"Workaround\" in "
59+
"https://lore.kernel.org/lkml/20251010094047.3111495-1-safinaskar@gmail.com\n");
15060
}
15161
}
15262
init_unlink("/initrd.image");
153-
return false;
15463
}

init/do_mounts_rd.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,11 @@
1818
static struct file *in_file, *out_file;
1919
static loff_t in_pos, out_pos;
2020

21-
static int __init prompt_ramdisk(char *str)
22-
{
23-
pr_warn("ignoring the deprecated prompt_ramdisk= option\n");
24-
return 1;
25-
}
26-
__setup("prompt_ramdisk=", prompt_ramdisk);
27-
2821
int __initdata rd_image_start; /* starting block # of image */
2922

3023
static int __init ramdisk_start_setup(char *str)
3124
{
25+
pr_warn("ramdisk_start= option is deprecated and will be removed soon\n");
3226
return kstrtoint(str, 0, &rd_image_start) == 0;
3327
}
3428
__setup("ramdisk_start=", ramdisk_start_setup);
@@ -183,7 +177,7 @@ static unsigned long nr_blocks(struct file *file)
183177
return i_size_read(inode) >> 10;
184178
}
185179

186-
int __init rd_load_image(char *from)
180+
int __init rd_load_image(void)
187181
{
188182
int res = 0;
189183
unsigned long rd_blocks, devblocks, nr_disks;
@@ -197,7 +191,7 @@ int __init rd_load_image(char *from)
197191
if (IS_ERR(out_file))
198192
goto out;
199193

200-
in_file = filp_open(from, O_RDONLY, 0);
194+
in_file = filp_open("/initrd.image", O_RDONLY, 0);
201195
if (IS_ERR(in_file))
202196
goto noclose_input;
203197

@@ -226,10 +220,7 @@ int __init rd_load_image(char *from)
226220
/*
227221
* OK, time to copy in the data
228222
*/
229-
if (strcmp(from, "/initrd.image") == 0)
230-
devblocks = nblocks;
231-
else
232-
devblocks = nr_blocks(in_file);
223+
devblocks = nblocks;
233224

234225
if (devblocks == 0) {
235226
printk(KERN_ERR "RAMDISK: could not determine device size\n");
@@ -273,13 +264,6 @@ int __init rd_load_image(char *from)
273264
return res;
274265
}
275266

276-
int __init rd_load_disk(int n)
277-
{
278-
create_dev("/dev/root", ROOT_DEV);
279-
create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
280-
return rd_load_image("/dev/root");
281-
}
282-
283267
static int exit_code;
284268
static int decompress_error;
285269

0 commit comments

Comments
 (0)