NI Linux Real-Time and opkg: Distributing Packages

Introduction

Oftentimes it can be desirable to extend the functionality provided by the Linux kernel and have access to other custom packages. This document will discuss how to create, package, and test loadable packages with NI Linux Real-Time.

A Note on Support

This document is meant as a walkthrough of general Linux concepts within NI Linux Real-Time. As these concepts are general to any Linux system and the open source software used, NI Support will not provide assistance through Technical Support channels should problems be encountered. NI does not provide official support for modifying the kernel such as through the addition of loadable kernel modules. For more information on how NI provides support for NI Linux Real-Time, refer to the NI Linux Real-Time FAQ. If problems are encountered, posting to the NI Linux Real-Time Community or other Linux discussion boards is the recommended way to get further guidance.

Requirements

The following software and hardware are required to follow this tutorial:

  • NI Linux Real-Time System with one of the following access to the online NI Repositories

  • Source for a Linux Package

    • NI recommends using the “Hello, World!” source available here for this tutorial, however one can use your own source or even pre-built shared libraries.

Opkg

Opkg is a light-weight package manager which uses the *.ipk format to install and manage packages on a filesystem. While slightly different, *.ipks are very similar to *.deb packages and are based on that standard. Due to the lightweight nature of opkg and its basis on a standard Linux package type, NI chose to use opkg as the package manager for NI Linux Real-Time.

This tutorial will cover the steps needed to use the opkg and opkg-build commands to create a package for distribution. *.ipks can be created on any system with opkg-build installed. For simplicity, this tutorial uses a Linux Real-Time system. For more information on opkg, refer to the official documentation.

Configuring the System

Before starting, the required software and toolchains must be installed to the NI Linux Real-Time system used. This can be accomplished through console access to the device via a serial port, SSH, or direct access via a keyboard and monitor. For the screenshots in this tutorial, SSH is used via PuTTY.

  1. Open a console to the NI Linux Real-Time system and log in as or switch to the admin user.

  2. Run the opkg update command to refresh the list of available packages. .. code:: bash

    opkg update

  3. Install the opkg-utils package to install the required tools for creating *.ipks. .. code:: bash

    opkg install opkg-utils

  4. Confirm that the installation completed successfully.

Source Files

To demonstrate building and testing a package, this tutorial will use a simple “Hello, World!” example. While this same process will apply to any package, NI recommends walking through the process for this simple module before moving to more complex designs.

The source for this “Hello, World!” package will consist of three main files:

  • helloworld.c – The C source code

  • CONTROL - The control file for the package

  • debain-binary - The debian-binary file

helloworld.c

This is C source code for a simple “Hello, World!” program.

#include <stdio.h>

int main()
{
  printf("Hello, World!!! \\n");
  return 0;
}

If you want to compile the source on the target, you could do so using the gcc toolchain:

gcc –o hello helloworld.c

Note: if you are following this tutorial and compiling on target, make sure to install the compile tools which will allow you to use gcc.

opkg install gcc binutils gcc-symlinks

At this point, you now have an executable called hello.

Creating the Package File

With the source in hand, the next step is to package it into an *.ipk for redistribution. As mentioned previously, *.ipks are very similar to *.deb packages and are based on that standard. For more information on creating *.ipks and the options for doing so, NI recommends referring to the official documentation for opkg and opkg-build.

Directory Structure

To create an *.ipk file, everything must be in the proper directory structure. For this tutorial the following directory structure will be used.

hellopkg
|-- CONTROL
|   `-- control
|-- debian-binary
`-- usr
    |-- bin
    |   `-- hello
    `-- lib

This mirrors the final structure contained in the built package, which is simply a special compressed form of that directory structure. As covered in the official opkg documentation, an *.ipk requires a few things with the other items being optional:

  1. A CONTROL directory with a control file. .. note:: Keep in mind that Linux is case sensitive.

  2. The data files to be installed in their proper directory structure.

The optional components required for a package are:

  1. A postinst script, to register the kernel module with DKMS following the installation.

  2. A prerm script, to remove and unregister the kernel module from DKMS prior to removal.

For more information on *.ipks and these files, refer to the official documentation and man pages for opkg. To proceed with this tutorial, recreate the file structure shown above on the NI Linux Real-Time system with the files provided for this tutorial.

Control File

The control file describes the package’s dependencies, maintainer, name, version, and other information required by opkg to ensure proper installation. Much of this information will also be returned if the opkg info command is run on a built or installed package.

Package: hellopkg
Version: 1.0.0
Architecture: x64
Maintainer: "somebody" <somebody@somewhere.com>
Description: hello world
Source: helloworld.c
Priority: optional
Section: libs

The debian-binary File

This file should be a text file containing only the following line, as described by the *.ipk standard.

2.0

Scripts

As mentioned previously, there are two optional scripts when creating *.ipk files for installing packages. These scripts handle the registration, installation, and removal of files during installation and removal of the package.

Note

In order to build a package, all scripts must have executable privileges. To ensure that this is the case, run chmod a+x <script> before attempting to build a package.

preinst

The preinst script will be run before the installation of the package files.

postinst

The postinst script will be run upon finishing the installation of the package files.

premrm

The prerm script will be run by opkg before any files are removed during package removal.

postrm

The postrm script will be run by opkg after files are removed during package removal.

Building the Package

Once the directory structure is in place, all that’s necessary is to build them into an *.ipk package.

  1. Change directories to the directory containing the top-level directory for the package. In this case, the directory containing the hellopkg/ directory.

  2. Run the opkg-build command on the package directory.

  3. Confirm that the *.ipk file is now present.

Building the Feed

If you wish to turn the directory into a feed, you can perform the following step to generate Packages and Packages.gz files.

  1. Run opkg-make-index –p Packages Packages

  2. From there, you can put these files onto a HTTP/S web server to access the feed remotely.

At this point, NI recommends testing the package on a different system from the one it was originally built on or testing by formatting the system used to create the *.ipk and installing from scratch. You can simply transfer the ipk to the target, and then install it using opkg.

A Note for More General Use Cases

The tutorial above just walked through the steps for building an ipk that includes a Hello World executable. If you want to apply this to an ipk that will include various shared libraries, you can still follow the steps above, and use the tree structure. For example:

examplepkg
|-- CONTROL
|   `-- control
`-- usr
    |-- bin
    |   `-- exampleexe
    `-- lib
        `-- example.so

Once you have the tree structure in place, you can follow the rest of the steps in the tutorial. For installing from the OS package manager, it is best practice to install shared libraries to /usr/ directories. It is best practice to use /usr/local/ for things not managed by opkg

Resources