diff --git a/860/Developer-Guide_Build-Switches/index.html b/860/Developer-Guide_Build-Switches/index.html index 229792c6..e2f30c22 100644 --- a/860/Developer-Guide_Build-Switches/index.html +++ b/860/Developer-Guide_Build-Switches/index.html @@ -2777,11 +2777,11 @@ root filesystem subvolume:

  • sha: generate SHA256 hash for image
  • gpg: sign image using gpg
  • xz: compress image only using xz format
  • zstd: compress image only using zstd format
  • diff --git a/860/search/search_index.json b/860/search/search_index.json index f57f34e7..5288377a 100644 --- a/860/search/search_index.json +++ b/860/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Armbian OS","text":""},{"location":"#preface","title":"Preface","text":"

    Welcome to the official documentation of Armbian Linux, a highly optimized base operating system specialized for single board computers (SBCs) and its extensive build framework.

    "},{"location":"#how-is-the-documentation-structured","title":"How is the documentation structured?","text":"

    The table of contents in the sidebar and the links at the top of the page should let you easily access the documentation for your topic of interest.

    If you are new to Armbian, the Introduction and the Getting Started sections provide everything you need to know about the project, where to find the resources for your board, and a tutorial for everything you need to get Armbian running and configured.

    It then continues on to Advanced Configuration tasks and tools for advanced users. The topics in this section cover a wide range of tasks: configuring the system or the network without using armbian-config, configuring your device automatically at first boot, and creating a custom image using the Armbian Build Framework.

    If you have read through the documentation and still need help, check out our Troubleshooting advice.

    "},{"location":"#where-to-find-additional-help","title":"Where to find additional help?","text":"

    If you still cannot find what you need here, visit the Armbian forum where your input can also help us improving this documentation.

    "},{"location":"#how-to-report-a-problem-in-this-documentation","title":"How to report a problem in this documentation?","text":"

    If you come across an issue in these pages, you can either report it here, or follow these instructions to suggest a fix yourself.

    "},{"location":"#what-is-armbian","title":"What is Armbian?","text":"

    Armbian\u2019s goal is to provide a highly optimized base operating system specialized for single board computers. It embodies extremely lightweight hardware features with a well-known and supported Debian-based user-space experience, an extensive build framework, and it is suitable for industrial or home use.

    Armbian is not a Linux distribution itself. Instead, we use Debian GNU/Linux and Ubuntu Linux as base for the images, that our users can download and deploy. We build our own set of optimized kernels for each board, and then provide an extensive and customizable framework to build, adjust, and configure these images. This framework is the heart of the project.

    graph LR\n  A[Hardware] --> B{50 x Armbian kernel};\n  B --> X[\"point release\"];\n  X ---->|minimal| E[Debian or Ubuntu];\n  X ---->|server| F[Debian or Ubuntu];\n  X -->|desktop| H[Debian or Ubuntu];\n  H -->Q[XFCE];\n  H -->W[Gnome];\n  H -->R[KDE];\n  H -->T[Cinnamon];\n
    "},{"location":"#key-features","title":"Key features","text":"

    As a user, you can simply download one of our images, deploy and run it on your SBC. As an advanced user, a manufacturer or provider, you can create fully configured custom images for your board or product.

    In any case, you will get these key advantages:

    Other features and performance tweaks worth mentioning "},{"location":"#comparison","title":"Comparison","text":"Distributions Armbian Downstream Upstream Primary focus making a value sales, profiting making a value User-space clean & minimal bloated with proprietary scripts clean Experience across hardware universal, predictable, reproducible random, chaotic, manually assembled porting, unofficial builds Contributing to FOSS extreme close to none great System config universal proprietary all / none Maintenance modular with review and unit tests endless spaghetti code traditional and modern Build framework advanced and user friendly none none Hardware maintainers 50+, teams per SoC, per vendor none none Upstream contribution 1000+ none little Downstream projects 10+ none 100+ Switching to upstream easy impossible / User-space changes standard proprietary standard Initial memory usage optimal bad bad Process usage optimal only hidden too broad Pre-installed packages optimized for fast install makes install of anything slower optimized for fast install Declaring support where we know maintainers everything is \u201csupported\u201d everything is \u201csupported\u201d"},{"location":"#which-hardware-is-supported","title":"Which hardware is supported?","text":"

    Armbian distributes stable images for many different single board computers (SBCs). But not each model receives the same amount of support and maintenance. This might be due to lack of man-power, lack of support by the manufacturer, etc. We have therefore a system that shows the support status for each board:

    Platinum Support

    At least one person is providing constant maintenance and support.

    Standard Support

    Support is not secured, but it is still overall good.

    Community maintained

    Most of the images for boards in this category will also work, but no warranty can be given as Armbian does not monitor their status.

    Supported / maintained is not a guarantee, though. It merely implies that a particular SBC is at a high level of software maturity and has a named maintainer. Due to the complexity and lack of cooperation in the ecosystem, it is unlikely that all specialized functionalities (like 3D, VE, I\u00b2C\u2026) are always available.

    For more information see the Board Support Guide

    "},{"location":"#where-to-find-images-and-sources","title":"Where to find images and sources?","text":"

    Our main website is https://www.armbian.com/. It is the default site for our users, and it contains the download section with all images, information about the support status for each board, links to our forum and this documentation.

    The project sources are hosted on GitHub and are organized in separate Git repositories. These are the resources for developers and participants, e.g. users helping with testing.

    "},{"location":"#how-can-you-contribute","title":"How can you contribute?","text":"

    If you want to contribute to our project, please read the collaboration notes.

    Unit testing

    All software targets and functions are automatically tested to catch as many problems as possible.

    "},{"location":"Board_Maintainers_Procedures_and_Guidelines/","title":"Board Maintainers Procedures and Guidelines","text":"Board Maintainers Procedures and Guidelines

    This topic should give you as new board maintainers a brief overview about what you should do, must do, and can do. What you as maintainer can expect from Armbian and what we expect from you.

    Requirements:

    Even though you became a maintainer already just to make sure everything is set.

    If you are a new maintainer, please make sure you have submitted your IDs and information using our maintainer registry form: Here

    Maintaining:

    So all requirements are met and you are a maintainer now. Now what?

    Maintainers must not necessarily be persons with development experience. They act as a intersection between end-users and the development team and serve the developers in best-effort manner. They are encouraged to answer basic/simple user questions (if possible, also best effort) without having to bother the development team. They are allowed to record bugs but are not allowed to escalate bugs. Team leaders do.

    Take note that it is still up to development team's discretion what gets attention since Armbian has to plan carefully how to spend its very limited resources.

    Jira and Forum expectations:

    Low priority issues are usually attended to and patched by the community. If the issue has existed for more than a release, you can create a Jira ticket for it. However the expectation is the issue will be low priority and may not be processed for some time. Issues such as, but not limited to, should be considered low priority:

    For high priority items you can create a Jira ticket so that when developers are able, they can process it. If you are going to create a Jira ticket, please be sure to collect as much information about the issue as possible first. If more information will be needed to process the issue, you should reply to the user asking for that additional information and make sure it is included in the ticket. Issues like these should be considered a higher priority:

    What should you do if you run into an issue on the forum?

    What should you do if there is a long standing Jira ticket?

    Losing support status:

    As mentioned in the board support rules the support status of a board will be revoked for at least the current and upcoming release cycle(s) if a \"must\" of the Maintaining section above is not fulfilled.

    As an example: August 30th is release date for 22.08 release, sign-off dead line is 21th. If maintainer misses the RC sign-off window the board is demoted to CSC for both 22.08 and 22.11 releases.

    The development team may grant exceptions on their discretion.

    Armbian's assistance:

    If you have questions about maintainer-ship or want to learn more deeper insights about the build framework and such Armbian will provide you with all information in best-effort. If time allows we can explain and teach you personally various aspects about the project. Otherwise, if you want to learn more about the build framework, dive in, play with it and read the documenenation. Also if you have other concerns please do not hesitate to reach out via forums, IRC or Discord. Armbian cares about the people who care about Armbian\u00a0

    "},{"location":"Community_Forums/","title":"Forums","text":"

    https://forum.armbian.com/

    "},{"location":"Community_Github/","title":"Main project repositories","text":""},{"location":"Community_Github/#armbian-build","title":"Armbian Build","text":"

    armbian/build

    Framework can build generic Armbian or custom Linux image.

    "},{"location":"Community_Github/#armbian-config","title":"Armbian Config","text":"

    armbian/configng

    Utility for configuring:

    "},{"location":"Community_Github/#armbian-os","title":"Armbian OS","text":"

    armbian/os

    Armbian OS assembly line:

    "},{"location":"Community_Github/#armbian-community","title":"Armbian Community","text":"

    armbian/community

    Armbian OS community assembly line:

    "},{"location":"Community_Github/#armbian-distribution","title":"Armbian Distribution","text":"

    armbian/distribution

    Armbian OS with pre-installed applications:

    "},{"location":"Community_IRC/","title":"Social media","text":""},{"location":"Community_IRC/#armbian-on-x-and-mastodon","title":"Armbian on X and Mastodon","text":"

    Armbian short announcements are done via \ud835\udd4f (formerly known as Twitter): https://twitter.com/armbian and https://fosstodon.org/@armbian

    "},{"location":"Community_IRC/#irc-channel-discord-matrix","title":"IRC Channel / Discord / Matrix","text":""},{"location":"Community_IRC/#overview","title":"\ud83d\udc4f Overview","text":"

    As announced in the forums everyone interested can communicate in realtime using the internet relay chat (or IRC for short). Well known IRC clients for CLI are Weechat or Irssi and for GUI Hexchat or Konversation. Mature clients for Matrix: Element or FluffyChat.

    Besides that communication is also possible via Discord or Matrix (closed beta).

    "},{"location":"Community_IRC/#how-to-connect","title":"\ud83d\udd0c How to connect","text":""},{"location":"Community_IRC/#irc","title":"IRC","text":"

    Libera network:

    OFTC network:

    In order to enter main #armbian channels registration with Nickserv is mandatory on Libera. Check Libera Chat documentation for further information.

    "},{"location":"Community_IRC/#discord","title":"Discord","text":"

    Simply click here: https://discord.com/invite/armbian

    Channels starting with #armbian- are relayed between Discord and Libera IRC so it does not matter if you join IRC or Discord as both ends receive your messages. Check #welcome-and-rules for more information. The main #armbian channel and #armbian-announcements are relayed between Discord, Libera, OFTC and Matrix.

    "},{"location":"Community_IRC/#matrix-closed-beta","title":"Matrix (closed beta)","text":""},{"location":"Community_IRC/#rules","title":"\ud83d\uded1 Rules","text":"

    Forums registration terms and rules apply for our chats: https://forum.armbian.com/terms

    "},{"location":"Community_IRC/#channels-depending-on-platform-only-a-limited-selection-might-be-available","title":"\ud83d\udcac Channels (depending on platform only a limited selection might be available)","text":""},{"location":"Community_IRC/#services","title":"\ud83d\udc6e Services","text":"

    Besides the services offered by IRC (like Nickserv or Chanserv) Armbian has set up some own services (on Libera only).

    ArmbianGithub

    DC-IRC

    ArmbianHelper

    "},{"location":"Community_IRC/#faq","title":"\u2754 FAQ","text":" "},{"location":"Community_IRC/#bottom-line","title":"\ud83d\udc49 Bottom line","text":"

    If you have any questions, comments regarding the IRC channels and/or services or found an issue in this documentation for think you can enhance it get in touch with Werner either via forums, IRC or Discord.

    "},{"location":"Developer-Guide_Adding-Board-Family/","title":"Adding a new board or board family","text":"

    There are no detailed instructions on how to add a new board or even a whole new board family to the build script yet. However there are a few commits / pull requests that give clues how to achieve that like

    "},{"location":"Developer-Guide_Build-Commands/","title":"Build commands","text":""},{"location":"Developer-Guide_Build-Commands/#kernel","title":"kernel","text":"

    Builds kernel and device tree (where applicable) and places it to the output/debs

    Usage: Bash

    ./compile.sh kernel BOARD=nanopi-r5c BRANCH=edge\n

    "},{"location":"Developer-Guide_Build-Commands/#kernel-config","title":"kernel-config","text":"

    Automatically call kernel\u2019s make menuconfig (add or remove modules or features)

    Usage: Bash

    ./compile.sh kernel-config BOARD=nanopi-r5c BRANCH=edge\n

    "},{"location":"Developer-Guide_Build-Commands/#dts-check","title":"dts-check","text":"

    Validate dts files and improve board & patch development overall.

    This option validates the dts/dtb file for the selected board against the device tree bindings and outputs the validation logs to the user. It can be used when adding a new board, developing or improving a dts file.

    Usage: Bash

    ./compile.sh dts-check BOARD=nanopi-r5c BRANCH=edge \n

    "},{"location":"Developer-Guide_Build-Commands/#inventory-boards","title":"inventory-boards","text":"

    Outputs a one-board-per-line CSV inventory of boards.

    Sets TARGETS_FILE to something that doesn\u2019t exist, so the default-targets.yaml is used (so same list for everyone, save for userpatched-boards)

    Usage: Bash

    ./compile.sh inventory-boards\n
    Outputs /info/boards-inventory.csv

    "},{"location":"Developer-Guide_Build-Commands/#kernel-dtb","title":"kernel-dtb","text":"

    Builds only DTB and outputs full preprocessed dts source

    Outputs preprocessed DTS source for the board in question to output/ also outputs the same preprocessed DTS source, ran through dtc with input and output DTS formats for \u201cnormalized\u201d comparisons

    Usage: Bash

    ./compile.sh kernel-dtb BOARD=xxxxx BRANCH=edge\n

    "},{"location":"Developer-Guide_Build-Commands/#uboot-patch","title":"uboot-patch","text":"

    Create patch files for u-boot.

    The output patch files are written to output/patch/u-boot-${LINUXFAMILY}-${BRANCH}.patch. To use them in subsequent builds they must be copied to the appropriate directories in the patch/u-boot directory. See: user-provided patches

    Any uncommitted changes in the work tree and index are committed to establish a clean work tree. It would be best if there are no uncommitted changes when running uboot-patch.

    If there is an existing patch file at the output path specified above, it may be applied before continuing work.

    When the prompt Press <ENTER\\> after you are done editing in ${pwd} appears, in a separate window, navigate to the specified directory and make any required changes. When changes are complete, return to the window running the uboot-patch command and press <ENTER>.

    A patch to recreate the changes introduced to the u-boot tree is presented and the prompt \u201cAre you happy with this patch?\u201d. You can respond yes to accept the patch as-is and generate the output patch file, stop to abort the command without producing the output patch file, or anything else to loop back, to make further changes.

    Instead of creating them while running uboot-patch, new device tree files should be created in the relevant dt directory under patch/u-boot and new _defconfig files should be created in the relevant configs directory under patch/u-boot. While the uboot-patch command will add these new files to the patch if they are created while running uboot-patch, this is not the preferred way of adding these files.

    "},{"location":"Developer-Guide_Build-Commands/#rewrite-uboot-patches","title":"rewrite-uboot-patches","text":"

    Prepares git, applies patches to git, and rewrites them back from git same as kernel, it does git archeology for mbox-less patches, etc.

    Note: MAINTAINER and MAINTAINEREMAIL should be set.

    Usage: Bash

    ./compile.sh rewrite-uboot-patches BOARD=xxxx BRANCH=edge \n

    "},{"location":"Developer-Guide_Build-Commands/#rewrite-kernel-patches","title":"rewrite-kernel-patches","text":"

    Prepares git, applies patches to git, and rewrites them back from git same as kernel, it does git archeology for mbox-less patches, etc.

    Usage: Bash

    ./compile.sh rewrite-kernel-patches BOARD=xxxx BRANCH=edge \n

    "},{"location":"Developer-Guide_Build-Commands/#targets","title":"targets","text":"

    Generates output/info/git_sources.json file containing URL, branch, and commit hash combo.

    The easiest way to generate file for all devices is to run ./compile.sh targets. Then, at the time of release, we will copy the output/info/git_sources.json file to config/sources/git_sources.json. Once the file is copied, the hash information from the file will be used to fetch resources for git repositories where branches are specified instead of tags or commits.

    Usage: Bash

    ./compile.sh targets\n

    "},{"location":"Developer-Guide_Build-Preparation/","title":"Armbian Build Framework Quick Start Guide","text":""},{"location":"Developer-Guide_Build-Preparation/#requirements","title":"Requirements","text":""},{"location":"Developer-Guide_Build-Preparation/#clone-repository","title":"Clone repository","text":"Bash
    git clone https://github.com/armbian/build\ncd build  \n

    Note

    gitGraph\n   commit\n   commit\n   checkout main\n   commit id: \"v24.08\" tag: \"v24.08\"\n   branch v24.08\n   commit\n   commit\n   commit\n   commit\n   checkout main\n   commit id: \"v24.11\" tag: \"v24.11\"\n   branch v24.11\n   commit\n   commit\n   commit\n   commit\n   checkout main\n   commit\n   commit\n   commit\n   commit\n   commit\n   commit\n   commit id: \"main\" type: REVERSE tag: \"Trunk\"
    "},{"location":"Developer-Guide_Build-Preparation/#interactive","title":"Interactive","text":"

    Run framework:

    Bash
    ./compile.sh\n
    Video

    "},{"location":"Developer-Guide_Build-Preparation/#cli","title":"CLI","text":"Bash
    ./compile.sh [command] [switch...] [config...]\n

    Troubleshooting: \u2018unknown terminal type\u2019 error

    When running the script, especially from modern terminal emulators (like Ghostty, Kitty, WezTerm), you might encounter an error like

    \u2018xterm-ghostty\u2019: unknown terminal type

    Quick workaround: you can force a more common terminal type before running the script: Bash

    env TERM=xterm-256color ./compile.sh\n

    Only one command can be specified.

    Switches are parameter settings that are used by the build framework itself (e.g. DEBUG=yes) or the specific command.

    Config files are bash shell scripts that are sourced in the order specified. They are primarily used to set switches but might also set hook functions. They must be located in the userpatches directory and must be named config-${arg}.conf or config-${arg}.conf.sh (where ${arg} is the argument from the command line): one or the other, but not both.

    Switches set on the commandline override settings from the config files, regardless of the order they appear on the comandline.

    Comprehensive list of build Commands and Switches

    Example:

    Bash
    ./compile.sh build \\\nBOARD=uefi-x86 \\\nBRANCH=current \\\nBUILD_DESKTOP=yes \\\nBUILD_MINIMAL=no \\\nDESKTOP_APPGROUPS_SELECTED='browsers chat desktop_tools' \\\nDESKTOP_ENVIRONMENT=gnome \\\nDESKTOP_ENVIRONMENT_CONFIG_NAME=config_base \\\nKERNEL_CONFIGURE=no \\\nRELEASE=noble\n

    Or, using config file userpatches/config-myboard.conf that sets all these switches:

    Bash
    ./compile.sh build \\\nmyboard\n

    Interpretation?

    This command will generate Ubuntu 24.04 Noble based Gnome desktop environment image for Intel based hardware (uefi-x86). Besides bare desktop, it will contain packages from browsers and desktop_tool sections and it will use unchanged kernel from current kernel branch.

    "},{"location":"Developer-Guide_Build-Preparation/#logging","title":"Logging","text":"

    Logs are written to output/logs. Old logs (all but the current build) are compressed and moved to output/logs/archive.

    Log formats are:

    For much more verbose logs set switch \u2018DEBUG=yes\u2019.

    "},{"location":"Developer-Guide_Build-Preparation/#github-actions","title":"GitHub Actions","text":"

    If you do not have the proper equipment to build images on your own, you can use our GitHub Action.

    "},{"location":"Developer-Guide_Build-Switches/","title":"Build Switches","text":"

    These parameters are meant to be applied to the ./compile.sh command. They are all optional. They can also be added to your build configuration file to save time. Default values are marked bold if applicable.

    "},{"location":"Developer-Guide_Build-Switches/#user-space","title":"User space","text":"

    BOARD ( string )

    Set the name of the board manually to skip the dialog prompt. Name of the board is a filename without extension.

    BRANCH ( string )

    Set kernel and U-Boot branch manually to skip dialog prompt

    Note

    Some branches may not be available for all devices.

    RELEASE ( string )

    Set packages release base manually to skip dialog prompt. Check here for currently available releases.

    Note

    Only stable and/or LTS upstream Debian or Ubuntu releases are officially supported. Others might work or not.

    BUILD_MINIMAL ( string )

    BSPFREEZE ( string )

    INSTALL_HEADERS ( string )

    "},{"location":"Developer-Guide_Build-Switches/#networking","title":"Networking","text":"

    NETWORKING_STACK ( string )

    Installs desired networking stack. If the parameter is undefined, it sets systemd-networkd for minimal images (MINIMAL=yes) and network-manager for the rest. Time synchronization is also changed; chrony is installed with network-manager, while systemd-timesyncd is used with systemd-networkd. In both cases, we control network settings using Netplan.

    Build switch example

    Bash
    ./compile.sh NETWORKING_STACK=\"network-manager\"\n
    "},{"location":"Developer-Guide_Build-Switches/#host-environment","title":"Host environment","text":"

    EXPERT ( string )

    Show development features and boards regardless of their support status in interactive mode.

    CLEAN_LEVEL ( comma-separated list )

    Defines what should be cleaned. Changing this option can be useful when rebuilding images or building more than one image

    CARD_DEVICE ( string )

    After successful compilation, do a verified burn of the image to the specified storage device (flash media / SD card).

    PREFER_DOCKER ( string ) - yes (default) - no

    Docker assisted compilation is on by default. Set to no if you prefer running compilation natively.

    DOCKER_ARMBIAN_BASE_IMAGE ( string )

    Defines the build host when using a Docker container (default). Here, you can see which other options are available.

    If enabled (true), the Docker build container will receive Docker credentials from the host (${HOME}/.docker/config.json) and the OCI_TARGET_BASE environment variable.

    Select the target for pull/push OCI cached images. If not set, default is used.

    GHCR_MIRROR_ADDRESS ( string )

    The default mirror address for ghcr.io, set by GHCR_MIRROR=dockerproxy, is ghcr.dockerproxy.com. When this address is unavailable, an alternative address can be set with GHCR_MIRROR_ADDRESS.

    Example:

    Bash
    ./compile.sh GHCR_MIRROR=dockerproxy GHCR_MIRROR_ADDRESS=ghcr.libcuda.so\n

    KERNEL_COMPILER ( string )

    The compiler used to compile the kernel. Usually, this option is set by the board config, but it can be set to clang to use LLVM to compile the kernel.

    Example:

    Bash
    ./compile.sh KERNEL_COMPILER=clang\n

    OPENSSHD_REGENERATE_HOST_KEYS ( boolean )

    - false (skip armbian-firstrun\u2019s OpenSSH host keys deletion and regeneration (eg: to let cloud-init set the SSH host keys) - true (execute armbian-firstrun\u2019s OpenSSH host keys deletion + regeneration)

    Manage OpenSSH host key regeneration at armbian-firstrun service.

    Example:

    Bash
    ./compile.sh OPENSSHD_REGENERATE_HOST_KEYS=false\n
    "},{"location":"Developer-Guide_Build-Switches/#filesystem","title":"Filesystem","text":"

    ROOTFS_TYPE ( string )

    Create image with different root filesystems instead of default ext4. Requires setting FIXED_IMAGE_SIZE to something smaller than the size of your SD card for F2FS

    BTRFS_COMPRESSION ( string )

    When choosing ROOTFS_TYPE=btrfs, select btrfs filesystem compression method and compression level. By default, the compression is zlib.

    Note

    The script does not check the legality of the input variable (compression ratio). Input like zlib:1234 is legal to the script but illegal to the kernel. Beware that setting this option does affect image creation only (shrinking disk size) and will not adjust /etc/fstab, so it is up to the user to later edit /etc/fstab if compression in daily operation is also wanted (beware of severe performance penalties with random IO patterns and heavy compression algorithms!).

    BTRFS_ROOT_SUBVOLUME ( string )

    When using a BTRFS image as a file system, the volume / is placed on btrfs subvolume @. The same subvolume is set as default for mounting without specifying the subvol=@ option at the time the image is mounted.

    Using BTRFS_ROOT_SUBVOLUME, you can set a different name for the root filesystem subvolume:

    Bash
    ./compile.sh ROOTFS_TYPE=btrfs BTRFS_ROOT_SUBVOLUME=@root\n

    CRYPTROOT_ENABLE ( string )

    LUKS (Linux Unified Key Setup) is a specification for block device encryption. It establishes an on-disk format for the data, as well as a passphrase/key management policy. LUKS uses the kernel device mapper subsystem via the dm-crypt module.

    When enabled, you need to provide additional information:
    CRYPTROOT_PASSPHRASE=\"MYSECRECTPASS\"             # Mandatory\nCRYPTROOT_AUTOUNLOCK=\"yes\"                       # Default: no. If set to yes you can omit CRYPTROOT_PASSPHRASE to do unattended unlocking\nCRYPTROOT_SSH_UNLOCK=\"yes\"                       # Default: yes\nCRYPTROOT_SSH_UNLOCK_PORT=\"2222\"                 # Default: 2022\nCRYPTROOT_MAPPER=armbian-root`                   # Default: armbian-root\nCRYPTROOT_PARAMETERS=\"custom cryptsetup options\" # Default: --pbkdf pbkdf2\n

    Tips and warnings

    "},{"location":"Developer-Guide_Build-Switches/#advanced","title":"Advanced","text":"

    INCLUDE_HOME_DIR ( string )

    Include directories created inside /home in final image.

    ENABLE_EXTENSIONS ( comma-separated list )

    Extensions allows to extend the Armbian build system without overloading the core with specific functionality. Extensions, stored in folder extensions are called

    Build switch example

    Bash
    ./compile.sh \\\nbuild \\\nBOARD=uefi-x86 \\\nBRANCH=current \\\nBUILD_DESKTOP=no \\\nBUILD_MINIMAL=no \\\nKERNEL_CONFIGURE=no \\\nRELEASE=noble \\\nENABLE_EXTENSIONS=mesa-vpu,nvidia \\\n

    CONSOLE_AUTOLOGIN ( string )

    Automatically login as root for local consoles at first run. Disable if your security threat model requires.

    CPUTHREADS ( string )

    Allows the user to override CTHREADS if CPUTHREADS is defined and a valid positive integer.

    If not defined, defaults to 150% the number of CPU Threads available to maximize compilation speed.

    USE_CCACHE ( string )

    Use a C compiler cache. Generally not needed due to git-worktree . Can slow performance on clean builds.

    PRIVATE_CCACHE ( string )

    Use $DEST/ccache as ccache home directory. Setting yes to this will enable CCACHE as well.

    KERNEL_BTF

    Default is to auto-detect based on build host available RAM. If not enough RAM available, use =no to accept building without BTF debug information, or use =yes to force building with BTF even if low RAM. Family code can set this to opt-out of BTF. For more information on BTF see https://docs.kernel.org/bpf/btf.html

    ARTIFACT_IGNORE_CACHE ( string )

    Enforce building from source instead of using pre-built artifacts.

    SKIP_ARMBIAN_REPO ( string )

    Enforce building without Armbian repository. Suitable for developing new releases or making custom images that don\u2019t need Armbian repository.

    SECTOR_SIZE ( value ) - 512 (default, for SD/EMMC/\u2026) - 4096 (for UFS, requires util-linux >2.41. Tested on Debian Trixie host)

    Enforce sfdisk to align partition sector sizes.

    SHARE_LOG ( string )

    Automatically upload full build logs for debugging to one of Armbian\u2019s paste servers at the end of the build process.

    Example:

    Bash
    ./compile.sh SHARE_LOG=yes\n
    "},{"location":"Developer-Guide_Build-Switches/#build-options-below-need-to-be-retested-and-added-above-could-be-deprecated","title":"Build options below need to be retested and added above (COULD BE DEPRECATED)","text":"

    DO NOT USE! Obsolete documentation, new documentation above is in progress.

    "},{"location":"Developer-Guide_Build-Switches/#hidden-options-to-minimize-user-input-for-build-automation","title":"Hidden options to minimize user input for build automation","text":""},{"location":"Developer-Guide_Build-Switches/#hidden-options-for-advanced-users-default-values-are-marked-bold","title":"Hidden options for advanced users (default values are marked bold)","text":""},{"location":"Developer-Guide_Building-with-Docker/","title":"Building with Docker","text":""},{"location":"Developer-Guide_Building-with-Docker/#officially-supported-and-tested-method-for-building-with-docker","title":"Officially supported and tested method for building with Docker","text":"

    This method works for building u-boot and kernel packages as well as building full OS images. Note! To write fresh-builded image directly to sdcard or other block device you have to enable Docker run in privileged mode. Uncomment line DOCKER_FLAGS+=(--privileged) in file userpatches\\config-docker.conf or your own docker-config file.

    Building additional packages (EXTERNAL_NEW) is not supported.

    "},{"location":"Developer-Guide_Building-with-Docker/#requirements","title":"Requirements","text":"

    Installation (https://docs.docker.com/engine/install/)

    "},{"location":"Developer-Guide_Building-with-Docker/#details","title":"Details","text":"

    There are 3 options to start build process:

    1. By passing configuration file name (config-<conf_name>.conf), stored in userpatches directory, as an argument: Text Only

    ./compile.sh docker <conf_name>\n
    2. By passing addtional line arguments to compile.sh after docker: Text Only
    ./compile.sh docker KERNEL_ONLY=yes BOARD=cubietruck BRANCH=current KERNEL_CONFIGURE=yes\n
    3. Interactively run inside docker container Text Only
    ./compile.sh docker-shell BOARD=rockpi-4a BRANCH=edge RELEASE=jammy\n

    The process creates and runs a named Docker container armbian with two named volumes armbian-cache and armbian-ccache, and mounts local directories output and userpatches.

    Options 1 and 2 compile the same as without Docker but in separate environment to prevent changes to the base system.

    The dockerfile of the created container is placed in userpatches directory, and all container-related options can be changed in userpatches/config-docker.conf file. Templates of both files are located in the config/templates directory.

    "},{"location":"Developer-Guide_Building-with-Docker/#docker-shell-interactive-mode","title":"docker-shell interactive mode","text":"

    The docker-shell interactive mode is useful for when you need to do more than just \u201cmake an image.\u201d This mode allows you to edit U-Boot and kernel sources before and after applying patches, investigate compilation errors, and so on.

    This mode also allows you to manually run individual steps of the build process.

    First, start docker-shell on the host build system: Text Only

    @droid:~/armbian$ ./compile.sh docker-shell RELEASE=bullseye BOARD=rockpi-4a BRANCH=edge\n
    From there, RELEASE=bullseye BOARD=rockpi-4a BRANCH=edge are passed into shell and will be set into envirounment variables.

    Next, we can simply start building an image: Text Only

    root@75ec76203b65:~/armbian# ./compile.sh\n
    Alternatively, you can run any function defined in the compile.sh script.

    For example, to compile U-Boot, prepare the environment with: Text Only

    ./compile.sh default prepare_host compile_sunxi_tools install_rkbin_tools\n
    Then, build U-Boot: Text Only
    ./compile.sh default compile_uboot\n
    To compile only the source code as it is without patching or modifications, run: Text Only
    ./compile.sh default COMPILE_ONLY=yes compile_uboot\n
    Note that you must enter docker-shell after a docker build, as you must download all of the required toolchains and sourcecodes beforehand.

    "},{"location":"Developer-Guide_Building-with-Multipass/","title":"Building with Multipass","text":"

    In order to build an Armbian image from scratch, whether for development purposes or to apply user customizations on top of a base image, a build environment is required. Per the Armbian documentation, Ubuntu 24.04 is the officially supported build platform.

    Multipass that is designed for quick and painless provisioning of Ubuntu VMs.

    "},{"location":"Developer-Guide_Building-with-Multipass/#creating-a-vm-and-preparing-for-build","title":"Creating a VM and preparing for build","text":"

    Multipass is available for macOS, Windows and Linux platforms.

    Once you have multipass installed, a Jammy (22.04) instance with 4 CPUs, 4GB of RAM and 25GB of space available can be provisioned with a single command:

    Bash
    multipass launch --cpus 4 --disk 25G --mem 4G --name jammy\n
    "},{"location":"Developer-Guide_Building-with-Multipass/#clone-the-build-repo","title":"Clone the build repo","text":"

    You can run commands direct on the instance to clone the build repo:

    Bash
    multipass exec jammy -- bash -c \"git clone --depth 1 https://github.com/armbian/build\" \n
    "},{"location":"Developer-Guide_Building-with-Multipass/#use-an-instance","title":"Use an instance","text":"

    Then you can get a shell to the instance and run the build as needed:

    Bash
    C:\\> multipass shell armbian\nWelcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.4.0-48-generic x86_64)\nLast login: Tue Jan 30 12:23:08 2024 from 172.22.111.1\n# Let's get building!  \nubuntu@armbian:~$ cd build\nubuntu@armbian:~/build$ ./compile.sh BOARD=orangepizero ... etc\n
    "},{"location":"Developer-Guide_Building-with-Multipass/#share-data-with-an-instance","title":"Share data with an instance","text":"

    The recommended way to share data between your host and an instance with Multipass is the command:mount Bash

    multipass mount /my/dir jammy\nmultipass info jammy\n

    Mounts: /my/dir => /my/dir

    From this point on will be available inside the instance./my/dir

    "},{"location":"Developer-Guide_Extensions-Hooks/","title":"Extension Hooks","text":""},{"location":"Developer-Guide_Extensions-Hooks/#hooks","title":"Hooks","text":""},{"location":"Developer-Guide_Extensions-Hooks/#post_family_config","title":"post_family_config","text":"

    give the config a chance to override the family/arch defaults

    This hook is called after the family configuration (sources/families/xxx.conf) is sourced. Since the family can override values from the user configuration and the board configuration, it is often used to in turn override those.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#user_config","title":"user_config","text":"

    Invoke function with user override

    Allows for overriding configuration values set anywhere else. It is called after sourcing the lib.config file if it exists, but before assembling any package lists.

    "},{"location":"Developer-Guide_Extensions-Hooks/#extension_prepare_config","title":"extension_prepare_config","text":"

    allow extensions to prepare their own config, after user config is done

    Implementors should preserve variable values pre-set, but can default values an/or validate them. This runs after user_config. Don\u2019t change anything not coming from other variables or meant to be configured by the user.

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_aggregate_packages","title":"post_aggregate_packages","text":"

    For final user override, using a function, after all aggregations are done

    Called after aggregating all package lists, before the end of compilation.sh. Packages will still be installed after this is called, so it is the last chance to confirm or change any packages.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_determine_cthreads","title":"post_determine_cthreads","text":"

    give config a chance modify CTHREADS programatically. A build server may work better with hyperthreads-1 for example.

    Called early, before any compilation work starts.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#add_host_dependencies","title":"add_host_dependencies","text":"

    run before installing host dependencies

    you can add packages to install, space separated, to ${EXTRA_BUILD_DEPS} here.

    "},{"location":"Developer-Guide_Extensions-Hooks/#fetch_sources_tools","title":"fetch_sources_tools","text":"

    fetch host-side sources needed for tools and build

    Run early to fetch_from_repo or otherwise obtain sources for needed tools.

    "},{"location":"Developer-Guide_Extensions-Hooks/#build_host_tools","title":"build_host_tools","text":"

    build needed tools for the build, host-side

    After sources are fetched, build host-side tools needed for the build.

    "},{"location":"Developer-Guide_Extensions-Hooks/#pre_install_distribution_specific","title":"pre_install_distribution_specific","text":"

    give config a chance to act before install_distribution_specific

    Called after create_rootfs_cache (prepare basic rootfs: unpack cache or create from scratch) but before install_distribution_specific (install distribution and board specific applications).

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#pre_install_kernel_debs","title":"pre_install_kernel_debs","text":"

    called before installing the Armbian-built kernel deb packages

    It is not too late to unset KERNELSOURCE here and avoid kernel install.

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_install_kernel_debs","title":"post_install_kernel_debs","text":"

    allow config to do more with the installed kernel/headers

    Called after packages, u-boot, kernel and headers installed in the chroot, but before the BSP is installed. If KERNELSOURCE is (still?) unset after this, Armbian-built firmware will not be installed.

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_family_tweaks","title":"post_family_tweaks","text":"

    customize the tweaks made by $LINUXFAMILY-specific family_tweaks

    It is run after packages are installed in the rootfs, but before enabling additional services. It allows implementors access to the rootfs (${SDCARD}) in its pristine state after packages are installed.

    "},{"location":"Developer-Guide_Extensions-Hooks/#pre_customize_image","title":"pre_customize_image","text":"

    run before customize-image.sh

    This hook is called before customize-image.sh is executed and before the overlay is mounted. It thus can be used for the same purposes as customize-image.sh without the overlay.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_customize_image","title":"post_customize_image","text":"

    post customize-image.sh hook

    Run after the customize-image.sh script is run, and the overlay is unmounted.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_post_debootstrap_tweaks","title":"post_post_debootstrap_tweaks","text":"

    run after removing diversions and qemu with chroot unmounted

    Last chance to touch the ${SDCARD} filesystem before it is copied to the final media. It is too late to run any chrooted commands, since the supporting filesystems are already unmounted.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#pre_prepare_partitions","title":"pre_prepare_partitions","text":"

    allow custom options for mkfs

    Good time to change stuff like mkfs opts, types etc.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#prepare_image_size","title":"prepare_image_size","text":"

    allow dynamically determining the size based on the $rootfs_size

    Called after ${rootfs_size} is known, but before ${FIXED_IMAGE_SIZE} is taken into account. A good spot to determine FIXED_IMAGE_SIZE based on rootfs_size. UEFISIZE can be set to 0 for no UEFI partition, or to a size in MiB to include one. Last chance to set USE_HOOK_FOR_PARTITION=yes and then implement create_partition_table hook_point.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_create_partitions","title":"post_create_partitions","text":"

    called after all partitions are created, but not yet formatted

    "},{"location":"Developer-Guide_Extensions-Hooks/#format_partitions","title":"format_partitions","text":"

    if you created your own partitions, this would be a good time to format them

    The loop device is mounted, so ${LOOP}p1 is it\u2019s first partition etc.

    "},{"location":"Developer-Guide_Extensions-Hooks/#pre_update_initramfs","title":"pre_update_initramfs","text":"

    allow config to hack into the initramfs create process

    Called after rsync has synced both /root and /root on the target, but before calling update_initramfs.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#pre_umount_final_image","title":"pre_umount_final_image","text":"

    allow config to hack into the image before the unmount

    Called before unmounting both /root and /boot.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_umount_final_image","title":"post_umount_final_image","text":"

    allow config to hack into the image after the unmount

    Called after unmounting both /root and /boot.

    Also known as (for backwards compatibility only):

    "},{"location":"Developer-Guide_Extensions-Hooks/#post_build_image","title":"post_build_image","text":"

    custom post build hook

    Called after the final .img file is built, before it is (possibly) written to an SD writer.

    "},{"location":"Developer-Guide_Extensions-Hooks/#run_after_build","title":"run_after_build","text":"

    hook for function to run after build, i.e. to change owner of $SRC

    Really one of the last hooks ever called. The build has ended. Congratulations.

    "},{"location":"Developer-Guide_Extensions-Hooks/#extension_metadata_ready","title":"extension_metadata_ready","text":"

    meta-Meta time!

    Implement this hook to work with/on the meta-data made available by the extension manager. Interesting stuff to process:

    "},{"location":"Developer-Guide_Extensions/","title":"Extensions","text":"

    \u201cI\u2019m gonna create a prepare_bootloader hook [in core] so we can refactor u-boot [into an extension]\u201d

    The extensions framework allows the board/family developers, extension authors, and users to extend the Armbian build system without overloading the core with specific functionality.

    It\u2019s a simple framework, written in Bash, that works based on function naming conventions. It provides the core and the extensions with tracing and debugging, (error control,?) inline documentation and very simple dependency resolution.

    "},{"location":"Developer-Guide_Extensions/#terminology","title":"Terminology","text":""},{"location":"Developer-Guide_Extensions/#example","title":"Example","text":""},{"location":"Developer-Guide_Extensions/#core-calls-extensions","title":"Core calls extensions","text":"

    The Armbian core build system has an extension method called run_after_build, also known as the \u201crun_after_build hook\u201d. You can find it in lib/main.sh around line 546.

    Bash
    # in lib/main.sh:546\ncall_extension_method \"run_after_build\" [...]\n
    "},{"location":"Developer-Guide_Extensions/#extension-method-implementation","title":"Extension method implementation","text":"

    Consider the following function:

    Bash
    function run_after_build__say_congratulations() { \n  echo \"Congrats, the build is finished!\"\n}\n

    Such a function is an \u201cextension method implementation\u201d called say_congratulations for the extension method run_after_build.

    "},{"location":"Developer-Guide_Extensions/#extension-file","title":"Extension file","text":"

    A file userpatches/extensions/be-festive.sh containing the above function is an \u201cextension\u201d called be-festive.

    "},{"location":"Developer-Guide_Extensions/#using-it","title":"Using it","text":"

    An user of the build system can enable that extension by adding a call to enable_extension \"be-festive\" on his configuration file, or by passing ENABLE_EXTENSIONS=be-festive as a parameter to the build.

    "},{"location":"Developer-Guide_Extensions/#naming-conventions-and-ordering","title":"Naming conventions and ordering","text":"

    An extension method implementation is just a Bash function that follows the pattern run_after_build__say_congratulations where

    The system will \u201cmagically\u201d compose a single run_after_build() function, based on all the hook functions that begin with run_after_build__.

    Hook functions will be sorted by their numerical value; hook functions that do not begin with a number will receive 500_ prefix automatically.

    So the examples run_after_build__do_this and run_after_build__500_do_this are equivalent, and will run

    "},{"location":"Developer-Guide_Extensions/#what-is-an-extension","title":"What is an extension?","text":"

    A extension is Bash source file that contains exclusively:

    Specifically, extension files should not contain any code outside of functions \u2013 they should do nothing when sourced.

    Extensions can be official Armbian fragments and live in /extensions, or can be user-specific in /userpatches/extensions.

    An extension could be implemented in any of the following file/dir structures:

    The official extensions can be used by boards, family includes, etc, while the user-specific extensions can only be used by userpatches code or via ENABLE_EXTENSIONS=my-ext,my-dir-ext build parameter.

    "},{"location":"Developer-Guide_Extensions/#single-file-vs-directory-based","title":"Single-file vs Directory-based","text":"

    They\u2019re the same, except:

    "},{"location":"Developer-Guide_Extensions/#faq","title":"FAQ","text":""},{"location":"Developer-Guide_Extensions/#can-you-give-me-examples-of-some-extensions-shipped-in-armbian","title":"Can you give me examples of some extensions shipped in Armbian?","text":""},{"location":"Developer-Guide_Extensions/#how-to-opt-out-of-a-specific-hook-function","title":"How to opt out of a specific hook function?","text":"

    Any function making use of the extension framework [generally of the form hook_name__individual_function] can be skipped in a board or family config, by way of

    Bash
    unset -f hook_name__individual_function\n

    Doing so is at the board/family maintainer\u2019s own risk and doing so is officially unsupported. Consider splitting the function into pieces so that only the part the board/family cannot tolerate is skipped.

    "},{"location":"Developer-Guide_Overview/","title":"Overview","text":""},{"location":"Developer-Guide_Overview/#what-it-does","title":"What it does?","text":"
    graph LR\n  A[./compile.sh] --> B{Change<br>kernel<br>config};\n  B ---> |yes| C[\"HW\"];\n  B ---> |no| C[\"HW\"];\n  C ---> |branch| D[\"legacy<br>vendor<br>current<br>edge\"];\n  D --> |base| E[\"Debian<br>Ubuntu\"];\n  E ---> |type| F[\"CLI\"];\n  F ---> |type| G[\"Server\"];\n  F ---> |type| H[\"Minimal\"];\n  E ---> I[\"Desktop\"];\n  I ---> K[\"XFCE\"];\n  I ---> L[\"Gnome\"];\n  I ---> M[\"Cinammon\"];\n  I ---> N[\"KDE Neon\"];
    "},{"location":"Developer-Guide_Overview/#key-advantages","title":"Key Advantages","text":"

    Check other similarities, advantages and disadvantages compared with leading industry standard build software.

    Function Armbian Yocto Buildroot Target general purpose embedded embedded / IOT U-boot and kernel compiled from sources compiled from sources compiled from sources Board support maintenance \u00a0 complete outside outside Root file system Debian or Ubuntu based custom custom Package manager APT any none Configurability limited large large Initramfs support yes yes yes Getting started quick very slow slow Cross compilation yes yes yes"},{"location":"Developer-Guide_Overview/#framework-structure","title":"Framework Structure","text":"Text Only
    \u251c\u2500\u2500 cache                                Work / cache directory\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 aptcache                         Packages\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 ccache                           C/C++ compiler\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 docker                           Docker last pull\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 git-bare                         Minimal Git\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 git-bundles                      Full Git\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 initrd                           Ram disk\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 memoize                          Git status\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 patch                            Kernel drivers patch\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 pip                              Python\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 rootfs                           Compressed userspaces\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 sources                          Kernel, u-boot and other sources\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 tools                            Additional tools like ORAS\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 utility\n\u251c\u2500\u2500 config                               Packages repository configurations\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 targets.conf                     Board build target configuration\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 boards                           Board configurations\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 bootenv                          Initial boot loaders environments per family\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 bootscripts                      Initial Boot loaders scripts per family\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 cli                              CLI packages configurations per distribution\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 desktop                          Desktop packages configurations per distribution\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 distributions                    Distributions settings\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 kernel                           Kernel build configurations per family\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 sources                          Kernel and u-boot sources locations and scripts\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 templates                        User configuration templates which populate userpatches\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 torrents                         External compiler and rootfs cache torrents\n\u251c\u2500\u2500 extensions                           Extend build system with specific functionality\n\u251c\u2500\u2500 lib                                  Main build framework libraries\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 functions\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 artifacts\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 bsp\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 cli\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 compilation\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 configuration\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 general\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 host\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 image\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 logging\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u251c\u2500\u2500 main\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 rootfs\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 tools\n\u251c\u2500\u2500 output                               Build artifact\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 deb                              Deb packages\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 images                           Bootable images - RAW or compressed\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 debug                            Patch and build logs\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 config                           Kernel configuration export location\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 patch                            Created patches location\n\u251c\u2500\u2500 packages                             Support scripts, binary blobs, packages\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 blobs                            Wallpapers, various configs, closed source bootloaders\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 bsp-cli                          Automatically added to armbian-bsp-cli package\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 bsp-desktop                      Automatically added to armbian-bsp-desktopo package\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 bsp                              Scripts and configs overlay for rootfs\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 extras-buildpkgs                 Optional compilation and packaging engine\n\u251c\u2500\u2500 patch                                Collection of patches\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 atf                              ARM trusted firmware\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 kernel                           Linux kernel patches\n|   |\u00a0\u00a0 \u2514\u2500\u2500 family-branch                Per kernel family and branch\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 misc                             Linux kernel packaging patches\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 u-boot                           Universal boot loader patches\n|       \u251c\u2500\u2500 u-boot-board                 For specific board\n|    \u00a0\u00a0 \u2514\u2500\u2500 u-boot-family                For entire kernel family\n\u251c\u2500\u2500 tools                                Tools for dealing with kernel patches and configs\n\u2514\u2500\u2500 userpatches                          User: configuration patching area\n    \u251c\u2500\u2500 config-example.conf              User: example user config file\n    \u251c\u2500\u2500 customize-image.sh               User: script will execute just before closing the image\n \u00a0\u00a0 \u251c\u2500\u2500 atf                              User: ARM trusted firmware\n \u00a0\u00a0 \u251c\u2500\u2500 extensions                       User: Extend build system with specific functionality\n \u00a0\u00a0 \u251c\u2500\u2500 kernel                           User: Linux kernel per kernel family\n \u00a0\u00a0 \u251c\u2500\u2500 misc                             User: various\n \u00a0\u00a0 \u2514\u2500\u2500 u-boot                           User: universal boot loader patches\n
    "},{"location":"Developer-Guide_User-Configurations/","title":"User Configuration","text":""},{"location":"Developer-Guide_User-Configurations/#user-provided-patches","title":"User provided patches","text":"

    You can add your own patches outside the build script. Place your patches inside the appropriate directory, for kernel or u-boot. There are no limitations except that all patches must have the file name extension .patch. userpatches directory structure mirrors directory structure of patch. Look for the hint at the beginning of patching process to select the proper directory for patches. Example:

    Text Only
    [ o.k. ] Started patching process for [ kernel sunxi-edge 4.4.0-rc6 ]\n[ o.k. ] Looking for user patches in [ userpatches/kernel/sunxi-edge ]\n

    Patches with the same file name and path in the userpatches directory tree override those in the patch directory. To replace a patch provided by Armbian maintainers, copy it from patch to the corresponding directory in userpatches and edit it to your needs. To disable a patch, create an empty file in the corresponding directory in userpatches.

    "},{"location":"Developer-Guide_User-Configurations/#user-provided-configuration","title":"User provided configuration","text":"

    A configuration file named userpatches/config-<something>.conf.sh (.conf also allowed) is a bash script that is sourced during the build if ./compile.sh something is issued. All parameters which normally are passed via command line can be used (PARAM1=value1 PARAM2=value) by using the same syntax, one separate line per PARAM. Command-line parameters still can override what is in the config file. More advanced use cases can use conditionals, define functions to implement hooks, source other/common config files, etc. A few, quite complex, examples can be found here.

    "},{"location":"Developer-Guide_User-Configurations/#user-provided-first-config","title":"User provided first config","text":"Text Only
    userpatches/firstboot.conf\n

    When detected, the system displays an informational alert and applies the first config configuration.

    "},{"location":"Developer-Guide_User-Configurations/#legacy-user-provided-configuration-deprecated-support-for-this-will-be-removed-at-some-point","title":"Legacy user provided configuration (deprecated, support for this will be removed at some point)","text":"

    If the file userpatches/lib.config exists, it will be called and can override the particular kernel and u-boot versions. For a comprehensive list of available variables, look through lib/functions/configuration/main-config.sh. Some examples of what you can change:

    Text Only
    [[ $LINUXFAMILY == sunxi64 && $BRANCH == edge ]] && BOOTBRANCH='tag:v2017.09' # conditionally change u-boot git branch/tag\nKERNELBRANCH=\"tag:v5.4.28\" #always change to this kernel tag\n
    "},{"location":"Developer-Guide_User-Configurations/#user-provided-kernel-config","title":"User provided kernel config","text":"

    If the file userpatches/linux-$LINUXFAMILY-$BRANCH.config exists, it will be used instead of the default one from config. Look for the hint at the beginning of the kernel compilation process to select the proper config file name. Example:

    Text Only
    [ o.k. ] Compiling current kernel [ 5.10.47 ]\n[ o.k. ] Using kernel config provided by user [ userpatches/linux-rockchip64-current.config ]\n
    "},{"location":"Developer-Guide_User-Configurations/#user-provided-sources-config-overrides","title":"User provided sources config overrides","text":"

    If file userpatches/sources/$LINUXFAMILY.conf exists, it will be used in addition to the default one from config/sources. Look for the hint at the beginning of the compilation process to select the proper config file name. Please note that there are some exceptions for LINUXFAMILY like sunxi (32-bit mainline sunxi) and sunxi64 (64-bit mainline sunxi)

    Example:

    Text Only
    [ o.k. ] Adding user provided sunxi64 overrides\n
    "},{"location":"Developer-Guide_User-Configurations/#user-provided-image-customization-script","title":"User provided image customization script","text":"

    You can run additional commands to customize the created image. Edit this file:

    Text Only
    userpatches/customize-image.sh\n

    and place your code here. You may test the values of variables noted in the file to use different commands for different configurations. Those commands will be executed in a chroot environment just before finalizing the image.

    To add files to the image easily, put them in userpatches/overlay and access them in /tmp/overlay from customize-image.sh

    Be advised that even though you are compiling an image on an amd64 machine, any additional apt packages you configure or commands you run in customize-image.sh will be automatically installed/executed/virtualized for the architecture of the build target SBC.

    "},{"location":"Developer-Guide_User-Configurations/#partitioning-of-the-sd-card","title":"Partitioning of the SD card","text":"

    In case you define $FIXED_IMAGE_SIZE at build time the partition containing the rootfs will be made of this size. Default behaviour when this is not defined is to shrink the partition to minimum size at build time and expand it to the card\u2019s maximum capacity at boot time (leaving an unpartitioned spare area of ~5% when the size is 4GB or less to help the SD card\u2019s controller with wear leveling and garbage collection on old/slow cards).

    You can prevent the partition expansion from within customize-image.sh by a touch /root/.no_rootfs_resize or configure the resize operation by either a percentage or a sector count using /root/.rootfs_resize (50% will use only half of the card\u2019s size if the image size doesn\u2019t exceed this or 3887103s for example will use sector 3887103 as partition end. Values without either % or s will be ignored).

    "},{"location":"Developer-Guide_Welcome/","title":"Welcome to the Armbian build framework documentation!","text":"

    Overview:

    "},{"location":"Developer-Guide_Welcome/#ansi-logging","title":"(ANSI) Logging","text":"

    Log output is stored in output/logs and provided in a few different formats. ANSI coloring is applied to both the screen and the log files themselves. Please add SHARE_LOG=yes to automatically upload logs to our paste service and provide us with the given url when reporting issues. That will allows us to check the logs on a web browser and keep to correct formatting.

    "},{"location":"Developer-Guide_Welcome/#command-line-syntax-has-changed","title":"Command line syntax has changed","text":"

    General CLI syntax: ./compile.sh PARAM=value OTHER_PARAM=other_value [<configfile> <configfile> ...] [<command>]

    "},{"location":"Developer-Guide_Welcome/#no-more-config-defaultconf-config-file-name-needs-to-be-specified-in-the-command-line","title":"No more config-default.conf, config file name needs to be specified in the command line","text":""},{"location":"Developer-Guide_Welcome/#artifacts-cache-what-the","title":"Artifacts, cache, what the \u2026?","text":"

    The armbian/build system is currently undergoing refactoring to improve its structure. Previously, the build system was a single, very complex bash script that mixed the building of .deb packages with the creation of images.

    This was reworked into a 1-to-N image-to-artifact dependency tree; a certain image build will depend on N possible \u201cartifacts\u201d. Artifacts are either .deb packages, a .tar of multiple .deb packages, or a rootfs.tar.zstd. Each artifact can be individually built, and has a specific name and a version.

    Each artifact is also now cached by default using OCI storage at ghcr.io (GitHub Container Registry). To achieve consistent caching, each artifact produces a version that includes hashes of its composing files, variables, patches, hooks, external git SHA1 references, etc. That way we can consistently check the remote OCI cache for previously-built artifacts, and possibly save image builders from having to build heavy packages just to produce an image.

    "},{"location":"Developer-Guide_Welcome/#tldr-about-artifacts-and-caching","title":"TL;DR about artifacts and caching:","text":""},{"location":"Developer-Guide_Welcome/#automatic-dockersudo-launcher","title":"Automatic Docker/sudo launcher","text":""},{"location":"Developer-Guide_Welcome/#kernel-git-trees-shallow-vs-full","title":"Kernel Git Trees: shallow vs full","text":"

    During the build, depending on which local or remote caches are hit, it might be necessary to build the Linux Kernel from scratch.

    The kernel\u2019s git repo is huge. Most build systems resort to fetching \u201cshallow\u201d trees directly from upstream git servers, to save bandwidth. Unfortunately that creates immense extra CPU load on the git servers. To avoid this problem, Armbian produces daily automated git tree exports cached in ghcr.io OCI repositories, and only uses git fetch to update the relatively small new changes from the upstream git server.

    There are two types of cached Kernel git trees:

    **TL;DR: ** KERNEL_GIT=full or KERNEL_GIT=shallow or let the system decide for you.

    "},{"location":"Developer-Guide_Welcome/#consider-forking-before-cloning-the-repo","title":"Consider forking before cloning the repo","text":"

    Before cloning the repo, consider forking it first. This will allow you to make changes and submit pull requests. You will need a GitHub account to do this; see GitHub\u2019s documentation for more information. If you fork, make sure to keep your fork up-to-date with the main repo, by rebasing your fork.

    "},{"location":"Developer-Guide_Welcome/#some-really-confusing-stuff-still-remains","title":"Some really confusing stuff still remains","text":"

    This is (by far) not a complete list:

    "},{"location":"Developer-Guide_Welcome/#multiple-u-boots-for-same-board","title":"Multiple u-boot\u2019s for same board","text":"

    We can build u-boot twice, using UBOOT_TARGET_MAP. Some example I did in https://github.com/armbian/build/blob/main/config/boards/odroidhc4.conf#L15-L20 may help.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/","title":"Development Code Review Procedures and Guidelines","text":""},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Development-Code-Review-Procedures-and-Guidelines","title":"Development Code Review Procedures and Guidelines","text":"

    This topic should give you as a developer a brief overview about what you should do, must do, aswell as can and can not do. What you as devepoler can expect from Armbian and what we expect from you.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Requirements","title":"Requirements:","text":"

    Even though you may already be a developer, just to make sure, here is an outline of the expectations for this process:

    Review Approve Merge Github ID Armbian Github Organisation Collaborator Armbian Github Organisation Member

    Armbian Organization Members are required to have:

    You should know development basics like how to get an Armbian image running on your hardware, do basic debugging, building a kernel and how to use the Armbian build system.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Code-Review","title":"Code Review:","text":"

    Some helpful guidelines for pull requests and code reviews

    It has often been said that programming is part art, part science - that is because lots of times there is no single, simple solution to a problem. Or if there is, we might not know about it. There is also an infamous joke that if there are n developers in the room, then there are n+1 opinions on how things should be done. That being said, here are some guidelines that should prevent friction when submitting or reviewing code.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#The-most-important-thing","title":"The most important thing","text":"The code has to work.

    Unless you open a PR (\u201cpull request\u201d) as a work in progress, the code should be built and tested on a device or emulator. Do not rely on CI test automation!

    If you have touched the build files and changed build setup, it is useful to test the whole build from scratch (clean build) and all of the types and flavours. If you updated external libraries, test the pertaining features. If you changed the build version, make a build and test that the version is correct.

    Having people review your code is one thing, but you should not expect them to also test the code for you when not explicitly asked for.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Context","title":"Context","text":"

    One important thing that lots of guidelines forget to mention is the context of the pull request: Sometimes it is a big refactor, sometimes it is a new feature, sometimes it is a bugfix. Some of those might be more urgent than others, and sometimes you might be under pressure to ship ASAP so the code might not be perfect or there will not be any tests or code might not be extendable. That is ok.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Everyone","title":"Everyone","text":"
  • There is no perfect code: good enough is usually good enough. That being said, try to keep the number of WTFs per minute to a minimum.
  • Accept that many programming decisions are opinions. Discuss trade-offs, which you prefer, and reach a resolution quickly.
  • Ask for clarification. (\"I didn't understand. Can you clarify?\")
  • Offer clarification, explain the decisions you made to reach a solution in question. Avoid using terms that could be seen as referring to personal traits. (\"dumb\", \"stupid\"). Assume everyone is intelligent and well-meaning.
  • Be humble. (\"I'm not sure - let's look it up.\")
  • Do not use hyperbole (\"always\", \"never\", \"endlessly\", \"nothing\"). Avoid sarcasm.
  • Remember that you are both on the same side - the goal is to make the code better. Understand that sometimes your ideas will be overruled. Even if you do turn out to be right, do not take revenge or say, \"I told you so\".
  • Talk synchronously (e.g. chat, screensharing, in person) if there are too many \"I didn't understand\" or \"Alternative solution:\" comments. Pull requests should not be the place for long discussions, architectural or otherwise.
  • Put notes on what is missing or could be improved in the PR description or comments. You can also make a Jira ticket with discussions points and possible problems or things to do and discuss it offline.
  • "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#As-a-Code-Submitter","title":"As a Code Submitter","text":"
  • PRs should be about one thing. If you do multiple things in one PR, it is hard to review. If you are fixing stuff as you go, you might want to make atomic commits and then cherry-pick those commits into separate branches, leaving the PR clean.
  • Try to keep the PRs small.
  • Having a PR description is useful. Additionally, you can also link to the Jira ticket.
  • Ideally, the PR should be finished when submitted. If the PR is work in progress, add (WIP) or [WIP] to the title.
  • You should have tests that at least cover the logic, and ideally also cover the input/output parameters and methods. (depends on context)
  • Make sure to add a documentation PR when needed https://github.com/armbian/documentation
  • "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#As-a-Reviewer","title":"As a Reviewer","text":"
  • Reviewing code is part of a normal workday. You should check for open/updated PRs / Jira ticket as often as you can.
  • Ask, do not tell. (\u201cWhat do you think about trying\u2026?\u201d rather than \u201cDon\u2019t do\u2026\u201d)
  • Offer ways to simplify or improve code.
  • Code beautification and refactoring ought to be tasks in the next sprint, except for obvious and easy-to-fix things.
  • Communicate which ideas you feel strongly about and those you do not. Explain your reasons why code should be changed. (Not in line with the style guide? A personal preference?)
  • If you disagree strongly, consider giving it a few minutes before responding; think before you react.
  • Offer alternative implementations, but assume the author already considered them. (\"What do you think about using a custom validator here?\")
  • If discussions turn too theoretical or touch big architectural questions, move the discussion offline. In the meantime, let the author make the final decision on alternative implementations.
  • Do not keep the code hostage. Keep in mind the context and the most important thing - does it work?
  • "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Merging-a-merge-request","title":"Merging a merge request","text":""},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Before-making-the-decision-to-merge","title":"Before making the decision to merge:","text":"
  • Set a milestone.
  • Consider warnings and errors from Github CI bots, code quality bots, and other reports. Unless a strong case can be made for the violation, these should be resolved before merging. A comment must be posted if the PR is merged with any failed job.
  • If the PR contains both quality and non-quality-related changes, the PR should be merged by the relevant maintainer or senior software engineer after the quality related changes are approved by more then one software engineer.
  • If a pull request is fundamentally ready, but needs only trivial fixes (such as typos), consider demonstrating a bias for action by making those changes directly without going back to the author. You can do this by using the suggest changes feature to apply your own suggestions to the pull request.

    Note that:

  • merging is limited to Armbian Github Organization members, you can apply here to become one, if you have not already been invited.
  • If the changes are not straightforward, please prefer allowing the author to make the change.
  • Before applying suggestions, edit the pull request to make sure squash and merge is enabled
  • Authors are not authorized to merge their own pull requests and need to seek approval from another maintainer / developer to merge.

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#Armbians-Assistance","title":"Armbian's Assistance","text":"

    If you have questions about being a developer or want to learn more and deeper insights about the build framework, Armbian will try to guide you to the appropriate documentation or information in a best-effort fashion. If time allows, at our descrection, we will try our best to explain and teach you personally various aspects about our processes. If best effort guidance is not enough, contact us for professional assistance.

    If you have any concerns please do not hesitate to reach out via forums, IRC or Discord. Armbian cares about the people who care about Armbian

    "},{"location":"Development-Code_Review_Procedures_and_Guidelines/#References--Sources","title":"References / Sources:","text":""},{"location":"Mirrors/","title":"How the Armbian Mirror System Works","text":""},{"location":"Mirrors/#introduction","title":"Introduction","text":"

    The Armbian mirror system is designed to efficiently distribute files, ensuring users get the best available server based on geographic proximity and server availability. This document outlines the mirroring system\u2019s operational flow, technical specifications for mirrors, and how to contribute a new server.

    "},{"location":"Mirrors/#operational-flow","title":"Operational Flow","text":"
    1. User Request

    2. Redirector Server Processing

    3. Mirror Assignment

    4. Download from Assigned Mirror

    "},{"location":"Mirrors/#benefits-of-the-mirroring-system","title":"Benefits of the Mirroring System","text":""},{"location":"Mirrors/#how-to-contribute-a-mirror","title":"How to Contribute a Mirror","text":"

    If you would like to contribute to the Armbian project by providing a mirror, follow these steps:

    "},{"location":"Mirrors/#1-choose-the-target-and-set-up-an-httphttps-hostname","title":"1. Choose the target and set up an HTTP/HTTPS hostname","text":"

    - The mirror must be accessible via HTTP, and HTTPS is preferred.

    "},{"location":"Mirrors/#2-set-up-synchronization-via-rsync","title":"2. Set up synchronization via rsync","text":"

    - Sync files from one of the official repositories using the following commands:

    Content Command Required Space Current images rsync -av rsync://rsync.armbian.com/dl 556G Packages rsync -av rsync://rsync.armbian.com/apt 84G Archived images rsync -av rsync://rsync.armbian.com/archive 1.9T Very old images rsync -av rsync://rsync.armbian.com/oldarchive 5.4T

    - Set up a cron job to sync every 2-4 hours.

    "},{"location":"Mirrors/#3-inform-us-about-your-mirror","title":"3. Inform us about your mirror","text":"

    - Once your server is configured, contact us via the contact form to integrate it into the official redirector system.

    Contributing a mirror helps improve Armbian\u2019s file distribution, ensuring faster and more reliable downloads for the global community.

    "},{"location":"Mirrors/#current-mirrors","title":"Current Mirrors","text":"Site Time Zone Flag Speed Packages Images Archive Rsync Atomo\u00a0Networks Europe/Rome 2500\u00a0Mbps Auroradev\u00a0Chicago America/Chicago 1000\u00a0Mbps Auroradev\u00a0Las\u00a0Vegas America/Los_Angeles 10000\u00a0Mbps Nardol Europe/Paris 1000\u00a0Mbps Systemonachip Europe/Vienna 1000\u00a0Mbps Distrohub Europe/Kiev 1000\u00a0Mbps SBC\u00a0mirror\u00a0Spain Europe/Madrid 1000\u00a0Mbps Hetzner\u00a0Germany Europe/Berlin 1000\u00a0Mbps Imola Europe/Ljubljana 1000\u00a0Mbps Kspace\u00a0Estonia Europe/Tallinn 10000\u00a0Mbps AARNet Australia/Sydney 100000\u00a0Mbps Albony Asia/Kolkata 1000\u00a0Mbps Macarne\u00a0LLC Europe/Amsterdam 50000\u00a0Mbps Hostiko Europe/Kiev 20000\u00a0Mbps ISCAS Asia/Shanghai 10000\u00a0Mbps OSS\u00a0Planet Asia/Taipei 1000\u00a0Mbps Digital\u00a0Streaming\u00a0Co. Asia/Taipei 50000\u00a0Mbps VineHost.NET Europe/London 1000\u00a0Mbps Yandex Europe/Moscow 10000\u00a0Mbps Alibaba\u00a0Mirrors Asia/Shanghai 10000\u00a0Mbps BFSU Asia/Shanghai 10000\u00a0Mbps c0urier.net Europe/Copenhagen 1000\u00a0Mbps CSTCloud Asia/Shanghai 10000\u00a0Mbps dotsrc.org Europe/Copenhagen 20000\u00a0Mbps Jevin\u00a0Canders\u00a0LLC America/New_York 10000\u00a0Mbps Lahansons America/Los_Angeles 10000\u00a0Mbps Nanjing\u00a0University Asia/Shanghai 10000\u00a0Mbps Shandong\u00a0University Asia/Shanghai 10000\u00a0Mbps Shanghai\u00a0Tech\u00a0University Asia/Shanghai 10000\u00a0Mbps SUSTech Asia/Shanghai 10000\u00a0Mbps Tsinghua\u00a0University Asia/Shanghai 10000\u00a0Mbps USTC Asia/Shanghai 10000\u00a0Mbps Zhejiang\u00a0University Asia/Shanghai 500\u00a0Mbps Netcup\u00a0Germany Europe/Berlin 2500\u00a0Mbps Netcup\u00a0Germany Europe/Berlin 2500\u00a0Mbps Netcup\u00a0Germany Europe/Berlin 2500\u00a0Mbps JetHome Europe/Moscow 2000\u00a0Mbps Xogium Europe/Paris 500\u00a0Mbps"},{"location":"Process_Armbian-Task-Tracking/","title":"Armbian Task Management","text":""},{"location":"Process_Armbian-Task-Tracking/#overview","title":"Overview","text":"

    TLDR; Keep task discussions in the forum. GitHub Issues are just for task metadata.

    Tasks associated with code will have an issue created in GitHub, but all dialog regarding tasks will reside on the forum in a topic containing the github Issue ID of the task.

    "},{"location":"Process_Armbian-Task-Tracking/#what-is-a-task","title":"What is a task?","text":"

    A task is something actionable that results in some sort of tangible output. ex: code, documentation, QA findings.

    Example sources of tasks include: feature requests, bugs, QA, general following of development roadmap.

    Not all support issues are tasks, but a support issue can generate a task.

    "},{"location":"Process_Armbian-Task-Tracking/#task-creation-procedure","title":"Task Creation Procedure","text":"
    1. Create issue in Armbian GitHub Repo under appropriate milestone -
    2. Copy the numeric ID of issue created
    3. Create new topic under the Tasks subforum on the Armbian Forums - Use the the naming convention of [ISSUE_ID] - Issue Name -
    4. Copy the URL of task subforum topic just created
    5. Create comment on GitHub Issue with the following Content:

      Text Only
        Please keep all discussion for this issue on the forum topic available below:\n\n  [URL](URL)\n

      -

    6. Lock comments on GitHub Issue

    "},{"location":"Process_Armbian-Task-Tracking/#task-tracking-with-github-issues","title":"Task tracking with GitHub Issues","text":"

    GitHub Issues provide an easy method to track and filter tasks by using tags and milestones. Issues also make it easy to easily associate commits and merge requests with a task. Effectively we just use GitHub issues for the metadata for reporting.

    "},{"location":"Process_Armbian-Task-Tracking/#labels","title":"Labels","text":"

    Use labels identify the purpose of a task.

    "},{"location":"Process_Armbian-Task-Tracking/#milestones","title":"Milestones","text":"

    Use milestones to divide tasks into claimed and unclaimed work.

    "},{"location":"Process_Armbian-Task-Tracking/#forum-tasks","title":"Forum Tasks","text":""},{"location":"Process_Armbian-Task-Tracking/#converting-a-topic-to-a-task","title":"Converting a topic to a task","text":"

    Sometimes support discussions can become tasks. A forum admin can assist in moving the topic to Tasks forum group. A cooresponding issue will need to be created.

    "},{"location":"Process_Armbian-Task-Tracking/#future-process-improvements","title":"Future Process Improvements","text":"

    Enhancements desired for this process (This should be a task!)

    "},{"location":"Process_Armbian-Task-Tracking/#issue-hook","title":"Issue Hook","text":"

    Ideally we can have a forum topic created upon issue creation. This will save some time.

    "},{"location":"Process_CI/","title":"Automation for developers and maintainers","text":"

    Core automation for generating images for release are held at armbian/os

    "},{"location":"Process_CI/#prepare-build-lists","title":"Prepare build lists","text":""},{"location":"Process_CI/#recommended-images","title":"Recommended images","text":"

    Recommended images on download pages are defined via regular expression mapping file https://github.com/armbian/os/blob/main/exposed.map (for changes sent PR to this file)

    Example:

    Text Only
    bananapim7/archive/Armbian_[0-9].*Bananapim7_noble_vendor_[0-9]*.[0-9]*.[0-9]*_gnome-kisak_desktop.img.xz\nbananapim7/archive/Armbian_[0-9].*Bananapim7_bookworm_vendor_[0-9]*.[0-9]*.[0-9]*_minimal.img.xz\n

    "},{"location":"Process_CI/#build-templates","title":"Build templates","text":"

    They have definitions on what kind of images we want to build - for section or for one specific board:

    YAML
    userpatches/targets-release-apps.template\nuserpatches/targets-release-community-maintained.template\nuserpatches/targets-release-nightly.template\nuserpatches/targets-release-standard-support.template\n

    From those templates we are autogenerating YAML files, which are passed to build matrix as input. Make sure to review generated YAML files if they have wanted build targets with correct exensions enabled.

    "},{"location":"Process_CI/#grouping-logic","title":"Grouping logic","text":"

    Boards are automatically divided into sections and each section is appendend to certain build scenario (minimal Debian image, Ubuntu testing with KDE, \u2026), which is defined in template.

    Section Condition standard-support-slow-hdmi HAS_VIDEO_OUTPUT = yes AND ARCH = armhf standard-support-fast-hdmi HAS_VIDEO_OUTPUT = yes AND ARCH = arm64 standard-support-headless HAS_VIDEO_OUTPUT = no standard-support-riscv64 ARCH = riscv64

    Example: if you want automated images without a desktop, add HAS_VIDEO_OUTPUT=no in board config file. Automation will only build two CLI images, Ubuntu server and Debian minimal. Which is suitable for hardware that will most likely be used headless.

    "},{"location":"Process_CI/#blacklisting","title":"Blacklisting","text":"

    Autogeneration is excluded for boards that are on blacklists:

    YAML
    userpatches/targets-automation.blacklist\nuserpatches/targets-automation-nightly.blacklist\n

    We do this if we are not happy with the automation outcomes and want to define build targets in the template.

    "},{"location":"Process_CI/#extensions","title":"Extensions","text":"

    Each board variant can have additional extensions and they are defined in this file:

    Text Only
    userpatches/targets-extensions.map\n

    Example:

    Text Only
    khadas-edge2,legacy:vendor:,ENABLE_EXTENSIONS=\"image-output-oowow,v4l2loopback-dkms,mesa-vpu\"\n
    "},{"location":"Process_CI/#kernel-descriptions-for-download-pages","title":"Kernel Descriptions for Download Pages?","text":"

    Each kernel branch can include an optional description, stored in kernel-description.json.

    "},{"location":"Process_CI/#testing","title":"Testing","text":"

    Unfortunatelly this part does not have testing at PR stage.

    "},{"location":"Process_CI/#prepare-standard-support-images-for-release","title":"Prepare Standard Support images for release","text":"Info

    Manual executing permissions are tied to release manager role.

    This build workflow is executed manually when making:

    Notes:

    "},{"location":"Process_CI/#1-open-workflow-and-click","title":"1. Open workflow and click","text":""},{"location":"Process_CI/#2-select-board","title":"2. Select board","text":"

    Bump version: Select if you want to trigger system wide version bump. Version override: Set version under which you want to release images.

    Images versions are stored in JSON files: - https://github.com/armbian/os/blob/main/stable.json - https://github.com/armbian/os/blob/main/nightly.json

    "},{"location":"Process_CI/#3-run-workflow","title":"3. Run workflow","text":"

    (Workflow takes around 15 minutes to complete. In case of network issues it can also take hours)

    Generated images are uploaded to incoming folder https://rsync.armbian.com/incoming/ under your GitHub username and once they are confirmed working, please notify @igorpecovnik to move them to official download pages. Once images are moved to main download section, automation refreshes download pages index within 15-30 minutes.

    "},{"location":"Process_CI/#aditional-options","title":"Aditional options","text":"

    Generates stable images defined in targets-release-standard-support.yaml.

    We are generating several images for each download / hardware target. They are automatically sorted by sections:

    Images generation can be customized:

    "},{"location":"Process_CI/#prepare-application-images-for-release-release-manager","title":"Prepare application images for release (release manager)","text":"

    This build workflow is executed manually when making:

    Notes:

    "},{"location":"Process_CI/#1-open-workflow-and-click_1","title":"1. Open workflow and click","text":""},{"location":"Process_CI/#2-select-board_1","title":"2. Select board","text":"

    Version override: Use this feature if you want to keep them under the same version, but not lower then last released.

    "},{"location":"Process_CI/#3-run-workflow_1","title":"3. Run workflow","text":"

    (Workflow takes around 15 minutes to complete. In case of network issues it can also take hours)

    Generated images are hosted at GitHub https://github.com/armbian/distribution/releases and released at once. Automation refreshes download pages within 15-30 minutes after/if workflow finished succesfully.

    "},{"location":"Process_CI/#aditional-options_1","title":"Aditional options","text":"

    Generates dedicated application images defined in targets-release-apps.yaml. This file is autogenerated from targets-release-apps.template. (You always edit template)

    Images generation can be customized:

    "},{"location":"Process_CI/#repository-update-cronjobrelease-manager","title":"Repository update (cronjob/release manager)","text":"

    This pulls packages from build framework OCI cache located at GitHub and from various 3rd party repositories such as Chrome, Chromium, Code, Discord, (latest) ZFS, Thunderbird, Zoom, \u2026 and pushes them to:

    "},{"location":"Process_CI/#1-open-workflow-and-click_2","title":"1. Open workflow and click","text":"

    Action is executed automatically when artifact generations completes. Or manually.

    "},{"location":"Process_CI/#2-include-artifacts-from-generated-images","title":"2. Include artifacts from generated image(s)","text":"

    When - [ ] Add https://netcup.armbian.com/partial/ to stable repo

    is selected.

    "},{"location":"Process_CI/#3-run-workflow_2","title":"3. Run workflow","text":"

    (Workflow takes around 60 minutes to complete)

    "},{"location":"Process_CI/#build-all-artifacts-cronjob","title":"Build all artifacts (cronjob)","text":"

    Generates all build artifacts cache for targets defined in targets-all-not-eos.yaml. This build job runs every 8 hours and can also be run manually when needed.

    This build job needs to be successfully completed in order to proceed generating any OS images!

    "},{"location":"Process_CI/#build-rolling-release-images-cronjob","title":"Build Rolling Release Images (cronjob)","text":"

    Generates all nighly (Rolling Release) images defined in targets-release-nightly.yaml. This file is autogenerated from targets-release-nightly.template.

    This build job runs every day at 9 a.m. UTC and can also be run manually when needed. Download pages are refreshed automatically after successful build.

    "},{"location":"Process_CI/#watchdog-cronjob","title":"Watchdog (cronjob)","text":"

    Runs every 15 minutes and re-trigger failed builds six (6) times before finally gives out. This addresses various instabilities when building many artifacts on different hardware:

    "},{"location":"Process_CI/#smoke-tests-on-hardware-devices-release-manager","title":"Smoke tests on hardware devices (release manager)","text":"

    Smoke testing is preliminary testing to reveal simple failures severe enough to, for example, reject a prospective software release. Our test case is constructed of three steps:

    "},{"location":"Process_CI/#automatic-pull-requests-labeler-pr","title":"Automatic Pull Requests Labeler (PR)","text":"

    Automatically label new pull request based on the paths of files which are being changed. Configuration file can be found in:

    Text Only
        .github/labeler.yml\n
    "},{"location":"Process_CI/#full-distro-test-builds-cronjobrelease-manager","title":"Full distro test builds (cronjob/release manager)","text":"

    Generates all supported build combinations (minimal, cli, desktops) for x86 architecture to check package level changes inconsistency and dependencies.

    Options:

    "},{"location":"Process_CI/#build-all-artifacts-adminpr","title":"Build all artifacts (admin/PR)","text":"

    Generates artifacts at Pull Requests code. Build starts when label of Pull Request is set to \u201cBuild\u201d. Requires administration privileges.

    "},{"location":"Process_CI/#lint-on-shell-scripts-pr","title":"Lint on shell scripts (PR)","text":"

    Run ShellCheck on changed shell scripts and report problems within. Linting runs automatically on pull requests.

    "},{"location":"Process_CI/#update-tools-in-build-scripts-cronjobadmin","title":"Update tools in build scripts (cronjob/admin)","text":"

    Some of our scripts download tools from a repo. These cannot be bumped by Dependabot, so this workflow is a self-created Dependabot to bump versions of those tools to stay up-to-date. This workflow only creates a PR if the version was actually updated. To add a new tool, it just needs to be added to the matrix in the script by filling out all the variables.

    "},{"location":"Process_CI/#scorecards-security-scan-pr","title":"Scorecards security scan (PR)","text":"

    Scorecards is an automated tool that assesses a number of important heuristics (\u201cchecks\u201d) associated with software security and assigns each check a score of 0-10. You can use these scores to understand specific areas to improve in order to strengthen the security posture of your project. You can also assess the risks that dependencies introduce, and make informed decisions about accepting these risks, evaluating alternative solutions, or working with the maintainers to make improvements.

    "},{"location":"Process_CI/#kernel-hardening-analysis-pr","title":"Kernel hardening analysis (PR)","text":"

    This analysis checks kernel configs and run if changed. There are plenty of security hardening options for the Linux kernel. A lot of them are not enabled by the major distros. We have to enable these options ourselves to make our systems more secure.

    "},{"location":"Process_Contribute/","title":"Collaborate on the project","text":""},{"location":"Process_Contribute/#overview","title":"Overview","text":"
    1. Fork the project.
    2. Make one or more well commented and clean commits to the repository.
    3. Perform a pull request in Github\u2019s web interface.

    If it is a new feature request, do not start the coding first. Remember to open an issue to discuss the new feature. If you want to add code to someone else pull request. Also check collection of git tips which will make your life easier.

    If you are struggling, check WEB or CLI step-by-step guide on contributing.

    "},{"location":"Process_Contribute/#source-code","title":"Source code","text":""},{"location":"Process_Contribute/#adding-a-new-board","title":"Adding a new board?","text":"

    There are no detailed instructions on how to add a new board or even a whole new board family to the build script yet. However there are a few commits / pull requests that give clues how to achieve that like

    "},{"location":"Process_Contribute/#board-maintainer","title":"Board maintainer","text":"

    If you are interested in being a maintainer please review Board Support Rules. Then apply here and wait for acceptance. Once accepted you will be added to our infrastructure. For this reason we need additional information to complete your registration process.

    Requirements?

    "},{"location":"Process_Contribute/#expectations","title":"Expectations","text":"

    Maintainers must not necessarily be persons with development experience. They act as a intersection between end-users and the development team and serve the developers in best-effort manner. They are encouraged to answer basic/simple user questions (if possible, also best effort) without having to bother the development team. They are allowed to record bugs but are not allowed to escalate bugs. Team leaders do.

    Take note that it is still up to development team\u2019s discretion what gets attention since Armbian has to plan carefully how to spend its very limited resources.

    What are we looking for?

    If something does not work, this is fine and normal. The important part is that it is documented and we get notified about the issues. Known problems should be placed into the Jira ticket and link placed to the board download page. While not required, you should have a build environment setup so you can build images with the most recent images and test them right away. Your feedback, either positive or negative, is very welcome. You are free to add comments to every commit and pull request.

    Ideally you have multiple microSD cards laying around to test regular updates on current releases and nightly without having to re-flash the same card every time to switch between branches.

    Alternatively you can use auto-built images - they are placed at the ever end of each board download pages under \u201cRolling releases\u201d.

    "},{"location":"Process_Contribute/#release-manager","title":"Release manager","text":"

    This role has additional permission that allows preparation of images for release.

    Release managers: https://github.com/orgs/armbian/teams/release-manager

    "},{"location":"Process_Managing_Workflow/","title":"Jira","text":"

    Jira where development work is entered and prioritized. https://armbian.atlassian.net/

    "},{"location":"Process_Managing_Workflow/#issue-types","title":"Issue Types","text":"

    When creating issues, try to assign issue type most appropriate. Issue type can be changed later so don\u2019t worry too much. If possible assign to a \u201cFix Version\u201d aka Release.

    "},{"location":"Process_Managing_Workflow/#special-issue-type","title":"Special Issue Type","text":""},{"location":"Process_Managing_Workflow/#work-queue","title":"Work Queue","text":"

    The easiest way to follow the work queue Upcoming Release Kanban Board. This board lists only work select for the upcoming release.

    Use the filter buttons at top to quickly see unassigned work, work assigned to you, bugs, and work recently updated.

    Work is listed in 3 columns, and sorted by priority.

    Columns: * Todo * Work prioritized to be done next * Pick up any task from this column * In Progress * Work In Progress * Done * Shows recently completed work. Has time limit to keep board clean

    "},{"location":"Process_Managing_Workflow/#managing-work","title":"Managing Work","text":"

    All issues for an upcoming release are assigned a \u201cFix Version\u201d to indicate release number.

    "},{"location":"Process_Managing_Workflow/#backlog","title":"Backlog","text":"

    With the Kanban Board, there are 2 states for the Upcoming Release backlog.

    All issues for an upcoming release are assigned a \u201cFix Version\u201d to indicate release number.

    "},{"location":"Process_Managing_Workflow/#mobile-access","title":"Mobile access","text":"

    You can download the app for Android or iOS.

    "},{"location":"Process_Release-Model/","title":"Release Model","text":""},{"location":"Process_Release-Model/#rolling-releases","title":"Rolling releases","text":"

    Armbian provides automated daily rolling releases of small selection of images for all supported targets. Images are available at respective board download pages: https://www.armbian.com/download. Armbian also populates its own packages repository so updates are available as an upgrade for existing installations.

    "},{"location":"Process_Release-Model/#point-releases","title":"Point releases","text":"

    Armbian runs \u201ctrain\u201d based point releases. Whatever is ready to board the train, does so. Whatever is not has to wait for the next train. This enables us to have a predictable release cycles making it easy to plan. It also puts the responsibility on developers to make sure they have features ready on time.

    Armbian releases quarterly at the end of February, May, August, November. Offset is because we all know that nothing happens for half of December. At the beginning of a release cycle, we have a planning meeting and two weeks before the end of the release we freeze integration of new features.

    "},{"location":"Process_Release-Model/#release-cycle","title":"Release Cycle","text":"

    Releases last three months. Each release starts with a meeting for planning. After planning, developers and development teams build their deliverable using whatever methods (scrum, kanban, waterfall, \u2026 ) they want but shall commit their code frequently, leading up to the last 2 weeks. The project does not accept \u201cdumps\u201d of code at the end. Commit early and often on master. Two weeks before the release date, we halt feature integration and only allow bug fixes. At some point during those two weeks, we start the release candidate process. This process starts by pulling a branch off master that will become the release branch. That frees up master for development on the next release. On the release candidate branch we work on bug fixes, and choose \u201crelease candidate\u201d, RC, tags. The software at that tag is a candidate for release, and it is submitted to automated and manual tests on real hardware. If automated tests are passing, we can officially tag it as the release. If it does not, we enter another bug fix cycle and create a new release candidate. We iterate until we have a candidate that can be the formal release. Usually, this takes 2-3 cycles and 1-3 weeks of time.

    Development epics, stories and bugs for each release are tracked through Jira.

    "},{"location":"Process_Release-Model/#release-branching-versioning-and-tags","title":"Release Branching, Versioning and Tags","text":"

    Branches in Armbian follow this convention:

    Each Armbian release will have the following version format:

    Format: <major>.<minor>.<revision>

    <major> and <minor> version are incremented at the end of the release cycles while <revision> is incremented for a fix.

    "},{"location":"Process_Release-Model/#release-naming","title":"Release Naming","text":"version codename release month work 19.11 Vaquita November done 20.02 Chiru February done 20.05 Kagu May done 20.08 Caple August done 20.11 Tamandua November done 21.02 Urubu February done 21.05 Jerboa May done 21.08 Caracal August done 21.11 Sambar November cancelled 22.02 Pig February done 22.05 Jade May done 22.08 Yapok August done 22.11 Goral November done 23.02 Quoll February done 23.05 Suni May done 23.08 Colobus August done 23.11 Topi November done 24.02 Kereru February done 24.05 Havier May done 24.08 Yelt August done 24.11 Stirk November planned 25.02 Iiwi February planned 25.05 Caiman May planned 25.08 Dunnart August planned 25.11 Brach November planned 26.02 Goa February planned

    by https://www.codenamegenerator.com from unusual animals

    "},{"location":"Process_Release-Model/#release-coordinating","title":"Release Coordinating","text":""},{"location":"Process_Release-Model/#summary","title":"Summary","text":"

    A release starts as a RC branch cut from main at freeze time. Once a RC branch is cut, main can be unfrozen and development can continue. RC branch is a rolling release that accepts bug fixes. The bug fixes should be cherry-picked back to main branch. Once the RC is stable, a final release as a branch named after its version. A release is never merged to main. Once a release is complete, it only should be updated for severe bugs and security vulnerabilities. A release is only maintained until the next release.

    "},{"location":"Process_Release-Model/#1-forum-communication","title":"1. Forum Communication","text":"

    Text Only

    Release Candidate Code Freeze Date: YYYY-MM-DD\nRelease Date: YYYY-MM-DD\nRelease Candidate Branch Link: URL\nRelease Changelog: URL\nRelease Coordinator: @yourname\nTesting Tracking Sheet: https://example.com/link  (google sheets)\n\nThe goal of this thread is to discuss testing, bugfixes, and the overall quality of the release.  Once the release is complete, this thread should be locked and unpinned. \n
    - Before Code Freeze \u2013 Make note in the thread the incomplete Jira issues tagged for the release example - After test images are procuded, engage in community for assistants wih testing.. forums, Twitter, etc. share this tool

    "},{"location":"Process_Release-Model/#2-release-candidate-branch-management","title":"2. Release Candidate Branch Management","text":""},{"location":"Process_Release-Model/#3-release","title":"3. Release","text":""},{"location":"Quick_facts/","title":"Quick Facts","text":""},{"location":"Quick_facts/#what-is-armbian-linux","title":"What is Armbian Linux?","text":"

    Armbian Linux provides optimized Debian and Ubuntu Linux images for ARM-based SBCs. There is an incredible ecosystem of small computing platforms that are powerful alternatives to the Raspberry Pi. Armbian\u2019s mission is to provide a uniform system offering that is trustworthy to run on any of the dozens of OS-neglected ARM single board computers.

    "},{"location":"Quick_facts/#challenges","title":"Challenges","text":""},{"location":"Quick_facts/#armbian-is-the-opposite-of-raspbian","title":"Armbian is the opposite of Raspbian","text":"

    Raspbian has dozens of contributors to focus on a single SBC platform. Armbian has a dozen contributors to focus on 100+ SBCs spread over 30 platforms.

    "},{"location":"Quick_facts/#balancing-development-and-support","title":"Balancing Development and Support","text":"

    Given the point above, resources are thin. Armbian developers have to focus on the core mission of maintaining the Armbian Build Platform. We heavily rely on other members of the community to support each other. Although Armbian does provide a lot of user friendly features, the reality is that Armbian is for more advanced users. If you are really struggling with your SBC, you may want to consider first getting more comfortable with Raspbian Linux on the Raspberry Pi.

    "},{"location":"Quick_facts/#more-sbcs-continuously-coming-to-market","title":"More SBCs continuously coming to market","text":"

    SBC and TV Box manufacturers love to design and ship new products. Unfortunately they do not like to spend time on software and instead rely on community projects such as Armbian to fill in the gaps.

    "},{"location":"Quick_facts/#benefits","title":"Benefits","text":""},{"location":"Quick_facts/#simple","title":"Simple","text":"

    BASH or ZSH shell, standard Debian/Ubuntu utilities. Common and specific features can be with minimalistic menu-driven utility. Login is possible via serial, HDMI/VGA or SSH.

    "},{"location":"Quick_facts/#light","title":"Light","text":"

    No bloatware or spyware. Special utilities are completely optional. Suitable for newcomers and professionals.

    "},{"location":"Quick_facts/#optimized","title":"Optimized","text":"

    A distributed image is compacted to real data size and starts at around of 1G. Size is optimized for SD card usage. Bigger is better. Installing applications later severely reduces the life of your SD card. They were not designed for this type of usage.

    "},{"location":"Quick_facts/#fast","title":"Fast","text":"

    Boards are optimized on kernel and userspace level. DVFS optimization, memory log caching, browser profile memory caching, swap usage tuning, garbage commit delay. Our system runs almost read-only and is one of the the fastest Linux for many development boards in just about every case.

    "},{"location":"Quick_facts/#secure","title":"Secure","text":"

    Security level is on a stock Debian/Ubuntu level and can be hardened with the configuration utility. It provides a good starting point for industrial or home usage. The system is regularly inspected by professionals within the community. Each official stable build is thoroughly tested. Images are a direct base for all 3rd party builders.

    "},{"location":"Quick_facts/#supported","title":"Supported","text":"

    Providing long term updates, security fixes, documentation, user support.

    "},{"location":"Quick_facts/#smart","title":"Smart","text":"

    Deep understanding how boards work, how operating system work and how hardware should be designed to run better. Involved in board design. Experience in Linux since early 90\u2019. Specialized in ARM development boards since 2013.

    "},{"location":"Quick_facts/#open","title":"Open","text":"

    Open source build script and kernel development, maintenance and distribution for more than 30 different ARM and ARM64 Linux kernels. Powerful build and software development tools. Can run in fully parallel mode. Can run under Docker.

    "},{"location":"Release_Board-Maintainers/","title":"Board Maintainers","text":""},{"location":"Release_Board-Maintainers/#how-to-become-a-maintainer","title":"How to become a maintainer?","text":"

    If you are interested in being a maintainer please review Board Support Rules. Then apply here and wait for acceptance. Once accepted you will be added to our infrastruture. For this reason we need additional information to complete your registration process.

    Requirements?

    "},{"location":"Release_Board-Maintainers/#expectations","title":"Expectations","text":"

    Maintainers must not necessarily be persons with development experience. They act as a intersection between end-users and the development team and serve the developers in best-effort manner. They are encouraged to answer basic/simple user questions (if possible, also best effort) without having to bother the development team. They are allowed to record bugs but are not allowed to escalate bugs. Team leaders do.

    Take note that it is still up to development team\u2019s discretion what gets attention since Armbian has to plan carefully how to spend its very limited resources.

    What are we looking for?

    If something does not work, this is fine and normal. The important part is that it is documented and we get notified about the issues. Known problems should be placed into the Jira ticket and link placed to the board download page. While not required, you should have a build environment setup so you can build images with the most recent images and test them right away. Your feedback, either positive or negative, is very welcome. You are free to add comments to every commit and pull request.

    Ideally you have multiple microSD cards laying around to test regular updates on current releases and nightly without having to re-flash the same card every time to switch between branches.

    Alternatively you can use auto-built images - they are placed at the ever end of each board download pages under \u201cRolling releases\u201d.

    "},{"location":"Release_Changelog/","title":"Changelog","text":""},{"location":"Release_Changelog/#whats-changed","title":"What\u2019s Changed","text":""},{"location":"Release_Changelog/#v25111-2025-11-30","title":"v25.11.1 (2025-11-30)","text":""},{"location":"Release_Changelog/#v2581-2025-8-26","title":"v25.8.1 (2025-8-26)","text":""},{"location":"Release_Changelog/#v2551-2025-5-26","title":"v25.5.1 (2025-5-26)","text":""},{"location":"Release_Changelog/#v2522-2025-2-25","title":"v25.2.2 (2025-2-25)","text":""},{"location":"Release_Changelog/#v24111-2024-11-28","title":"v24.11.1 (2024-11-28)","text":""},{"location":"Release_Changelog/#v2484-2024-10-12","title":"v24.8.4 (2024-10-12)","text":""},{"location":"Release_Changelog/#v2483-2024-09-13","title":"v24.8.3 (2024-09-13)","text":""},{"location":"Release_Changelog/#v2481-2024-08-31","title":"v24.8.1 (2024-08-31)","text":""},{"location":"Release_Changelog/#v2455-2024-25-7","title":"v24.5.5 (2024-25-7)","text":""},{"location":"Release_Changelog/#v2454-2024-21-7","title":"v24.5.4 (2024-21-7)","text":""},{"location":"Release_Changelog/#v2453-2024-01-7","title":"v24.5.3 (2024-01-7)","text":""},{"location":"Release_Changelog/#v2452-2024-18-6","title":"v24.5.2 (2024-18-6)","text":""},{"location":"Release_Changelog/#v2451-2024-25-5","title":"v24.5.1 (2024-25-5)","text":""},{"location":"Release_Changelog/#closed-projects","title":"Closed projects","text":"