nix-community / raspberry-pi-nix

NixOS modules to aid in configuring NixOS for raspberry pi products
MIT License
144 stars 34 forks source link

Bluetooth is missing #4

Closed lilyball closed 1 year ago

lilyball commented 1 year ago

I finally managed to build my existing configuration using raspberry-pi-nix instead of nixos-hardware and deploy it to my raspberry pi, and rebooted, and now bluetooth is gone. bluetoothctl says no default controller available and rfkill doesn't list bluetooth.

My configuration uses the following, which AIUI should be sufficient:

{
  hardware = {
    bluetooth.enable = true;
    raspberry-pi = {
      config.all.base-dt-params = {
        # enable autoprobing of bluetooth driver
        # https://github.com/raspberrypi/linux/blob/c8c99191e1419062ac8b668956d19e788865912a/arch/arm/boot/dts/overlays/README#L222-L224
        krnbt = {
          enable = true;
          value = "on";
        };
      };
    };
  };
}

I really don't know very much about the Linux booting process, is there any way to confirm that it is indeed booting through the correct process?

lilyball commented 1 year ago

Ah hah, I think it was the bootloader. I don't know what was going on, but I just ran NIXOS_INSTALL_BOOTLOADER=1 /nix/var/nix/profiles/system/bin/switch-to-configuration boot and rebooted and now I have bluetooth.

I'm going to close this since I suspect this has to do with the history of me mucking about on this machine in the past, though any information on migration might want to include the recommendation of telling nixos to reinstall the bootloader just in case.

tstat commented 1 year ago

Oh hrm, I'm glad that you resolved the issue and bluetooth is working. I believe you should be good to go after the firmware migration service runs, then rebooting.

Did you run something like nixos-rebuild boot to switch to this new configuration? If so, I think I could see what went wrong: that migration service won't run until after your new system boots. At that point I would expect you just need to reboot again to boot with the u-boot that the migration installed.

I'm in the habit of doing a nixos-rebuild switch, after which a reboot would boot with the newly installed u-boot.

tstat commented 1 year ago

I really don't know very much about the Linux booting process

I'm not an expert either, but my high-level/handwavy understanding for this particular setup is:

  1. The raspberry pi firmware boot sequence runs, which finds the firmware partition of the SD card and runs start.elf
  2. It loads and manipulates the appropriate device tree binary from the firmware partition then starts the kernel (as specified in config.txt) passing it the manipulated device tree. The kernel we have specified is not a linux kernel, but instead u-boot.
  3. U-boot then executes its own boot sequence which will find the partition with the /boot/extlinux/extlinux.conf file (this is our only other partition, the root partition)
  4. U-boot presents the prompt with the options specified in extlinux.conf, and boots the default after some amount of time passes. It passes the kernel the device tree it was passed.
  5. Normal NixOS boot flow from there

You can look at the device tree of the current running system with

dtc -I fs /sys/firmware/devicetree/base

which would be the thing that was wrong in your example, but it would take some familiarity with the mainline device tree vs the raspberry pi linux kernel device tree fork to tell the difference.

lilyball commented 1 year ago

Did you run something like nixos-rebuild boot to switch to this new configuration? If so, I think I could see what went wrong: that migration service won't run until after your new system boots. At that point I would expect you just need to reboot again to boot with the u-boot that the migration installed.

Ahh ok. I ran deploy --boot, which installs the closure on the remote machine and then presumably runs switch-to-configuration boot. I didn't know there was a two-step process here.

Having said that, after the machine was running for a couple of days, bluetooth failed. I was getting this problem with my older approach too (of just resetting the kernel packages back to the default), which was why I was originally interested in changing up approaches. I haven't done anything about it yet, I just know that Home Assistant can't talk to my bluetooth accessory anymore. The only solution I found in the past was to reboot the machine. Is there any other debugging I can do here?

tstat commented 1 year ago

Having said that, after the machine was running for a couple of days, bluetooth failed. I was getting this problem with my older approach too (of just resetting the kernel packages back to the default), which was why I was originally interested in changing up approaches. I haven't done anything about it yet, I just know that Home Assistant can't talk to my bluetooth accessory anymore. The only solution I found in the past was to reboot the machine. Is there any other debugging I can do here?

Well, that's a bummer. I haven't experienced an issue with bluetooth failing after a while. What do you mean by bluetooth failed? If you run bluetoothctl is there still a controller and you can still scan for bluetooth devices to pair with and whatnot?

lilyball commented 1 year ago

I was on mobile at the time so I didn't try running that, I rebooted because I needed bluetooth back. If it happens again I'll check that, I just have very little experience with Linux outside of the context of a cloud server somewhere, so I don't know anything about testing hardware and whatnot. I just know that Home Assistant would complain that it couldn't talk to my device and failed to power cycle the bluetooth, although it also seemed to indicate that power cycling succeeded right after saying it failed (but the device was still unreachable).