Mainline Linux/Debian for NanoPi R5S/C

Workaround:

cat << '_EOF_' > /root/reboot-on-missing-wifi.sh
#!/bin/dash
if [ -e '/sys/class/net/wlan0' ]
then
	echo 'OK: wlan0 interface exists, proceeding with boot'
	rm -f /root/reboot-on-missing-wifi.flag

elif [ -e '/root/reboot-on-missing-wifi.flag' ]
then
	echo 'FAILED: Reboot has been done already, but wlan0 interface is still missing!'
else
	echo 'PENDING: wlan0 interface does not exist, creating flag and doing reboot'
	> /root/reboot-on-missing-wifi.flag
	reboot
	exit 0
fi
_EOF_
chmod +x /root/reboot-on-missing-wifi.sh
cat << '_EOF_' > /etc/systemd/system/reboot-on-missing-wifi.service
[Unit]
Description=Reboot on missing WiFi
DefaultDependencies=no
After=systemd-remount-fs.service -.mount
Wants=local-fs-pre.target
Before=local-fs-pre.target

[Service]
Type=oneshot
StandardOutput=file:/root/reboot-on-missing-wifi.log
ExecStart=/root/reboot-on-missing-wifi.sh

[Install]
WantedBy=local-fs.target
_EOF_
systemctl daemon-reload
systemctl enable reboot-on-missing-wifi

At early boot, just after the rootfs has been mounted R/W, it checks whether the wlan0 interface exists, and does a reboot if not. It also creates a flag file, and does not reboot anymore if this exists already but the interface is still missing. The flag is removed once the interface exists.

This workaround works very well and the impact on boot time is not high.
Thanks
Just a small error on line 2 : should be bash and not dash.

I had a look on Armbian : they have now a community build for R5C. It works fine and wlan0 is present, but there is still the problem to build the module. The headers are installed OK by armbian-config, but if I want to build, I get a missing “build” file. So I install linux 6.6.31 from kernel.org and build OK.
But when I want to build the module I get the traditional error about symvers missing.
With dietpi the building of the module was immediate, it worked at first try.

This workaround works really well. Thank you.
It is much better than our previous script which was a bit handcrafted.

I used dash (bourne shell) intentionally, being a bit faster. I hope I did not accidentally left bash syntax inside. However, using bash will of course work as well.

Great that it works. It currently appends a log entry to /root/reboot-on-missing-wifi.log on every (re)boot. Good to monitor for some (re)boots to see whether it works reliably. Afterwards, you could remove the StandardOutput line from /etc/systemd/system/reboot-on-missing-wifi.service to disable file logging. You can then still see the last entry via:

journalctl -u reboot-on-missing-wifi

That one should match exactly our kernel+bootloader and there was no recent related commit. Are you sure it works consistently on cold boots? The first boot of Armbian AFAIK includes a reboot, after partition/filesystem expansion, so that would not count.

I guess it is just the symlink missing or revised:

rm -R "/lib/modules/$(uname -r)/build"
ln -s "/usr/src/linux-headers-$(uname -r)" "/lib/modules/$(uname -r)/build"

Not sure how you installed Linux 6.6.31, but there are quite a few things to take care of, including all the symlinks in /boot. So I would not recommend that, unless you know well how the Armbian bootloader and scripts work, i.e. which files/dirs they are looking for etc.

Sorry, I did not know dash.
Armbian : you are right, it worked first time because of the reboot (I did not notice that), but after that, it has the same problem : wlan0 not present on cold boots, only on reboot, no difference.

About 6.6.31 : I just used the armbian-config menu which allows to choose different kernels, as I experienced in the past that it installs the proper headers. This is just for infomation, because Armbian is not interesting if the WiFi problem is the same.

About R5S / R5C, the last images of Dietpi work very well (with the limit of the discussion above for R5C). I was able to compile an app with the headers present. But now I must compile a kernel module, and this requires additional stuff, because the system complains about the missing /lib/modules/6.6.32-current-rockchip64/build.
Where can I find the kernel files necessary to compile a kernel module ? I prefer to ask you, because you will know what are the proper files.

If you can switch images I‘d recommend you to switch to the Armbian built ones as they’re a better “dev environment” and have proper repo‘s for all the kernel related stuff. (I use it myself at this point)

The DietPi image should also be based on their builder (not sure what the update interval is) but I‘m not sure if updates etc. are also in sync with their system on DietPi.

Here you can find the Debian 12 one under the Server / IOT built: Nanopi R5S - Armbian or Nanopi R5C - Armbian

I checked with Armbian, but the problem is exactly the same :
make[1]: *** /lib/modules/6.6.32-current-rockchip64/build : no file or directory of this type. Halt.

To create this “build” directory, I need the kernel files for 6.6.31-current-rockchip64. But Armbian does not give them (or at least I didn’t find). I tried to use armbian-config to change to 6.6.35 (6.6.32 is not offered), same problem. The kernel files are not offered, only the modules, overlays and headers. They are installed by the .deb file found here :
https://mirrors.dotsrc.org/armbian-apt/pool/main/l/linux-6.6.32/

So, I came back to Dietpi and tried to get the 6.6.32 from kernel.org. It was then possible to build the module, but when I want to install it I get the error :

tlsfilter: version magic '6.6.32 SMP preempt mod_unload aarch64' should be '6.6.32-current-rockchip64 SMP preempt mod_unload aarch64'
insmod: ERROR: could not insert module tlsfilter.ko: invalide module format.

So I really need the kernel files 6.6.32-current-rockchip64, but I find them nowhere.

