Hardware/system recovery guide for M1 MacBook Air running Fedora Asahi Remix. User shell/editor/desktop config belongs in ~/dotfiles or the future dotfiles-desktop repo.
-
Install Fedora Asahi Remix — https://asahilinux.org/
- Select 16K kernel variant during install
- After install:
sudo dnf upgrade --refresh
-
Install Rust/Cargo —
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -
Clone this repo
git clone <this-repo> ~/asahi-dotfiles cd ~/asahi-dotfiles ./install.sh
Each step is interactive (Enter to run, 's' to skip):
| Step | What | Details |
|---|---|---|
| 1 | COPR repos | Enables 13 COPR repos (hyprland, swayosd, walker, ghostty, etc.) |
| 2 | DNF packages | Installs ~293 packages (skips already-installed) |
| 3 | Cargo tools | Installs bluetui, impala, xremap, battop |
| 4 | Flatpaks | Installs Vesktop, Calculator, LocalSend |
| 5 | Config files | Copies Asahi/system configs such as audio, PipeWire, WirePlumber, systemd |
| 6 | Custom scripts | Copies Asahi/helper scripts to ~/.local/bin/ + recreates helper symlinks |
| 7 | Retired | Omarchy-Fedora helpers are no longer restored |
| 8 | .zshrc | Restores shell config (backs up existing) |
| 9 | System files | Udev rules, NM iwd config, DNF versionlock |
| 10 | Systemd | Enables Asahi user services and timers |
| 11 | Snapper | Creates btrfs snapshot configs for root + home |
| 12 | Hyprland build | Builds Hyprland 0.54.0 from source with Apple GPU patch |
| 13 | CPU freq | Uncaps CPU frequency (fixes 600MHz clamping issue) |
The default Asahi audio DSP is bypassed for cleaner sound:
- Open
pavucontrol→ Configuration tab - Set the audio device to Pro Audio profile
- In Output Devices, select Pro 1 (raw speakers)
- Custom PipeWire EQ is auto-loaded from
~/.config/pipewire/pipewire.conf.d/user-eq.conf
Details:
- HPF at 80Hz protects laptop speakers from sub-bass
speakersafetydstill provides hardware-level protection- Caveat: Pro Audio profile may not auto-switch to headphones — test this
- Do NOT install EasyEffects — it crashes and corrupts WirePlumber state
The COPR binary crashes on Apple GPU because drmGetFormatModifierName() returns NULL for Apple DRM modifiers. The fix is a one-line null check in src/helpers/Format.cpp:
// Before (crashes):
std::string name = n;
// After (fixed):
std::string name = n ? n : "UNKNOWN";This was merged upstream in PR #13416 (commit 4206421). Check if the COPR package version is newer than 0.54.0 before rebuilding from source — the fix may already be included:
dnf check-update hyprlandThe build script also compiles xkbcommon 1.11.0 (system has 1.8.1) and patches out a Nix-only dependency.
Build prerequisites (installed by step 2):
- cmake, meson, ninja-build, gcc-c++, golang
- hyprland-protocols-devel, hyprlang-devel, hyprutils-devel, etc.
- Full list in
build/build-hyprland.sh
Walker uses Elephant as a data provider. The COPR elephant package has a protobuf plugin crash, so it was rebuilt from source:
# Clone and build with matching Go toolchain
git clone https://github.com/nicholasgasior/elephant
cd elephant
GOSUMDB=sum.golang.org CGO_LDFLAGS="-fuse-ld=bfd" GOTOOLCHAIN=auto make build
sudo cp elephant /usr/bin/elephant
# Build plugins with same env and copy to /etc/xdg/elephant/providers/Key: COPR Go plugins must be built with the same toolchain as the main binary (protobuf registration conflict).
- Use
--ambit classicflag when doing rollbacks (Fedora requirement) - btrfs default subvolume is 256 (root)
- fstab mounts by
subvol=root(safe for rollbacks) system-snapshotwrapper script handles both root + home
Hyprland and hypridle are version-locked to prevent COPR updates from overwriting the custom build:
# Check locks
dnf5 versionlock list
# Remove locks when COPR has fixed version
sudo dnf5 versionlock delete hyprland
sudo dnf5 versionlock delete hypridleProvides macOS-like shortcuts in Brave (Super as Ctrl). Built from cargo with hypr feature:
cargo install xremap --features hyprConfig: ~/.config/xremap/config.yml
Udev rule: /etc/udev/rules.d/99-xremap.rules (grants uinput access)
- Udev rule auto-switches governor:
performanceon AC,schedutilon battery - Also resets
scaling_max_freqto hardware max on each power state change lid-shutdown.timerpowers off if the lid stays closed on battery for 5 minutes- hypridle: lock 5min, screen off 5min, suspend 10min
- s2idle only (~1.4%/hr drain during suspend — Asahi firmware limitation)
- Hibernate is not possible on Asahi (firmware state can't be saved)
- s2idle only: ~1.4%/hr battery drain during suspend (Asahi limitation)
- No hibernate: firmware state can't be saved on Apple Silicon
- Headphone auto-switch: untested with Pro Audio profile
- Brave maximize on open: Hyprland windowrule doesn't support this cleanly
When you make Asahi hardware/system changes, update this repo. User config changes should go to ~/dotfiles instead.
cd ~/asahi-dotfiles
# Examples of Asahi-owned state
cp -r ~/.config/asahi-audio/ config/asahi-audio/
cp -r ~/.config/wireplumber/ config/wireplumber/
cp -r ~/.config/pipewire/ config/pipewire/
# Then commit
git add -A && git commit -m "Update configs"
git pushConsider running system-snapshot before and after major changes.