Testing deployment on Raspberry PI model 1 B+

Hello,

I was evaluating balena on my (old) Raspi model 1 B+ - the device looks to be supported.

I clone and deploy the sample hello-world application and I expect but fil to see in the logs the “hello, raspberry pi” line.

Logging into the container and running by hand the hello executable gives me back a segfault.

I’m confused about what should I do to make it work.

Does anybody has experience with deploying on Model 1? I underlie and am very specific about that because it is a pretty different device from other more recent Raspis.

EDIT: forgot to mention that the project I’m trying to run is:

Thanks for any hint on this issue!

It may be that your container images are being built on our builders, which are armv8, and therefore your device is being sent container images with binaries for the wrong architecture (RPI 1 B+ uses the ARM Cortex-A7 processor which is armv7).

In writing our rust-hello-world app, we had to do some tricks like changing the uname -m output, which rust depended on to set the right build architecture. You can see that script gets called from the Dockerfile and reacts to the %%RESIN_ARCH%% .template file meta-variable.

Which hello-world repo are you basing your project on?

Hi, thanks for the feedback.

you mean armv6? I’m always confused by ARM architectures, but from the balena CLI I see this:

# cat /proc/cpuinfo
processor       : 0
model name      : ARMv6-compatible processor rev 7 (v6l)
...

The hello-world Rust project I’m trying to run is this:

This seems odd. You’re deploying the same project I linked above, the one with the detection of architecture for compilation, so that shouldn’t be a problem.

Now, both the manufacturer website and wikipedia list the ARM Cortex-A7 as armv7. One wonders, then, why /proc/cpuinfo is reporting ARMv6.

Ah, it seems the CPU model for the 1 B+ is not Cortex-A7. Per Wikipedia, it should be an armv6 cpu, so we’re at least in a sane world for now.

According to the docs (“Define a container - Dockerfile templates”), when you deploy using a Dockerfile.template file, the type of the app you deploy to determines the RESIN_ARCH variable, which is going to be used by modify-uname.sh to hint the compiler by changing the uname in the builder. An app with device type “Raspberry Pi (v1 and Zero)” will have the variable contain rpi, which you can see maps to armv6l in the script. So the issue isn’t there, either.

I think next step should be to check the binary:

readelf -a ${whatever the executable is called} | grep -i Machine

Have you modified the code in any way which might lead to a segfault? Just sanity-checking here.

As another sanity check, it’s worth checking that the application type is “Raspberry Pi (v1 and Zero)”

ok @dt-rush here some answers:

  • I had switched to rust nightly, now I came back to stable and now when I run the executable I get an “Illegal instruction” so we are 100% sure that the binary is compiled for the wrong architecture

  • I’ve inspected a bit the ELF and it looks ok:

$ readelf -a hello | grep -i machine
  Machine:                           ARM
$  file hello
hello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=205..., not stripped

However I have a hint for you here: I tried crosscompiling for Rasberry Pi one and I’ve encountered the same weird error.

In the Rust world you can crosscompile for Raspberry PI Model 1 using one of these two targets:

  • arm-unknown-linux-gnueabihf (hard floating point unit)
  • arm-unknown-linux-gnueabi

The armv6 arch has indeed a hardware floating point, but the -hf failed on my containers with the same “Illegal instruction” error. I had to compile for the other architecture.

I suspect that your armv8 builders are using the arm-unknown-linux-gnueabihf target, thus producing the wrong binary.

Sorry for the lenghty explaination, I’m not sure the two things are connected, but I hope this will shed some light.

This is odd as arm-unknown-linux-gnueabihf target should be working fine on the RPi 1. Our WiFi Connect project compiles with this target and is running fine on it.

This may have to do with the cross-compilation toolchain. The Debian one had problems in the past with armv6 and produced armv7 binaries instead, so we had to use the Raspberry one. It could be a different cause though.

I will double check the Rust hello world build on the RPi 1 to see what happens.

I can confirm that the Rust hello world application is segfaulting on the RPi 1. I will post more information once we have an answer.

It is compiled as an armv7 binary:

root@a92f62a:/app# readelf -A hello
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_FP_arch: VFPv3-D16
  Tag_ABI_PCS_GOT_use: GOT-indirect
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6
  Tag_ABI_FP_16bit_format: IEEE 754
1 Like

I am debugging this now and it looks like something has changed in the rustup installer. We are downloading an armv6 installer, which installs an armv7 toolchain. Will look into the installer source code to see how it determines the toolchain to be installed.

Here is the tracking issue for this problem:

We should be able to resolve it soon.

1 Like

I’d like to inform you that we’re correctly reporting architecture on our ARM builders now (+ couple of other issues were fixed as well) and the Rust installer is downloading the proper toolchain. Can you test it? Should work for you now.