Running the Embox RTOS on Banana Pi M1

I learned about this operating system on this resource, from numerous publications by its developers. For those who are not in the know, this is a domestic open-source real-time operating system for embedded devices. Her The official repository is located here. There was a desire to try this project in action. Thanks to the project documentation, we were able to run configurations for different platforms on the qemu virtual machine. However, a virtual machine is not for real Jedi).

Having carefully studied the list of supported single-board devices, I chose the Banana Pi M1 with the Allwinner A20 ARM processor. The board was ordered from Aliexpress and when it arrived it was time to experiment. But, as expected, everything turned out to be not so simple…

1. Installing the bootloader

The developers have a publication about running Embox on Rasbery Pi. However, when I got acquainted with it, I was slightly disappointed. The fact is that it first installs the Rasbian Linux distribution, and then by manipulating the kernel images, instead of the Linux kernel, the U-boot boot loader is given the Embox image. At least that’s how I understood it. I wanted something else – to set up U-boot and install Embox, setting up the bootloader, without any installation of Linux (although I also tried this option, but it didn’t work). In my research, I relied on the materials of this publication.

So, first of all we get the bootloader code with official repository on Github

$ git clone https://github.com/u-boot/u-boot.git u-boot

Next, you need to get a toolchain for cross-compilation for the target platform. You can take it right hereto make things easier, I’ll give direct link to download the toolchain that I used. Strictly speaking, this is a gcc compiler and other equipment for assembly for the 32-bit ARM platform, designed to work on the x86_64 architecture under GNU/Linux. In my case, the ArchLinux distribution is used. Therefore, I did it even simpler – installed the toolchain in the system from AUR repository

$ tar arm-linux-gnueabihf-gcc13-linaro-bin.tar.gz
$ cd arm-linux-gnueabihf-gcc13-linaro-bin
$ makepkg -si

which results in the package being built and installed

Next, go to the directory with the u-boot code and set the build environment

$ CROSS_COMPILE=arm-linux-gnueabihf-
$ export CROSS_COMPILE

Now we configure the assembly for the target single-board

$ make Bananapi_defconfig  

exhaust

  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  YACC    scripts/kconfig/zconf.tab.c
  LEX     scripts/kconfig/zconf.lex.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#

shows us that the configuration has been completed. Next we assemble

$ make; make all

After compilation, we have the following files directly in the source tree

Result of U-boot bootloader compilation

Result of U-boot bootloader compilation

Now you need to prepare the media, which will contain the Embox image and the bootloader itself. The Banana Pi M1 is quite an old board, so it uses SD cards that were found in the pocket of the wife’s camera case. I “requisitioned” one of them for diabolical experiments)

Test bench.  USB <-> USART adapter connected and power via microUSB” title=”Test bench.  USB <-> USART adapter connected and power via microUSB” width=”2560″ height=”1920″ data-src=”https://habrastorage.org/getpro/habr/upload_files/cd1/11c/e16/cd111ce16db2d1b067225ca6df730cf7.jpg” data-blurred=”true”/></p><p><figcaption>Test bench.  USB <-> USART adapter connected and power via microUSB</figcaption></p></figure><p>The flash drive must be marked in a special way.  The markup looks like this</p><div><div class=

No. of the first sector

Section size

Purpose

0

8 KB

512 bytes for MBR and 7680 bytes for system needs

8

24 KB

SPL (Secondary Loader)

32

512 KB

U-Boot

544

128 KB

For U-Boot needs (storing environment variables, etc.)

672

352 KB

Reserved

1024

Is not limited

Available for creating sections

Naturally, you will also need a card reader. I have one on my laptop, but I perform cross-compilation on a desktop, whose capabilities are much wider than a laptop (i9-10900 KF vs Intel 2020M). That’s why. I decided to buy a USB card reader. Now we connect the card reader and insert the drive into it. Finding out the device name

