diff --git a/doc/setup.rst b/doc/setup.rst index 25765c4591ab182c4159522f2c6af45458fc1a3d..bb46dbdc9913660965d80443960563b703117735 100644 --- a/doc/setup.rst +++ b/doc/setup.rst @@ -32,11 +32,11 @@ From GitLab LISA is hosted on `GitLab `_. The following references are available: - * ``main`` branch: Main development branch where pull requests are merged as they - come. - * ``release`` branch: Branch updated upon release of the ``lisa-linux`` package on - PyPI. - * ``vX.Y.Z`` tags: One tag per release of ``lisa-linux`` PyPI package. +* ``main`` branch: Main development branch where pull requests are merged as they + come. +* ``release`` branch: Branch updated upon release of the ``lisa-linux`` package on + PyPI. +* ``vX.Y.Z`` tags: One tag per release of ``lisa-linux`` PyPI package. LISA has a minimum Python version requirement of: @@ -66,10 +66,10 @@ that Ubuntu splits the Python distribution into multiple packages, which must all be installed. The list is available inside ``install_base.sh`` and is more or less: - * python3 - * python3-pip - * python3-venv - * python3-tk +* python3 +* python3-pip +* python3-venv +* python3-tk You might also find a ``python3.X-full`` package that contains everything you need. @@ -133,21 +133,21 @@ Target installation LISA's "device under test" is called target. In order to be able to run e.g. tests on a target, you will need the provide a minimal environment composed of: - * An ``adb`` or ``ssh`` server - * For some tests, a working Python 3 installation +* An ``adb`` or ``ssh`` server +* For some tests, a working Python 3 installation This can be provided by a a regular GNU/Linux or Android distribution, but can also be done with a minimal buildroot environment. The benefits are: - * Almost no background task that can create issues when testing the Linux - kernel scheduler - * Can be used as a in-memory initramfs, thereby avoiding activity of USB or - NFS-related kthreads, as it has been the source of issues on some boards - with wonky USB support. - * Using initramfs has the added advantages of ease of deployment (can be - integrated in the kernel image, reducing the amount of assets to flash) - and avoids issues related to board state (a reboot fully resets the - userspace). +* Almost no background task that can create issues when testing the Linux + kernel scheduler +* Can be used as a in-memory initramfs, thereby avoiding activity of USB or + NFS-related kthreads, as it has been the source of issues on some boards + with wonky USB support. +* Using initramfs has the added advantages of ease of deployment (can be + integrated in the kernel image, reducing the amount of assets to flash) + and avoids issues related to board state (a reboot fully resets the + userspace). Buildroot image creation is assisted with these commands, available in lisa shell :ref:`buildroot-commands`. @@ -198,38 +198,38 @@ LISA Python package will compile and load the module automatically when required for tracing so there is usually no reason to do so manually. The most reliable way to configure LISA for building the module is: - * Kernel config (also available under ``$LISA_HOME/tools/kmodules/kconfig_fragment.config``): +* Kernel config (also available under ``$LISA_HOME/tools/kmodules/kconfig_fragment.config``): - .. exec:: - :literal: + .. exec:: + :literal: - from pathlib import Path - from lisa._assets import ASSETS_PATH - frag_path = Path(ASSETS_PATH) / 'kmodules' / 'kconfig_fragment.config' - frag = frag_path.read_text() - print(frag) + from pathlib import Path + from lisa._assets import ASSETS_PATH + frag_path = Path(ASSETS_PATH) / 'kmodules' / 'kconfig_fragment.config' + frag = frag_path.read_text() + print(frag) - * Target configuration (:class:`lisa.target.TargetConf`): +* Target configuration (:class:`lisa.target.TargetConf`): - .. code-block:: yaml + .. code-block:: yaml - target-conf: - kernel: - # If this is omitted, LISA will try to download a kernel.org - # released tarball. If the kernel has only minor differences with - # upstream, it will work, but can also result in compilation - # errors due to mismatching headers. - src: /home/foobar/linux/ - modules: - # This is not mandatory but will use a tested chroot to build - # the module. If that is omitted, ``CROSS_COMPILE`` will be - # used (and inferred if not set). - build-env: alpine + target-conf: + kernel: + # If this is omitted, LISA will try to download a kernel.org + # released tarball. If the kernel has only minor differences with + # upstream, it will work, but can also result in compilation + # errors due to mismatching headers. + src: /home/foobar/linux/ + modules: + # This is not mandatory but will use a tested chroot to build + # the module. If that is omitted, ``CROSS_COMPILE`` will be + # used (and inferred if not set). + build-env: alpine - # It is advised not to set that, but in case overlayfs is - # unusable (e.g. inside an LXC or docker container for a CI - # system depending on config), this should do the trick. - # overlay-backend: copy + # It is advised not to set that, but in case overlayfs is + # unusable (e.g. inside an LXC or docker container for a CI + # system depending on config), this should do the trick. + # overlay-backend: copy .. note:: If ``build-env: host`` is used (default), ensure that your setup is ready to compile a kernel. Notably, ensure that you have kernel build @@ -247,15 +247,15 @@ events provided by the module are required). In order to improve interoperation with other systems, a CLI tool is also provided to load the module easily: - .. code-block:: sh +.. code-block:: sh - # Compile and load the module. - lisa-load-kmod --conf target_conf.yml + # Compile and load the module. + lisa-load-kmod --conf target_conf.yml - # Runs "echo hello world" with the module loaded, then unloads it. - lisa-load-kmod --conf target_conf.yml -- echo hello world + # Runs "echo hello world" with the module loaded, then unloads it. + lisa-load-kmod --conf target_conf.yml -- echo hello world - # See # lisa-load-kmod --help for more options. + # See # lisa-load-kmod --help for more options. .. note:: The module name may be different if it was compiled manually vs @@ -265,8 +265,8 @@ provided to load the module easily: Manual route ............ - .. _manual-module-setup-warning: - .. _manual-module-setup-warning2: +.. _manual-module-setup-warning: +.. _manual-module-setup-warning2: Manual build of the module are not supported. You may be able to hack your way but if you do so, you are on your own. Also keep in mind that you will need to diff --git a/lisa/_assets/kmodules/build_module b/lisa/_assets/kmodules/build_module deleted file mode 100755 index c56e6f6b0e47b0bc162f6df384ade7eb79322af8..0000000000000000000000000000000000000000 --- a/lisa/_assets/kmodules/build_module +++ /dev/null @@ -1,55 +0,0 @@ -#! /bin/bash -# SPDX-License-Identifier: Apache-2.0 -# -# Copyright (C) 2021, ARM Limited and contributors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -set -eu - -export KERNEL_SRC=$(readlink -fe "$1") -export MODULE_SRC=$(readlink -fe "$2") -INSTALL_MOD_PATH=${3:-$(dirname "${BASH_SOURCE[0]}")} - -export INSTALL_MOD_PATH=$(readlink -fe "$INSTALL_MOD_PATH") -export ARCH=${ARCH:-$LISA_HOST_ABI} - -convert_arch() { - case $1 in - x86_64) echo x86;; - aarch64) echo arm64;; - *) echo "$1";; - esac -} - -export ARCH=$(convert_arch "$ARCH") -LISA_HOST_ABI=$(convert_arch "$LISA_HOST_ABI") - -echo "Building module for ARCH=$ARCH" - -case $ARCH in - $LISA_HOST_ABI) - ;; - arm64) - export CROSS_COMPILE=${CROSS_COMPILE:-aarch64-linux-gnu-} - ;; - arm) - export CROSS_COMPILE=${CROSS_COMPILE:-arm-linux-gnueabi-} - ;; - *) - echo "ERROR: Unknown ARCH=$ARCH" >&2 - exit 1 - ;; -esac - -make -C "$MODULE_SRC" diff --git a/lisa/_assets/kmodules/lisa/Makefile b/lisa/_assets/kmodules/lisa/Makefile index 639d75eaf07c5e2c64eac8638f27ee056c7ac265..af2fe3dfdcc94f0d9c36e98272822b3746274e50 100644 --- a/lisa/_assets/kmodules/lisa/Makefile +++ b/lisa/_assets/kmodules/lisa/Makefile @@ -17,48 +17,17 @@ # This would break the IN_TREE_BUILD detection ifeq ($(KBUILD_ABS_SRCTREE),1) -$(error KBUILD_ABS_SRCTREE=1 is not handled by the lisa module +$(error KBUILD_ABS_SRCTREE=1 is not handled by the lisa module) endif -ifeq ($(srctree),.) - IN_TREE_BUILD := 0 -else - IN_TREE_BUILD := 1 -endif - -# Kbuild +# Invoked by Kbuild ifneq ($(KERNELRELEASE),) MODULE_OBJ := $(obj) - KERNEL_SRC ?= $(srctree) -# Kbuild in-tree build -ifeq ($(IN_TREE_BUILD),1) - MODULE_SRC ?= $(srctree)/$(src) -# Kbuild out-of-tree build -else MODULE_SRC ?= $(src) -endif -# This did not lie: -# https://tooling.sites.arm.com/lisa/latest/setup.html#manual-module-setup-warning2 -# Maintaining a patch to get in-tree build will be the least of your worries -# before long. -# If you remove this check, you won't be able to claim you have not been warned, -# and you will forego any sort of support. The world is your oyster. -ifeq ($(IN_TREE_BUILD),1) -# There is a comment 2 lines above you should read -$(error obscure error) -# There is a comment 4 lines above you should read, seriously -endif -# There is a comment ... by now you know the drill. -# -# Note: asking for this snippet to be removed will ultimately result in pulling -# the plug on the whole in-tree build support. Remove it on your local tree and -# maintain the patch if you are motivated enough to deal with that. Pull -# requests to fix issues related to in-tree build are welcome, *provided that -# they were tested in normal flow as well*. -# non-Kbuild + KERNEL_SRC ?= $(srctree) else - MODULE_SRC ?= $(PWD) MODULE_OBJ := $(PWD) + MODULE_SRC ?= $(PWD) KERNEL_SRC ?= /lib/modules/`uname -r`/build endif @@ -163,6 +132,13 @@ $(RUST_OBJECT) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C): $(RUST_BUILD_DIR) $(CARGO_TA cp $(RUST_OBJECT) $(RUST_OBJECT)_shipped touch $(RUST_OBJECT_CMD) +# This rule is necessary as Kbuild cannot cope with absolute paths on the +# object file list to link in the module. Unfortunately, make is not smart +# enough to realize that the relative path being asked for is the same location +# as the absolute path we use in $(RUST_OBJECT), so we need to make that +# explicit here. +generated/rust/rust.o: $(RUST_OBJECT) + genbin: $(RUST_OBJECT) $(RUSTUP_HOME): @@ -189,8 +165,8 @@ LISA_KMOD_NAME ?= lisa obj-m := $(LISA_KMOD_NAME).o $(LISA_KMOD_NAME)-y := main.o tp.o wq.o features.o pixel6.o introspection_data.o rust/lisakmod/runtime.o rust/lisakmod/tests.o generated/rust/rust.o -# -fno-stack-protector is needed to possibly undefined __stack_chk_guard symbol -ccflags-y := "-I$(MODULE_SRC)" -std=gnu11 -fno-stack-protector -Wno-declaration-after-statement -Wno-error +# -fno-stack-protector is needed to avoid possibly undefined __stack_chk_guard symbol +ccflags-y := "-I$(MODULE_SRC)" "-I$(MODULE_OBJ)" -std=gnu11 -fno-stack-protector -Wno-declaration-after-statement -Wno-error # Ensure we get appropriate debug info so that pahole can work on the object # file regardless of the kernel config. @@ -203,13 +179,7 @@ SYMBOL_NAMESPACES_H := $(GENERATED)/symbol_namespaces.h MODULE_VERSION_H := $(GENERATED)/module_version.h KALLSYMS := $(GENERATED)/kallsyms -ldflags-y += -T $(FEATURES_LDS) -T $(RUST_LDS) - -ifeq ($(IN_TREE_BUILD),1) -ccflags-y += -I$(srctree) -D_IN_TREE_BUILD -else -ldflags-y += -T $(SYMBOLS_LDS) -endif +ldflags-y += -T $(FEATURES_LDS) -T $(RUST_LDS) -T $(SYMBOLS_LDS) INTROSPECTION_DATA_H := $(GENERATED)/introspection_data.h @@ -222,11 +192,7 @@ _SYNTHETIC_VMLINUX := $(MODULE_OBJ)/introspection_data.o BTF_BLOB := $(GENERATED)/btf.blob ifeq ("$(wildcard $(_BTF_VMLINUX))","") -ifeq ($(IN_TREE_BUILD),1) - VMLINUX := $(_SYNTHETIC_VMLINUX) -else VMLINUX := $(_REAL_VMLINUX) -endif else VMLINUX := $(_BTF_VMLINUX) endif @@ -264,9 +230,10 @@ $(SYMBOLS_LDS): $(GENERATED) $(KALLSYMS) # There does not seem to be any other source for the info in e.g. sysfs or # procfs, so we rely on that hack for now. $(SYMBOL_NAMESPACES_H): $(GENERATED) - printf '#pragma once\n' > $@ + printf '#pragma once\n#include "linux/module.h"\n#include "utils.h"\n' > $@ find "$(KERNEL_SRC)" '(' -name '*.c' -o -name '*.h' ')' -print0 | xargs -0 sed -n 's/MODULE_IMPORT_NS([^;]*;/\0/p' | sort -u >> $@ - echo "MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);" >> $@ + echo 'LISA_MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);' >> $@ + cat $@ $(MODULE_VERSION_H): $(GENERATED) printf '#pragma once\n' > $@ @@ -280,8 +247,10 @@ $(MODULE_VERSION_H): $(GENERATED) $(KALLSYMS): $(GENERATED) cat $(MODULE_SRC)/kallsyms > $@ || $(NM) $(_REAL_VMLINUX) > $@ || touch $@ -# Make all object files depend on the generated sources -$(addprefix $(MODULE_OBJ)/,$($(LISA_KMOD_NAME)-y)): $(INTROSPECTION_DATA_H) $(SYMBOL_NAMESPACES_H) $(MODULE_VERSION_H) $(SYMBOLS_LDS) $(RUST_CBINDGEN_H) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C) +# Make all object files depend on the generated sources. We use both the +# relative and absolute paths as kernels <= 6.12 require an absolute path +# whereas >= 6.13 requires a relative path. +$($(LISA_KMOD_NAME)-y) $(addprefix $(MODULE_OBJ)/,$($(LISA_KMOD_NAME)-y)): $(INTROSPECTION_DATA_H) $(SYMBOL_NAMESPACES_H) $(MODULE_VERSION_H) $(SYMBOLS_LDS) $(RUST_CBINDGEN_H) $(RUST_C_SHIMS_H) $(RUST_C_SHIMS_C) # Non-Kbuild part else diff --git a/lisa/_assets/kmodules/lisa/utils.h b/lisa/_assets/kmodules/lisa/utils.h index 6666fa0a50dc5aaaa8f765740a88d7f4466f6097..4a55d3e4137022cb91145b8641ce5028c21994a8 100644 --- a/lisa/_assets/kmodules/lisa/utils.h +++ b/lisa/_assets/kmodules/lisa/utils.h @@ -11,6 +11,9 @@ #endif #include "linux/kernel.h" +#include "linux/module.h" +#include "linux/version.h" +#include "linux/stringify.h" #define IGNORE_WARNING(warning, expr) ({ \ __diag_push(); \ @@ -35,4 +38,13 @@ (type)(expr) \ ) + +// Kernel commit cdd30ebb1b9f36159d66f088b61aee264e649d7a changed +// MODULE_IMPORT_NS() from taking an identifier to taking a string literal. +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,13,0) +# define LISA_MODULE_IMPORT_NS(ns) MODULE_IMPORT_NS(ns) +#else +# define LISA_MODULE_IMPORT_NS(ns) MODULE_IMPORT_NS(__stringify(ns)) +#endif + #endif /* _UTILS_H */