Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230
Boot without extracting initramfs to memory?
Boot without extracting initramfs to memory?
Hello forums,
I've been searching quite hard for a solution to take a bit of a different approach to loading the initramfs for legacy systems. The issue is that the distro will not boot on much less than 256mb because the initramfs is too big.
Is there a way to establish swap first, or to load initramfs by mounting it instead of extracting, or can I even just load loose files? I don't want to compile my own kernel. But I'm fine with making my own initramfs, if required.
I use GRUB to boot, if that's of any help. I'm sure it's possible somehow but I haven't found anything that can accomplish it.
I've been searching quite hard for a solution to take a bit of a different approach to loading the initramfs for legacy systems. The issue is that the distro will not boot on much less than 256mb because the initramfs is too big.
Is there a way to establish swap first, or to load initramfs by mounting it instead of extracting, or can I even just load loose files? I don't want to compile my own kernel. But I'm fine with making my own initramfs, if required.
I use GRUB to boot, if that's of any help. I'm sure it's possible somehow but I haven't found anything that can accomplish it.
-
- Debian Developer
- Posts: 442
- Joined: 2022-07-12 14:10
- Has thanked: 1 time
- Been thanked: 87 times
Re: Boot without extracting initramfs to memory?
Easiest solution is probably to remove extra kernel modules from the initramfs and compress the rest with "xz -9". You can use "lsmod" to see what modules you actually need. Using MODULES=list in /etc/initramfs-tools/initramfs.conf you can include only modules listed in /etc/initramfs-tools/modules.
You can use xz to compress the modules in /lib. If you regenerate the initramfs it will then include those compressed versions. Note that you should not change the file extension. The kernel will automatically decompress XZ as CONFIG_DECOMPRESS_XZ=y is set in debian kernels if you use something like:
There is probably a way to keep the files in /lib intact and run xz only when generating the initramfs but that will of course slow down initramfs generation quite a lot as xz -9 is slow.
You can use xz to compress the modules in /lib. If you regenerate the initramfs it will then include those compressed versions. Note that you should not change the file extension. The kernel will automatically decompress XZ as CONFIG_DECOMPRESS_XZ=y is set in debian kernels if you use something like:
Code: Select all
for i in $(find /lib/modules -name "*.ko"); do
if [ "$(file "$i"|grep ELF)" != "" ]; then
xz -v -1 $i
mv $i.xz $i
fi
done
Re: Boot without extracting initramfs to memory?
I use MODULES=dep
Default gzip compression can be changed to xv.
Code: Select all
/etc/initramfs-tools/initramfs.conf
# MODULES: [ most | netboot | dep | list ]
MODULES=dep
Code: Select all
update-initramfs -u
Code: Select all
ls -sh /boot/initrd.img-5.17.0-1-amd64
14M /boot/initrd.img-5.17.0-1-amd64
Default gzip compression can be changed to xv.
Code: Select all
/etc/initramfs-tools/initramfs.conf
# COMPRESS: [ gzip | bzip2 | lz4 | lzma | lzop | xz ]
COMPRESS=xz
Re: Boot without extracting initramfs to memory?
It's much better now. The OS boots on 128MB (for now)! Thank you!
I've compressed the modules like @lindi suggested (with -9 instead of -1, as speed is of no concern), and I've also done COMPRESS=xz like @L_V said. Though I doubt COMPRESS=xz will do much -- As far as I understand, the initramfs is decompressed into memory, and that decompression in itself requires some memory to happen, I will test that a little later. No compression could be best in this case, if I'm right.
Unfortunately, I can't just do MODULES=dep -- To give a bit more detail, I'm making my own distro with Devuan, and that involves making an ISO. I might make another initramfs with this option sourced from a VM for really desperate systems (as long as sd* devices are there, it should be okay for most systems, I reckon?), and offer it as an extra option in GRUB.
I'm open to more suggestions if anyone has them, especially if there is some way to boot an initramfs (or something like it) without extracting it into memory at all, that would be super amazing.
I've compressed the modules like @lindi suggested (with -9 instead of -1, as speed is of no concern), and I've also done COMPRESS=xz like @L_V said. Though I doubt COMPRESS=xz will do much -- As far as I understand, the initramfs is decompressed into memory, and that decompression in itself requires some memory to happen, I will test that a little later. No compression could be best in this case, if I'm right.
Unfortunately, I can't just do MODULES=dep -- To give a bit more detail, I'm making my own distro with Devuan, and that involves making an ISO. I might make another initramfs with this option sourced from a VM for really desperate systems (as long as sd* devices are there, it should be okay for most systems, I reckon?), and offer it as an extra option in GRUB.
I'm open to more suggestions if anyone has them, especially if there is some way to boot an initramfs (or something like it) without extracting it into memory at all, that would be super amazing.
Re: Boot without extracting initramfs to memory?
If you build the drivers in to the kernel (intead of building them as modules) then you don't need an initramfs at all. You just need hardware drivers and the file system for your root file system. If all your targets for example use SATA with AHCI and ext4 then you don't need much at all.
In the beginning we loaded the kernel from the first floppy disk, then swapped it for the root floppy. The kernel only contained the ext2 file system and the floppy disk driver, and whatever else we could fit on a single disk.
In the beginning we loaded the kernel from the first floppy disk, then swapped it for the root floppy. The kernel only contained the ext2 file system and the floppy disk driver, and whatever else we could fit on a single disk.
- Head_on_a_Stick
- Posts: 14114
- Joined: 2014-06-01 17:46
- Location: London, England
- Has thanked: 81 times
- Been thanked: 133 times
Re: Boot without extracting initramfs to memory?
^ This. Unfortunately there doesn't seem to be "none" (or "cat") listed as a compression option in the man page but you could try it. Or perhaps lindi will point me to the source code
I just load the modules I know are needed to pivot_root. Here's my Arch configuration:
Code: Select all
archie:~$ dec /etc/mkinitcpio.conf
MODULES=(amdgpu nvme btrfs)
BINARIES=()
FILES=()
HOOKS=(base)
COMPRESSION="cat"
archie:~$
EDIT: and remember to disable Busybox, that should save a few MiB.
deadbang
-
- Debian Developer
- Posts: 442
- Joined: 2022-07-12 14:10
- Has thanked: 1 time
- Been thanked: 87 times
Re: Boot without extracting initramfs to memory?
Hehe, I guess you can use any binary that is found in PATH that accepts the "-c" parameter. So you could put a wrapper script in /usr/local/bin. However, are you sure that this is actually helpful? You would think that when the data is being decompressed both compressed and decompressed versions exist in the memory at the same time so it actually would be helpful to have the initramfs (cpio archive) be compressed.Head_on_a_Stick wrote: ↑2022-08-16 05:45 ^ This. Unfortunately there doesn't seem to be "none" (or "cat") listed as a compression option in the man page but you could try it. Or perhaps lindi will point me to the source code
Speaking of source code references, at least on my system the /init inside the initramfs runs run-init from the klibc-utils package. If you check the source code you can see that it actually does not use pivot_root at all, only vanilla chroot:Head_on_a_Stick wrote: ↑2022-08-16 05:45 I just load the modules I know are needed to pivot_root. Here's my Arch configuration:
https://sources.debian.org/src/klibc/2. ... l=170#L158
- Head_on_a_Stick
- Posts: 14114
- Joined: 2014-06-01 17:46
- Location: London, England
- Has thanked: 81 times
- Been thanked: 133 times
Re: Boot without extracting initramfs to memory?
I have no idea, I just thought it would be useful for the OP to check.
Fascinating, thanks for the info. And welcome to the forums btw. Your expert presence here is very much appreciated.
And for the OP here's a link from one of the Arch developers about minifying the initramfs:
http://blog.falconindy.com/articles/opt ... tcpio.html
The information pertains to Arch but can be easily adapted to Debian.
deadbang
Re: Boot without extracting initramfs to memory?
Alright, I did some testing.
/usr/bin/wdvn-cat:
This script ignores the -c flag, so cat can be used. I set COMPRESS to wdvn-cat. Unfortunately, it cannot be in /usr/local/bin, since update-initramfs doesn't seem to use $PATH.
I'm also using @lindi's script, on both xz and cat initramfs images, with a few changes. Named /usr/local/bin/update-initramfs, so it is used every time the initramfs is updated:
In my testing, the cat initramfs booted at 116M minimum and the xz initramfs at 105M. So it seems like @L_V and @lindi were right, and compressing your initramfs image definitely lowers memory usage.
I will experiment around with making a super minimal initramfs, as @Head_on_a_Stick suggested in the next few days. I have a bit of a headache and I'm starting to get a little burnt out from looking at terminals and waiting
EDIT: When using -9 instead of -1 in the script, and
in the live-boot config, it boots on 97M of RAM, with the xz compressed initramfs. As this is will be an initramfs for legacy systems, USB boot is not as important.
/usr/bin/wdvn-cat:
Code: Select all
#!/bin/sh
cat "$2"
I'm also using @lindi's script, on both xz and cat initramfs images, with a few changes. Named /usr/local/bin/update-initramfs, so it is used every time the initramfs is updated:
Code: Select all
#!/bin/bash
set -e
>&2 echo "Compressing modules ..."
for i in $(find /lib/modules -name "*.ko"); do
if [ "$(file "$i"|grep ELF)" != "" ]; then
>&2 echo "> $i ..."
xz -1 $i
mv $i.xz $i
fi
done
/usr/sbin/update-initramfs $*
exit $?
I will experiment around with making a super minimal initramfs, as @Head_on_a_Stick suggested in the next few days. I have a bit of a headache and I'm starting to get a little burnt out from looking at terminals and waiting
EDIT: When using -9 instead of -1 in the script, and
Code: Select all
DISABLE_FAT=true
DISABLE_FUSE=true
DISABLE_NTFS=true
DISABLE_USB=true
MINIMAL=true
Re: Boot without extracting initramfs to memory?
Alright, I have decided this is good enough. Thanks everyone!
-
- Global Moderator
- Posts: 3049
- Joined: 2017-09-17 07:12
- Has thanked: 5 times
- Been thanked: 132 times
Re: Boot without extracting initramfs to memory?
Not quite. You still need an initramfs when the root filesystem is defined by UUID or LABEL, is on software RAID, LVM, LUKS encryption...because all these require userspace programs.
Clarification about the initramfs:
The initramfs image file is a compressed cpio archive.
At boot time, the boot loader loads the kernel and the initramfs images into memory.
The kernel mounts a special tmpfs instance (rootfs) on / and extracts the contents of the initramfs into it (just like tar -x extracts a tarball), and frees the memory which contains the initramfs image.
The kernel executes /init.
In a normal system, /init mounts the real root filesystem on /, deletes everything in the rootfs and executes /sbin/init.