Showing posts with label embedded. Show all posts
Showing posts with label embedded. Show all posts

Tuesday, January 05, 2021

Ethernet on the BananaPi M2 Zero

Even though it does not look like it does, the BPI-M2 Zero also has a wired ethernet interface. Unfortunately, it is disabled by default in its device tree blob.

But enabling it is easy:

# copy into /root
cp /boot/dtb/sun8i-h2-plus-bananapi-m2-zero.dtb .
# decompile
dtc -I dtb sun8i-h2-plus-bananapi-m2-zero.dtb \
    -O dts -o sun8i-h2-plus-bananapi-m2-zero.dts
# edit
vi sun8i-h2-plus-bananapi-m2-zero.dts # :-)
# compile
dtc -i dts sun8i-h2-plus-bananapi-m2-zero.dts \
    -O dtb -o /boot/custom.dtb
How do you need to edit the DTB file?

In the "ethernet@1c30000" block, you need to apply this "diff":

-       status = "disabled";
+       status = "okay";
+       phy-handle = <0x4d>;
+       phy-mode = "mii";
        phandle = <0x4b>;

The "phy-handle" value is taken from the "phandle" of the "ethernet-phy@1" block a few lines down. Then another change is adding an alias for ethernet0 to the "aliases" block:

       aliases { 

              serial0 = "/soc/serial@1c28000";
              serial1 = "/soc/serial@1c28400";
+             ethernet0 = "/soc/ethernet@1c30000";
       };

Ethernet will work without that, but we'll need this for setting the MAC address later.

Now reboot and try it out in a temporary way. Either by:

  • interrupting u-boot and doing setenv fdtfile custom.dtb (no "saveenv" yet!), then "boot"
  • editing the GRUB menu, adding an additional line after "initrd..." that reads devicetree /boot/custom.dtb
Check if the ethernet device eth0 appears after boot. If it does, the u-boot method can be persisted by issuing a saveenv command after the setenv.

Persisting the MAC address:
At my first tries I noticed that the MAC address was randomly assigned on every boot, in later experiments I could not reproduce this anymore but it looked like the MAC was at least reassigned on every deployment. I have no idea if this has to do with saving the environment in u-boot or if there is something in the userspace (a systemd service maybe?) that makes the MAC address semi-persistent. I decided to fix the MAC address once and for all, since I'm running a static DHCP setup, this is pretty important for my use case.

Because of the "ethernet0" alias in the device tree, persisting the MAC address is easy. All you need to do is setenv ethaddr 22:33:44:55:66:77 in u-boot and then persist this with saveenv and you are done. Note that u-boot has some precautions to disallow changing the MAC address later by accident so you are not able to easily undo this later. You can always remove "/boot/efi/uboot.env" in your booted system or by inserting the SD card into another machine and start from scratch.

Sunday, January 03, 2021

GRUB, u-boot, kernels and DTB loading (on the BPi M2 Zero and others)

While I was experimenting with the BananaPi M2 Zero board, I soon needed to adopt its device tree file (dtb).

Fortunately, the friendly members of the openSUSE:Factory:ARM community quickly hinted me at the grub2 "devicetree" command which can be specified similar to "linux" or "initrd" to name a file that's loaded as device tree.

Unfortunately, there is no way to make this really persistent, short of editing the grub generator scripts which will get lost on every grub2 update.

The other option would be to decompile the board's DTB file ("/boot/dtb/sun8i-h2-plus-bananapi-m2-zero.dtb" in my case), change and then recompile it, replacing the original file. This has two downsides: first, it will get overwritten with every update of the "dtb-sun8i" package (no idea how often this will be the case) and second, you might want to have the original file as fallback ready. In general, editing package managed files is not a good idea in my book, if it can be avoided it should be.

So I looked into the "who loads which device tree file" and found out that actually the dtb is loaded by u-boot, even before grub starts. U-boot has the name of the board built-in and thus the file name it is looking for. Additionally it has a search list of directories that it searches to find the dtb file. So the simplest way to apply your own dtb file would probably be to put it, with the original file name into the search path after the original file. I tried this approach at first, but then went for explicitly specifying a different filename, which is just not as subtle in case you need to debug this years later ;-)

So the method is relatively easy:

  1. put your modified dtb file into /boot, I named it custom.dtb.
  2. boot into u-boot, interrupt booting on the serial console
  3. in u-boot console, enter setenv fdtfile custom.dtb
  4. in u-boot console, enter saveenv
That's it. Now boot and verify that your dtb file is used.

