Installing Nixos On A Macbook Pro
Table of Contents
Edit 7/17/24: looked into the nixos-hardware repo which has an entry for my exact model, 14,1 which states what’s broken/working.
This is essentially a follow up to my other post on a possible switch to mac. This isn’t going to be a whole Nix(OS) tutorial, as I’m still learning, just some issues I’ve faced and some partial solutions I guess.
⚠As you may be aware, macbooks weren’t really designed with linux being the main OS that would run on them, it’s important do some research on linux compatibility with your make and model, mine for instance, is a MacBookPro14,1, and I used this repo to get an idea of what’s working and what isn’t. Even with that, be aware somethings that others say work, may still not work properly depending on other factors.
Backstory
Following that post, I went to configure macos with yabai and skhd, to have a tiling window manager and keybinding after watching this video . Having both a tiling window manager and keybinding was great for using the macbook whenever I wasn’t using my desktop, which is now running Arch Linux with Hyperland, as it allowed me to have a similar workflow that I’ve grown used to. But as time went on, I realized I mostly only used the macbook when it was either really hot and didn’t want my desktop on, or the few rare times I want to do some research/learning/development in a different environments, So why not tinker with it some?
At first I was planning on just installing Arch on it and copying my dotfiles over from my desktop. However with the recent “explosion” of NixOS across the linux desktop user space, I was curious and as any responsible user does, actually decided to set it up in a VM since one of the main features of NixOS is the reproducible nature of it, so all I’d have to do is put the config file on the newly installed system and rebuild it, as simple as that, or even try out someone else’s setup or several if I so please.
Installing NixOS
First and foremost, I decided to create a macOS Ventura recovery usb following this video just in case I ever decided I want to go back to macOS (so far, about a month in nixos, there have been a couple apple ecosystem things I’ve missed, universal clipboard being probably the biggest.) Following is the usual OS install steps :
- Either flash ventoy to a flash drive and then simply dropping any ISO files into the drive. (My preferred way, allows for multiple ISO’s on one drive.)
- Or by Getting the Linux distro ISO file, get an empty flash drive and a flashing software such as etcher to make the drive bootable with only that ISO image.
- After flashing the drive. Restart the MacBook and holding down the
option
key while it reboots. Choose EFI boot/drive from the boot manager. - If using ventoy, select the proper ISO image to install, and boot into the live environment. Recommend trying it out for a bit to see if you like it and everything works fine.
- Most distros have graphical installers now, click the installer icon and follow the installation instructions. As I went away from the recommended Gnome Desktop Environment, I would recommend the Gnome Desktop Environment, it really has come a long way since I last remember using it, and even now consider using it occasionally.
- Unless you want to dual boot (out of the scope of this post). Erasing the disk and installing NixOS will take some time, it may stop at
47%
but its still installing in the background, there should be a check box to display a terminal to see what it’s doing. - Once it’s finished, restart and you’re done.
Issues and Solutions(maybe)?
Webcam
Firstly, by default the FaceTime webcam wasn’t working, not that big of a deal to me, if anything I welcome that, but it was as simple as adding the following to the configuration.nix file:
hardware.facetimehd.enable = true;
Bluetooth
The repo shows that bluetooth is working, however my out of the box experience in hyprland, gnome, and even budgie has been different, reading the repo further shows:
Works out of the box, except for the models without Touch Bar, which still suffer from a bug and need an additional patch
So I’ll be having to learn how to patch the system, in which I will update this section to have the proper config options for it.
Suspend & Hibernation
This one seems to be an on-going battle for me to figure out what exactly i need to do, and even others using laptops with it in general seems to be a pain. Starting it seemed that going into suspend/hibernation would maybe power off the macbook or just stop the track pad and keyboard from being recognized, causing me to have to hard restart.
The github repo says you have to disable the d3cold
PCIe power state for the NVMe controller to successfully wake up again by running:
echo 0 > /sys/bus/pci/devices/0000\:01\:00.0/d3cold_allowed
However, it’s not as simple as running that command, as even with sudo, I get a permission denied error. So I went to A.I with the problem and information from the repo and after several exchanges and reading a couple other nixos forums about laptops, I have the following in my config for now, which I cannot confirm really fixes the issue but may be a step in the right direction:
# hardware-configuration.nix:
boot.resumeDevice = "/dev/disk/by-uuid/{UUID for swap}";
boot.kernelParams = [
"resume_offset=SWAP_OFFSET"
"acpi_osi=Linux"
"acpi_backlight=video"
];
# configuration.nix:
boot.kernelParams = [ "button.lid_init_state=open" ];
powerManagement.enable = true;
powerManagement.resumeCommands = "sudo ${pkgs.kmod}/bin/rmmod atkbd; sudo ${pkgs.kmod}/bin/modprobe atkbd reset=1";
services.logind.extraConfig = ''
HandlePowerKey=suspend-then-hibernate
HandlePowerKeyLongPress=poweroff
HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=suspend-then-hibernate
HandleLidSwitchDocked=suspend-then-hibernate
HoldoffTimeoutSec=5s
IdleAction=suspend
IdleActionSec=300s
'';
systemd.services.disable-nvme-d3cold = {
enable = true;
description = "Disable d3cold for NVMe to fix suspend issues";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.coreutils}/bin/echo 0 > /sys/bus/pci/devices/0000:01:00.0/d3cold_allowed";
RemainAfterExit = true;
};
};
services.logind = {
lidSwitch = "suspend";
};
# Macbook pro fan controlls is an option too.
services.mbpfan = {
enable = true;
aggressive = false;
settings.general = { # even more agressive settings for the fan
low_temp = 50;
high_temp = 55;
max_temp = 65;
};
};
I do use hyprland and maybe don’t have everything I should have installed or something, but closing and opening the lid still causes the built in trackpad and keyboard to not be recognized, but an external mouse is able to wake it back up, however at the cost of not being connected or able to connect to wifi without restarting. Having the macbook docked and plugged into a monitor via hdmi, also causes the monitor to no longer be displayed to unless restarted as well.
However on gnome when closing the lid while docked, the monitor acts as the main display, haven’t fully tested when not docked, but i image I either get the same issues of not connected or able to connect to wifi and no trackpad/keyboard recognition or it solves my problems and i should just stick to gnome despite my love for tiling window managers, esp when using one display.
LUKS Decryption
During installation, I do LUKS encrypt my drives, however, on boot up, the built-in keyboard would work on systemd-boot to choose what generation to boot from, but when asked to decrypt the drive, I would need an external keyboard to do so. Don’t remember which one exactly fixes (probably hid_apple), but I added these to be available at boot and it works now:
# hardware-configuration.nix
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "hid_generic" "applespi" "applesmc" "coretemp" "hid_apple" "intel_lpss_pci" "spi_pxa2xx_platform" ];
Documentation and Packaging
Two for one since they’re both short points, everyone knows, documentation is fairly sparse, especially when compared to what could be considered Arch’s most useful feature, the archiwiki, even other distros wikis refer to it at times. From what I’ve gathered in my brief use and research, you pretty much have to look into source code to get a better idea of what to do. And I simply haven’t looked into packaging yet, but I do plan on adding Apple’s SFPro fonts to my system as I do really like them.
Basically, skill issues on my part.
Reasons I Like NixOS
Although NixOS is already a lot to learn, and installing it on a MacBookPro brought about even more problems to look into, I do genuinely love the idea of NixOS, enough to contemplate wiping my Arch install in favor of it, or even install it on my pi. The idea of EVERYTHING being configured in one file, or multiple if you want modularity, from services, drivers, software to install, even your dotfiles if you use home-manager (most of my dotfiles are still in ~/.config, was planning on using stow but maybe i’ll move more things over to home-manager,) does provide a level of simplicity, as you can just add/edit/replace corresponding lines in the config to get what you want.
And there’s rarely a chance you can rebuild and something not work, and if it does happen, reboot, go back to a generation that was fine, and remove the broken changes from your config. Speaking of which, rebuilding and going back to previous generations don’t version your config, however since everything is in one place, it makes it perfect to version with git which allows even quicker recovery in the event something happens to your hardware.
Also package sandboxing, not having to deal with dependency hell or dealing with one package not being updated but a dependency for it was, or by installing the package via a different package manager, like via cargo, and that version not being updated. This is avoided because all packages and dependencies have unique paths (hashes) generated for them by nix. So if you wanted to, you’d be able to have different versions of the same program and have no issues running them, granted you’ probably wouldn’t do that.
Moving Forward/Closing
To deal with the issue suspend/hibernation issue, I’m either going to try using gnome as my main environment, or just be fine with shutting off the laptop when not in use, probably the latter. My development environment includes using zellij which does allow me to reconnect to the sessions I’ve previously had plus a very basic nix-shell setup which I’ll likely flesh out overtime.
While I’ve have to deal with more hardships because the choice of hardware I decided to install NixOS on, I did know what I was signing up for so I welcome the challenges, they’re simply a way to learn more. Maybe this will be the start of a full switch to NixOS across all my devices and future servers.