Skip to content

Commit

Permalink
cli: Add command "dts-check"
Browse files Browse the repository at this point in the history
Validates the dts/dtb file for the selected board and outputs the validation logs to the user.
This can be used when adding a new board, developing or improving a dts file. Should lead to higher quality device trees and patches overall, if used.
Will show warnings/errors if patches patch in some functionalities to a devicetree file without patching in the dt-bindings .yaml at the same time.
  • Loading branch information
ColorfulRhino authored and rpardini committed Jun 23, 2024
1 parent ec18180 commit c4373fa
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 13 deletions.
6 changes: 6 additions & 0 deletions lib/functions/cli/commands.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

function armbian_register_commands() {
# More than one command can map to the same handler. In that case, use ARMBIAN_COMMANDS_TO_VARS_DICT for specific vars.
# The handlers' functions "cli_${ARMBIAN_COMMAND_HANDLER}_pre_run" and "cli_${ARMBIAN_COMMAND_HANDLER}_run" get automatically called in "utils-cli.sh"
# Example: For command "docker-purge", the handler is "docker", which means the functions "cli_docker_pre_run" and "cli_docker_run" inside "cli-docker.sh are automatically called by "utils-cli.sh"
declare -g -A ARMBIAN_COMMANDS_TO_HANDLERS_DICT=(
["docker"]="docker" # thus requires cli_docker_pre_run and cli_docker_run
["docker-purge"]="docker"
Expand Down Expand Up @@ -70,6 +72,9 @@ function armbian_register_commands() {
["kernel-config"]="artifact"
["rewrite-kernel-config"]="artifact"

# Patch kernel and then check & validate the dtb file
["dts-check"]="artifact" # Not really an artifact, but cli output only. Builds nothing.

["uboot"]="artifact"
["uboot-patch"]="artifact"
["atf-patch"]="artifact"
Expand Down Expand Up @@ -129,6 +134,7 @@ function armbian_register_commands() {
["rewrite-kernel-config"]="WHAT='kernel' KERNEL_CONFIGURE='yes' ARTIFACT_WILL_NOT_BUILD='yes' ARTIFACT_IGNORE_CACHE='yes' ${common_cli_artifact_vars}"
["kernel-patch"]="WHAT='kernel' CREATE_PATCHES='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}"
["kernel-dtb"]="WHAT='kernel' KERNEL_DTB_ONLY='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}"
["dts-check"]="WHAT='kernel' DTS_VALIDATE='yes' ARTIFACT_WILL_NOT_BUILD='yes'" # Not really an artifact, but cli output only. Builds nothing.

["uboot"]="WHAT='uboot' ${common_cli_artifact_vars}"
["uboot-config"]="WHAT='uboot' UBOOT_CONFIGURE='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}"
Expand Down
22 changes: 22 additions & 0 deletions lib/functions/compilation/kernel-dts-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2013-2024 Armbian
#
# This file is a part of the Armbian Build Framework
# https://github.com/armbian/build/


# Validate the dts/dtb file against dt bindings found in "linux/Documentation/devicetree/bindings/"
# See slide 15 in https://elinux.org/images/1/17/How_to_Get_Your_DT_Schema_Bindings_Accepted_in_Less_than_10_Iterations_-_Krzysztof_Kozlowski%2C_Linaro_-_ELCE_2023.pdf
function validate_dts() {
[[ -z "${BOOT_FDT_FILE}" ]] && exit_with_error "BOOT_FDT_FILE not set! No dts file to validate."
display_alert "Validating dts/dtb file for selected board" "${BOOT_FDT_FILE} ; see output below" "info"

# "make CHECK_DTBS=y" uses the pip modules "dtschema" and "yamllint"
prepare_python_and_pip

# Run "make CHECK_DTBS=y" for the selected board's dtb file
run_kernel_make "CHECK_DTBS=y ${BOOT_FDT_FILE}"
}
13 changes: 7 additions & 6 deletions lib/functions/compilation/kernel-make.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ function run_kernel_make_internal() {
prepare_distcc_compilation_config

common_make_envs=(
"CCACHE_BASEDIR=\"$(pwd)\"" # Base directory for ccache, for cache reuse # @TODO: experiment with this and the source path to maximize hit rate
"CCACHE_TEMPDIR=\"${CCACHE_TEMPDIR:?}\"" # Temporary directory for ccache, under WORKDIR
"PATH=\"${toolchain}:${PATH}\"" # Insert the toolchain first into the PATH.
"DPKG_COLORS=always" # Use colors for dpkg @TODO no dpkg is done anymore, remove?
"XZ_OPT='--threads=0'" # Use parallel XZ compression
"TERM='${TERM}'" # Pass the terminal type, so that 'make menuconfig' can work.
"CCACHE_BASEDIR=\"$(pwd)\"" # Base directory for ccache, for cache reuse # @TODO: experiment with this and the source path to maximize hit rate
"CCACHE_TEMPDIR=\"${CCACHE_TEMPDIR:?}\"" # Temporary directory for ccache, under WORKDIR
"PATH=\"${toolchain}:${PYTHON3_INFO[USERBASE]}/bin:${PATH}\"" # Insert the toolchain and the pip binaries into the PATH
"PYTHONPATH=\"${PYTHON3_INFO[MODULES_PATH]}:${PYTHONPATH}\"" # Insert the pip modules downloaded by Armbian into PYTHONPATH (needed for dtb checks)
"DPKG_COLORS=always" # Use colors for dpkg @TODO no dpkg is done anymore, remove?
"XZ_OPT='--threads=0'" # Use parallel XZ compression
"TERM='${TERM}'" # Pass the terminal type, so that 'make menuconfig' can work.
"COLUMNS='${COLUMNS:-160}'"
"COLORFGBG='${COLORFGBG}'"
)
Expand Down
13 changes: 11 additions & 2 deletions lib/functions/compilation/kernel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function compile_kernel() {
declare hash pre_patch_version
kernel_main_patching # has it's own logging sections inside

# Stop after patching;
# Stop after patching.
if [[ "${PATCH_ONLY}" == yes ]]; then
display_alert "PATCH_ONLY is set, stopping." "PATCH_ONLY=yes and patching success" "cachehit"
return 0
Expand All @@ -72,21 +72,30 @@ function compile_kernel() {
# re-read kernel version after patching
declare version
version=$(grab_version "$kernel_work_dir")
display_alert "Compiling $BRANCH kernel" "$version" "info"

# determine the toolchain
declare toolchain
LOG_SECTION="kernel_determine_toolchain" do_with_logging do_with_hooks kernel_determine_toolchain

kernel_config # has it's own logging sections inside

# Validate dts file if flag is set and stop after validation.
# Has to happen after kernel .config file was created
if [[ "${DTS_VALIDATE}" == yes ]]; then
LOG_SECTION="validate_dts" do_with_logging validate_dts
display_alert "DTS_VALIDATE is set, stopping." "DTS_VALIDATE=yes and dts sucessfully checked. See output above to fix your board's dts file." "cachehit"
return 0
fi

# Stop after configuring kernel, but only if using a specific CLI command ("kernel-config").
# Normal "KERNEL_CONFIGURE=yes" (during image build) is still allowed.
if [[ "${KERNEL_CONFIGURE}" == yes && "${ARMBIAN_COMMAND}" == *kernel-config ]]; then
display_alert "Stopping after configuring kernel" "" "cachehit"
return 0
fi

display_alert "Compiling $BRANCH kernel" "$version" "info"

# build via make and package .debs; they're separate sub-steps
kernel_prepare_build_and_package # has it's own logging sections inside

Expand Down
17 changes: 14 additions & 3 deletions lib/functions/general/python-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ function early_prepare_pip3_dependencies_for_python_tools() {
"oras==0.1.30" # for OCI stuff in mapper-oci-update
"Jinja2==3.1.4" # for templating
"rich==13.7.1" # for rich text formatting
"dtschema" # for checking dts files and dt bindings (use latest version)
"yamllint" # for checking dts files and dt bindings (use latest version)
)
return 0
}
Expand All @@ -47,14 +49,20 @@ function prepare_python_and_pip() {
fi

# Check that the actual python3 --version is 3.9 at least
declare python3_version python3_full_version
python3_full_version="$("${python3_binary_path}" --version)" # "cut" below masks errors, do it twice.
declare python3_version python3_version_full
python3_version_full="$("${python3_binary_path}" --version)" # "cut" below masks errors, do it twice.
python3_version="$("${python3_binary_path}" --version | cut -d' ' -f2)"
display_alert "Python3 version" "${python3_version} - '${python3_full_version}'" "info"
display_alert "Python3 version" "${python3_version} - '${python3_version_full}'" "info"
if ! linux-version compare "${python3_version}" ge "3.9"; then
exit_with_error "Python3 version is too old (${python3_version}), need at least 3.9"
fi

declare python3_version_majorminor python3_version_string
# Extract the major and minor version numbers (e.g., "3.12" instead of "3.12.2")
python3_version_majorminor=$(echo "${python3_version_full}" | awk '{print $2}' | cut -d. -f1,2)
# Construct the version string (e.g., "python3.12")
python3_version_string="python$python3_version_majorminor"

# Check actual pip3 version
# Note: we don't use "/usr/bin/pip3" at all, since it's commonly missing. instead "python -m pip"
# The hostdep package python3-pip is still required, and other crazy might impact this.
Expand Down Expand Up @@ -100,16 +108,19 @@ function prepare_python_and_pip() {
declare python_hash_base="${python_pip_cache}/pip_pkg_hash"
declare python_hash_file="${python_hash_base}_${python3_pip_dependencies_hash}"
declare python3_user_base="${python_pip_cache}/base"
declare python3_modules_path="${python3_user_base}/lib/${python3_version_string}/site-packages"
declare python3_pycache="${python_pip_cache}/pycache"

# declare a readonly global dict with all needed info for executing stuff using this setup
declare -r -g -A PYTHON3_INFO=(
[BIN]="${python3_binary_path}"
[USERBASE]="${python3_user_base}"
[MODULES_PATH]="${python3_modules_path}"
[PYCACHEPREFIX]="${python3_pycache}"
[HASH]="${python3_pip_dependencies_hash}"
[DEPS]="${python3_pip_dependencies[*]}"
[VERSION]="${python3_version}"
[VERSION_STRING]="${python3_version_string}"
[PIP_VERSION]="${pip3_version}"
)

Expand Down
13 changes: 11 additions & 2 deletions lib/library-functions.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# This file is/was autogenerated by lib/tools/gen-library.sh; don't modify manually
# This file is/was autogenerated by ./lib/tools/gen-library.sh; don't modify manually

# no errors tolerated. invoked before each sourced file to make sure.
#set -o pipefail # trace ERR through pipes - will be enabled "soon"
Expand Down Expand Up @@ -361,6 +361,15 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true
# shellcheck source=lib/functions/compilation/kernel-debs.sh
source "${SRC}"/lib/functions/compilation/kernel-debs.sh

# no errors tolerated. invoked before each sourced file to make sure.
#set -o pipefail # trace ERR through pipes - will be enabled "soon"
#set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled
set -o errtrace # trace ERR through - enabled
set -o errexit ## set -e : exit the script if any statement returns a non-true return value - enabled
### lib/functions/compilation/kernel-dts-check.sh
# shellcheck source=lib/functions/compilation/kernel-dts-check.sh
source "${SRC}"/lib/functions/compilation/kernel-dts-check.sh

# no errors tolerated. invoked before each sourced file to make sure.
#set -o pipefail # trace ERR through pipes - will be enabled "soon"
#set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled
Expand Down Expand Up @@ -1185,4 +1194,4 @@ source "${SRC}"/lib/functions/rootfs/trap-rootfs.sh
#set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled
set -o errtrace # trace ERR through - enabled
set -o errexit ## set -e : exit the script if any statement returns a non-true return value - enabled
# This file is/was autogenerated by lib/tools/gen-library.sh; don't modify manually
# This file is/was autogenerated by ./lib/tools/gen-library.sh; don't modify manually

0 comments on commit c4373fa

Please sign in to comment.