Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,11 @@ ARG MIRROR=edge
RUN pacman-key --recv-keys 40DFB630FF42BCFFB047046CF0134EE680CAC571 --keyserver keys.openpgp.org && \
pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571 && \
printf '\n[omarchy]\nSigLevel = Optional\nServer = https://pkgs.omarchy.org/%s/$arch\n' "${MIRROR}" >> /etc/pacman.conf && \
pacman -Sy --noconfirm && \
pacman -S --noconfirm omarchy-keyring && \
pacman-key --populate omarchy && \
if [ "${TARGETARCH}" = "amd64" ]; then \
pacman -Sy --noconfirm && \
pacman -S --noconfirm omarchy-keyring && \
pacman-key --populate omarchy; \
fi && \
sed -i '/^\[omarchy\]/,/^$/d' /etc/pacman.conf

RUN pacman -Syu --noconfirm && \
Expand Down
23 changes: 18 additions & 5 deletions pkgbuilds/limine-mkinitcpio-hook/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ _pkgname="limine-entry-tool"
pkgname="limine-mkinitcpio-hook"
_pkgver=1.37.1
_extver=""
_gradle_version=9.7.1
pkgver="${_pkgver}${_extver}"
pkgrel=1
pkgrel=4
pkgdesc="Install kernels for the Limine bootloader."
arch=('x86_64' 'aarch64')
url="https://gitlab.com/Zesko/limine-entry-tool"
source=("${_pkgname}::git+${url}.git#tag=${pkgver}")
source=("${_pkgname}::git+${url}.git#tag=${pkgver}"
'aarch64-kernel-without-pkgbase.patch'
'accept-shim-pkgbase.patch'
'upstream-efi-architecture-support.patch'
"https://services.gradle.org/distributions/gradle-${_gradle_version}-bin.zip")
source_x86_64=("https://github.com/graalvm/graalvm-ce-builds/releases/download/graal-25.1.3/graalvm-community-jdk-25i1-25.0.3_linux-x64_bin.tar.gz")
source_aarch64=("https://github.com/graalvm/graalvm-ce-builds/releases/download/graal-25.1.3/graalvm-community-jdk-25i1-25.0.3_linux-aarch64_bin.tar.gz")
license=("GPL3")
Expand All @@ -27,14 +32,21 @@ optdepends=(
'sbctl: Signs UEFI boot files for Secure Boot when enabled'
'journalctl-desktop-notification: Sends desktop notifications when errors occur'
)
makedepends=('git' 'gradle')
makedepends=('git')
backup=(etc/limine-entry-tool.conf)
conflicts=('limine-entry-tool')
sha256sums=('e0a1d5800ef1b0a79eee935d1a295d4b929a713686e8bb8340484d402deb5621')
sha256sums=('e0a1d5800ef1b0a79eee935d1a295d4b929a713686e8bb8340484d402deb5621'
'90eaa3f5d9869250fec2096871dc834a6642832e5ec1cc9a54112ed3f6001027'
'ee4e9ca4b9bd5cda4c758bfd2f3e42eb5f08e9ba778809ebd13bfca882e4ced7'
'04e419787304b0ccc4db2f862489411fa625c298ca7476544c7ea38734176055'
'acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a')
sha256sums_x86_64=('e9cd1637be853e105f8b09125b4b19fbce385696465d782cbca8bb80e1df8f0d')
sha256sums_aarch64=('5e79978983439d28506ebef82254fe9f98995121208dc8be77c604f4ad5bc579')

