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

peripheral-firmware: extract on boot by default #94

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
79 changes: 53 additions & 26 deletions apple-silicon-support/modules/peripheral-firmware/default.nix
Original file line number Diff line number Diff line change
@@ -1,44 +1,71 @@
{ config, pkgs, lib, ... }:
{
config = lib.mkIf config.hardware.asahi.enable {
assertions = lib.mkIf config.hardware.asahi.extractPeripheralFirmware [
{ assertion = config.hardware.asahi.peripheralFirmwareDirectory != null;
imports = [
(lib.mkRemovedOptionModule [ "hardware" "asahi" "extractPeripheralFirmware" ] "This option is no longer necessary as the peripheral firmware will be extracted every boot automatically.")
];

config = let
inherit (lib) mkIf;
cfg = config.hardware.asahi;
pkgs' = cfg.pkgs;
in mkIf config.hardware.asahi.enable {
assertions = mkIf cfg.usePeripheralFirmwareFromNixStore [
{ assertion = cfg.peripheralFirmwareDirectory != null;
message = ''
Asahi peripheral firmware extraction is enabled but the firmware
location appears incorrect.
Managing the peripheral firmware in the Nix Store is enabled
but the firmware location appears incorrect.
'';
}
];

hardware.firmware = let
pkgs' = config.hardware.asahi.pkgs;
in
lib.mkIf ((config.hardware.asahi.peripheralFirmwareDirectory != null)
&& config.hardware.asahi.extractPeripheralFirmware) [
(pkgs.stdenv.mkDerivation {
name = "asahi-peripheral-firmware";
hardware.firmware = mkIf (cfg.peripheralFirmwareDirectory != null && cfg.usePeripheralFirmwareFromNixStore) [
(pkgs.stdenv.mkDerivation {
name = "asahi-peripheral-firmware";

nativeBuildInputs = [ pkgs'.asahi-fwextract pkgs.cpio ];

buildCommand = ''
mkdir extracted
asahi-fwextract ${cfg.peripheralFirmwareDirectory} extracted

mkdir -p $out/lib/firmware
cat extracted/firmware.cpio | cpio -id --quiet --no-absolute-filenames
mv vendorfw/* $out/lib/firmware
'';
})
];

nativeBuildInputs = [ pkgs'.asahi-fwextract pkgs.cpio ];
boot.postBootCommands = mkIf (!cfg.usePeripheralFirmwareFromNixStore) ''
echo Extracting Asahi firmware...
mkdir -p /tmp/.fwsetup/{esp,extracted}

buildCommand = ''
mkdir extracted
asahi-fwextract ${config.hardware.asahi.peripheralFirmwareDirectory} extracted
mount /dev/disk/by-partuuid/`cat /proc/device-tree/chosen/asahi,efi-system-partition` /tmp/.fwsetup/esp
${pkgs'.asahi-fwextract}/bin/asahi-fwextract /tmp/.fwsetup/esp/asahi /tmp/.fwsetup/extracted
umount /tmp/.fwsetup/esp

mkdir -p $out/lib/firmware
cat extracted/firmware.cpio | cpio -id --quiet --no-absolute-filenames
mv vendorfw/* $out/lib/firmware
'';
})
];
pushd /tmp/.fwsetup/
cat /tmp/.fwsetup/extracted/firmware.cpio | ${pkgs.cpio}/bin/cpio -id --quiet --no-absolute-filenames
mkdir -p /lib/firmware
mv vendorfw/* /lib/firmware
popd
rm -rf /tmp/.fwsetup
'';
};

options.hardware.asahi = {
extractPeripheralFirmware = lib.mkOption {
usePeripheralFirmwareFromNixStore = lib.mkOption {
type = lib.types.bool;
default = true;
default = false;
description = ''
Automatically extract the non-free non-redistributable peripheral
firmware necessary for features like Wi-Fi.
By default, the non-free non-redistributable peripheral firmware is
automatically extracted every boot. If you want more purity,
this option will add the firmware to the Nix Store and manage it
like all other firmware in NixOS.

The firmware is necessary for features like Wi-Fi.

It is not recommended for flake users to enable this option as the
firmware is non-redistributable.
'';
};

Expand Down
20 changes: 6 additions & 14 deletions docs/uefi-standalone.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Start the Mac, and U-Boot should start booting from the USB drive automatically.

<details>
<summary>If "mounting `/dev/root` on `/mnt-root/iso` failed: No such file or directory" during boot…</summary>

1. Was the ISO transferred to your flash drive correctly as described above? `dd` is the only correct way to do this. The ISO must be transferred to the drive block device itself, not a partition on the drive.
2. There is sometimes a [race condition](https://github.com/tpwrules/nixos-apple-silicon/issues/60) which causes booting to fail. Reboot the machine and try again.
3. Some flash drives have quirks. Try a different drive, or use the following steps:
Expand Down Expand Up @@ -168,7 +168,7 @@ Identify the number of the new root partition (type code 8300, typically second
```
nixos# sgdisk /dev/nvme0n1 -p
Disk /dev/nvme0n1: 244276265 sectors, 931.8 GiB
Model: APPLE SSD AP1024Q
Model: APPLE SSD AP1024Q
Sector size (logical/physical): 4096/4096 bytes
Disk identifier (GUID): 27054D2E-307A-41AA-9A8C-3864D56FAF6B
Partition table holds up to 128 entries
Expand All @@ -180,9 +180,9 @@ Total free space is 0 sectors (0 bytes)
Number Start (sector) End (sector) Size Code Name
1 6 128005 500.0 MiB FFFF iBootSystemContainer
2 128006 219854567 838.2 GiB AF0A Container
3 219854568 220465127 2.3 GiB AF0A
4 220465128 220590311 489.0 MiB EF00
5 220590312 242965550 85.4 GiB 8300
3 219854568 220465127 2.3 GiB AF0A
4 220465128 220590311 489.0 MiB EF00
5 220590312 242965550 85.4 GiB 8300
6 242965551 244276259 5.0 GiB FFFF RecoveryOSContainer
```

Expand Down Expand Up @@ -230,15 +230,7 @@ Add the `./apple-silicon-support` directory to the imports list and switch off t

The configuration above is the minimum required to produce a bootable system, but you can further edit the file as desired to perform additional configuration. Uncomment the relevant options and change their values as explained in the file. Note that some advertised features may not work properly at this time. Refer to the [NixOS installation manual](https://nixos.org/manual/nixos/stable/index.html#ch-configuration) for further guidance.

Various non-free non-redistributable peripheral firmware files are required to use system hardware like Wi-Fi. The Asahi Linux installer grabs these from macOS and stores them on the EFI system partition when it is created. The NixOS installer loads them from there while booting so that all hardware is available during installation. By default, the Apple Silicon support module will automatically reference the files in the EFI system partition and incorporate them into your configuration to be managed by the normal NixOS mechanisms.

Currently, the only supported way to update the peripheral firmware files is to destroy and re-create the EFI system partition, so they will not change unexpectedly. If you do not want the impurity of referencing them (or are using flakes where this is prohibited), copy them off the EFI system partition (e.g. on the installation ISO `mkdir -p /mnt/etc/nixos/firmware && cp /mnt/boot/asahi/{all_firmware.tar.gz,kernelcache*} /mnt/etc/nixos/firmware`) and specify this path in your configuration:
```
# Specify path to peripheral firmware files.
hardware.asahi.peripheralFirmwareDirectory = ./firmware;
# Or disable extraction and management of them completely.
# hardware.asahi.extractPeripheralFirmware = false;
```
Various non-free non-redistributable peripheral firmware files are required to use system hardware like Wi-Fi. The Asahi Linux installer grabs these from macOS and stores them on the EFI system partition when it is created. The NixOS installer loads them from there while booting so that all hardware is available during installation. By default, the Apple Silicon support module will also load the firmware from EFI system partition rather than being managed by the normal NixOS mechanisms.

If you want to install a desktop environment, you will have to uncomment the option to enable X11 and NetworkManager, then add an option to include your favorite desktop environment. You may also wish to include graphical packages such as `firefox` in `environment.systemPackages`. For example, to install Xfce:
```
Expand Down
23 changes: 1 addition & 22 deletions iso-configuration/installer-configuration.nix
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@
swapDevices = lib.mkOverride 60 [ ];
fileSystems = lib.mkOverride 60 config.lib.isoFileSystems;

boot.postBootCommands = let
inherit (config.hardware.asahi.pkgs) asahi-fwextract;
in ''
boot.postBootCommands = ''
for o in $(</proc/cmdline); do
case "$o" in
live.nixos.passwd=*)
Expand All @@ -39,26 +37,8 @@
;;
esac
done

echo Extracting Asahi firmware...
mkdir -p /tmp/.fwsetup/{esp,extracted}

mount /dev/disk/by-partuuid/`cat /proc/device-tree/chosen/asahi,efi-system-partition` /tmp/.fwsetup/esp
${asahi-fwextract}/bin/asahi-fwextract /tmp/.fwsetup/esp/asahi /tmp/.fwsetup/extracted
umount /tmp/.fwsetup/esp

pushd /tmp/.fwsetup/
cat /tmp/.fwsetup/extracted/firmware.cpio | ${pkgs.cpio}/bin/cpio -id --quiet --no-absolute-filenames
mkdir -p /lib/firmware
mv vendorfw/* /lib/firmware
popd
rm -rf /tmp/.fwsetup
'';

# can't legally be incorporated into the installer image
# (and is automatically extracted at boot above)
hardware.asahi.extractPeripheralFirmware = false;

isoImage.squashfsCompression = "zstd -Xcompression-level 6";

environment.systemPackages = with pkgs; [
Expand Down Expand Up @@ -88,7 +68,6 @@
enable = true;
settings.General.EnableNetworkConfiguration = true;
};


nixpkgs.overlays = [
(final: prev: {
Expand Down