Skip to content
Kaiwan N Billimoria edited this page Dec 14, 2023 · 17 revisions

SEALs - "Simple Embedded Arm Linux system"

Custom kernel + DTB + root filesystem images for an "embedded" QEMU/ARM-32 Linux system.

How to use this project: Familiarize yourself with the embedded Linux build environment, prerequisites (GNU toolchain), etc. (read through the links provided below).
(And do glance through the 'Home' wiki page first).


Steps:

0. Prereqs: Debian/Ubuntu users: install the following packages:

sudo apt install qemu-system-arm lzop libncurses-dev libncursesw6 libncursesw6-dev mkfs.ext4 make In case you face issues installing the libncursesw package, do refer this link: https://askubuntu.com/a/1254311/245524.

1. UPDATE

We now have a simple installer script. Pl do this: a) verify your build.config is correct (you can use the provided default one as a base, a template) b) first time running, run the install script first: install.sh

It will create the staging dir, and interactively install both the Busybox and Linux kernel source trees for you, in the locations as specified by your build.config file.

2. Install latest toolchain (as of Jan 2023): Best is to download the latest stable x86_64-to-AArch64 toolchain from the official ARM downloads page: ARM Toolchain download, from the ARM GNU Toolchain Downloads page

Once there, scroll to (careful!) this section (for a given tc release):
x86_64 Linux hosted cross toolchains and then (assuming you want the 64-bit one) to this:
AArch64 GNU/Linux target (aarch64-none-linux-gnu)

(Here we assume your build host is Linux x86_64 and the target is AArch64; change accordingly...).

Examples:

Fetch the compressed x86_64-to-Arm[64] toolchain:

wget <URL> (URL is as above).

Extract to, say, ~/Downloads :

The copy-pasted URL from the first link seen in the above screenshot shows up as:

https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz?rev=6750d007ffbf4134b30ea58ea5bf5223

Remove the ?rev... and everything following it from the URL; thus, we get the URL as:

https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz

Fetch it:

wget https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz

...

`HTTP request sent, awaiting response... 200 OK Length: 130708344 (125M) [application/octet-stream]`` ``Saving to: ‘arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz’``

arm-gnu-toolchain-12.2.rel1-x8 100%[=================================================>] 124.65M 4.24MB/s in 30s

...

$ ls -lth

total 250M -rw-rw-r-- 1 osboxes osboxes 18K Jan 25 09:35 wget-log -rw-rw-r-- 1 osboxes osboxes 125M Dec 21 01:37 arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz $

Extract the above .tar.xz files (I extracted them into my ~/Downloads dir):

$ tar xf arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz

... $ ls

**arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/** wget-log arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz

Look inside the extracted toolchain folder:

$ ls arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/

12.2.rel1-x86_64-aarch64-none-linux-gnu-manifest.txt bin/ lib/ libexec/ aarch64-none-linux-gnu/ include/ lib64/ share/

The actual toolchain binary executables are under the bin/ folder:

$ ls arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/

aarch64-none-linux-gnu-addr2line* aarch64-none-linux-gnu-gcc-ar* aarch64-none-linux-gnu-ld.bfd* aarch64-none-linux-gnu-ar* aarch64-none-linux-gnu-gcc-nm* aarch64-none-linux-gnu-ld.gold* aarch64-none-linux-gnu-as* aarch64-none-linux-gnu-gcc-ranlib* aarch64-none-linux-gnu-lto-dump*

[...]

aarch64-none-linux-gnu-gcc-12.2.1* aarch64-none-linux-gnu-ld* aarch64-none-linux-gnu-strip*

Let’s run the cross-compiler gcc:

$ arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc -v

Using built-in specs. COLLECT_GCC=arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/osboxes/Downloads/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin/../libexec/gcc/aarch64-none-linux-gnu/12.2.1/lto-wrapper Target: aarch64-none-linux-gnu Configured with: /data/jenkins/workspace/GNU-toolchain/arm-12/src/gcc/configure --target=aarch64-none-linux-gnu --prefix= --with-sysroot=/aarch64-none-linux-gnu/libc --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-12/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-12/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-12/build-aarch64-none-linux-gnu/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-12/build-aarch64-none-linux-gnu/host-tools --with-isl=/data/jenkins/workspace/GNU-toolchain/arm-12/build-aarch64-none-linux-gnu/host-tools --enable-fix-cortex-a53-843419 --with-pkgversion='Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)' Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.2.1 20221205 (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) $

It works!

  1. Setup your PATH environment variable to point to the toolchain binaries:

Eg. $ export PATH=${PATH}:~/Downloads/arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-linux-gnu/bin

Let's try:

$ aarch64-none-linux-gnu-<TAB-TAB>

aarch64-none-linux-gnu-addr2line aarch64-none-linux-gnu-gcc-ar aarch64-none-linux-gnu-ld.bfd aarch64-none-linux-gnu-ar aarch64-none-linux-gnu-gcc-nm aarch64-none-linux-gnu-ld.gold aarch64-none-linux-gnu-as aarch64-none-linux-gnu-gcc-ranlib aarch64-none-linux-gnu-lto-dump

[...]

aarch64-none-linux-gnu-gcc-12.2.1 aarch64-none-linux-gnu-ld aarch64-none-linux-gnu-strip

$ aarch64-none-linux-gnu-gcc

aarch64-none-linux-gnu-gcc: fatal error: no input files compilation terminated. $

Okay.

  1. Test the cross toolchain: ensure a ‘C’ program compiles and links correctly.

4. The build configuration script
Name: build.config Update it's content to reflect the hardware details, staging dir, Linux kernel ver and location, busybox location, etc.

build.config is a soft (symbolic) link to the actual config file (by default it's set to point to the build.config.arm64_qemuvirt config file). Update it to point to your required config file, if different (f.e. if your new config file is named build.config.myboard, can use ln -sf build.config.myboard build.config )

To help the developer configure the project environment, the build scripts parse in and use a configuration script. This lets you (the developer/user) easily change things like the paths to the toolchain, busybox source, images folder, etc. Also, the CPU arch ISA to build against (choice currently is the ARMv7 and Aarch64 ARMv8), the Linux kernel + busybox source tree location, etc.

5. The SEALs - "Simple Embedded Arm Linux system" - build script: Run it!

build_SEALS.sh : the SEALS main build script. ARMv7/ARMv8 Linux kernel, enhanced root filesystem: dynamic busybox, shared libraries, init & etc files/scripts, device nodes, etc. We now use an ext4 filesystem, formatted upon a non-volatile SDcard (for ARM) as the root filesystem!

Resources / Links
Please refer these links for detailed info; in fact, the scripts were developed using these resources extensively!

Kernel / embedded :

Many thanks to Balau for the knowledge and original inspiration! :)

-Kaiwan N Billimoria
Em: kaiwan-dot-billimoria-at-gmail-dot-com
Web: kaiwantech.wordpress.com