Skip to content

Develop your Application

These are general guidelines for developing your application in Welma:

  • Compile and install your app into an app directory, which will be installed as the appro partition (mounted on /app).
  • Follow best practices in terms of cybersecurity
  • Have your application start automaticaly at boot
  • Use either the -dev or -dbg welma image (with SSH access)
  • Use remote debugging

Application partition structure

The application directory will become a system partition (appro). It is recommended to organize it in subdirectories. Eg:

  • app/bin: binaries
  • app/lib: libraries
  • app/etc: configurations
  • app/share: architecture-independent data

Ensure you manage the permissions (using chmod) so that the files have the appropriate access rights.

Cybersecurity recommendations

  • Do not let your app execute code from sysrw (/var), or it would break secure boot.
  • Avoid using the setuid bit.
  • Have your programs run as unprivileged users.
  • Isolate your processes in unprivileged user sessions.
  • Configuration recommendations of a gnu/linux system

Auto start application

You generally want to have your application start automatically at boot. Welma is using systemd to start services at boot time and systemd user instances are configured to look for systemd units in /app; see SYSTEMD_UNIT_PATH in the reference manual.

To that end, create:

  • app/lib/systemd/user/myapp.service: definition of the service
  • app/user/<uid>/systemd/user/default.target.wants/myapp.service: symbolic link that indicates that the service shall actually be started at boot.
    • <uid> being the identifier of the user that will run the service (0 for root, 2000 for the default unprivileged user in Welma)

See a more detailed example in Code, deploy and test using welma-update-gen.

Mender limitation

When using mender, the installation procedure will first extract the image (compressed by default) into /var/lib/mender. Therefore, be sure to have enough space in sysrw for that.

Debug with remote gdb

Reference: https://docs.yoctoproject.org/dev/dev-manual/debugging.html

In this chapter you should use the -dbg image (with SSH access and gdbserver).

The main steps of the setup are:

  • Have debugging symbols installed on the host;
  • Have cross gdb installed on the host;
  • Run gdbserver and gdb

To prepare the debugging symbols, add in local.conf:

IMAGE_GEN_DEBUGFS = "1"
IMAGE_FSTYPES_DEBUGFS = "tar.bz2"
IMAGE_FSTYPES:append = " tar.bz2"

On the host, run bitbake:

bitbake <image>
bitbake meta-toolchain

On the host, install debugfs:

$ mkdir debugfs
$ cd debugfs
$ tar xvf <build-dir>/tmp/deploy/images/<machine>/<image>-<machine>.tar.bz2
$ tar xvf <build-dir>/tmp/deploy/images/<machine>/<image>-<machine>-dbg.tar.bz2

On the host, install the SDK (in order to get $GDB). Reference: https://docs.yoctoproject.org/sdk-manual/using.html.

On the target, run gdbserver. For example either of:

# gdbserver localhost:1234 COMMAND
# gdbserver --attach localhost:1234 PID

On the host, run gdb. Example:

$ cd .../debugfs/..
$ $GDB
(gdb) set sysroot debugfs
(gdb) set substitute-path /usr/src/debug debugfs/usr/src/debug
(gdb) set substitute-path ../git/src debugfs/usr/src/debug/demo-headless-app/1.0.0-r0/git/src
(gdb) target remote 169.254.0.1:1234
...
(gdb) n
50              FILE *f_stat = fopen("/proc/stat", "r");
(gdb) n
51              if (!f_stat) return cpu_info;