prepare() {
patch -d "${_pkgname}" -Np1 -i "$srcdir/aarch64-kernel-without-pkgbase.patch"
patch -d "${_pkgname}" -Np1 -i "$srcdir/accept-shim-pkgbase.patch"
patch -d "${_pkgname}" -Np1 -i "$srcdir/upstream-efi-architecture-support.patch"
[[ -d "${_graalvm_version}" ]] && rm -rf "${_graalvm_version}"
mv graalvm-community-*/ "${_graalvm_version}"
if ! command -v "${_graalvm_version}"/bin/javac >/dev/null 2>&1; then
Expand All @@ -48,7 +60,8 @@ build() {
export GRAALVM_HOME="$srcdir/${_graalvm_version}"
export JAVA_HOME="${GRAALVM_HOME}"
export NATIVE_IMAGE_OPTIONS="-march=compatibility --future-defaults=all"
/usr/bin/gradle clean nativeCompile -Dorg.gradle.java.home="${JAVA_HOME}"
"$srcdir/gradle-${_gradle_version}/bin/gradle" clean nativeCompile \
-Dorg.gradle.java.home="${JAVA_HOME}"
}

package() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
diff --git a/install/arch-linux/limine-mkinitcpio-hook/usr/share/libalpm/scripts/limine-mkinitcpio-install b/install/arch-linux/limine-mkinitcpio-hook/usr/share/libalpm/scripts/limine-mkinitcpio-install
index 5e36a73..c9b2ea3 100755
--- a/install/arch-linux/limine-mkinitcpio-hook/usr/share/libalpm/scripts/limine-mkinitcpio-install
+++ b/install/arch-linux/limine-mkinitcpio-hook/usr/share/libalpm/scripts/limine-mkinitcpio-install
@@ -73 +73,8 @@ collect_pkgbase_files() {
- PKGBASE_FILES=(/usr/lib/modules/*/pkgbase)
+ # Enumerate module directories rather than pkgbase files: a kernel whose
+ # package omits the marker still has a module directory. process_kernel()
+ # decides whether each one is usable.
+ PKGBASE_FILES=()
+ local _moddir
+ for _moddir in /usr/lib/modules/*/; do
+ PKGBASE_FILES+=("${_moddir}pkgbase")
+ done
@@ -79,3 +86,3 @@ set_kernel_context() {
- local pkgbase_file="$1"
- # Read kernel name from pkgbase file
- KERNEL_NAME="$(<"$pkgbase_file")"
+ local pkgbase_file="$1" kernel_name="${2:-}"
+ # Read kernel name from pkgbase file, unless the caller already knows it
+ KERNEL_NAME="${kernel_name:-$(<"$pkgbase_file")}"
@@ -242,4 +249,14 @@ process_kernel() {
- [[ -f "$pkgbase_file" ]] || return 0
- # Skip if pkgbase file is not owned by any package
- pacman -Qqo "$pkgbase_file" &>/dev/null || return 0
- set_kernel_context "$pkgbase_file" || return 0
+ if [[ -f "$pkgbase_file" ]]; then
+ # Skip if pkgbase file is not owned by any package
+ pacman -Qqo "$pkgbase_file" &>/dev/null || return 0
+ set_kernel_context "$pkgbase_file" || return 0
+ else
+ # No marker: recover the kernel name from the package owning the module
+ # tree. Query a file inside the directory rather than the directory
+ # itself, whose entry may belong to a different package.
+ local kernel_dir="${pkgbase_file%/pkgbase}" owner=""
+ [[ -f "${kernel_dir}/modules.builtin" ]] || return 0
+ owner="$(pacman -Qqo "${kernel_dir}/modules.builtin" 2>/dev/null)" || return 0
+ [[ -n "$owner" ]] || return 0
+ set_kernel_context "$pkgbase_file" "$owner" || return 0
+ fi
28 changes: 28 additions & 0 deletions pkgbuilds/limine-mkinitcpio-hook/accept-shim-pkgbase.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Accept a shim-written pkgbase in a package-owned kernel directory

Arch Linux ARM installs its kernel as /boot/Image. Omarchy's
linux-aarch64-pkgbase-shim copies that image into the module directory and
writes the pkgbase marker that mkinitcpio and Limine expect, but the marker is
not itself owned by the kernel package. Accept it when the surrounding kernel
directory is package-owned. This is the ownership half of Jimmy Van Veen's
original Snapdragon patch, adapted to follow the kernel discovery change
merged in Zesko/limine-entry-tool!64.

Retire with linux-aarch64-pkgbase-shim when Arch Linux ARM ships both pkgbase
and vmlinuz in its kernel module directory.

--- a/install/arch-linux/limine-mkinitcpio-hook/usr/share/libalpm/scripts/limine-mkinitcpio-install
+++ b/install/arch-linux/limine-mkinitcpio-hook/usr/share/libalpm/scripts/limine-mkinitcpio-install
@@ -247,8 +247,10 @@ process_kernel() {
local pkgbase_file="$1"

if [[ -f "$pkgbase_file" ]]; then
- # Skip if pkgbase file is not owned by any package
- pacman -Qqo "$pkgbase_file" &>/dev/null || return 0
+ # The ALARM shim writes this marker, so accept it when either the
+ # marker itself or its package-owned kernel directory is owned.
+ pacman -Qqo "$pkgbase_file" &>/dev/null ||
+ pacman -Qqo "${pkgbase_file%/pkgbase}" &>/dev/null || return 0
set_kernel_context "$pkgbase_file" || return 0
else
# No marker: recover the kernel name from the package owning the module
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
diff --git a/install/arch-linux/limine-entry-tool/usr/bin/limine-install b/install/arch-linux/limine-entry-tool/usr/bin/limine-install
index f9491f8..d2a36d8 100755
--- a/install/arch-linux/limine-entry-tool/usr/bin/limine-install
+++ b/install/arch-linux/limine-entry-tool/usr/bin/limine-install
@@ -71,2 +71,2 @@ fi
-is_x64 || {
- info_msg "The system is not x86_64."
+is_supported_arch || {
+ info_msg "No Limine EFI binary for $(uname -m)."
@@ -375 +375 @@ if [[ "${FIND_BOOTLOADERS:-no}" == "yes" && "${SKIP_UEFI:-no}" == "no" ]]; then
- bootloader_path="${ESP_PATH}/EFI/systemd/systemd-bootx64.efi"
+ bootloader_path="${ESP_PATH}/EFI/systemd/systemd-boot$(limine_efi_arch | tr "[:upper:]" "[:lower:]").efi"
@@ -385 +385 @@ if [[ "${FIND_BOOTLOADERS:-no}" == "yes" && "${SKIP_UEFI:-no}" == "no" ]]; then
- bootloader_path="${ESP_PATH}/EFI/BOOT/BOOTX64.EFI"
+ bootloader_path="${ESP_PATH}/EFI/BOOT/BOOT$(limine_efi_arch).EFI"
diff --git a/install/arch-linux/limine-entry-tool/usr/lib/limine/limine-common-functions b/install/arch-linux/limine-entry-tool/usr/lib/limine/limine-common-functions
index b56cc30..1db04b9 100644
--- a/install/arch-linux/limine-entry-tool/usr/lib/limine/limine-common-functions
+++ b/install/arch-linux/limine-entry-tool/usr/lib/limine/limine-common-functions
@@ -58,0 +59,17 @@ is_x64() {
+# Limine ships BOOTX64/BOOTIA32/BOOTAA64/BOOTRISCV64/BOOTLOONGARCH64; this tool
+# only ever used the x64 one. Map the machine to the binary it actually has.
+limine_efi_arch() {
+ case "$(uname -m)" in
+ x86_64) echo "X64" ;;
+ i?86) echo "IA32" ;;
+ aarch64) echo "AA64" ;;
+ riscv64) echo "RISCV64" ;;
+ loongarch64) echo "LOONGARCH64";;
+ *) return 1 ;;
+ esac
+}
+
+is_supported_arch() {
+ limine_efi_arch >/dev/null 2>&1
+}
+
@@ -330 +347 @@ reset_enroll_config() {
- is_x64 || return 0
+ is_supported_arch || return 0
@@ -345 +362 @@ enroll_config() {
- is_x64 || return 0
+ is_supported_arch || return 0
@@ -388 +405 @@ initialize_header() {
- export BINARY_SOURCE_PATH="/usr/share/limine/BOOTX64.EFI"
+ export BINARY_SOURCE_PATH="/usr/share/limine/BOOT$(limine_efi_arch).EFI"
@@ -392,2 +409,3 @@ initialize_header() {
- export LIMINE_EFI_FILE="limine_x64.efi"
- export LIMINE_BACKUP_FILE="limine_x64.bak"
+ _limine_arch_lc="$(limine_efi_arch | tr '[:upper:]' '[:lower:]')"
+ export LIMINE_EFI_FILE="limine_${_limine_arch_lc}.efi"
+ export LIMINE_BACKUP_FILE="limine_${_limine_arch_lc}.bak"
@@ -397 +415 @@ initialize_header() {
- export BINARY_FALLBACK_PATH="${ESP_PATH}/EFI/BOOT/BOOTX64.EFI"
+ export BINARY_FALLBACK_PATH="${ESP_PATH}/EFI/BOOT/BOOT$(limine_efi_arch).EFI"
diff --git a/src/main/java/org/limine/entry/tool/Main.java b/src/main/java/org/limine/entry/tool/Main.java
index 3898db2..e699492 100644
--- a/src/main/java/org/limine/entry/tool/Main.java
+++ b/src/main/java/org/limine/entry/tool/Main.java
@@ -283,2 +283,2 @@ public class Main {
- if (!Utility.isSystemAmd64()) {
- exitWithError("Your system is not using x86_64 architecture");
+ if (!Utility.isSystemSupportedArch()) {
+ exitWithError("Limine has no UEFI binary for this architecture");
@@ -314,2 +314,2 @@ public class Main {
- if (shouldCheckDevice && !Utility.isSystemAmd64()) {
- exitWithError("Your system is not using x86_64 architecture");
+ if (shouldCheckDevice && !Utility.isSystemSupportedArch()) {
+ exitWithError("Limine has no UEFI binary for this architecture");
diff --git a/src/main/java/org/limine/entry/tool/processes/Utility.java b/src/main/java/org/limine/entry/tool/processes/Utility.java
index 728e2c7..6e0d715 100644
--- a/src/main/java/org/limine/entry/tool/processes/Utility.java
+++ b/src/main/java/org/limine/entry/tool/processes/Utility.java
@@ -572,0 +573,13 @@ public class Utility {
+ /**
+ * Check if Limine ships a UEFI binary for this architecture.
+ * Limine provides BOOTX64/BOOTIA32/BOOTAA64/BOOTRISCV64/BOOTLOONGARCH64,
+ * so gating entry management on x86_64 alone is unnecessarily narrow.
+ */
+ public static boolean isSystemSupportedArch() {
+ String arch = System.getProperty("os.arch").toLowerCase();
+ return arch.equals("x86_64") || arch.equals("amd64")
+ || arch.equals("aarch64") || arch.equals("arm64")
+ || arch.equals("riscv64") || arch.equals("loongarch64");
+ }
+
+
14 changes: 9 additions & 5 deletions pkgbuilds/limine-snapper-sync/PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Maintainer: Zesko
pkgname="limine-snapper-sync"
pkgver=1.31.0
pkgrel=1
pkgrel=2
_gradle_version=9.7.1
pkgdesc="Integrates Limine boot entries with Snapper snapshots."
arch=('x86_64' 'aarch64')
url="https://gitlab.com/Zesko/limine-snapper-sync"
source=("${pkgname}::git+${url}.git#tag=${pkgver}")
source=("${pkgname}::git+${url}.git#tag=${pkgver}"
"https://services.gradle.org/distributions/gradle-${_gradle_version}-bin.zip")
source_x86_64=("https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-25.0.2/graalvm-community-jdk-25.0.2_linux-x64_bin.tar.gz")
source_aarch64=("https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-25.0.2/graalvm-community-jdk-25.0.2_linux-aarch64_bin.tar.gz")
license=("GPL3")
Expand All @@ -25,10 +27,11 @@ optdepends=(
'b3sum: Fast Blake3 hash function to prevent duplication.'
'xxhash: Fast hashing utility for deduplication with shorter hashes.'
)
makedepends=('git' 'gradle')
makedepends=('git')
backup=(etc/limine-snapper-sync.conf)
conflicts=('limine-snapper-cli' 'limine-snapper-sync-git')
sha256sums=('ed236f1bbab966950bf11ba5a7958e97a76e66db7fd647b7737bab4b48c9fc40')
sha256sums=('ed236f1bbab966950bf11ba5a7958e97a76e66db7fd647b7737bab4b48c9fc40'
'acd53f1edaf02f1a8ff99879f8a34b302661a057d9b063ae9e35b552f804d20a')
sha256sums_x86_64=('e0be791c8fda4d03b6b0a0cb824fef3149736170057b3a515252b44419606af0')
sha256sums_aarch64=('b4580d9f223d0a4b3a1757e58b18ff4c1db950e67e105fc5cb741457d2384a71')

Expand All @@ -46,7 +49,8 @@ build() {
export GRAALVM_HOME="$srcdir/${_graalvm_version}"
export JAVA_HOME="${GRAALVM_HOME}"
export NATIVE_IMAGE_OPTIONS="-march=compatibility"
/usr/bin/gradle clean nativeCompile -Dorg.gradle.java.home="${JAVA_HOME}"
"$srcdir/gradle-${_gradle_version}/bin/gradle" clean nativeCompile \
-Dorg.gradle.java.home="${JAVA_HOME}"
}

package() {
Expand Down
3 changes: 3 additions & 0 deletions pkgbuilds/linux-aarch64-pkgbase-shim/.omarchy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"source": "local"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Run before mkinitcpio and Limine discover installed kernels.
[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Target = usr/lib/modules/*/

[Trigger]
Type = Package
Operation = Install
Operation = Upgrade
Target = linux-aarch64-pkgbase-shim

[Action]
Description = Writing pkgbase and vmlinuz for Arch Linux ARM kernels...
When = PostTransaction
Exec = /usr/share/libalpm/scripts/linux-aarch64-pkgbase-shim
NeedsTargets
26 changes: 26 additions & 0 deletions pkgbuilds/linux-aarch64-pkgbase-shim/PKGBUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Maintainer: Jimmy Van Veen

# Add kernel metadata required by mkinitcpio and Limine on Arch Linux ARM.

pkgname=linux-aarch64-pkgbase-shim
pkgver=1
pkgrel=3
pkgdesc="Writes usr/lib/modules/<ver>/{pkgbase,vmlinuz} for Arch Linux ARM kernels so mkinitcpio and Limine hooks find them"
arch=('aarch64')
url="https://github.com/omacom-io/omarchy-pkgs"
license=('MIT')
depends=('bash' 'pacman')
optdepends=('limine-mkinitcpio-hook: rebuild the UKI and Limine entry when the shim is installed after the kernel')
options=('!debug')
source=(
'85-linux-aarch64-pkgbase-shim.hook'
'linux-aarch64-pkgbase-shim'
'README.package.md'
)
sha256sums=('SKIP' 'SKIP' 'SKIP')

package() {
install -Dm644 85-linux-aarch64-pkgbase-shim.hook "${pkgdir}/usr/share/libalpm/hooks/85-linux-aarch64-pkgbase-shim.hook"
install -Dm755 linux-aarch64-pkgbase-shim "${pkgdir}/usr/share/libalpm/scripts/linux-aarch64-pkgbase-shim"
install -Dm644 README.package.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
}
30 changes: 30 additions & 0 deletions pkgbuilds/linux-aarch64-pkgbase-shim/README.package.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# linux-aarch64-pkgbase-shim

Arch Linux ARM's kernel packages install the kernel as `/boot/Image` and ship
no `usr/lib/modules/<ver>/pkgbase` or `usr/lib/modules/<ver>/vmlinuz`.
mkinitcpio's and limine-entry-tool's pacman hooks find kernels through those
two files, so on an Arch Linux ARM system nothing builds an initramfs or UKI,
and nothing writes a Limine entry, when a kernel is installed or upgraded.

This package is one pacman hook. After a kernel package is installed or
upgraded (`usr/lib/modules/*/`), and when the shim itself is installed, it
writes into every package-owned modules directory that lacks `pkgbase`:

- `pkgbase`: the name of the package that owns the directory
- `vmlinuz`: a copy of `/boot/Image` (the owner must own that too)

It runs as `85-`, before `90-mkinitcpio-install`, so the usual hook then builds
the initramfs/UKI and the Limine entry. If that hook would not run in the same
transaction (the shim installed after the kernel, or a kernel package that
does not touch `usr/lib/initcpio/`), the script runs
`limine-mkinitcpio-install` itself. Leftover directories of removed kernels
that hold nothing but these two files are cleaned up.

`limine-mkinitcpio-hook` carries `accept-shim-pkgbase.patch` so it accepts
metadata created outside package ownership.

## Retirement

Delete this package and the Limine patch when `linux-aarch64` ships `pkgbase`
and `vmlinuz` itself. Existing metadata is never modified, so both approaches
can coexist during the transition.
Loading