Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initramfs-tools implementation for cpio firmware loading #30

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,19 @@ install-arch: install install-mkinitcpio
install -dD $(DESTDIR)$(PREFIX)/share/libalpm/hooks
install -m0644 -t $(DESTDIR)$(PREFIX)/share/libalpm/hooks libalpm/hooks/95-m1n1-install.hook

install-initramfs: install
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use initramfstools here instead of initramfs? Otherwise it's confusing to people...

install -d $(DESTDIR)/etc/initramfs-tools/hooks/
install -m0755 -t $(DESTDIR)/etc/initramfs-tools/hooks/ initramfs/hooks/asahi
install -d $(DESTDIR)/etc/initramfs-tools/scripts/init-top
install -m0755 -t $(DESTDIR)/etc/initramfs-tools/scripts/init-top initramfs/scripts/init-top/asahi
install -d $(DESTDIR)/etc/initramfs-tools/scripts/init-bottom
install -m0755 -t $(DESTDIR)/etc/initramfs-tools/scripts/init-bottom initramfs/scripts/init-bottom/asahi
install -m0644 -t $(DESTDIR)$(PREFIX)/share/asahi-scripts initramfs/modules

install-fedora: install install-dracut

install-ubuntu: install install-initramfs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be install-debian.


uninstall:
rm -f $(addprefix $(DESTDIR)$(BIN_DIR)/,$(SCRIPTS))
rm -rf $(DESTDIR)$(PREFIX)/share/asahi-scripts
Expand All @@ -67,6 +78,11 @@ uninstall-mkinitcpio:
uninstall-dracut:
rm -f $(DESTDIR)$(DRACUT_CONF_DIR)/10-asahi.conf

uninstall-initramfs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here wrt initramfs.

rm -f $(DESTDIR)/etc/initramfs-tools/hooks/asahi
rm -f $(DESTDIR)/etc/initramfs-tools/scripts/init-top/asahi
rm -f $(DESTDIR)/etc/initramfs-tools/scripts/init-bottom/asahi

uninstall-arch: uninstall-mkinitcpio
rm -f $(addprefix $(DESTDIR)$(BIN_DIR)/,$(ARCH_SCRIPTS))
rm -f $(addprefix $(DESTDIR)$(PREFIX)/lib/systemd/system/,$(UNITS))
Expand All @@ -75,4 +91,6 @@ uninstall-arch: uninstall-mkinitcpio

uninstall-fedora: uninstall-dracut

uninstall-ubuntu: uninstall-initramfs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be uninstall-debian.


.PHONY: clean install install-mkinitcpio install-dracut install-arch install-fedora uninstall uninstall-mkinitcpio uninstall-dracut uninstall-arch uninstall-fedora
4 changes: 2 additions & 2 deletions functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ mount_sys_esp() {
mount --bind "$bootmnt" "$mountpoint"
warn "System ESP not identified in device tree, using $bootmnt"
else
mount "PARTUUID=$esp_uuid" "$mountpoint"
mount "/dev/disk/by-partuuid/$esp_uuid" "$mountpoint"
fi
dev="$(grep "$mountpoint" /proc/mounts | cut -d" " -f1)"
info "Mounted System ESP $dev at $mountpoint"
Expand Down Expand Up @@ -72,7 +72,7 @@ mount_boot_esp() {
return 1
fi

mount "PARTUUID=$esp_uuid" "$mountpoint"
mount "/dev/disk/by-partuuid/$esp_uuid" "$mountpoint"
fi
info "Mounted Boot ESP at $mountpoint"
}
27 changes: 27 additions & 0 deletions initramfs/hooks/asahi
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/sh
# SPDX-License-Identifier: MIT

PREREQ=""

prereqs()
{
echo "$PREREQ"
}

case $1 in
prereqs)
prereqs
exit 0
;;
esac

# Hooks for loading asahi modules and firmware

. /usr/share/initramfs-tools/hook-functions

mkdir -p "${DESTDIR}/lib/firmware"
mkdir -p "${DESTDIR}/usr/share/asahi-scripts"
cp -r /usr/share/asahi-scripts/* "${DESTDIR}/usr/share/asahi-scripts"
copy_exec /usr/bin/cpio

add_modules_from_file /usr/share/asahi-scripts/modules
33 changes: 33 additions & 0 deletions initramfs/modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# For NVMe & SMC
apple-mailbox
# For NVMe
nvme_apple
# For USB and HID
pinctrl-apple-gpio
# SMC core
macsmc
macsmc-rtkit
# For USB
i2c-apple
tps6598x
apple-dart
dwc3
dwc3-of-simple
nvmem-apple-efuses
phy-apple-atc
xhci-pci
pcie-apple
gpio_macsmc
# For HID
spi-apple
spi-hid-apple
spi-hid-apple-of
# For RTC
rtc-macsmc
simple-mfd-spmi
spmi-apple-controller
nvmem_spmi_mfd
# For MTP HID
apple-dockchannel
dockchannel-hid
apple-rtkit-helper
20 changes: 20 additions & 0 deletions initramfs/scripts/init-bottom/asahi
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/sh
# SPDX-License-Identifier: MIT

PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac

. /scripts/functions

mount -t tmpfs -o mode=0755 vendorfw "${rootmnt}"/lib/firmware/vendor
cp -r /vendorfw/* /vendorfw/.vendorfw.manifest "${rootmnt}"/lib/firmware/vendor
62 changes: 62 additions & 0 deletions initramfs/scripts/init-top/asahi
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/sh
# SPDX-License-Identifier: MIT

PREREQ="udev"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this script run before udev? From https://github.com/AsahiLinux/docs/wiki/Open-OS-Ecosystem-on-Apple-Silicon-Macs#linux-specific:

Firmware must be located and loaded before udev starts up. This is because udev can arbitrarily cause modules to load and devices to probe (even if not triggered directly, the kernel can e.g. discover PCI devices while the initramfs is already running), and this creates race conditions where firmware might not be available when it is needed.

prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac

. /scripts/functions

if [ -e /lib/firmware/vendor ]; then
log_failure_msg "Vendor firmware was loaded by the bootloader"
return 1
fi

if [ ! -e /proc/device-tree/chosen/asahi,efi-system-partition ]; then
log_failure_msg "Missing asahi,efi-system-partition variable, firmware will not be loaded!"
return 1
fi

log_success_msg "Load NVME modules"
modprobe apple-mailbox
modprobe nvme-apple

for i in $(seq 0 50); do
[ -e /sys/bus/platform/drivers/nvme-apple/*.nvme/nvme/nvme*/nvme*n1/ ] && break
sleep 0.1
done

if [ ! -e /sys/bus/platform/drivers/nvme-apple/*.nvme/nvme/nvme*/nvme*n1/ ]; then
err "Timed out waiting for NVMe device"
return 1
fi

# If the above exists, hopefully the /dev device exists and this will work

VENDORFW="/run/.system-efi/vendorfw/"

(
. /usr/share/asahi-scripts/functions.sh
mount_sys_esp /run/.system-efi
)

if [ ! -e "$VENDORFW/firmware.cpio" ]; then
log_failure_msg "Vendor firmware not available in ESP!"
umount /run/.system-efi
return 1
fi


( cd /; cpio -i < "$VENDORFW/firmware.cpio" )
umount /run/.system-efi

log_success_msg "Asahi: Vendor firmware unpacked successfully"