Note that the u-boot environment is saved on the EFI partition of the SD card (first partition, FAT format) as file "uboot.env". If you need to reset the environment to the built-in defaults, then you can always mount the SD card in another machine and move away or delete uboot.env.


Saturday, January 02, 2021

openSUSE Tumbleweed on the Banana Pi BPI-M2 ZERO

This is the first post of a small series about openSUSE on the Banana Pi BPI-M2 ZERO.

Preface

I recently got myself a Banana Pi M2 Zero board while ordering other stuff at an electronics distributor. The M2 zero is the same form factor and feature set as the Raspberry Pi Zero W (the GPIO pin headers are said to be compatible, it has WiFi and Bluetooth built in and an USB OTG port). The CPU is an Allwinner H2+, a quad-core ARM processor running a 1GHz clock speed, RAM size is 512MB. Processing power is probably comparable to a Raspberry Pi 2 board.

I bought the M2 Zero to use it with an RTLSDR stick to receive the signal of my outside RF temperature sensor. This worked with the Raspberry Pi Zero W, but was a bit too much for the slower CPU which has other more important things to do anyway (playing internet radio ;-), so the M2 Zero was a cheap, more powerful alternative. The box will be running headless and thus I do not care about support for graphics and multimedia anyway.

In the end, I switched the RF receiver to a RaspyRFM board whih is using less energy and simpler to use than an RTLSDR stick just to receive some sensors and now the M2 Zero board is free for tinkering...


openSUSE on the M2 Zero

There was already an image available for the Banana Pi M2 Plus (called "sinovoipbpim2plus"), which is the "bigger brother" of the M2 zero, but that image did not boot. Experimenting with the u-boot image from armbian lead to success in "openSUSE Tumbleweed boots with armbian u-boot". Thanks to the friendly openSUSE ARM community, a matching u-boot version for the M2 Zero was built quickly and I could submit the updated image in OBS to get an image ready for the board (called "sinovoipbpim2zero").

Some small things are still to be sorted out, this is why I would suggest you use the image from the home:seife:bananapi repository for now. Since the board has only WiFi networking (more on that in a later post...), you'll need a serial console wired up for initial setup and I strongly suggest to use at least the "openSUSE-Tumbleweed-ARM-X11-..." image and not the JeOS image, since JeOS does not contain NetworkManager and using WiFi with wicked (actually using anything with wicked) is not fun.

So put the image on the SD card, connect the serial console, boot the box up. Log in as root. WiFi connection is easily established then:

nmcli dev wifi connect YOUR_SSID password YOUR_PASSWORD

That's it, have fun! ;-)



Addon note: When I started to write this post, my home:seife:bananapi repo was necessary for actually getting WiFi to work (contained a fixed kernel-firmware package). This has all been submitted to upstream or openSUSE:Factory:ARM now. All that's "special" in my repo now is a slightly extended package selection in the image (the "dtc" package is included) and a fixed config.sh script that makes NetworkManager actually work correctly, including name resolution, see boo#1180234 for details), so the image from openSUSE:Factory:ARM should be "good enough" for most uses already and in the near future I'll probably retire the home:seife:bananapi project or use it just for development stuff).

Saturday, November 15, 2014

Switching from syslog-ng to rsyslog - it's easier than you might think

I had looked into rsyslog years ago, when it became default in openSUSE and for some reason I do not remember anymore, I did not really like it. So I stayed at syslog-ng.
Many people actually will not care who is taking care of their syslog messages, but since I had done a few customizations to my syslog-ng configuration, I needed to adapt those to rsyslog.

Now with Bug 899653 - "syslog-ng does not get all messages from journald, journal and syslog-ng not playing together nicely" which made it into openSUSE 13.2, I had to reconsider my choice of syslog daemon.

Basically, my customizations to syslog-ng config are pretty small:

  • log everything from VDR in a separate file "/var/log/vdr"
  • log everything from dnsmasq-dhcp in a separate file "/var/log/dnsmasq-dhcp"
  • log stuff from machines on my network (actually usually only a VOIP telephone, but sometimes some embedded boxes will send messages via syslog to my server) in "/var/log/netlog"
So I installed rsyslog -- which due to package conflicts removes syslog-ng -- and started configuring it to do the same as my old syslog-ng config had done. Important note: After changing the syslog service on your box, reboot it before doing anyting else. Otherwise you might be chasing strange problems and just rebooting is faster.

