Open yshym opened 3 years ago
Looking at google results it seems that some kernels broke Bluetooth support, so updating kernel to the latest revision in style of https://github.com/NixOS/nixpkgs/pull/118548 might fix it.
fkms-3d overlay can't be built with boot.kernelPackages = pkgs.linuxPackages_latest;
:
Applying overlay rpi4-vc4-fkms-v3d-overlay to bcm2711-rpi-4-b.dtb
Failed to apply '/nix/store/igz72xqn4w32hgbgiz8ab4493kj87j63-rpi4-vc4-fkms-v3d-overlay-dtbo': FDT_ERR_NOTFOUND
builder for '/nix/store/5ma90bwh3j5ljg5p078yf8x5h19m7ixn-device-tree-overlays.drv' failed with exit code 1
cannot build derivation '/nix/store/amm3mv4c7hy203gbx9w1y3i044phry7w-nixos-system-rpi4-21.05pre-git.drv': 1 dependencies couldn't be built
Sorry, I meant packaging the latest raspberrypi kernel revision.
Oh, ok. I'll try it
A bit newer release doesn't fix the problem. Latest revisions from both rpi-5.11.y and rpi-5.12.y have compilation issues
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/raspberry-pi-4-bluetooth-audio/13876/2
A bit newer release doesn't fix the problem. Latest revisions from both rpi-5.11.y and rpi-5.12.y have compilation issues
What are the compilation issues? Are they not fixable?
Same issues here, I tried https://github.com/raspberrypi/linux/releases/tag/1.20211007 version.
This remains to be an issue. Have hit this today using the pkgs.linuxPackages_rpi4
kernel.
I noticed that console=ttyAMA0,115200n8
in my kernel commandline (via sd-image.nix) breaks bluetooth. I had a number of dmesg lines about hc0, e.g. hci0 command 0x0c03 tx timeout
. Removing the ttyAMA0 entry made bluetooth work with something like
{
imports = [ (modulesPath + "/installer/sd-card/sd-image-aarch64.nix") ];
hardware = {
bluetooth = {
package = pkgs.bluez;
enable = true;
powerOnBoot = false;
};
};
}
nixpkgs@ 35db2e60df598e3d5c88adab65f70b91f6645b45,
linuxPackages_latest.kernel.version
= 5.16.12
I edited the kernel command line in extlinux.conf by hand for now, nixified it would probably look like this:
{
# via sd-image: boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
boot.kernelParams = lib.mkForce ["console=ttyS0,115200n8" "console=tty0"];
}
@pschyska Could you share a full config with working bluetooth? And just in case, could you also share your /boot/config.txt
? I have been unable to get bluetooth working by downgrading kernels or adopting any of the configs in this thread. If I manually run sudo btattach -B /dev/ttyAMA0 -P bcm -S 3000000
, I can see the adapter with rfkill
:
ID TYPE DEVICE SOFT HARD │
1 bluetooth hci0 unblocked unblocked
but bluetoothctl power on
still fails with No default controller available
. I do see these errors in dmesg
upon running btattach
:
[ 525.931400] Bluetooth: hci0: command 0x0c03 tx timeout │
[ 533.995470] Bluetooth: hci0: BCM: Reset failed (-110)
but I do not have the problematic kernel command line params you referenced.
@Majiir I'm afraid I can't. I switched to https://github.com/pftf/RPi4 and install nixos like on any other uefi system. I couldn't make the bluetooth controller appear in bluetoothctl any longer (the resulting installation is probably all kinds of broken now in other ways, but I have no clue about rpis). As I didn't end up using bluetooth I didn't notice. With the snippet above I did get it to work and was able to pair a device and didn't see any issues. I also can't experiment much because I need my rpi working for some network functions. Sorry
@Majiir I recently worked on my system again, and was able to use bluetooth with upstream kernels 5.15.63 (linuxPackages @ nixos-unstable) and 5.19.4 (linuxPackages_latest). I didn't do anything special. I'm not importing nixos-hardware.
config.txt:
arm_64bit=1
enable_uart=1
uart_2ndstage=1
enable_gic=1
armstub=RPI_EFI.fd
disable_commandline_tags=1
disable_overscan=1
device_tree_address=0x1f0000
device_tree_end=0x200000
dtoverlay=miniuart-bt
#dtoverlay=upstream-pi4
(upstream-pi4 always crashed the system during boot) EEPROM is https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware/stable/pieeprom-2022-08-02.bin RPI_EFI and the boot code is from https://github.com/pftf/RPi4/releases/tag/v1.33. I have a 4 B rev 1.1 with 4G RAM and removed the 3G limit in UEFI and set the boot mode to ACPI+DeviceTree (with just ACPI I'm missing a lot of functionality like raspberrypi_cpufreq).
relevant nix config:
{pkgs, ...}: {
boot = {
loader = {
timeout = 3;
# requires uefi firmware!
systemd-boot = {
enable = true;
consoleMode = "max";
};
efi.canTouchEfiVariables = true;
generic-extlinux-compatible.enable = false;
};
kernelPackages = pkgs.linuxPackages_latest; # or without _latest
# kernelParams not set, defaults to = ["loglevel=4"];
initrd.availableKernelModules = [ "pcie-brcmstb" "reset-raspberrypi" ]; # USB hid in initrd to unlock luks devices
};
hardware.enableRedistributableFirmware = true;
hardware.deviceTree.filter = "bcm2711-rpi-4-b.dtb";
systemd.services."getty@".enable = false;
powerManagement.cpuFreqGovernor = "schedutil";
}
Bear in mind that depending on you UART settings, the bluetooth device is either /dev/ttyAMA0, or one of the /dev/ttyS (IIRC it was /dev/ttyS1 for me with miniuart-bt, but for most it's /dev/ttyS0, IDK why it moved to the 1 for me ¯\(ツ)/¯). In either case, make sure you don't put a linux console onto this device (e.g. with the referenced kernel params, or via enabling getty@tty or similar). If you use mini UART, you have to update btattach -B /dev/ttyS0 -P bcm -S 3000000
accordingly. Afterwards I systemctl restart bluetooth
and could the the controller in bluetoothctl, and could power on
and scan on
and got results.
I can't give you the full config, is split up into many modules within my system flake, but I can query specific config values in repl for you if you want to know more.
Thanks, @pschyska. I tried pieces of your config, and I narrowed the issue down to, believe it or not, the kernel: linuxPackages
works fine, but linuxPackages_rpi
does not.
(Also, I'm using sd-image-aarch64.nix
as a base, so I had to set kernelParams = lib.mkForce [ "console=ttyS0,115200n8" "console=tty0" ]
in order to remove the default console=ttyAMA0,115200n8
parameter.)
I don't think the issue is in the kernel itself, since I had bluetooth working when running the same kernel version on Raspberry Pi OS. I'll run some more experiments to verify one way or the other.
Thanks, @pschyska. I tried pieces of your config, and I narrowed the issue down to, believe it or not, the kernel:
linuxPackages
works fine, butlinuxPackages_rpi
does not.
I assume you mean linuxPackages_rpi4
and it's not hard to believe that this is the issue 🙁 Raspberry foundation are doing some things that upstream kernel doesn't agree with, IIUC, beginning with the naming of the SoC in DeviceTree (e.g. for pi3-b, rpi foundation calls it bcm2710-rpi-3-b. and upstream kernel bcm2837-rpi-3-b, although it looked like at least for the 4's both name it bcm2711, but I'm no expert...) and probably custom kernel modules, firmware blobs and so on.
Did you take a look at nixos-hardware/raspberry-pi/4 and its includes? This config is supposed to work with linuxPackages_rpi4. In particular, you need hardware.enableRedistributableFirmware so that you get pkgs.raspberrypiWirelessFirmware
.
Is btattach
a requirement to get the Pi 4B's Bluetooth working (once everything is configured properly)? If so, would it make sense to "fix" this in nixos-hardawre with some combination of udev rules and systemd services to start btattach
automatically?
There's also the krnbt
device tree parameter:
krnbt Set to "on" to enable autoprobing of Bluetooth
driver without need of hciattach/btattach
(default "off")
I read that krnbt
is the preferred approach, but I can't recall where I read that. It's certainly simpler, when it works.
Thing is, I haven't been able to get btattach
to work either. To summarize, these are the results I'm seeing:
@Majiir Thanks for the mention of krnbt
; I didn't know it existed.
I have btattach
and NixOS with the Raspberry Pi kernel working. Funny enough, I can't boot with the default kernel.
Here is what works for me.
configuration.nix
boot.kernelParams = [
"8250.nr_uarts=1"
"console=ttyS0,115200"
"console=tty1"
];
boot.kernelPackages = pkgs.linuxPackages_rpi4;
hardware.bluetooth.enable = true;
(I think those are the only relevant lines)
config.txt
[pi4]
kernel=Tow-Boot.noenv.rpi4.bin
enable_gic=1
armstub=armstub8-gic.bin
disable_overscan=1
[all]
arm_64bit=1
enable_uart=1
avoid_warnings=1
nix-info -m
"aarch64-linux"
Linux 5.15.32, NixOS, 22.11 (Raccoon), 22.11pre418904.db25c4da285
yes
yes
nix-env (Nix) 2.11.0
"nixos"
/nix/var/nix/profiles/per-user/root/channels/nixos
Perhaps that can help you narrow down what isn't working for you? Happy to provide any extra information.
@ChanceHarrison Could you share the btattach
command you are using?
Of course! I knew I was forgetting something.
btattach -B /dev/ttyAMA0 -P bcm
There's also the
krnbt
device tree parameter: - @Majiir
Edit: It works just fine for me, if you type it correctly. 😉
Original text:
For what it's worth, adding dtparm=krnbt=on
to my config.txt
and rebooting didn't change anything; I still had to use btattach
to get bluetoothctl
to see the controller. Am I doing something obviously wrong? Do I also have to set the krnbt_baudrate
param? I'm not well-versed in debugging device tree shenanigans.
I'm not well-versed in it either, but I only needed the dtparam=krnbt=on
line. That worked for me in NixOS (with the default kernel) and also in Raspberry Pi OS (with the btattach
systemd units disabled).
Your post says dtparm
, but it should be dtparam
- did the same typo make it into your config?
Your post says
dtparm
, but it should bedtparam
- did the same typo make it into your config?
D'oh! The typo made its way into the config first, actually. Thank you for catching it. It works as advertised if you actually type it correctly.
I think there are some lessons learned here that can be documented on the wiki, perhaps? I would be happy to try my hand at those changes, though I have never done so before.
As for your issue, did you have any luck finding why Bluetooth (either via btattach
or krnbt
) is working for me and not for you?
No such luck! I tried using the same nixpkgs
commit, the same NixOS config, and the same config.txt
contents. The behavior is the same every time: btattach
runs, and rfkill
shows a device:
$ rfkill
ID TYPE DEVICE SOFT HARD
0 bluetooth hci0 unblocked unblocked
but still no working Bluetooth:
$ bluetoothctl power on
No default controller available
dmesg
reports:
[ 204.090325] uart-pl011 fe201000.serial: no DMA platform data
[ 204.116448] Bluetooth: HCI UART driver ver 2.3
[ 204.120994] Bluetooth: HCI UART protocol H4 registered
[ 204.126231] Bluetooth: HCI UART protocol BCSP registered
[ 204.131728] Bluetooth: HCI UART protocol LL registered
[ 204.137010] Bluetooth: HCI UART protocol Three-wire (H5) registered
[ 204.143629] Bluetooth: HCI UART protocol Broadcom registered
[ 204.149465] Bluetooth: HCI UART protocol QCA registered
[ 204.317159] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 204.322579] Bluetooth: BNEP filters: protocol multicast
[ 204.328044] Bluetooth: BNEP socket layer initialized
[ 206.174626] Bluetooth: hci0: command 0x0c03 tx timeout
[ 214.238705] Bluetooth: hci0: BCM: Reset failed (-110)
In all of my testing, the only thing that works is switching to the default kernel instead of linuxPackages_rpi4
. But the issue isn't the Raspberry Pi kernel itself, because that kernel works with both manual attachment and krnbt
on other distros.
I put together a minimal-ish system flake for testing this: https://github.com/Majiir/btpi You can build an SD image with nix build --flake '.#btpi-sd
, or you can rebuild an existing system with nixos-rebuild --flake '.#btpi'
.
@ChanceHarrison Would you be willing to build a fresh SD image and give that a try? If it works, then that narrows the issue down to hardware or firmware. If it doesn't, then maybe you can make adjustments or offer an alternative flake that does work.
[EDIT] Just to rule out this one device being the problem, I tested the btattach
method on a Raspberry Pi Compute Module 4 with a similar config, and I'm seeing the same issue.
Would you be willing to build a fresh SD image and give that a try? - @Majiir
I would be willing to give it a try, yes. I'll get back to you in a few days once I have a new spare SD card to use. To make sure I'm clear on the process:
dd
onto SD, and bootgit clone https://github.com/Majiir/btpi
and cd btpi
nixos-rebuild --flake '.#btpi'
Or, would I just do step 2 (on an existing NixOS system) and nix-build --flake '.#btpi-sd'
and then dd
output (where does the output go?) onto SD and boot? Excuse my lack of understanding there, but does /etc/nixos/configuration.nix
get populated when building an SD image this way?
Of note, I am not using the SD image to get NixOS on my Pi. I used the aarch64 minimal installer (specific version nixos-minimal-22.11pre409157.da6a05816e7-aarch64-linux.iso
, though I don't know how to find the build on Hydra) that I wrote to a USB flash drive. I wrote Tow-Boot (the shared.disk-image.img
from raspberryPi-aarch64-2021.10-005
) on the SD card for UEFI booting. From there, I installed NixOS onto a SSD (also connected via USB). Do you think it's possible that the differences in our observed behavior are because I'm not using the SD image and you are? I suppose we might find out when I give the SD image route a try myself.
We have a few different options. For best reproducing my setup, you should do something like this:
git clone https://github.com/Majiir/btpi
cd btpi
nix build '.#btpi-sd'
ls result/sd-image
Then, you can write that image to an SD card, boot the Pi, and log in with test
/test
.
The SD image will create a config.txt
that contains dtparam=krnbt=on
, but that can be manually removed by mounting the firmware partition (mount /dev/disk/by-label/FIRMWARE
) and editing /boot/firmware/config.txt
. It shouldn't make a difference to the test (except that, y'know, Bluetooth might just work when you boot up).
If you do all that, you won't have anything in /etc/nixos
. You can clone the repo to the Pi and nixos-rebuild switch --flake '.#btpi'
there, or you can remotely deploy from another machine with --target-host
.
My thinking is that by using a flake and building the whole SD image, we ideally get the exact same setup, and Bluetooth should fail for you with that setup. If it does, you could try taking your existing, working system (after taking a backup!) and deploy the minimal flake with nixos-rebuild
. The results will be interesting! Thank you for taking the time to test this out.
Meanwhile, I will see if I can replicate your install steps.
@Majiir I finally got my spare SD card(s) and I went ahead and booted my Pi with your minimal example. Thanks for the guidance on using it. Sure enough, I run into the same Bluetooth issues. Adding hardware.enableRedistributableFirmware = true;
and rebuilding the system with the flake didn't help.
I compared dmesg output between my known-good system and the minimal example system. Here's the two outputs:
Known good:
[ 11.921327] Bluetooth: HCI device and connection manager initialized
[ 11.921345] Bluetooth: HCI socket layer initialized
[ 11.921364] Bluetooth: L2CAP socket layer initialized
[ 11.921383] Bluetooth: SCO socket layer initialized
[ 12.073632] Bluetooth: HCI UART driver ver 2.3
[ 12.073653] Bluetooth: HCI UART protocol H4 registered
[ 12.073658] Bluetooth: HCI UART protocol BCSP registered
[ 12.073741] Bluetooth: HCI UART protocol LL registered
[ 12.076474] Bluetooth: HCI UART protocol Three-wire (H5) registered
[ 12.079804] Bluetooth: HCI UART protocol Broadcom registered
[ 12.441954] Bluetooth: hci0: BCM: chip id 107
[ 12.442231] Bluetooth: hci0: BCM: features 0x2f
[ 12.443316] Bluetooth: hci0: BCM4345C0
[ 12.443335] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0000
[ 12.456244] Bluetooth: hci0: BCM4345C0 'brcm/BCM4345C0.hcd' Patch
[ 13.144837] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 13.144857] Bluetooth: BNEP filters: protocol multicast
[ 13.144877] Bluetooth: BNEP socket layer initialized
[ 13.167354] Bluetooth: hci0: BCM43455 37.4MHz Raspberry Pi 3+
[ 13.167377] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0342
btpi (with enableRedistributableFirmware
):
[ 9.122898] Bluetooth: Core ver 2.22
[ 9.140820] Bluetooth: HCI device and connection manager initialized
[ 9.141508] Bluetooth: HCI socket layer initialized
[ 9.141536] Bluetooth: L2CAP socket layer initialized
[ 9.141972] Bluetooth: SCO socket layer initialized
# btattach
[ 437.675481] uart-pl011 fe201000.serial: no DMA platform data
[ 437.705865] Bluetooth: HCI UART driver ver 2.3
[ 437.710439] Bluetooth: HCI UART protocol H4 registered
[ 437.715687] Bluetooth: HCI UART protocol BCSP registered
[ 437.721161] Bluetooth: HCI UART protocol LL registered
[ 437.726454] Bluetooth: HCI UART protocol Three-wire (H5) registered
[ 437.733011] Bluetooth: HCI UART protocol Broadcom registered
[ 437.738863] Bluetooth: HCI UART protocol QCA registered
[ 439.777322] Bluetooth: hci0: command 0x0c03 tx timeout
[ 447.969540] Bluetooth: hci0: BCM: Reset failed (-110)
I also confirmed that switching to the non-rpi4 kernel (I tried with linuxPackages_latest
) works just fine:
[ 14.071134] Bluetooth: Core ver 2.22
[ 14.071328] Bluetooth: HCI device and connection manager initialized
[ 14.071352] Bluetooth: HCI socket layer initialized
[ 14.071363] Bluetooth: L2CAP socket layer initialized
[ 14.071404] Bluetooth: SCO socket layer initialized
[ 14.397969] Bluetooth: HCI UART driver ver 2.3
[ 14.402607] Bluetooth: HCI UART protocol H4 registered
[ 14.407929] Bluetooth: HCI UART protocol BCSP registered
[ 14.490109] Bluetooth: HCI UART protocol LL registered
[ 14.497315] Bluetooth: HCI UART protocol Broadcom registered
[ 14.565484] Bluetooth: HCI UART protocol QCA registered
[ 14.573000] Bluetooth: HCI UART protocol Marvell registered
[ 14.912586] Bluetooth: hci0: BCM: chip id 107
[ 14.922423] Bluetooth: hci0: BCM: features 0x2f
[ 14.928848] Bluetooth: hci0: BCM4345C0
[ 14.928870] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0000
[ 14.946924] Bluetooth: hci0: BCM4345C0 'brcm/BCM4345C0.hcd' Patch
[ 15.230121] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 15.235649] Bluetooth: BNEP socket layer initialized
[ 15.765508] Bluetooth: hci0: BCM: features 0x2f
[ 15.771862] Bluetooth: hci0: BCM43455 37.4MHz Raspberry Pi 3+
[ 15.777712] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0342
[ 15.802863] Bluetooth: MGMT ver 1.22
So now I am very interested how I have my known-good system working with the rpi4 kernel but I can't get it to boot with the normal kernel...
I haven't tried
taking your existing, working system (after taking a backup!) and deploy the minimal flake with nixos-rebuild
Is relying on being able to boot the previous generation a sufficient backup? 🤔
I hope we can work together to figure this out. Hopefully others will chime in if they know something or have any suggestions.
I'm a newcomer to this issue. Today I was playing with my newly acquired Raspberry Pi 4B, 4GB and played around with this issue. I would like to confirm this bug with the current nixpkgs, and I would like to provide a summary of the current status:
My nixpkg revision is 5dc7114b7b256d217fe7752f1614be2514e61bb8. It's nixpkgs-unstable
, pin updated at 27-11-2022.
I played with a couple of kernels. A summary is below:
Following the wiki and the linked nix.dev article sets up an install using the generic aarch64 SD image. After following these guides, one ends up importing nixos-hardware.nixosModules.raspberry-pi-4
from the NixOS-hardware repo. This setup will use the Linux kernel as provided by the Raspberry foundation (attribute name pkgs.linuxPackages_rpi4
).
This setup has the following problems:
sudo btattach -B /dev/ttyAMA0 -P bcm
to get one step closer to something working, but it is still broken, as described above.One can use kernel 5.15, by setting boot.kernelPackages = pkgs.linuxPackages;
(or pkgs.linuxPackages_5_15
to be precise) in the NixOS config (as of 5dc7114b7b256d217fe7752f1614be2514e61bb8). This changes the following:
NixOS/nixos-hardware
stop working. Specifically, most device tree overlays defined in raspberry-pi/4/...
fail to apply. Luckily, most things should just work in the kernel itselfhdmi_force_hotplug = 1
in config.txt
made no real difference here.V3D GPU
driver to work on precisely this kernel.Here is a (reduced) version of the config that works for me:
{ config, pkgs, lib, ... }:
{
hardware = {
bluetooth.enable = true;
enableRedistributableFirmware = true;
pulseaudio.enable = true;
deviceTree.filter = "bcm2711-rpi-*.dtb";
};
boot = {
# Bluetooth doesn't work with rpi4 kernel
# https://github.com/NixOS/nixpkgs/issues/123725
kernelPackages = pkgs.linuxPackages;
# Not sure how much of this this is relevant
initrd.availableKernelModules = [
"usbhid"
"usb_storage"
"vc4"
"pcie_brcmstb" # required for the pcie bus to work
"reset-raspberrypi" # required for vl805 firmware to load
];
loader = {
generic-extlinux-compatible.enable = true;
};
};
fileSystems = {
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
options = [ "noatime" ];
};
};
}
Some elements taken from nixos-hardware
. I copied those over manually because I load that repo in through a flake, which doesn't make for a nice snippet.
This kernel can be used by setting boot.kernelPackages = pkgs.linuxPackages_latest;
(or pkgs.linuxPackages_6_0
to be precise). This kernel failed to boot to desktop, as the x-server started to SEGFAULT on boot.
Edit 28-11: interestingly, this article states that video driver support was merged for kernel version 6, but implies there are some bugs. That may explain the SEGFAULTs I'm seeing. I haven't looked further into this.
Kernels between 5.15 and 6.0.9 have dropped upstream support, and have been removed from nixpkgs. Therefore I haven't tried them.
Edit: I've added a link to this issue in the Wiki page: https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi_4
One way to get bluetooth to work is by copying the firmware and kernel from a raspbian image and then hacking it into NixOS. Here's how.
@avieth If I already have a configured raspberry pi, is there a way to update it in place with this?
@avieth If I already have a configured raspberry pi, is there a way to update it in place with this?
The typical update step from the README on the page I linked should work fine since it's just a typical switch-to-configuration
$ nix-build rpi4.nix --argstr hostName <your hostname> -A update -o update
$ nix-copy-closure --to <pi address> ./update
$ ssh <pi address> $(readlink update)
What's missing is the bootloader setup and it's a bit weird. You could build the initial image just like in the README
$ nix-build rpi4.nix --argstr hostName <your hostname> -A initial -o initial
and then mount the boot partition of the image
sudo mount -o loop,offset=$((16384*512)) ./sd-image/sd-image/nixos-sd-image-21.11pre-git-aarch64-linux.img <mount point>
and replace your existing Pi's boot with the contents of this. But also edit cmdline.txt
to change the root
and rootfstype
parameters accordingly. It's set to use PARTUUID=ffffffff-2
and the sd-image is set to match but that's probably not going to match your setup.
The firmware does some manipulation before passing the device tree to the kernel. The device tree in the raspberry pi kernel seems to expect this manipulation to happen, as the device tree in their fork isn't fully configured like the one in the mainline kernel. This is problematic since NixOS does not (by default) use the device tree provided by the firmware and instead supplies its own.
In this case I believe the problem is that the firmware configures the bluetooth flow control pins. I have fixed the bluetooth issue in the past by creating an overlay that mimics the firmware manipulation. Something like:
// Configure uart0 pins so that bluetooth works
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&uart0_pins>;
__overlay__ {
brcm,pins = <30 31 32 33>;
brcm,pull = <2 0 0 2>;
};
};
};
It is tedious and error prone to maintain these patches. So, more recently I have pursued using the device tree that the firmware provides (using u-boot's CONFIG_OF_BOARD
option) rather than trying to mimic the manipulation. This approach has worked well for me.
I packaged up this approach here and an example with working bluetooth can be found here.
@tstat That looks promising. Is there any guide to migrating an existing deploy onto your raspberry-pi-nix
approach? I don't know much at all about the Linux booting process and I'm leery about just changing the way an existing system boots because if it gets screwed up I don't know how to fix it.
Right now my system is configured to use nixos-hardware.nixosModules.raspberry-pi-4
and then sets boot.kernelPackages = pkgs.linuxPackages
. It looks like this is using boot.loader.generic-extlinux-compatible
(that's what nixos-hardware
sets, though I've noticed there's a separate boot.loader.raspberryPi
and I don't know what the difference is or why nixos-hardware
doesn't set that).
There isn't a guide for migrating an existing deploy. In your case it sounds the steps would be:
raspberry-pi-nix
module from the v0.2.0
releasenixos-hardware
moduleboot.kernelPackages = pkgs.linuxPackages
since raspberry-pi-nix
boots a recent raspberry-pi kernel forkconfig.txt
file then port those customizations to your nixos configurationIf you are using nixos-hardware
now then migrating shouldn't change the way your system boots; nixos-hardware
also boots with u-boot on the firmware partition, which then locates /boot/extlinux/extlinux.conf
on your root partition to discover the kernel location and whatnot.
If you want to be cautious you could always back up an image of your sd-card before attempting, or you could be less cautious and only backup your firmware partition as that is destructively modified, whereas your root partition is not (edit: I just recalled that modifying boot.loader.generic-extlinux-compatible.useGenerationDeviceTree
is destructive when changed, so being cautious you might want to back up /boot/extlinux/extlinux.conf
as well). Feel free to open an issue on raspberry-pi-nix
if you have other questions or want to discuss creation of a migration guide.
The readme of raspberry-pi-nix
attempts to describe how it works and motivate the design, which might be helpful or interesting to you.
If you end up attempting a migration please let me know how it goes!
@tstat I just attempted it tonight, but I ran into a roadblock which is that compiling the kernel requires the big-parallel
feature and I don't have that (I'm using a hacky Docker setup to build for aarch64-linux
so I don't have to build on my rpi). Is there any binary cache available?
raspberry-pi-nix
is comprised solely of nixos modules and does not pin a version of nixpkgs (i.e. nixpkgs
is not an input to the raspberry-pi-nix
flake), so I can't guarantee any cache hits. However, I built the kernel and other packages defined in the overlay against nixos-22.11 and pushed that to cachix. The example in the readme now shows the appropriate substituter and trusted key settings.
@tstat Thanks for trying! Unfortunately it's not working for me. I'm guessing this is because I'm doing this on aarch64-darwin and based on the narHash issue I filed on your repo it looks like the linux source is affected by being unpacked and hashed on APFS, which presumably changes the resulting out path. I'm attempting to get access to a big-parallel
builder so hopefully I'll be able to build it myself.
@tstat I finally managed to build and deploy to my raspberry pi, and now it can't find bluetooth. I double-checked and the /boot/config.txt
does indeed have dtparam=krnbt=on
, but rfkill
doesn't list bluetooth and bluetoothctl
says there's no default controller. The only thing I omitted from your example was the bluez-tools
package, since I'm not sure what that's for (and the source repo lists it as a beta and hasn't had any commits in almost 3 years), but that shouldn't affect anything AFAICT.
Do you have any idea what's wrong?
EDIT: I'm going to file an issue on your repo for this instead.
For those looking to fix this when using nixos-hardware
(linuxPackages_rpi4
kernel, no change to useGenerationDeviceTree
), here's a quick hack to apply the above bits to the device tree Linux-side:
# bluetooth.nix
{ config, lib, pkgs, ... }:
let
cfg = config.hardware.raspberry-pi."4".bluetooth;
in
{
options.hardware = {
raspberry-pi."4".bluetooth = {
enable = lib.mkEnableOption ''
configuration for bluetooth
'';
};
};
config = lib.mkIf cfg.enable {
hardware.raspberry-pi."4".apply-overlays-dtmerge.enable = lib.mkDefault true;
# doesn't work for the CM module, so we exclude e.g. bcm2711-rpi-cm4.dts
hardware.deviceTree.filter = "bcm2711-rpi-4*.dtb";
hardware.deviceTree = {
overlays = [
{
name = "bluetooth-overlay";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&uart0_pins>;
__overlay__ {
brcm,pins = <30 31 32 33>;
brcm,pull = <2 0 0 2>;
};
};
};
'';
}
];
};
};
}
# configuration.nix
imports =
[
# ...
./bluetooth.nix
# ...
];
hardware.bluetooth.enable = true;
hardware.raspberry-pi."4".bluetooth.enable = true;
systemd.services.btattach = {
before = [ "bluetooth.service" ];
after = [ "dev-ttyAMA0.device" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.bluez}/bin/btattach -B /dev/ttyAMA0 -P bcm -S 3000000";
};
};
With that I was able to:
rfkill
show bluetooth right away (fixed by btattach
)dmesg | grep -I blue
i.e no Bluetooth: hci0: BCM: Reset failed (-110)
anymorehcitool dev
list the hci0
bluetooth devicebluetoothctl
(no more No default controller available
)I'm probably going to contribute that back to the nixos-hardware
repo.
I've been tinkering with this for the past few days. I'm using the rpi kernel (via nixos-hardware) on my Pi 4, in large part so I have access to /dev/gpiomem
for some GPIO home automation stuff.
For my Pi4, which uses the nixos-hardware
pi4 module (which sets the kernel to linuxPackages_rpi4
), I did not have luck with:
dtparam=krnbt=on
, alone or in combination with...CONFIG_OF_BOARD
I did have to use:
btattach
systemd service as shown above and at https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi_3#Bluetoothhardware.bluetooth.enable = true;
deviceTree
overlays and filters from aboveI would rather be using the mainline kernel, but then I don't know how to get /dev/gpiomem
, so this config seems workable for now.
I'm on ZFS root and tried switching over to the uefi firmware and grub with kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
(6.1.45). I removed all references to nixos-hardware and all the deviceTree
stuff from above, thinking that bluetooth might "just work", as this config seems pretty similar to what @pschyska was using above.
hci0 appears with rfkill list
and is unblocked, but unfortunately I get No default controller available
when I try to power on, and btattach
just hangs. No difference with or without dtparam=krnbt=on
.
I see the following in dmesg after btattach
:
Bluetooth: hci1: command 0x0c03 tx timeout
Bluetooth: hci1: BCM: Reset failed (-110)
I also seem to only get 2 GPIO pins listed under /dev/gpiochip0
, which seems weird:
$ sudo gpioinfo
gpiochip0 - 2 lines:
line 0: unnamed unused output active-high
line 1: unnamed unused output active-high
gpiochip1 - 3 lines:
line 0: unnamed unused output active-high
line 1: unnamed unused output active-high
line 2: unnamed unused output active-high
Boot fails when I try to switch to the rpi kernel.
I feel bad that I never followed up above. My Pi4 has been running fairly well for the last several months with the following setup, which provided functional GPIO and bluetooth
nixpkgs/release-23.05
compatibility=grub2
)kernelPackages = pkgs.linuxKernel.packages.linux_rpi4;
hardware.bluetooth.enable = true;
dtparam=krnbt=on
is not setUnfortunately I updated to 23.11 a few days ago and bluetooth is gone again.
EDIT: Bluetooth is working again on 23.11, I think the issue was with my UEFI setup, after reconfiguring that and a reboot I'm back in business.
Issue description
"No default controller available" issue while trying to use
bluetoothctl
tool. I've recently installed NixOS on a Raspberry Pi 4 Model B using this very cool tutorial and everything seems to be fine for now except for this bluetooth functionality. I've read that https://github.com/RPi-Distro/pi-bluetooth is used in most similar cases, but, as far as I understand,btattach
systemd service (https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi_3#Bluetooth) is already doing the same (if it is suitable for both rpi 3 and 4)rpi-related imports:
systemd services:
hardware:
Steps to reproduce
Technical details
"aarch64-linux"
Linux 5.10.17, NixOS, 21.05pre-git (Okapi)
yes
yes
nix-env (Nix) 2.3.11
""
"home-manager, nixos"
/nix/var/nix/profiles/per-user/root/channels/nixos