View previous topic :: View next topic |
Author |
Message |
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Sun Dec 22, 2024 7:51 pm Post subject: how to use a custom initramfs and get a unified kernel image |
|
|
I have a custom initramfs with busytbox and I want to use it and create a unified kernel image. If its possible I'd like to have it done with install kernel. I've tried to use ukify but I can't get it working. Help appreciated |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5239 Location: Bavaria
|
Posted: Sun Dec 22, 2024 8:41 pm Post subject: |
|
|
Although these two pages:
https://wiki.gentoo.org/wiki/Unified_kernel_image
https://wiki.archlinux.org/title/Unified_kernel_image
say that a UKI can have a UEFI boot stub like systemd-stub:
Quote: | A unified kernel image (UKI) is a single executable which can be booted directly from UEFI firmware, or automatically sourced by boot loaders with little or no configuration. It is the combination of a UEFI boot stub program like systemd-stub(7), a Linux kernel image, an initrd, and further resources in a single UEFI PE file. |
our developers are of the opinion that it is only a UKI if it has the systemd-stub ... ... but I don't know how to name a UKI with the kernel's own stub.
I built my “UKI” 5 years ago when the term UKI didn't even exist. Of course I used the kernel's own stub ... and to this day I boot a signed (for SecureBoot) kernel image that contains everything ... it is even a monolithic kernel (=without module support).
Now if you already have a self-made initramfs (like me) then I recommend you to do everything else manually as well, because it's easier than you think (and installkernel is more complicated than you think; I even dont know if it is possible to use an own initramfs).
If you want go the manual route you have to do:
1. Ensure you have in your kernel the CPU microcode built-in (CONFIG_EXTRA_FIRMWARE) and maybe some firmware files if you need it,
2. Option for EFI-stub is enabled in your kernel (CONFIG_EFI_STUB=y),
3. Embedd your external initramfs into the kernel with these settings:
https://wiki.gentoo.org/wiki/User:Pietinger/Tutorials/Initramfs_Overview#Special_Case:_Building_an_embedded_initramfs_with_a_CPIO_archive _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Sun Dec 22, 2024 9:57 pm Post subject: |
|
|
okay so I've just read the article. So when you're including files they have to also exist within the initramfs file system e.g
Code: |
file /sbin/mdadm /root/initramfs/bins/sbin/mdadm 755 0 0
|
so the how does this line "This lets the initramfs be built dynamically, always using the latest files from the system" make sense? aren't you still copying the static binaries. Or is it suggesting that you should make a script to create this file? (https://wiki.gentoo.org/wiki/Custom_Initramfs#External_file_list)
Last edited by Cheesyjuggler64 on Sun Dec 22, 2024 10:53 pm; edited 2 times in total |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 22867
|
Posted: Sun Dec 22, 2024 10:49 pm Post subject: |
|
|
The Wiki is a bit confusing on this point. An initramfs list will always build the initramfs as part of the kernel, using the files specified as sources as they exist at build time. You can choose to specify those files as being pulled from the main filesystem (file /sbin/mdadm /sbin/mdadm 755 0 0 would pull from live), in which case they are always current to your routine updates, or you can choose to pull them from a hand-curated directory that changes only when you want to change it (as shown in the code fragment you posted). The text describes doing the former, but the shown example does the latter. |
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Sun Dec 22, 2024 10:54 pm Post subject: |
|
|
ah thanks maybe the wiki could do with some clarification there. Im going to try set it up now. I'm trying to build the initramfs for an encrypted btrfs root. |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 61
|
Posted: Mon Dec 23, 2024 12:00 am Post subject: |
|
|
I'm not sure what a UKI helps with if the initramfs is built into the kernel itself.
Are you building that file list outside of the kernel build process? _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Mon Dec 23, 2024 12:46 am Post subject: |
|
|
Ah so if I embed my intramfs into the kernel the kernel will just be a single binary and as such I can boot it directly from uefi? |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 61
|
Posted: Mon Dec 23, 2024 1:03 am Post subject: |
|
|
Cheesyjuggler64 wrote: | what do you mean by outside the build process? So if I embed the initramfs I can just rename it to .efi and have it boot via uefi ? |
I mean you can use that file list with gen_init_cpio to create an actual CPIO, or you can use CONFIG_INITRAMFS_SOURCE on a directory to have the kernel pack that initramfs into the image at build time.
The initramfs exists as a "CPIO" which may be compressed if the kernel supports it. It's not directly executable.
A UKI can pack this "external" initramfs into a single file along with your kernel and more which can be booted by an EFI system. This is mostly useful if you use some initramfs generator and the CPIO is a separate file. If you pack the initramfs into the kernel directly, the UKI may handle your microcode and possibly your kernel cmdline, but these could also be built into the kernel image itself.
I think the main advantage of a UKI is it allows you to easily reuse a kernel with a new initramfs, as embedding it into the kernel generally requires at least a partial rebuild. _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5239 Location: Bavaria
|
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5239 Location: Bavaria
|
Posted: Mon Dec 23, 2024 1:22 am Post subject: |
|
|
Cheesyjuggler64 wrote: | Ah so if I embed my intramfs into the kernel the kernel will just be a single binary and as such I can boot it directly from uefi? |
YES
(... if you add also your CPU microcode into the kernel) _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 61
|
Posted: Mon Dec 23, 2024 1:24 am Post subject: |
|
|
^^
If you're already building everything, you may as well build it into the kernel.
I think UKIS are mostly helpful if you're packing already made kernels/initramfs/etc into a file after the fact. If you're already going the custom route and building things into your kernel, the rest may not be necessary. _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Mon Dec 23, 2024 1:48 am Post subject: |
|
|
How exactly would I add the mircocode and how can I test my init is working without building the intramfs. Is there some sort of kernel parameter? |
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 61
|
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Mon Dec 23, 2024 3:08 am Post subject: |
|
|
okay so just to check I do this
Code: | mkdir --parents /usr/src/initramfs/{bin,dev,etc,lib,lib64,mnt/root,proc,root,sbin,sys}
emerge --ask --verbose sys-apps/busybox
cd /usr/src/initramfs
nano init |
Code: | nano initramfs_list |
then I go into the kernel and set CONFIG_INITRAMFS_SOURCE="/usr/src/initramfs/initramfs_list"
Code: | cd /usr/src/linux
make -j8 && make -j8 modules_install
make install
|
with the installkernel config being set as efistub
Code: |
layout="efistub"
initrd_generator=none
uki_generator=none
|
then reboot and it should work |
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Mon Dec 23, 2024 11:17 am Post subject: |
|
|
Also is there anyway to automate grabbing the required dependencies for something like btrfs and cryptsetup? |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5239 Location: Bavaria
|
Posted: Mon Dec 23, 2024 1:15 pm Post subject: |
|
|
Cheesyjuggler64 wrote: | Also is there anyway to automate grabbing the required dependencies for something like btrfs and cryptsetup? |
No .. You have to find out with "ldd" or "lddtree. An example doing it is here:
https://wiki.gentoo.org/wiki/Initramfs_-_make_your_own#Example_List_of_Requirements
=====
Please let me add some comments:
1. You dont need this when working with a initramfs_list:
Code: | mkdir --parents /usr/src/initramfs/{bin,dev,etc,lib,lib64,mnt/root,proc,root,sbin,sys} |
You have only two files in /usr/src/initramfs: Your "init" file and the file-list file.
2. I dont know if "installkernel" works the way you want ... I really dont know.
3. Get a static Busybox:
Code: | USE="-pam static static-libs" emerge -pvD busybox |
see again: https://wiki.gentoo.org/wiki/User:Pietinger/Tutorials/Initramfs_Overview#Simple_Skeleton
4. My building of my signed UKI was:
4a. Manually configuring the kernel with
* efistub-support (CONFIG_EFI_STUB=y)
* CPU microcode (and all needed firmware files because I have disabled module-support and have all modules static in the kernel) in:
Code: | CONFIG_EXTRA_FIRMWARE="intel-ucode/06-b7-01 i915/adls_dmc_ver2_01.bin rtl_nic/rtl8125b-2.fw i915/tgl_guc_70.bin i915/tgl_huc.bin" |
(how to decide which microcode you need: https://forums.gentoo.org/viewtopic-t-1065464.html )
* Every Kernel command line parameters inside the kernel (so no need to configure the UEFI boot entry with parameters):
Code: | CONFIG_CMDLINE="root=PARTUUID=6979eed7-ffaf-425e-8ac7-2832f6d15e0a ro loglevel=8 lsm.debug ima_appraise=enforce quiet hardened_usercopy=1 page_alloc.shuffle=1 pti=on" |
(please be aware of: https://wiki.gentoo.org/wiki/User:Pietinger/Tutorials/Confusion_with_root%3DPARTUUID%3D_and_root%3DUUID%3D )
* Secured against overwriting by the UEFI boot entry:
Code: | CONFIG_CMDLINE_OVERRIDE=y |
* And of course embedding the initramfs:
Code: | General setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
(/usr/src/initramfs/initramfs_list) Initramfs source file(s)
[*] Support initial ramdisk/ramfs compressed using gzip
Built-in initramfs compression mode (Gzip) ---> |
( see also: https://wiki.gentoo.org/wiki/User:Pietinger/Tutorials/Manual_kernel_configuration + https://wiki.gentoo.org/wiki/User:Pietinger/Experimental/Manual_Configuring_Current_Kernel )
4b. I dont use "installkernel". After building the kernel with "make -j32" I installed it with a simple copy (instead a make install):
https://wiki.gentoo.org/wiki/User:Pietinger/Tutorials/Boot_kernel_via_UEFI
(in reality between step 4a and 4b I also signed this stub-kernel (my "UKI") for SecureBoot:
https://forums.gentoo.org/viewtopic-p-8492354.html#8492354 ) _________________ https://wiki.gentoo.org/wiki/User:Pietinger |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 5239 Location: Bavaria
|
|
Back to top |
|
|
zen_desu n00b
Joined: 25 Oct 2024 Posts: 61
|
Posted: Mon Dec 23, 2024 4:41 pm Post subject: |
|
|
Cheesyjuggler64 wrote: | Also is there anyway to automate grabbing the required dependencies for something like btrfs and cryptsetup? |
if you're really interested in automation, ugrd was designed using the custom initramfs wiki article as a reference. It more or less follows those steps in an automated manner.
If you don't want all the features and autodetection/checks ugrd offers, you can disable the "base" module and use it to simply add "dependencies"
If you define a "dependency" in ugrd, it finds the location of that binary, then runs lddtree on it and includes all required libraries: https://github.com/desultory/ugrd/blob/1.28.2/src/ugrd/base/core.py#L39
Some things may not say they use libgcc, but may use it anyways. Because of this, it's generally a good idea to include it regardless: https://github.com/desultory/ugrd/blob/1.28.2/src/ugrd/base/core.py#L166
At the very least, you always want to run ldd/lddtree on programs you're adding to the initramfs, unless they are statically compiled. This isn't a guarantee those programs have everything they need, but this is the best way to at least find libraries that binary is linked against. _________________ µgRD dev
Wiki writer |
|
Back to top |
|
|
Cheesyjuggler64 n00b
Joined: 16 May 2024 Posts: 28
|
Posted: Mon Dec 23, 2024 7:08 pm Post subject: |
|
|
I'll look into ugrd. In the mean time I managed to get it to boot successfully. These were my configs encase anyone else has this idea:
Code: |
GNU nano 4.8 /mnt/usr/src/initramfs/init
#!/bin/busybox sh
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:${PATH}"
rescue_shell() {
echo "$@"
# The symlinks are not required but it helps tab completion
busybox --install -s
echo "Something went wrong"
exec bin/sh
}
echo "Mounting proc, sys and devtmpfs ..."
busybox mount -t devtmpfs none /dev || rescue_shell "Error: mount /devtmpfs failed !"
busybox mount -t proc none /proc || rescue_shell "Error: mount /proc failed !"
busybox mount -t sysfs none /sys || rescue_shell "Error: mount /sysfs failed !"
echo 0 > /proc/sys/kernel/printk
busybox clear
cryptsetup luksOpen /dev/nvme0n1p3 cryptroot || rescue_shell "Failed to decrypt"
wait
mount -o ro,subvol=@ /dev/mapper/cryptroot /mnt/root
umount /proc
umount /sys
umount /dev
exec /bin/busybox switch_root /mnt/root /sbin/init
|
initramfs_list
Code: |
# basic root directories
dir /bin 755 0 0
dir /dev 755 0 0
dir /etc 755 0 0
dir /lib 755 0 0
dir /lib64 755 0 0
dir /mnt 755 0 0
dir /mnt/root 755 0 0
dir /proc 755 0 0
dir /root 700 0 0
dir /sbin 755 0 0
dir /sys 755 0 0
dir /usr 755 0 0
dir /usr/bin 755 0 0
dir /usr/lib64 755 0 0
dir /var 755 0 0
dir /run 755 0 0
dir /run/cryptsetup 755 0 0
# busybox
nod /dev/random 0666 0 0 c 1 8
nod /dev/urandom 0666 0 0 c 1 9
nod /dev/console 0600 0 0 c 5 1
file /bin/busybox /bin/busybox 755 0 0
#
# fsck deps
#
file /sbin/fsck /sbin/fsck 755 0 0
file /lib64/libmount.so.1 /lib64/libmount.so.1 755 0 0
file /lib64/libblkid.so.1 /lib64/libblkid.so.1 755 0 0
file /lib64/libc.so.6 /lib64/libc.so.6 755 0 0
file /lib64/libuuid.so.1 /lib64/libuuid.so.1 755 0 0
file /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 755 0 0
#
# fsck.ext4 and added deps
#
file /sbin/fsck.ext4 /sbin/fsck.ext4 755 0 0
file /lib64/libext2fs.so.2 /lib64/libext2fs.so.2 755 0 0
file /lib64/libcom_err.so.2 /lib64/libcom_err.so.2 755 0 0
file /lib64/libe2p.so.2 /lib64/libe2p.so.2 755 0 0
file /lib64/libpthread.so.0 /lib64/libpthread.so.0 755 0 0
#
# btrfs utils and added deps
#
file /sbin/btrfs /sbin/btrfs 755 0 0
file /sbin/btrfs-convert /sbin/btrfs-convert 755 0 0
file /sbin/btrfs-find-root /sbin/btrfs-find-root 755 0 0
file /sbin/btrfs-image /sbin/btrfs-image 755 0 0
file /sbin/btrfs-map-logical /sbin/btrfs-map-logical 755 0 0
file /sbin/btrfsck /sbin/btrfsck 755 0 0
file /sbin/btrfstune /sbin/btrfstune 755 0 0
file /sbin/mkfs.btrfs /sbin/mkfs.btrfs 755 0 0
file /lib64/libz.so.1 /lib64/libz.so.1 755 0 0
file /lib64/liblzo2.so.2 /lib64/liblzo2.so.2 755 0 0
file /usr/lib64/libzstd.so.1 /usr/lib64/libzstd.so.1 755 0 0
## cryptsetup utils
#
file /sbin/cryptsetup /sbin/cryptsetup 755 0 0
#
# init script
#
file /init /usr/src/initramfs/init 755 0 0
#
# fstab
#
file /etc/fstab /etc/fstab 644 0 0
|
I does successfully unlock the root drive but I get the following error
Code: |
Enter passphrase for /deu/nvme0n1p3:
INIT: version 3.09 booting
OpenRC 0.55.1 is starting up Gentoo Linux (x86_64)
Mounting /proc
Mounting /run ..
/run/openrc: creating directory
/run/lock: creating directory
/run/lock: correcting owner
Caching seruice dependencies ...
Service 'busybox-crond' needs non existent service 'logger'
Mounting /sys
Mounting efivarfs filesystem
Mounting devtmpfs on /dev
Mounting /dev/pts
Mounting /dev/shm
Creating list of required static device nodes for the current kernel . • •
Create Static Devices Nodes in /dev
Starting udev
Generating a rule to create a /dev/root symlink
Populating /dev with existing devices through uevents
Setting system clock using the hardware clock [UTC]
Mounting misc binary format filesystem
Loading custom binary format handlers
Checking local filesystems
fsck.fat 4.2 (2021-01-31)
/dev/nvme0n1p1: 8 files, 16946/127746 clusters
Remounting root filesystem read/write ...
Remounting filesystems
Updating /etc/mtab
Creating mtab symbolic link
Activating swap devices
Mounting local filesystems
mount: /efi: wrong fs type, bad option, bad superblock on /dev/nvme0n1p1, missing codepage or helper program, or other error.
dmesg(1) may haue more information after failed mount system call.
Some local filesystem failed to mount
Configuring kernel parameters
Creating user login records
wiping /tmp directory ...
Setting hostname to localhost from /etc/conf.d/hostname
Setting terminal encoding [UTF-8]
Setting keyboard mode [UTF-8]
Loading key mappings [us]
Bringing up network interface lo
Saving key mapping ...
Saving terminal encoding
Seeding random number generator
Seeding 256 bits and crediting
Saving 256 bits of creditable seed for next boot
Create Volatile Files and Directories ...
INIT: Entering runlevel: 3
Starting DHCP Client Daemon ...
Mounting network filesystems
Starting local ...
this is localhost (Linux x86_64 6.6.62-gentoo) 19:32:17
localhost login:
|
|
|
Back to top |
|
|
|