Getting Started with Mendel Linux

Check out the repository

We've stored our code in Gerrit, and like the Android developers before us, we use repo to manage the projects in our Gerrit repositories.

To get started, first, you're going to need to pull down a copy of the repo tool from our public facing sites and add it to your path:

mkdir -p bin
export PATH=$PATH:$HOME/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

Make sure you've initialized git with your name and email address, and have configured it properly for fetching the sources:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Once you‘ve done this, you’re actually ready to check out the sources. Make a new directory where you'd like it to live, and do the following:

repo init -u sso://aiyprojects/manifest -g default,imx
repo sync -j$(nproc)

After a short wait, you'll be ready to go for making changes to the repository and building images.

Build the tree

To isolate the build from your host system, we build using Docker. We recommend configuring Docker so that a non-root user can use it. For gLinux users, follow the install instructions here.

For all other users, follow the official directions

To build the tree, first you need to prepare your environment:

source build/setup.sh

At this point you'll have a couple of extra functions available to navigate around the tree and build things in part or in whole.

The next step is to install the prerequisite packages by running:

m prereqs

Now you can build the tree by running:

m

If you have not modified any packages, and would like to speed your install:

FETCH_PACKAGES=true m

This will cause packages to be fetched from Aptitude.

Artifact caching

There are a few build artifacts that generally don't change, and can be cached to provide a build speedup.

cache/base.tgz

  • Filesystem tarball for pbuilder. Set FETCH_PBUILDER_DIRECTORY in your environment to the folder containing a copy of the file to use an already built version.

rootdir_ARCH.raw.img

  • Base filesystem tarball made by multistrap. Set ROOTFS_RAW_CACHE_DIRECTORY in your environment to the folder containing a copy of the file to use an already built version.

cache/aiy-board-builder.dar

  • Docker container that the build happens in. Set PREBUILT_DOCKER_ROOT in your environment to the folder containing a copy of the file to use an already built version.

Fastboot

You will need to install Fastboot either via the Android SDK Manager or through your distro's package manager.

Once you have fastboot installed, you'll want to go sudo-less to flash your device by making a new .rules file:

sudo sh -c "echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0525\", MODE=\"0664\", \
GROUP=\"plugdev\", TAG+=\"uaccess\"' >> /etc/udev/rules.d/65-android-local.rules"
sudo udevadm control --reload-rules && udevadm trigger

Now you can check that you can flash your device without root previlages by running:

fastboot devices

Flash a device

After the above is complete, you should be able to flash the device:

flash.sh

To build the world for an sdcard, build the sdcard target:

m docker-sdcard

If the device was flashed properly you should be able to login to it:

shell.sh

Quick Explanation of the Build System

The build system is relatively straightforward. It's a selection of split out multi-target makefiles defined in the build/ directory. Each makefile is designed to be as standalone as possible so that each can be built individually using the mm command, or collectively using m.

Adding modules is also relatively straightforward, assuming a decent understanding of GNU Make rules. An example of how to get started is available in the build/template.mk script. Simply copy this file to a new filename, and then add the following line to the list of includes in the toplevel build/Makefile file:

include $(ROOTDIR)/build/your-module.mk

Note that targets and clean are special partial targets. The rules must be defined with a double colon (::) and not added to your module's .PHONY target. Additionally, the output of the targets command is a list of strings of the form:

targetname - some short description of your target

This is actually parsed by the mm function to help with tab completion. It's relatively robust in the face of spaces, but you must separate your targetname with a dash (-) from the description, or the completion routine will likely break.

If you follow the conventions in the template, mm will autocomplete your module and it's targets listed in the targets make target.

Quick Tour of setup.sh Functions

m -- Make everything from the toplevel

The m function can be called from any directory in the filesystem to build the entire tree from the ground up. Effectively the command does a pushd to the root of the tree and issues a make command. You can specify any options or targets you'd like to build, including the targets command to have a look around in the build system.

mm -- Make an individual Module

The mm function can, like the m function, be called from any directory in the filesystem to build an individual module. It has autocompletion functions, so simply typing mm and then hitting TAB will autocomplete the list of modules available. Additionally, if you press TAB again, after you've autocompleted a module name, it will autocomplete the list of targets available in that module, as returned by the targets target.

j -- Jump around the directory tree

This is a kind of switchboard of sorts that lets you jump around the tree quickly. Many of the paths are arcane because of historical reasons, so this tool was written to make things a bit easier.

If you issue the j command with no arguments, it will automatically change your current working directory to the root of the tree. If, however, you issue j help, it will list a list of target names you can “jump” to. You can open up build/setup.sh to see which ones are currently defined, or just jump around and explore.

Quick Tour of the Directory Layout

build/

Contains build scripts, the setup.sh script and rootfs overlay, as well as some additional tooling.

cache/

Contains the debootstrap tarball you must build before starting any other build lives here. This directory is ephemeral and doesn‘t exist on a first clone, but will also not be removed when the clean target is run. Bear in mind: if you update the package list in build/debootstrap.mk, you’ll need to re-reun mm deboostrap make-debootstrap-tarball to regenerate this.

docs/

Contains this documentation, as well as other documentation about the build system and working in the tree.

imx-firmware/

Contains the atheros and qualcomm Wifi firmware blobs. Cloned from the AndroidThings repository and will likely migrate out as time goes on and bom selections change.

linux-imx/

Contains the source code for the Linux kernel.

out/

The ephemeral directory that contains both local host binaries and tools, as well as build artifacts and the final images produced. It has a specific structure documented elsewhere.

packages/

Debian package sources used to build the packages installed to make the distribution more functional for the Enterprise board.

tools/

Contains miscellaneous tools to support the image. Bpt and img2simg are forked from the Android Things tree, and imx-mkimage from NXP.

uboot-imx/

Contains the u-boot bootloader, with support for i.MX8 devices.