Now to the config: I did not really like the default time format of rsyslog:
2014-11-10T13:30:15.425354+01:00 susi rsyslogd: ...
Yes, I know that this is a "good" format. Easy to parse, unambiguosly, clear. But It is usually me reading the Logs and I still hate it, because I do not need microsecond precision, I do know in which timezone I'm in and it uses half of a standard terminal width if I don't scroll to the right.
So the first thing I changed was to create /etc/rsyslog.d/myformat.conf with the following content:
$template myFormat,"%timegenerated:1:4:date-rfc3339%%timegenerated:6:7:date-rfc3339%%timegenerated:9:10:date-rfc3339%-%timegenerated:12:21:date-rfc3339% %syslogtag%%msg%\n"
$ActionFileDefaultTemplate myFormat
This changes the log format to:
20141110-13:54:23.0 rsyslogd: ...
Which means the time is shorter, still can be parsed and has sub-second-precision, the hostname is gone (which might be bad for the netlog file, but I don't care) and it's 12 characters shorter.
It might be totally possible to do this in an easier fashion, I'm not a rsyslog wizard at all (yet) ;)

For /var/log/vdr and /var/log/dnsmasq-dhcp, I created the config file /etc/rsyslog.d/myprogs.conf, containing:
if $programname == 'dnsmasq-dhcp' then {
    -/var/log/dnsmasq-dhcp
    stop
}
if $programname == 'vdr' then {
    -/var/log/vdr
    stop
}
That's it! It's really straightforward, I really can't understand why I hated rsyslog years ago :)

The last thing missing was the netlog file, handled by /etc/rsyslog.d/mynet.conf:
$ModLoad imudp.so # provides UDP syslog reception
$UDPServerRun 514 # start syslog server, port 514
if $fromhost-ip startswith '192.168.' then {
    -/var/log/netlog
    stop
}
Again, pretty straightforward.
And that's it! Maybe I'll add an extra logformat for netlog to specify the hostname in there, but that would just be the icing on the cake.

What I liked especially on the rsyslog implementation in openSUSE (it might be default, but I don't know that) is, that the location of the "$IncludeConfig /etc/rsyslog.d/*.conf" is placed so that you really can do useful things without touching the distributions default config. With syslog-ng, the include of the conf.d directory was too late (for me), so you could not "split off" messages from the default definitions, e.g. the VDR messages would appear in /var/log/messages and /var/log/vdr. In order to change this, you had to change the syslog-ng.conf and this would need to be checked after a package update, and new distro-configs would need to be re-merged into my changed configuration.
Now it is totally possible that after an update of the distribution, I will need to fix my rsyslog configs because of changes in syntax or such, but at least it is possible that it might just work without that.

Thursday, September 25, 2014

Building Yocto/Poky on openSUSE Factory

Since a few weeks, openSUSE Factory no longer is labeled as "openSUSE Project 13.2", but as:
seife@susi:~> lsb_release -ir
Distributor ID: openSUSE project
Release: 20140918
When trying to build the current Yocto poky release, you get the following Warning:
WARNING: Host distribution "openSUSE-project-20140918" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.
Now I know these warnings and have ignored those before. The list of tested distributions is hard coded in the build system configuration and in general it would be a bad idea to add not yet released versions (as 13.2) or rolling releases. And since the Factory release number changes every few days, it is clearly impossible to keep this up to date: once you have tested everything, the version has increased already. But apart from this, purely cosmetic warning, there is a really annoying consequence of the version change: the configuration cache of bitbake (the build tool used by Yocto poky/OpenEmbedded) is rebuilt on every change of the host distribution release. Updating the cache takes about 2 minutes on my machine, so doing a simple configuration check on your already built Yocto distribution once a week can get quite annoying. I looked for a solution and went for the "quick hack" route:
  • bitbake parses "lsb_release -ir"
  • I  replace "lsb_release" with a script that emits filtered output and is before the original lsb_release in $PATH
This is what I have put into ~/bin/lsb_release (the variable check is a bit of paranoia to let this only have an effect in a bitbake environment):

#!/bin/bash
if [ -z "$BB_ENV_EXTRAWHITE" -o "x$1" != "x-ir" ]; then
        exec lsb-release $@
fi
printf "Distributor ID:\topenSUSE project\nRelease:\t2014\n"

Then "chmod 755 ~/bin/lsb_release" and now the warning is
WARNING: Host distribution "openSUSE-project-2014" has not been validated...
And more important: it stays the same after updating Factory to the next release. Mission accomplished.

UPDATE: Koen Kooi noted that "Yocto" is only the umbrella project and what I'm fixing here is actually the "poky" build system that's part of the project, so I edited this post for clarity. Thanks for the hint!