$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    0   5,5T  0 disk 
├─sda1        8:1    0   128M  0 part 
└─sda2        8:2    0   5,5T  0 part /mnt/bigdata
sdb           8:16   0   2,7T  0 disk 
└─sdb1        8:17   0   2,7T  0 part /mnt/data
sdc           8:32   0   1,8T  0 disk 
├─sdc1        8:33   0   150G  0 part 
├─sdc2        8:34   0 195,6G  0 part 
├─sdc3        8:35   0     1T  0 part /home
├─sdc4        8:36   0     1K  0 part 
├─sdc5        8:37   0   100G  0 part 
└─sdc6        8:38   0 390,4G  0 part /home/maisvendoo/ntfs_part
sdd           8:48   1  59,3G  0 disk  
sde           8:64   1     0B  0 disk 
sdf           8:80   1     0B  0 disk 
sr0          11:0    1  1024M  0 rom  
nvme0n1     259:0    0 465,8G  0 disk 
├─nvme0n1p1 259:1    0   100M  0 part /boot/efi
├─nvme0n1p2 259:2    0   300G  0 part 
└─nvme0n1p3 259:3    0 165,7G  0 part /

In my case, the 64 GB flash drive turned out to be a device named /dev/sdd. Ok, let’s launch the markup program

# fdisk /dev/sdd

Create a new MBR table

Command (m for help): o
Created a new DOS disklabel with disk identifier 0xa53166ce.

To run Embox, we need one partition, 50 to 100 MB in size, formatted in FAT, to accommodate the bootloader script and the Embox image. Guided by the cheat sheet article, I created a 75 MB partition

Command (m for help): n   
       Partition type
          p   primary (0 primary, 0 extended, 4 free)
          e   extended (container for logical partitions)
       Select (default p): p
       Partition number (1-4, default 1): 1
       First sector (2048-7831551, default 2048): 2048
       Last sector, +sectors or +size{K,M,G,T,P} (2048-7831551, default 7831551): +75M

       Created a new partition 1 of type 'Linux' and of size 75 MiB.

Use the “w” command to write the changes to disk. Next we format this section

$ mkfs.vfat /dev/sdd1

Now we need to clear some space to place the bootloader. In this case, care must be taken not to overwrite the MBR – the first 512 bytes, and not to affect sector 1024 and beyond, based on the table above. We give the command

# dd if=/dev/zero of=/dev/sdd bs=1K count=1023 seek=1

The meaning of the spell: write zeros (device /dev/zero) to the SD card (device /dev/sdd) in blocks of 1 KB (bs=1K), up to 1023 sectors (count=1023) skipping the zero sector (seek=1)

Next, we write the secondary U-boot bootloader using its image located in the file u-boot-sunxi-with-spl.binobtained after compilation

# dd if=u-boot-sunxi-with-spl.bin of=/dev/sdd bs=1024 seek=8

We start recording from the eighth sector (seek=8), according to the marking table above. Ok, the bootloader is installed, you can turn on the board for the first time. Insert the SD card into the connector on the board, connect the USB <-> USART converter in accordance with the pinout

Connecting a USB <-> USART adapter based on the FL232RL chip to Banana Pi M1″ title=”Connecting a USB <-> USART adapter based on the FL232RL chip to Banana Pi M1″ width=”4500″ height=”6000″ data-src=”https://habrastorage.org/getpro/habr/upload_files/f03/911/589/f03911589e1b750f07f2f1ed3ea762bb.jpg” data-blurred=”true”/></p><p><figcaption>Connecting a USB <-> USART adapter based on the FL232RL chip to Banana Pi M1</figcaption></p></figure><p>Connect the terminal to USART</p><pre><code class=$ minicom -D /dev/ttyUSB0

We provide power to the “banana” and observe this kind of activity in the terminal

Booting U-Boot

Booting U-Boot

The system is alive, the bootloader is working! Further, he is literally trying to “reach out to heaven,” because he did not receive any instructions from us about what to load and where from.

U-Boot's unsuccessful attempts to find where to load the OS... Poor thing, but it's trying

U-Boot’s unsuccessful attempts to find where to load the OS… Poor thing, but it’s trying

But it’s not scary, the U-Boot system is smart, as I have seen more than once during the debugging process. Now we will teach him how to load Embox.

