Venice Board Support Package (BSP)
Gateworks provides a Board Support Package for Venice which provides source code and an easy mechanism to build different images, including a minimal Buildroot based distro as well as an Ubuntu based distro.
The Gateworks BSP is the easiest comprehensive software process because it contains everything. If a deep dive, expert path is desired, each piece of the BSP (boot firmware, rootfs, kernel) can all be built separately.
Notes:
- For pre-built images and instructions on installation see venice/firmware
- For details of Gateworks Ubuntu based OS for Venice see venice/ubuntu
BSP Source Code
Source code for the firmware, bootloader and kernel are hosted at GitHub. We highly recommend you create a GitHub account and 'Watch' these repositories to keep abreast of important feature additions, bugfixes, and firmware-releases. You can configure your GitHub account to e-mail you when changes are made to repositories here.
The following GitHub repos are used for Venice:
- https://github.com/Gateworks/bsp-venice - Venice BSP support scripts and Makefile (watch)
- https://github.com/Gateworks/manifest-venice - Venice BSP repo Manifest (watch)
- atf-venice - ARM Trusted Firmware (watch)
- uboot-venice - Venice Bootloader (watch)
- linux-venice - Venice Linux Kernel (watch)
Building the BSP from source
Below are instructions for building the entire BSP, which includes all of the bootloader components, Linux kernel, and Ubuntu. Pre-built images are available above.
The Gateworks Venice Board Support Package uses the Google git-repo tool to manage multiple code repositories.
The following pre-requisites are needed to build the Venice BSP:
- Linux Development host (desktop or laptop computer) (Ubuntu 16.04 is used by Gateworks and tested)
- Python 2.x (required by the 'repo' tool)
- Git (used for source code repositories)
- repo (used to manage multiple git repos)
NOTE: Building images requires root privileges
Installing pre-requisites:
# install packages sudo apt-get install build-essential git python3 python-is-python3 python3-setuptools python3-distutils python3-dev swig libssl-dev ncurses-dev kmod bison flex device-tree-compiler wget cpio unzip rsync bc fdisk file -y # configure git git config --global user.email "you@example.com" git config --global user.name "Your Name" git config --global color.ui true
Install the latest version of repo
(Do not rely on Ubuntu apt package being up to date):
sudo wget https://storage.googleapis.com/git-repo-downloads/repo -O /usr/local/bin/repo sudo chmod a+rx /usr/local/bin/repo
To obtain the code:
- Initialize repo (fetch the repo manifest)
mkdir $HOME/venice cd $HOME/venice repo init -u https://github.com/Gateworks/manifest-venice.git
- Sync repositories (repeat this when you want to fetch the latest code updates)
repo sync
- This will fetch/update the source repos described above. The first time it can take several minutes depending on your Internet connection and will take approximately ~3GB of disk space
- Setup build environment (*repeat this each time you open a shell*)
source setup-environment
- Build desired software target as defined below. For example:
make -j8 ubuntu-image # build <distro>-venice.img.gz compressed disk images
Working with the repo tool
The repo
tool unifies Git repositories into a single project by specifying Git repos and directories they exist in. The tool was created for the Android project as Android is comprised of hundreds of repos however it has since been used by many projects that benefit from its git repo management tool.
See:
- https://source.android.com/setup/develop#repo
- https://gerrit.googlesource.com/git-repo/+/refs/heads/master/README.md
- https://source.android.com/setup/develop/repo
Updating to the latest code (repo sync)
When working with the repo
tool you can update to the latest code using the repo sync
command:
$ repo sync Fetching: 100% (8/8), done in 5.258s Garbage collecting: 100% (8/8), done in 0.188s repo sync has finished successfully.
The repo
tool works off of a manifest file in .repo/manifests/default.xml
which specifies the various projects, what repo they are in, and where they are checked out in your directory structure. If a branch has changed, a project added, or a project removed the manifest file will be updated when you run repo sync
then it will update the various project repos. If a branch has changed to something new you can encounter an error such as:
$ repo sync remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0 Unpacking objects: 100% (3/3), done. project .repo/manifests/ Updating 5c981dac1797..0b0055e7445e Fast-forward error: in `sync`: revision v5.10.76-venice in Gateworks/linux-venice not found
This specific error is saying that the 'v5.10.76-venice' revision (or branch) is not in the current working copy of the repo. To resolve this you need to do a git remote update
for that project. You can also use repo foreach
to update all projects:
repo forall -c git remote update # update all projects git -C linux remote update # update just the project in the linux path
Showing diffs for all projects (repo diff)
You can show all the diffs for each project using repo diff
Using the latest version
The repo
tool is updated frequently. While it is rarely necessary to have the latest version it will inform you if there is an update and how to install that update in the current working directory:
$ repo sync ... A new version of repo (2.17) is available. ... You should upgrade soon: cp /usr/src/venice/bsp/.repo/repo/repo /home/user/bin/repo ...
To update the repo
tool just copy the file as mentioned above:
cp .repo/repo/repo $HOME/bin/repo
Modifying the stand-alone Linux Kernel
The Gateworks Venice BSP instructions above create an environment for building the Linux kernel among other targets.
Some additional instructions for common actions (make sure you have already installed the BSP and setup your shell environment as specified above):
- Make standard Gateworks Venice kernel with Gateworks venice_defconfig
make linux # first build the kernel with the standard venice_defconfig
- Modify Kernel configuration (enabling modules etc):
make -C linux menuconfig # make your changes make -C linux savedefconfig # create a minimal 'defconfig' file in the linux kernel dir diff linux/defconfig linux/arch/arm64/configs/imx8mm_venice_defconfig # show diffs (optional) cp linux/defconfig linux/arch/arm64/configs/imx8mm_venice_defconfig # copy the modified defconfig over the one used for venice
- Build kernel tarball:
make uboot # builds uboot, a requirement to build the kernel and modules and tarball make kernel_image # builds the kernel and modules and tarball
- Build new disk image using the updated kernel tarball:
make ubuntu-image
Toolchain
Buildroot based toolchain
The Venice BSP uses buildroot to build the toolchain used to build the kernel and bootloader firmware.
The buidlroot config is venice/buildroot-imx8mm_venice_defconfig which is copied to buildroot/configs/imx8mm_venice_defconfig.
The bsp Makefile has a 'toolchain' target which is built as a pre-requisite for building the bootloader and kernel.
The buildroot version is 2020.05.3 and builds a toolchain with the following details (which are all defaults for buildroot):
- Linux 5.6.x kernel headers
- uClibc libc
- binutils 2.32
- gcc 8.x
- C++ support (default is to disable this; we enable it)
The specific details can be shown by running 'gcc -v' for example:
user@host:/usr/src/venice/bsp$ . ./setup-environment # configure PATH and CROSS_COMPILER env vars user@host:/usr/src/venice/bsp$ ${CROSS_COMPILE}gcc -v Using built-in specs. COLLECT_GCC=/usr/src/venice/bsp/buildroot/output/host/bin/aarch64-linux-gcc.br_real COLLECT_LTO_WRAPPER=/usr/src/venice/bsp/buildroot/output/host/libexec/gcc/aarch64-buildroot-linux-uclibc/8.4.0/lto-wrapper Target: aarch64-buildroot-linux-uclibc Configured with: ./configure --prefix=/usr/src/venice/bsp/buildroot/output/host --sysconfdir=/usr/src/venice/bsp/buildroot/output/host/etc --enable-static --target=aarch64-buildroot-linux-uclibc --with-sysroot=/usr/src/venice/bsp/buildroot/output/host/aarch64-buildroot-linux-uclibc/sysroot --enable-__cxa_atexit --with-gnu-ld --disable-libssp --disable-multilib --disable-decimal-float --with-gmp=/usr/src/venice/bsp/buildroot/output/host --with-mpc=/usr/src/venice/bsp/buildroot/output/host --with-mpfr=/usr/src/venice/bsp/buildroot/output/host --with-pkgversion='Buildroot 2020.05.3' --with-bugurl=http://bugs.buildroot.net/ --disable-libquadmath --disable-libsanitizer --enable-tls --enable-threads --without-isl --without-cloog --with-abi=lp64 --with-cpu=cortex-a53 --enable-languages=c,c++ --with-build-time-tools=/usr/src/venice/bsp/buildroot/output/host/aarch64-buildroot-linux-uclibc/bin --enable-shared --disable-libgomp Thread model: posix gcc version 8.4.0 (Buildroot 2020.05.3)
Note there are other options you may want to change for your needs such as using a different libc, different compiler version, or enable WCHAR support or additional threading support. To do so you can:
cd buildroot make menuconfig # select options desired under Toolchain make clean make
- make sure you clean and rebuild when changing toolchain options
The buildroot based toolchain is used by virtue of sourcing the setup-environment file which adds to your PATH and sets the CROSS_COMPILE variable.
External toolchain
The Venice BSP uses buildroot to build the toolchain used to build the kernel and bootloader firmware.
While the BSP makefile will always build the buildroot toolchain (unless you comment that out in the Makefile) you can easily use a toolchain of your liking by modifying the environment like 'setup-environment' does. Simply make sure to set CROSS_COMPILE to the prefix of your toolchains 'gcc' compiler and other tools, and make sure your external toolchain shows up first in your PATH.
Cross compile examples
Examples of cross-compiling using the buildroot toolchain
- ANSI-C hello world:
cat << EOF > helloworld.c #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { printf("hello world!\n"); return 0; } EOF . ./setup-environment # setup environment for buildroot toolchain ${CROSS_COMPILE}gcc helloworld.c --static -o helloworld
- Note that if you want to use shared libraries you would either need to copy the toolchains libc (buildroot/output/target/lib/) to the target so that the interpreter and shared libs are present or you can use Ubuntu's cross-toolchain instead (see ubuntu/cross-compile)
- C++ hello world:
cat << EOF > helloworld.cpp #include <iostream> using namespace std; int main() { cout << "Hello World!"; return 0; } EOF . ./setup-environment # setup environment for buildroot toolchain ${CROSS_COMPILE}gcc helloworld.cpp --static -lstdc++ -o helloworld
- Note that if you want to use shared libraries you would either need to copy the toolchains libc (buildroot/output/target/lib/) to the target so that the interpreter and shared libs are present or you can use Ubuntu's cross-toolchain instead (see ubuntu/cross-compile)
- kernel module:
. ./setup-environment # setup environment for buildroot toolchain make kernel_image # first build the kernel make -C linux M=$PWD/my-module modules
- Note that some out-of-tree kernel modules do not follow the suggested Makefile standards and may need to be modified to use the CROSS_COMPILE prefix and/or specify the kernel directory (as opposed to the above example where you do a make in the linux dir and set M to the path of your module)
Building External or Out-of-Tree Kernel Modules on Target
Gateworks Venice BSP now creates images that have built in support for building external or out-of-tree kernel modules on a target board, allowing users to extend the functionality of the kernel with custom or third-party modules. Below are some examples demonstrating how to build and install external modules on a one of our Venice boards:
Before building any external kernel modules, it's essential to ensure your system has necessary dependencies installed. We recommend starting with an update of package lists followed by the installation of essential tools. Run the following commands:
apt update apt install -y build-essential git bc file
Examples:
- cryptodev-linux:
git clone http://github.com/cryptodev-linux/cryptodev-linux cd cryptodev-linux make && make modules_install modprobe cryptodev
- nrc7292 (mac80211):
git clone http://github.com/Gateworks/nrc7292 cd nrc7292/package/src/nrc/ make && make modules_install modprobe nrc
These examples illustrate the process of building and installing external kernel modules. Users can adapt these instructions for other modules as needed, ensuring that dependencies are met and the module is properly installed and loaded into the kernel.
It's important to note that while many out-of-tree kernel modules follow standard Makefile conventions and can be built and installed using a simple 'make && make modules_install' command sequence, some modules may not adhere to these conventions.
These non-standard modules may require modifications to their Makefiles or build processes to ensure compatibility with the standard build procedure. In such cases, it's advisable to consult the module's documentation or source repository for specific instructions on building and installing the module.
Always verify the requirements and instructions provided by the module's developers to ensure successful integration with your kernel environment.