What I do to create the build directory is just :

  • Copy the config file from boot to the kernel files directory
  • make oldconfig
  • make modules_prepare
  • then in the module directory : make -C ~/kernel/linux-6.6.32

You can clone armbian/build from Github. While the 6.6 kernel is the upstream one Armbian applies some patches onto it. With the armbian/build tool you can download and compile the kernel source that you need

The answer of Micha was :

Good evening Dysmas,
the kernel headers can be installed with:
apt install linux-headers-current-rockchip64
Best regards,
Micha (aka MichaIng)
DietPi project lead

Simple, and it worked. After that install, the module built without problem.
But thank you for your answers, nevertheless, meco, it was kind of you.

@Averell7 I thought you had the kernel headers already and that’s why I was confused lol

Well, question was I thought also I had them ! But it was only the modules.

@Averell7 @Krophil just in case you might be interested knowing that the PCIe device detection issues seems to have been solved, by this commit: arm64: dts: rockchip: Fix rk356x PCIe range mappings · torvalds/linux@f63ea19 · GitHub

At least on the R5C I have that was affected by a missing PCIe Ethernet interface in like 95% of boots, they are now all present reliably, and the commit touches the very code sections we were looking at as possible culprit, sadly only figuring out half of the needed fix that time.

I am optimistic that this really was the main reason for a lot of random PCIe device detection issues that we have seen across a lot of RK356x boards, but I am curious see some verification. The kernel update is on our APT server since a few days, i.e. apt update && apt upgrade.

I was busy by the General Chapter, that is why I can test only now. I will try on R5C, no problem to upgrade, since I have no device in production.

For,the R5S they are in production and it is not possible to change too much. Here the PCIe issue concerns the NVMe SSD which is not recognized. I tried an upgrade, and it requires important fixes afterward, impossible to do on the devices in production.

Gemini says it is only the dtb which changes. I can copy the new and update directly the file. But there is surely some recompilation to do ?

You mean fixes regarding the kernel? Which kernel is it using currently?

You mean only the dtb requires a fix? If so, that fix would be very good to know. You usually cannot use a dtb from a much older kernel version or different branch with a newer version. Maybe a single dtb change fixes things, but it was applied on a very different dtb. So we’d need to apply this fix as a patch in our kernel sources.

I btw faced the issue again on my R5C. Before the kernel upgrade after which I did the last comment here, like 9 of 10 or 19 of 20 boots ended up with just a single Ethernet port loaded. After the upgrade, I did 5 reboots or so, with both Ethernet ports functional every time, hence I thought it was fixed. And with the commit I found which touched the very things we guessed being the culprit, it all made sense. But on more recent tests, I faced the missing Ethernet port again. It happens much less often, and also it seems to be functional when the device is cold, and happens more often when it heated up/reached production temperature. I faced such temperature-dependent issues on another SBC in another context, I think it was an onboard WiFi adapter, as if some resistor was too temperature sensitive, or a solder spot looses connectivity. Since various RK356x SBCs are/were affected by PCIe issues affecting various different devices, even on the very same SBC, a hardware weakness on the PCB however seems unlikely.

The proposal of Claude is interesting but i have not tested it yet :

Option 1 — Patch DTB à la main (pas de mise à jour kernel)

C’est 3 lignes à modifier dans le DTB compilé. Le diff exact du commit est :

# rk3568.dtsi — pcie3x1 (pcie@fe270000)
- <0x03000000 0x0 0x40000000 0x3 0x40000000 0x0 0x40000000>;
+ <0x03000000 0x3 0x40000000 0x3 0x40000000 0x0 0x40000000>;

# rk3568.dtsi — pcie3x2 (pcie@fe280000)
- <0x03000000 0x0 0x40000000 0x3 0x80000000 0x0 0x40000000>;
+ <0x03000000 0x3 0x80000000 0x3 0x80000000 0x0 0x40000000>;

# rk356x-base.dtsi — pcie2x1 (pcie@fe260000)
- <0x03000000 0x0 0x40000000 0x3 0x00000000 0x0 0x40000000>;
+ <0x03000000 0x3 0x00000000 0x3 0x00000000 0x0 0x40000000>;

Procédure :

bash

# Copie de sauvegarde
cp /boot/dtbs/$(uname -r)/rockchip/rk3568-nanopi-r5s.dtb \
   /boot/dtbs/$(uname -r)/rockchip/rk3568-nanopi-r5s.dtb.bak

# Décompiler
dtc -I dtb -O dts \
  /boot/dtbs/$(uname -r)/rockchip/rk3568-nanopi-r5s.dtb \
  -o /tmp/r5s.dts

# Éditer /tmp/r5s.dts (les 3 lignes ci-dessus), puis recompiler
dtc -I dts -O dtb /tmp/r5s.dts \
  -o /boot/dtbs/$(uname -r)/rockchip/rk3568-nanopi-r5s.dtb

Redémarrer, et le fix est actif sans toucher au kernel.

The explanation given is:

What this fix does

The `f63ea193` commit corrects the PCIe `ranges` mappings in the RK356x DTS files: the PCIe bus address must be mapped 1:1 to the CPU-side MMIO address; otherwise, the same address may be allocated from normal system memory, which breaks DMA for the endpoints. [github]( arm64: dts: rockchip: Fix rk356x PCIe range mappings · torvalds/linux@f63ea19 · GitHub )

Specifically, this is a fix in the **Device Tree Source** (`.dtsi`) files, not in the C kernel code—which has significant implications for updating.