2. Building the Embox image

We go to the official project repository and do it in a convenient place in the file system

$ git clone https://github.com/embox/embox.git embox

And then I will begin to outline my ordeals. Guided by the rule of collecting a release, I switched to it

4 git checkout v0.6.0

Then, being in the root of the repository, we configure the assembly for our “banana”

 $ make confload-platform/banana_pi/bpi_m1

Exhaust

Config complete

tells you what you can collect

$ make -j20

Yes, yes, yes, I have 20 logical cores… However, during assembly you can have a smoke (smoking is harmful to your health, it’s better to drink tea), as a result, in the source tree we get directories build/base/bin and conf/. The first contains the build result

In the second, the build configuration configs were copied – they will come in handy later!

The OS image file – embox.bin, is designed to run on the target system. The embox file is a 32-bit ARM ELF file containing debugging information. So, what to do with the assembled kernel? We need to somehow force U-Boot to launch it.

3. Setting up loading the Embox kernel in U-Boot

The embox.bin kernel should be copied to the boot partition that we created, the same 75 MB FAT partition.

Having little knowledge of the subject area, I tried everything. Yes, I ran Linux via U-Boot on two Orange Pi models using the above article. But then the scythe found a stone. The trick of replacing the kernel image, as in the Raspberry developers’ publication, did not work. Yes, I did deploy Arch on the banana and it loaded fun and easy. Reconfiguring U-Boot did nothing. The problem was solved in several approaches with breaks, which was used – I’m ashamed to say and I won’t say. Along the way, I read the U-Boot docs, some commands worked adequately, but there was no download. Then I googled what exists telegram chat, where there are developers. There I asked a desperate “CHYAND!”

In response, I received a very quick response asking me to show the build configs. And then it dawned on me… While I was waiting for an answer, I found this this sample is for downloading BPI M2 Zero

It became clear that I was uploading the file to the wrong virtual address and was transferring control to the village to my grandfather. Where can I get this download address? Yes on file conf/lds.conf!

Linker configuration when building Embox for BPI M1

Linker configuration when building Embox for BPI M1

In general, armed with the information received, I switched U-Boot to command mode: at the message “Hit any key to stop autoboot:” with a countdown, press any button in the terminal. A command line prompt will appear. Further boldly typed

=> load mmc 0:1 0x43008040 embox.bin
611916 bytes read in 27 ms (21.6 MiB/s)

Ok, next

=> go 0x43008040

And lo and behold!

The Embox core casually announced the start of its loading and… froze… But this was already a victory. Next, I managed to boot into the BPI M2 Zero config, but the developers took into account the information received from me, advised me, made amendments to the code, and I managed to boot the system on my hardware configuration. In the end, this was expressed in a pull request that had not yet been accepted. I’ll provide the file for now platform/banana_pi/templates/bpi_m1/mods.conf, for a successful launch from my fork, taking into account the latest commits to the main repository.

Now let’s write a script to automatically boot the system. In the section of the flash drive where we put the kernel, we create a file boot.cmd following contents

load mmc 0:1 0x43008040 embox.bin
go 0x43008040

that is, we list the loading commands. The first one loads the image into memory at the specified address, the second one transfers control to the given address. Next we compile the download script

$ mkimage -C none -A arm -T script -d boot.cmd boot.scr

a binary file is generated boot.scr, which U-Boot looks for in the root of the boot partition and, parsing it, executes the commands listed there. In the end, we will get our desired result

Uploaded to BPI M!  Embox

Uploaded to BPI M! Embox

Acknowledgments

Many thanks to the guys from the Embox team, especially Alexey Zhmulin and Anton Bondarev for advice, information, efficiency and pleasant communication and interaction. As a result, a mutually beneficial problem was solved – I received a working system, the developers received a test on one of the hardware platforms. I hope this is not the last collaboration in this vein. The Embox project is interesting and not typical for Russian IT – openness and the absence of toxic communication is something that many domestic software developers could adopt. Good luck to the project, I will follow and support as best I can.

Thank you for attention!