7Ji-PKGBUILDs / .meta

1 stars 0 forks source link

Hook for extlinux maintenance #30

Closed hbiyik closed 3 months ago

hbiyik commented 3 months ago

Problem: When switching bunch of different kernels it is a pain to modify the extlinux.conf to point exact same kernel and initramfs that you just installed, i always make typos and write something wrong and the kernel does not boot, also waste of time to do that.

Instead: If there was a hook for maintainance of extlinux.conf. And that hook would.

1) The hook will lookup user defined variables, like kernel CMDLINE, or specific overlays. A user config could be placed under /etc/default/something.cfg 2) The hook will lookup kernel specific parameters from the pkg, ie: kernel file, initramfs file, and dtb root directory. 3) The hook will add a new entry or update the existing entry in /boot/extlinux.conf file, and the latest installed kernel entry will always be at top.

This way when a new kernel is installed it will be automatically picked up by uboot (the first entry in extlinux.conf).

@kwankiu, @7Ji

kwankiu commented 3 months ago

The way i did for acu is to first look for extlinux.arch.template (current dev branch is updated to look for extlinux.*.template) else it will apply a new extlinux.conf using a template based on the one i build an arch linux image for that device.

This is the function i wrote for acu: (https://github.com/kwankiu/acu/blob/dev/acu)

update_kernel_extlinux() {

    # Update extlinux.conf
    colorecho "$BLUE" "INFO  $NC | Generate extlinux.conf for $1 ..."

    if ! sudo pacman -Q "$1" > /dev/null 2>&1 ; then
        colorecho "$RED" "ERROR $NC | Package $1 is not installed"
        colorecho "$BLUE" "INFO  $NC | extlinux.conf will not be updated"
        sudo cp -r /etc/mkinitcpio.old/* /etc/mkinitcpio.d
        sudo rm -rf /etc/mkinitcpio.old
        exit 1
    fi

    if found_file=$(sudo ls -1 /boot/extlinux/extlinux.*.template 2>/dev/null); then
        colorecho "$BLUE" "INFO  $NC | Using package provided template: $found_file"
        sudo mv "$found_file" /boot/extlinux/extlinux.conf
    elif [ -n "$device_config" ] && [ -e /boot/vmlinuz-$1 ]; then
        # Kernel does not provide template, get sbc template
        colorecho "$GREEN" "  ->  Downloading extlinux template for ${device_config}"
        curl -LRO https://github.com/kwankiu/archlinux-installer-rock5/releases/download/kernel/${device_config}.extlinux.template
        sudo mv ${device_config}.extlinux.template /boot/extlinux/extlinux.conf
    else
        colorecho "$BLUE" "INFO  $NC | No available template, skipping ..."
        colorecho "$YELLOW" "WARNING  $NC | You may need to update extlinux.conf before booting into the new kernel"
        exit 0
    fi        

    colorecho "$BLUE" "INFO  $NC | Getting rootfs UUID ..."
    # Get rootfs partition from the current mount point "/"
    rootfs_partition=$(mount | grep "on / " | awk '{print $1}')

    # Find the UUIDs of the root partition
    root_uuid=$(sudo blkid $rootfs_partition | awk '{print $2}' | tr -d '"')
    colorecho "$DEBUG" "Root partition UUID: $root_uuid"

    colorecho "$BLUE" "INFO  $NC | Updating extlinux.conf ..."

    # Change pkgbase for extlinux.conf
    if sudo test ! -e "/boot/dtbs/$1"; then 
        sudo sed -i "s|/dtbs/%PKGBASE%|/dtbs|" /boot/extlinux/extlinux.conf
    fi

    # fix rockchip overlay directory name
    if sudo test -e "/boot/dtbs/$1/rockchip/overlay"; then
        sudo sed -i "s|/rockchip/overlays|/rockchip/overlay|" /boot/extlinux/extlinux.conf
    fi

    sudo sed -i "s|%PKGBASE%|$1|" /boot/extlinux/extlinux.conf

    # Change UUID for extlinux.conf   
    sudo sed -i "s|UUID=\\*\\*CHANGEME\\*\\*|$root_uuid|" /boot/extlinux/extlinux.conf
    sudo sed -i "s|UUID=CHANGEME|$root_uuid|" /boot/extlinux/extlinux.conf

    # Check if /boot is mounted as a partition or directory
    if mountpoint -q /boot; then
        colorecho "$DEBUG" "INFO  $NC | /boot is mounted as a partition"
    else
        colorecho "$DEBUG" "INFO  $NC | /boot is mounted as a directory"
        colorecho "$BLUE" "INFO  $NC | Updating paths for extlinux.conf ..."
        sudo sed -i "s| /vmlinuz| /boot/vmlinuz|" /boot/extlinux/extlinux.conf
        sudo sed -i "s| /initramfs| /boot/initramfs|" /boot/extlinux/extlinux.conf
        sudo sed -i "s| /initrd| /boot/initrd|" /boot/extlinux/extlinux.conf
        sudo sed -i "s| /dtbs| /boot/dtbs|" /boot/extlinux/extlinux.conf
        sudo sed -i "s| /dtbo| /boot/dtbo|" /boot/extlinux/extlinux.conf
    fi

    sudo rm -rf /etc/mkinitcpio.old
}

BredOS also has another way to generate extlinux.conf : https://github.com/BredOS/sbc-pkgbuilds/blob/main/update-extlinux/update-extlinux

hbiyik commented 3 months ago

this template thing is not a norm, so it should not rely on that, also it should not be necessary to lookup UUID to create CMDLINE, instead user should give the whole CMDLINE once in config, so the script should not try to guess it, and frankly there is no way to guess it, unless the script itself has created the boot partions (just like in your case).

so some parts of the script can be reused in that purpose

kwankiu commented 3 months ago

this template thing is not a norm, so it should not rely on that, also it should not be necessary to lookup UUID to create CMDLINE, instead user should give the whole CMDLINE once in config, so the script should not try to guess it, and frankly there is no way to guess it, unless the script itself has created the boot partions (just like in your case).

so some parts of the script can be reused in that purpose

yeah, the function i wrote has a limitation that it only handle two situation:

  1. kernel package provided a template
  2. the device is one of that my installer has a template for it

For BredOS's update-extlinux script, it looks like they just defined a very simple CMDLINE in env.txt and expects users to update the CMDLINE if needed.

hbiyik commented 3 months ago

yeah but in their case they also need user to full up LABEL, KERNEL and INITRD, which is not necessary, kernel package already provides those, if the the hook detects that the installed package is a kernel package, it can automatically fetch those..

7Ji commented 3 months ago

Generating a whole extlinux.conf with all labels is not right, extlinux.conf should only contain the minimum for the menu and a bunch of "include" lines to include per-kernel configs, and a "default" line to decide the current default label. Those per-kernel configs are then each generated, with each of them able to define their own booting configs.

Also there're traps if you would want to apply the same DTB name across different kernels. E.g. some boards have different DTB names in mainline and BSP.

Also, do not go from the Bred method. It only supports single-boot with a single kernel package installed. Applying different kernel cmdline for different kernel shall not be a trivia thing, especially when we mix mainline and BSP.

My personal preference though is that I don't want pre-generated configs. I use efistub and optionally systemd-boot on x64 and always write my own config. And on aarch64, I would have different labels pointing to different btrfs subvols as root. This is something a hook in a single root could never cover

hbiyik commented 3 months ago

Generating a whole extlinux.conf with all labels is not right, extlinux.conf should only contain the minimum for the menu and a bunch of "include" lines to include per-kernel configs, and a "default" line to decide the current default label. Those per-kernel configs are then each generated, with each of them able to define their own booting configs.

using include statements is neat but i am not sure u-boot supports that, u-boot only has a subset of syslinux, so have you ever tested that uboot works with such include statements?

Also there're traps if you would want to apply the same DTB name across different kernels. E.g. some boards have different DTB names in mainline and BSP.

But still FDTDIR must come from the package, FDT itself can be a part of user config. In today %99 of the use cases FDT name is embedded in uboot, so knowing FDTDIR is enough for kernel. In case user has a specific FDT then the hook should use the FDT that user provided. I agree this might be kernel specific then user can always create his own extlinux entry, the hook will not delete, just will add a new entry for each kernel package and maintain it with default user configs.

Also, do not go from the Bred method. It only supports single-boot with a single kernel package installed. Applying different kernel cmdline for different kernel shall not be a trivia thing, especially when we mix mainline and BSP. My personal preference though is that I don't want pre-generated configs. I use efistub and optionally systemd-boot on x64 and always write my own config. And on aarch64, I would have different labels pointing to different btrfs subvols as root. This is something a hook in a single root could never cover

Not for EFI but the same approach of CMDLINE is also available in grup config. But this does not mean users can not create their own custom configs.