Building the firmware¶
Ethernet Switch OS is built with the Yocto Project. This repository is the build entry point. It holds kas configuration files that describe, per board, which Yocto layers to check out and how to configure them, so a build needs nothing on the host but Docker, git and a POSIX shell. The result is a flashable firmware image.
Requirements¶
Docker, git and a POSIX shell. VS Code with the Dev Containers extension if you want to work in the development container from the editor.
Everything else (bitbake's host dependencies, the cross toolchain, Python,
Rust) is inside the container image. kas-container in the repository is the
upstream script from siemens/kas, vendored
and pinned to kas 5.5.
Get the sources¶
git clone https://github.com/AlbrechtL/ethernet-switch-os
cd ethernet-switch-os
Choose the board¶
Each supported hardware has a board file in kas/board/. It is the one file
to name on the command line; it pulls in the layers, the machine and the
build targets:
| Hardware | Board file |
|---|---|
| Zyxel GS1900-8 (rev A1), also for rtl838x-qemu | kas/board/zyxel-gs1900-8-a1.yml |
| Albrecht RTL8382MI test switch (experimental) | kas/board/albrecht-rtl8382mi-test.yml |
| Raspberry Pi Zero with the 4-port managed switch HAT (experimental) | kas/board/rpi-managed-switch-rpi0.yml |
| 8 port switch emulated in QEMU x86-64 (experimental) | kas/board/qemux86-64-switch.yml |
Note
Use the board file of your hardware. The examples on this page build the
GS1900-8 (kas/board/zyxel-gs1900-8-a1.yml); for any other hardware,
replace it with that hardware's board file. An image built for another
board does not work on your switch.
The images land in build/tmp/deploy/images/<board>/, where <board> is the
file name without .yml.
Build¶
The build always runs in a container, and there are two ways into it. The kas
commands are the same in both; only the name differs: kas inside the dev
container, ./kas-container on the host.
In VS Code, with the dev container¶
Open the checkout in VS Code and run Dev Containers: Reopen in Container.
VS Code builds the development image from Dockerfile (the upstream kas
image plus tools for working on the project) and mounts the checkout at
/work. .devcontainer/devcontainer.json already sets KAS_BUILD_DIR,
DL_DIR and SSTATE_DIR, so in a terminal there:
# Replace the board file with the one for your hardware.
kas build kas/board/zyxel-gs1900-8-a1.yml
On the shell, with kas-container¶
kas-container runs kas in a Docker container by itself, so this is all a
build needs:
# Replace the board file with the one for your hardware.
./kas-container build kas/board/zyxel-gs1900-8-a1.yml
That uses the upstream ghcr.io/siemens/kas/kas:5.5 image and puts
everything under build/. Two optional additions, both what the dev
container does too:
- The development image from
Dockerfile: the upstream kas image plus tools for working on the project (a host Rust toolchain,dtc,mkimage, the JFFS2 tools, a Docker client for rtl838x-qemu). It builds the same artifacts.kas-containerdoes not build images, so build it once, and again wheneverDockerfilechanges. The tag has to match the vendoredkas-container(5.5), or kas refuses to run. - Downloads and shared state outside
build/, so they survive deleting it and are shared between boards.kas-containercreates the directories and mounts them into the container.
docker build -t ethernet-switch-os/kas:5.5 - < Dockerfile
export KAS_CONTAINER_IMAGE=ethernet-switch-os/kas:5.5
export KAS_BUILD_DIR=$PWD/build DL_DIR=$PWD/downloads SSTATE_DIR=$PWD/sstate-cache
./kas-container build kas/board/zyxel-gs1900-8-a1.yml
A first build takes hours. kas/opt/sstate-mirror.yml pulls oe-core's share
of it from the Yocto Project's CDN instead:
./kas-container build kas/board/zyxel-gs1900-8-a1.yml:kas/opt/sstate-mirror.yml
Other kas commands¶
Written for the shell; in the dev container replace ./kas-container with
kas.
| Command | What it does |
|---|---|
./kas-container build kas/board/<board>.yml |
Build a board. |
./kas-container shell kas/board/<board>.yml |
A shell with bitbake ready, e.g. for bitbake -c menuconfig virtual/kernel. |
./kas-container checkout kas/board/<board>.yml |
Clone the layers and write build/conf/ without building anything. |
./kas-container dump kas/board/<board>.yml |
Print the fully resolved configuration. |
ls kas/board/ |
The boards that can be built. |
rm -rf build |
Start over. Layers, downloads and shared state are kept, so the next build is fast. |
rm -rf build layers downloads sstate-cache |
Drop everything kas created. |
What comes out¶
For the Zyxel GS1900-8, in build/tmp/deploy/images/zyxel-gs1900-8-a1/:
| File | What it is for |
|---|---|
ethernet-switch-os-initramfs-zyxel-gs1900-8-a1.bin |
TFTP boot image; the first install and recovery run entirely from RAM. |
ethernet-switch-os-swu-factory-zyxel-gs1900-8-a1.swu |
First install, uploaded from the TFTP initramfs. Writes firmware, wipes data. |
ethernet-switch-os-swu-upgrade-zyxel-gs1900-8-a1.swu |
Update in place. Rewrites firmware, keeps user data. |
The flash layout, the TFTP procedure and what to type at the stock bootloader are in Installation. How the images are put together is in the TECHNICAL.md of meta-rtl83xx-bsp.
The Raspberry Pi switch is different: its board builds an SD card image,
rpi-switch-image-rpi-managed-switch-rpi0.rootfs.wic.bz2 with its
.wic.bmap, which is the first install, and
ethernet-switch-os-swu-upgrade-rpi-managed-switch-rpi0.swu for updates.
There is no factory .swu and no TFTP image. The SD card layout and the A/B
update are in
Raspberry Pi 4-port switch.
Once the switch is up: https://192.168.1.1/ for the status and settings
page (the first visit creates the admin account), then
ssh <username>@192.168.1.1 for the CLI, https://192.168.1.1/update/ for SWUpdate. Getting started
takes it from there.
The QEMU switch builds a disk image in the same A/B shape, with EFI Boot
Guard instead of U-Boot: qemu-switch-image-qemux86-64-switch.rootfs.wic
with its .wic.bmap, and
ethernet-switch-os-swu-upgrade-qemux86-64-switch.swu. The build also leaves
the UEFI firmware (ovmf.*.qcow2) and a QEMU for running it; see
QEMU x86-64 switch.
Building this documentation¶
The documentation is plain MkDocs with the Material theme, and needs only Docker too. Serve it on http://localhost:8000, rebuilt on every change:
docker run --rm -it -p 8000:8000 -v $PWD:/docs squidfunk/mkdocs-material:9.7.7
Or build it into site/ the way CI does, failing on warnings and broken
links:
docker run --rm -u $(id -u):$(id -g) -v $PWD:/docs squidfunk/mkdocs-material:9.7.7 build --strict
The image version matches docs/requirements.txt, which CI installs with
pip.