Creating a Linux distribution

The example Linux user distribution is built using Buildroot. In this section we’ll create a new Linux distribution based on the example Linux user distribution. The new user Linux distribution will have a new application, the Hello ACU6 application, as well as a few other customizations shown in this guide.

First of all, this guide does not go into detail about how to use Buildroot. Please read the Buildroot documentation for more details.

Project template

To save you some typing there is a template project included at this zip file. Extract it to a root directory somewhere on your development machine.

The basic folder structure is layed out as:

├── externals
│   └── myproj
│      ├── Config.in
│      ├── configs
│      ├── external.desc
│      ├── external.mk
│      └── package
├── files
│   ├── sign.sh
│   ├── user-product-number.txt
│   └── user-software-version.txt
├── Makefile
└── sdk

externals is for the br2-external trees with customizations, configurations and software packages specific for this project. In the template a single br2-external tree called myproj is provded as an example.

files is for customization files that are necessary for your integration, such as signing scripts, version configuration and keys.

Lastly, the sdk subdirectory is where the Actia ACU6-Pro SDK should be extracted. Keeping the SDK separated from any project specific code and customizations makes it easier to both keep a good structure and to update to a newer SDK version when one is released.

Before the template project can be compiled a few steps must be performed:

  1. Extract the ACU6-Pro SDK zip file into the sdk directory. After extracting it should look like:

    sdk
    └── acu6-pro-sdk-vX.Y.Z
    
  2. Write your device’s Maintenance password into a file called device-password.txt in the files directory. The password is needed for flashing the device using the debug USB port.

    Note

    If you do not have the password, you can request it from Actia. You need to provide the device’s UUID. The UUID can be retrieved using make uuid or by scanning the big QR code on the device label.

  3. Write your user software product number into user-product-number.txt in the files directory. The user software product number is a string on the form AAAA-BBB-CC provided by ACTIA that identifies the user software.

    Note

    While not required during development, it is expected that software used in production contains this identifier. Before a user software product number has been provided by ACTIA the default of 0000-000-00 shall be used.

  4. Write the version of your software to user-software-version.txt in the files directory. The version is expected to follow Semver.

  5. Place your keystore and private key file in the files directory. The name of

    the keystore should should match the glob *keystore*.bpak, and the private key should match the glob *.pem.

  6. Configure the example Linux distribution to use the default Actia configuration.

    $ make defconfig
    
  7. Configure and build the initial image by running

    $ make
    

    Building the initial image takes between a few minutes and upwards of half an hour depending on how powerful computer is used for building and Internet bandwidth. When it is done the final output should be

    user-bundle/
    user-bundle/user_boot.bpak
    user-bundle/user_rootfs.bpak
    user-bundle/user_keystore.bpak
    MANIFEST
    Final output provided in <path>/output/images/user-bundle.tar
    make: Leaving directory '<path>/output'
    make[1]: Leaving directory '<path>/sdk/acu6-pro-sdk-vX.Y.Z'
    
  8. Make sure the ONSW signal is on. (Without ONSW, the device will suspend if no application has requested power.)

    Note

    If the make command fails and you are using VirtualBox, you should add the USB device Punch BOOT to the USB Device Filters list. To get to the add device view, right click on your virtual machine and then click Settings -> USB.

    $ make shell
    $ ./utils/onsw.sh on
    $ exit
    
  9. Flash the initial image to the ACU6-Pro OH device by executing

    $ make flash
    
  10. Connect to the ACU6-Pro device with SSH and print build information. The build time should be close to the current UTC time.

    Note that the first SSH connection attempt will take longer time, as the example Linux distribution generates its SSH keys on the first connection.

    Note

    If you can flash the device but cannot connect via SSH, try toggling the power.

    $ ssh acu6pro
    # uname -a
    Linux buildroot 6.1.14 #1 SMP Thu Dec 19 09:10:58 UTC 2024 aarch64 GNU/Linux
    #
    
  11. To test Internet connectivity, request the cellular service and ping the Google DNS (8.8.8.8).

    It takes up to a minute for the ACU6-Pro device to connect to the cellular network and get an Internet connection, so be patient.

    # modemcontrol-demo request
    # ping -c 3 8.8.8.8
    PING 8.8.8.8 (8.8.8.8): 56 data bytes
    64 bytes from 8.8.8.8: seq=0 ttl=51 time=204.807 ms
    64 bytes from 8.8.8.8: seq=1 ttl=51 time=203.942 ms
    64 bytes from 8.8.8.8: seq=2 ttl=51 time=194.986 ms
    
    --- 8.8.8.8 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 194.986/201.245/204.807 ms
    #
    

Enabling the hello-acu6 application

Now that the initial image has been built and loaded it can be modified. The easiest form of modification or customization is to enable (or disable) a package that is included with a br2-external tree, either ones provided by Actia or ones developed by you the user.

Included in the myproj br2-external tree is a package called hello-acu6, lets enable it.

  1. First reset the configuration by

    $ make defconfig
    
  2. Open the graphical configuration menu

    $ make menuconfig
    

    Navigate to External Options -> My Custom ACU6 project and then select the hello-acu6 package (ensure there is a [*] in front of it). Exit and save the configuration.

    The updated configuration will be saved to output/.config file, and can be built and flashed as above.

  3. Optional Save the new defconfig back to externals/myproj/configs

    To make the changes of the configuration permanent you could either copy the output/.config file to externals/myproj/configs/myproj_defconfig however this file will contain many redundancies and things set to their default value. To help saving a minimal defconfig Buildroot provides a helper target that can be accessed by

    $ make savedefconfig
    

Modifying the hello-acu6 application

A second level of modification is to modify the source of the hello-acu6 application. To do that, open the source file from externals/myproj/package/hello-acu6/files/hello.c in your favourite text editor and add a second print command, for example like the following

// Copyright (C) 2023 Actia Nordic AB. All rights reserved.

#include <stdio.h>

int main(void)
{
   printf("Hello ACU6 User\n");
   printf("This is hello-acu6 calling\n");

   return 0;
}

Now if you try to build it using only

$ make

as before, you will notice that nothing gets rebuilt.

This is the result of an unforutnate limitation in Buildroot where it does not consider local source files referenced in packages as dependencies that will trigger an automatic rebuild. To force a rebuild of the hello-acu6 packet the following sequence needs to be used, which first removes the compiled result for only the hello-acu6 package and then rebuilds all required parts of the full image.

$ make buildroot-hello-acu6-dirclean
....
$ make

Starting hello-acu6 on boot

As a last step, lets add hello-acu6 so it is started automatically when the system boots. There are a few different ways this can be done, however here one of the simplest will be shown.

  1. In the externals/myproj/package/hello-acu6 directory, create a new file named S60hello-acu6 and make the content be

    #!/bin/sh
    #
    # Start the hello-acu6 program on startup, and send any output to syslog
    #
    
    case "$1" in
    start)
       echo "Starting hello-acu6..."
       hello-acu6 | logger -s -t hello-acu6
       ;;
    stop)
       ;;
    restart|reload)
       ;;
    *)
       echo "Usage: $0 {start|stop|restart}"
       exit 1
    esac
    
    exit $?
    
  2. Modify the file externals/myproj/package/hello-acu6/hello-acu6.mk and add the following at the end, but before the $(eval …) call

    define HELLO_ACU6_INSTALL_INIT_SYSV
       $(INSTALL) -D -m 0755 $(HELLO_ACU6_PKGDIR)/S60hello-acu6 \
          $(TARGET_DIR)/etc/init.d/S60hello-acu6
    endef