diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-11 13:40:35 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-11 13:40:35 -0800 |
| commit | 41f1a08645abb5ef7d2a3ed8835c747334878774 (patch) | |
| tree | e79f0bbc52b04e3034a309e3c06823968b304031 /scripts | |
| parent | 38ef046544aad88de3b520f38fa3eed2c44dc0a8 (diff) | |
| parent | d8ad80a85b96649a6ef30976762660245ae61a25 (diff) | |
Merge tag 'kbuild-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux
Pull Kbuild/Kconfig updates from Nathan Chancellor:
"Kbuild:
- Drop '*_probe' pattern from modpost section check allowlist, which
hid legitimate warnings (Johan Hovold)
- Disable -Wtype-limits altogether, instead of enabling at W=2
(Vincent Mailhol)
- Improve UAPI testing to skip testing headers that require a libc
when CONFIG_CC_CAN_LINK is not set, opening up testing of headers
with no libc dependencies to more environments (Thomas Weißschuh)
- Update gendwarfksyms documentation with required dependencies
(Jihan LIN)
- Reject invalid LLVM= values to avoid unintentionally falling back
to system toolchain (Thomas Weißschuh)
- Add a script to help run the kernel build process in a container
for consistent environments and testing (Guillaume Tucker)
- Simplify kallsyms by getting rid of the relative base (Ard
Biesheuvel)
- Performance and usability improvements to scripts/make_fit.py
(Simon Glass)
- Minor various clean ups and fixes
Kconfig:
- Move XPM icons to individual files, clearing up GTK deprecation
warnings (Rostislav Krasny)
- Support
depends on FOO if BAR
as syntactic sugar for
depends on FOO || !BAR
(Nicolas Pitre, Graham Roff)
- Refactor merge_config.sh to use awk over shell/sed/grep,
dramatically speeding up processing large number of config
fragments (Anders Roxell, Mikko Rapeli)"
* tag 'kbuild-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux: (39 commits)
kbuild: remove dependency of run-command on config
scripts/make_fit: Compress dtbs in parallel
scripts/make_fit: Support a few more parallel compressors
kbuild: Support a FIT_EXTRA_ARGS environment variable
scripts/make_fit: Move dtb processing into a function
scripts/make_fit: Support an initial ramdisk
scripts/make_fit: Speed up operation
rust: kconfig: Don't require RUST_IS_AVAILABLE for rustc-option
MAINTAINERS: Add scripts/install.sh into Kbuild entry
modpost: Amend ppc64 save/restfpr symnames for -Os build
MIPS: tools: relocs: Ship a definition of R_MIPS_PC32
streamline_config.pl: remove superfluous exclamation mark
kbuild: dummy-tools: Add python3
scripts: kconfig: merge_config.sh: warn on duplicate input files
scripts: kconfig: merge_config.sh: use awk in checks too
scripts: kconfig: merge_config.sh: refactor from shell/sed/grep to awk
kallsyms: Get rid of kallsyms relative base
mips: Add support for PC32 relocations in vmlinux
Documentation: dev-tools: add container.rst page
scripts: add tool to run containerized builds
...
Diffstat (limited to 'scripts')
41 files changed, 1069 insertions, 543 deletions
diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index d42042b6c9e2..fc10671c297c 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -73,8 +73,6 @@ rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC)) # $(rustc-option,<flag>) # Return y if the Rust compiler supports <flag>, n otherwise -# Calls to this should be guarded so that they are not evaluated if -# CONFIG_RUST_IS_AVAILABLE is not set. # If you are testing for unstable features, consider testing RUSTC_VERSION # instead, as features may have different completeness while available. rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index e429d68b8594..0718e39cedda 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -410,7 +410,7 @@ FIT_COMPRESSION ?= gzip quiet_cmd_fit = FIT $@ cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ - --name '$(UIMAGE_NAME)' \ + --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \ $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) diff --git a/scripts/Makefile.package b/scripts/Makefile.package index 83bfcf7cb09f..0ec946f9b905 100644 --- a/scripts/Makefile.package +++ b/scripts/Makefile.package @@ -201,7 +201,6 @@ quiet_cmd_cpio = CPIO $@ cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio - $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio $(call cmd,cpio) PHONY += modules-cpio-pkg diff --git a/scripts/Makefile.warn b/scripts/Makefile.warn index 68e6fafcb80c..5567da6c7dfe 100644 --- a/scripts/Makefile.warn +++ b/scripts/Makefile.warn @@ -16,7 +16,7 @@ KBUILD_CFLAGS += -Werror=return-type KBUILD_CFLAGS += -Werror=strict-prototypes KBUILD_CFLAGS += -Wno-format-security KBUILD_CFLAGS += -Wno-trigraphs -KBUILD_CFLAGS += $(call cc-option, -Wno-frame-address) +KBUILD_CFLAGS += -Wno-frame-address KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member) KBUILD_CFLAGS += -Wmissing-declarations KBUILD_CFLAGS += -Wmissing-prototypes @@ -55,6 +55,9 @@ else KBUILD_CFLAGS += -Wno-main endif +# Too noisy on range checks and in macros handling both signed and unsigned. +KBUILD_CFLAGS += -Wno-type-limits + # These result in bogus false positives KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) @@ -72,7 +75,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign # In order to make sure new function cast mismatches are not introduced # in the kernel (to avoid tripping CFI checking), the kernel should be # globally built with -Wcast-function-type. -KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) +KBUILD_CFLAGS += -Wcast-function-type # Currently, disable -Wstringop-overflow for GCC 11, globally. KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) @@ -99,7 +102,7 @@ KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) KBUILD_CFLAGS += -Werror=date-time # enforce correct pointer usage -KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) +KBUILD_CFLAGS += -Werror=incompatible-pointer-types # Require designated initializers for all marked structures KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) @@ -116,7 +119,7 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wmissing-format-attribute KBUILD_CFLAGS += -Wmissing-include-dirs -KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) +KBUILD_CFLAGS += -Wunused-const-variable KBUILD_CPPFLAGS += -Wundef KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 @@ -125,12 +128,12 @@ else # Some diagnostics enabled by default are noisy. # Suppress them by using -Wno... except for W=1. -KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable) -KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable) +KBUILD_CFLAGS += -Wno-unused-but-set-variable +KBUILD_CFLAGS += -Wno-unused-const-variable KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) ifdef CONFIG_CC_IS_GCC -KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation) +KBUILD_CFLAGS += -Wno-format-truncation endif KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) @@ -145,14 +148,11 @@ KBUILD_CFLAGS += -Wno-format # problematic. KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull -# Requires clang-12+. -ifeq ($(call clang-min-version, 120000),y) KBUILD_CFLAGS += -Wformat-insufficient-args endif -endif -KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast) +KBUILD_CFLAGS += -Wno-pointer-to-enum-cast KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare -KBUILD_CFLAGS += $(call cc-option, -Wno-unaligned-access) +KBUILD_CFLAGS += -Wno-unaligned-access KBUILD_CFLAGS += -Wno-enum-compare-conditional endif @@ -166,7 +166,7 @@ ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) KBUILD_CFLAGS += -Wdisabled-optimization KBUILD_CFLAGS += -Wshadow KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) -KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) +KBUILD_CFLAGS += -Wunused-macros KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 @@ -174,7 +174,6 @@ else # The following turn off the warnings enabled by -Wextra KBUILD_CFLAGS += -Wno-missing-field-initializers -KBUILD_CFLAGS += -Wno-type-limits KBUILD_CFLAGS += -Wno-shift-negative-value ifdef CONFIG_CC_IS_CLANG diff --git a/scripts/container b/scripts/container new file mode 100755 index 000000000000..b05333d8530b --- /dev/null +++ b/scripts/container @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2025 Guillaume Tucker + +"""Containerized builds""" + +import abc +import argparse +import logging +import os +import pathlib +import shutil +import subprocess +import sys +import uuid + + +class ContainerRuntime(abc.ABC): + """Base class for a container runtime implementation""" + + name = None # Property defined in each implementation class + + def __init__(self, args, logger): + self._uid = args.uid or os.getuid() + self._gid = args.gid or args.uid or os.getgid() + self._env_file = args.env_file + self._shell = args.shell + self._logger = logger + + @classmethod + def is_present(cls): + """Determine whether the runtime is present on the system""" + return shutil.which(cls.name) is not None + + @abc.abstractmethod + def _do_run(self, image, cmd, container_name): + """Runtime-specific handler to run a command in a container""" + + @abc.abstractmethod + def _do_abort(self, container_name): + """Runtime-specific handler to abort a running container""" + + def run(self, image, cmd): + """Run a command in a runtime container""" + container_name = str(uuid.uuid4()) + self._logger.debug("container: %s", container_name) + try: + return self._do_run(image, cmd, container_name) + except KeyboardInterrupt: + self._logger.error("user aborted") + self._do_abort(container_name) + return 1 + + +class CommonRuntime(ContainerRuntime): + """Common logic for Docker and Podman""" + + def _do_run(self, image, cmd, container_name): + cmdline = [self.name, 'run'] + cmdline += self._get_opts(container_name) + cmdline.append(image) + cmdline += cmd + self._logger.debug('command: %s', ' '.join(cmdline)) + return subprocess.call(cmdline) + + def _get_opts(self, container_name): + opts = [ + '--name', container_name, + '--rm', + '--volume', f'{pathlib.Path.cwd()}:/src', + '--workdir', '/src', + ] + if self._env_file: + opts += ['--env-file', self._env_file] + if self._shell: + opts += ['--interactive', '--tty'] + return opts + + def _do_abort(self, container_name): + subprocess.call([self.name, 'kill', container_name]) + + +class DockerRuntime(CommonRuntime): + """Run a command in a Docker container""" + + name = 'docker' + + def _get_opts(self, container_name): + return super()._get_opts(container_name) + [ + '--user', f'{self._uid}:{self._gid}' + ] + + +class PodmanRuntime(CommonRuntime): + """Run a command in a Podman container""" + + name = 'podman' + + def _get_opts(self, container_name): + return super()._get_opts(container_name) + [ + '--userns', f'keep-id:uid={self._uid},gid={self._gid}', + ] + + +class Runtimes: + """List of all supported runtimes""" + + runtimes = [PodmanRuntime, DockerRuntime] + + @classmethod + def get_names(cls): + """Get a list of all the runtime names""" + return list(runtime.name for runtime in cls.runtimes) + + @classmethod + def get(cls, name): + """Get a single runtime class matching the given name""" + for runtime in cls.runtimes: + if runtime.name == name: + if not runtime.is_present(): + raise ValueError(f"runtime not found: {name}") + return runtime + raise ValueError(f"unknown runtime: {name}") + + @classmethod + def find(cls): + """Find the first runtime present on the system""" + for runtime in cls.runtimes: + if runtime.is_present(): + return runtime + raise ValueError("no runtime found") + + +def _get_logger(verbose): + """Set up a logger with the appropriate level""" + logger = logging.getLogger('container') + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter( + fmt='[container {levelname}] {message}', style='{' + )) + logger.addHandler(handler) + logger.setLevel(logging.DEBUG if verbose is True else logging.INFO) + return logger + + +def main(args): + """Main entry point for the container tool""" + logger = _get_logger(args.verbose) + try: + cls = Runtimes.get(args.runtime) if args.runtime else Runtimes.find() + except ValueError as ex: + logger.error(ex) + return 1 + logger.debug("runtime: %s", cls.name) + logger.debug("image: %s", args.image) + return cls(args, logger).run(args.image, args.cmd) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + 'container', + description="See the documentation for more details: " + "https://docs.kernel.org/dev-tools/container.html" + ) + parser.add_argument( + '-e', '--env-file', + help="Path to an environment file to load in the container." + ) + parser.add_argument( + '-g', '--gid', + help="Group ID to use inside the container." + ) + parser.add_argument( + '-i', '--image', required=True, + help="Container image name." + ) + parser.add_argument( + '-r', '--runtime', choices=Runtimes.get_names(), + help="Container runtime name. If not specified, the first one found " + "on the system will be used i.e. Podman if present, otherwise Docker." + ) + parser.add_argument( + '-s', '--shell', action='store_true', + help="Run the container in an interactive shell." + ) + parser.add_argument( + '-u', '--uid', + help="User ID to use inside the container. If the -g option is not " + "specified, the user ID will also be set as the group ID." + ) + parser.add_argument( + '-v', '--verbose', action='store_true', + help="Enable verbose output." + ) + parser.add_argument( + 'cmd', nargs='+', + help="Command to run in the container" + ) + sys.exit(main(parser.parse_args(sys.argv[1:]))) diff --git a/scripts/dummy-tools/python3 b/scripts/dummy-tools/python3 new file mode 100755 index 000000000000..24c5584861b6 --- /dev/null +++ b/scripts/dummy-tools/python3 @@ -0,0 +1,4 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only + +true diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 4b0234e4b12f..37d5c095ad22 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -46,7 +46,6 @@ struct addr_range { }; static unsigned long long _text; -static unsigned long long relative_base; static struct addr_range text_ranges[] = { { "_stext", "_etext" }, { "_sinittext", "_einittext" }, @@ -57,6 +56,7 @@ static struct addr_range text_ranges[] = { static struct sym_entry **table; static unsigned int table_size, table_cnt; static int all_symbols; +static int pc_relative; static int token_profit[0x10000]; @@ -280,7 +280,7 @@ static void read_map(const char *in) static void output_label(const char *label) { printf(".globl %s\n", label); - printf("\tALGN\n"); + printf("\t.balign 4\n"); printf("%s:\n", label); } @@ -343,15 +343,6 @@ static void write_src(void) unsigned int *markers, markers_cnt; char buf[KSYM_NAME_LEN]; - printf("#include <asm/bitsperlong.h>\n"); - printf("#if BITS_PER_LONG == 64\n"); - printf("#define PTR .quad\n"); - printf("#define ALGN .balign 8\n"); - printf("#else\n"); - printf("#define PTR .long\n"); - printf("#define ALGN .balign 4\n"); - printf("#endif\n"); - printf("\t.section .rodata, \"a\"\n"); output_label("kallsyms_num_syms"); @@ -434,34 +425,24 @@ static void write_src(void) output_label("kallsyms_offsets"); for (i = 0; i < table_cnt; i++) { - /* - * Use the offset relative to the lowest value - * encountered of all relative symbols, and emit - * non-relocatable fixed offsets that will be fixed - * up at runtime. - */ - - long long offset; - - offset = table[i]->addr - relative_base; - if (offset < 0 || offset > UINT_MAX) { - fprintf(stderr, "kallsyms failure: " - "relative symbol value %#llx out of range\n", - table[i]->addr); - exit(EXIT_FAILURE); + if (pc_relative) { + long long offset = table[i]->addr - _text; + + if (offset < INT_MIN || offset > INT_MAX) { + fprintf(stderr, "kallsyms failure: " + "relative symbol value %#llx out of range\n", + table[i]->addr); + exit(EXIT_FAILURE); + } + printf("\t.long\t_text - . + (%d)\t/* %s */\n", + (int)offset, table[i]->sym); + } else { + printf("\t.long\t%#x\t/* %s */\n", + (unsigned int)table[i]->addr, table[i]->sym); } - printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym); } printf("\n"); - output_label("kallsyms_relative_base"); - /* Provide proper symbols relocatability by their '_text' relativeness. */ - if (_text <= relative_base) - printf("\tPTR\t_text + %#llx\n", relative_base - _text); - else - printf("\tPTR\t_text - %#llx\n", _text - relative_base); - printf("\n"); - sort_symbols_by_name(); output_label("kallsyms_seqs_of_names"); for (i = 0; i < table_cnt; i++) @@ -701,22 +682,12 @@ static void sort_symbols(void) qsort(table, table_cnt, sizeof(table[0]), compare_symbols); } -/* find the minimum non-absolute symbol address */ -static void record_relative_base(void) -{ - /* - * The table is sorted by address. - * Take the first symbol value. - */ - if (table_cnt) - relative_base = table[0]->addr; -} - int main(int argc, char **argv) { while (1) { static const struct option long_options[] = { {"all-symbols", no_argument, &all_symbols, 1}, + {"pc-relative", no_argument, &pc_relative, 1}, {}, }; @@ -734,7 +705,6 @@ int main(int argc, char **argv) read_map(argv[optind]); shrink_table(); sort_symbols(); - record_relative_base(); optimize_token_table(); write_src(); diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index fb50bd4f4103..5baf1c44ffa2 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -201,7 +201,7 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags # qconf: Used for the xconfig target based on Qt hostprogs += qconf qconf-cxxobjs := qconf.o qconf-moc.o -qconf-objs := images.o $(common-objs) +qconf-objs := $(common-objs) HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs) HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags) @@ -219,7 +219,7 @@ targets += qconf-moc.cc # gconf: Used for the gconfig target based on GTK+ hostprogs += gconf -gconf-objs := gconf.o images.o $(common-objs) +gconf-objs := gconf.o $(common-objs) HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags) diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 8b164ccfa008..9f8586cb8a3e 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -5,7 +5,6 @@ #include <stdlib.h> #include "lkc.h" -#include "images.h" #include <gtk/gtk.h> @@ -951,12 +950,24 @@ static void fixup_rootmenu(struct menu *menu) } /* Main Window Initialization */ -static void replace_button_icon(GtkWidget *widget, const char * const xpm[]) +static void replace_button_icon(GtkWidget *widget, const char *filename) { GdkPixbuf *pixbuf; GtkWidget *image; + GError *err = NULL; + + char *env = getenv(SRCTREE); + gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL); + + pixbuf = gdk_pixbuf_new_from_file(path, &err); + g_free(path); + + if (err) { + g_warning("Failed to load icon %s: %s", filename, err->message); + g_error_free(err); + return; + } - pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm); image = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); @@ -1078,17 +1089,17 @@ static void init_main_window(const gchar *glade_file) single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); g_signal_connect(single_btn, "clicked", G_CALLBACK(on_single_clicked), NULL); - replace_button_icon(single_btn, xpm_single_view); + replace_button_icon(single_btn, "single_view.xpm"); split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); g_signal_connect(split_btn, "clicked", G_CALLBACK(on_split_clicked), NULL); - replace_button_icon(split_btn, xpm_split_view); + replace_button_icon(split_btn, "split_view.xpm"); full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); g_signal_connect(full_btn, "clicked", G_CALLBACK(on_full_clicked), NULL); - replace_button_icon(full_btn, xpm_tree_view); + replace_button_icon(full_btn, "tree_view.xpm"); widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); g_signal_connect(widget, "clicked", @@ -1269,7 +1280,17 @@ static void init_right_tree(void) g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(renderer_edited), tree2_w); - pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu); + char *env = getenv(SRCTREE); + gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL); + GError *err = NULL; + + pix_menu = gdk_pixbuf_new_from_file(path, &err); + g_free(path); + + if (err) { + g_warning("Failed to load menu icon: %s", err->message); + g_error_free(err); + } for (i = 0; i < COL_VALUE; i++) { column = gtk_tree_view_get_column(view, i); diff --git a/scripts/kconfig/icons/back.xpm b/scripts/kconfig/icons/back.xpm new file mode 100644 index 000000000000..2a4c30127608 --- /dev/null +++ b/scripts/kconfig/icons/back.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * back_xpm[] = { +"22 22 3 1", +". c None", +"# c #000083", +"a c #838183", +"......................", +"......................", +"......................", +"......................", +"......................", +"...........######a....", +"..#......##########...", +"..##...####......##a..", +"..###.###.........##..", +"..######..........##..", +"..#####...........##..", +"..######..........##..", +"..#######.........##..", +"..########.......##a..", +"...............a###...", +"...............###....", +"......................", +"......................", +"......................", +"......................", +"......................", +"......................" +}; diff --git a/scripts/kconfig/icons/choice_no.xpm b/scripts/kconfig/icons/choice_no.xpm new file mode 100644 index 000000000000..306e314ed9c6 --- /dev/null +++ b/scripts/kconfig/icons/choice_no.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * choice_no_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .... ", +" .. .. ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .. .. ", +" .... ", +" " +}; diff --git a/scripts/kconfig/icons/choice_yes.xpm b/scripts/kconfig/icons/choice_yes.xpm new file mode 100644 index 000000000000..edeb91067379 --- /dev/null +++ b/scripts/kconfig/icons/choice_yes.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * choice_yes_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .... ", +" .. .. ", +" . . ", +" . .. . ", +" . .... . ", +" . .... . ", +" . .. . ", +" . . ", +" .. .. ", +" .... ", +" " +}; diff --git a/scripts/kconfig/icons/load.xpm b/scripts/kconfig/icons/load.xpm new file mode 100644 index 000000000000..8c2d8725d1ef --- /dev/null +++ b/scripts/kconfig/icons/load.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char * load_xpm[] = { +"22 22 5 1", +". c None", +"# c #000000", +"c c #838100", +"a c #ffff00", +"b c #ffffff", +"......................", +"......................", +"......................", +"............####....#.", +"...........#....##.##.", +"..................###.", +".................####.", +".####...........#####.", +"#abab##########.......", +"#babababababab#.......", +"#ababababababa#.......", +"#babababababab#.......", +"#ababab###############", +"#babab##cccccccccccc##", +"#abab##cccccccccccc##.", +"#bab##cccccccccccc##..", +"#ab##cccccccccccc##...", +"#b##cccccccccccc##....", +"###cccccccccccc##.....", +"##cccccccccccc##......", +"###############.......", +"......................" +}; diff --git a/scripts/kconfig/icons/menu.xpm b/scripts/kconfig/icons/menu.xpm new file mode 100644 index 000000000000..8ae1b74b3c0c --- /dev/null +++ b/scripts/kconfig/icons/menu.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * menu_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" " +}; diff --git a/scripts/kconfig/icons/menuback.xpm b/scripts/kconfig/icons/menuback.xpm new file mode 100644 index 000000000000..f988c2c323c3 --- /dev/null +++ b/scripts/kconfig/icons/menuback.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * menuback_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" " +}; diff --git a/scripts/kconfig/icons/save.xpm b/scripts/kconfig/icons/save.xpm new file mode 100644 index 000000000000..f8be53d83b40 --- /dev/null +++ b/scripts/kconfig/icons/save.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char * save_xpm[] = { +"22 22 5 1", +". c None", +"# c #000000", +"a c #838100", +"b c #c5c2c5", +"c c #cdb6d5", +"......................", +".####################.", +".#aa#bbbbbbbbbbbb#bb#.", +".#aa#bbbbbbbbbbbb#bb#.", +".#aa#bbbbbbbbbcbb####.", +".#aa#bbbccbbbbbbb#aa#.", +".#aa#bbbccbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aaa############aaa#.", +".#aaaaaaaaaaaaaaaaaa#.", +".#aaaaaaaaaaaaaaaaaa#.", +".#aaa#############aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +"..##################..", +"......................" +}; diff --git a/scripts/kconfig/icons/single_view.xpm b/scripts/kconfig/icons/single_view.xpm new file mode 100644 index 000000000000..33c3b239dc8e --- /dev/null +++ b/scripts/kconfig/icons/single_view.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * single_view_xpm[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"......................", +"......................" +}; diff --git a/scripts/kconfig/icons/split_view.xpm b/scripts/kconfig/icons/split_view.xpm new file mode 100644 index 000000000000..09e22246d936 --- /dev/null +++ b/scripts/kconfig/icons/split_view.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * split_view_xpm[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......................", +"......................" +}; diff --git a/scripts/kconfig/icons/symbol_mod.xpm b/scripts/kconfig/icons/symbol_mod.xpm new file mode 100644 index 000000000000..769465fcb0ce --- /dev/null +++ b/scripts/kconfig/icons/symbol_mod.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * symbol_mod_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . .. . ", +" . .... . ", +" . .... . ", +" . .. . ", +" . . ", +" . . ", +" .......... ", +" " +}; diff --git a/scripts/kconfig/icons/symbol_no.xpm b/scripts/kconfig/icons/symbol_no.xpm new file mode 100644 index 000000000000..e4e9d46c9aca --- /dev/null +++ b/scripts/kconfig/icons/symbol_no.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * symbol_no_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .......... ", +" " +}; diff --git a/scripts/kconfig/icons/symbol_yes.xpm b/scripts/kconfig/icons/symbol_yes.xpm new file mode 100644 index 000000000000..dab7e10ae7a9 --- /dev/null +++ b/scripts/kconfig/icons/symbol_yes.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * symbol_yes_xpm[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . . . ", +" . .. . ", +" . . .. . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" " +}; diff --git a/scripts/kconfig/icons/tree_view.xpm b/scripts/kconfig/icons/tree_view.xpm new file mode 100644 index 000000000000..290835b802eb --- /dev/null +++ b/scripts/kconfig/icons/tree_view.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char * tree_view_xpm[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......................", +"......................" +}; diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c deleted file mode 100644 index 2f9afffa5d79..000000000000 --- a/scripts/kconfig/images.c +++ /dev/null @@ -1,328 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> - */ - -#include "images.h" - -const char * const xpm_load[] = { -"22 22 5 1", -". c None", -"# c #000000", -"c c #838100", -"a c #ffff00", -"b c #ffffff", -"......................", -"......................", -"......................", -"............####....#.", -"...........#....##.##.", -"..................###.", -".................####.", -".####...........#####.", -"#abab##########.......", -"#babababababab#.......", -"#ababababababa#.......", -"#babababababab#.......", -"#ababab###############", -"#babab##cccccccccccc##", -"#abab##cccccccccccc##.", -"#bab##cccccccccccc##..", -"#ab##cccccccccccc##...", -"#b##cccccccccccc##....", -"###cccccccccccc##.....", -"##cccccccccccc##......", -"###############.......", -"......................"}; - -const char * const xpm_save[] = { -"22 22 5 1", -". c None", -"# c #000000", -"a c #838100", -"b c #c5c2c5", -"c c #cdb6d5", -"......................", -".####################.", -".#aa#bbbbbbbbbbbb#bb#.", -".#aa#bbbbbbbbbbbb#bb#.", -".#aa#bbbbbbbbbcbb####.", -".#aa#bbbccbbbbbbb#aa#.", -".#aa#bbbccbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aa#bbbbbbbbbbbb#aa#.", -".#aaa############aaa#.", -".#aaaaaaaaaaaaaaaaaa#.", -".#aaaaaaaaaaaaaaaaaa#.", -".#aaa#############aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -".#aaa#########bbb#aa#.", -"..##################..", -"......................"}; - -const char * const xpm_back[] = { -"22 22 3 1", -". c None", -"# c #000083", -"a c #838183", -"......................", -"......................", -"......................", -"......................", -"......................", -"...........######a....", -"..#......##########...", -"..##...####......##a..", -"..###.###.........##..", -"..######..........##..", -"..#####...........##..", -"..######..........##..", -"..#######.........##..", -"..########.......##a..", -"...............a###...", -"...............###....", -"......................", -"......................", -"......................", -"......................", -"......................", -"......................"}; - -const char * const xpm_tree_view[] = { -"22 22 2 1", -". c None", -"# c #000000", -"......................", -"......................", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......########........", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......########........", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......#...............", -"......########........", -"......................", -"......................"}; - -const char * const xpm_single_view[] = { -"22 22 2 1", -". c None", -"# c #000000", -"......................", -"......................", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"..........#...........", -"......................", -"......................"}; - -const char * const xpm_split_view[] = { -"22 22 2 1", -". c None", -"# c #000000", -"......................", -"......................", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......#......#........", -"......................", -"......................"}; - -const char * const xpm_symbol_no[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" .......... ", -" "}; - -const char * const xpm_symbol_mod[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . . ", -" . .. . ", -" . .... . ", -" . .... . ", -" . .. . ", -" . . ", -" . . ", -" .......... ", -" "}; - -const char * const xpm_symbol_yes[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . . ", -" . . . ", -" . .. . ", -" . . .. . ", -" . .... . ", -" . .. . ", -" . . ", -" .......... ", -" "}; - -const char * const xpm_choice_no[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .... ", -" .. .. ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" . . ", -" .. .. ", -" .... ", -" "}; - -const char * const xpm_choice_yes[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .... ", -" .. .. ", -" . . ", -" . .. . ", -" . .... . ", -" . .... . ", -" . .. . ", -" . . ", -" .. .. ", -" .... ", -" "}; - -const char * const xpm_menu[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . .. . ", -" . .... . ", -" . ...... . ", -" . ...... . ", -" . .... . ", -" . .. . ", -" . . ", -" .......... ", -" "}; - -const char * const xpm_menu_inv[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" .......... ", -" .. ...... ", -" .. .... ", -" .. .. ", -" .. .. ", -" .. .... ", -" .. ...... ", -" .......... ", -" .......... ", -" "}; - -const char * const xpm_menuback[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" .......... ", -" . . ", -" . .. . ", -" . .... . ", -" . ...... . ", -" . ...... . ", -" . .... . ", -" . .. . ", -" . . ", -" .......... ", -" "}; - -const char * const xpm_void[] = { -"12 12 2 1", -" c white", -". c black", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/scripts/kconfig/images.h b/scripts/kconfig/images.h deleted file mode 100644 index 7212dec2006c..000000000000 --- a/scripts/kconfig/images.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> - */ - -#ifndef IMAGES_H -#define IMAGES_H - -#ifdef __cplusplus -extern "C" { -#endif - -extern const char * const xpm_load[]; -extern const char * const xpm_save[]; -extern const char * const xpm_back[]; -extern const char * const xpm_tree_view[]; -extern const char * const xpm_single_view[]; -extern const char * const xpm_split_view[]; -extern const char * const xpm_symbol_no[]; -extern const char * const xpm_symbol_mod[]; -extern const char * const xpm_symbol_yes[]; -extern const char * const xpm_choice_no[]; -extern const char * const xpm_choice_yes[]; -extern const char * const xpm_menu[]; -extern const char * const xpm_menu_inv[]; -extern const char * const xpm_menuback[]; -extern const char * const xpm_void[]; - -#ifdef __cplusplus -} -#endif - -#endif /* IMAGES_H */ diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 56548efc14d7..798985961215 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -82,7 +82,7 @@ void menu_warn(const struct menu *menu, const char *fmt, ...); struct menu *menu_add_menu(void); void menu_end_menu(void); void menu_add_entry(struct symbol *sym, enum menu_type type); -void menu_add_dep(struct expr *dep); +void menu_add_dep(struct expr *dep, struct expr *cond); void menu_add_visibility(struct expr *dep); struct property *menu_add_prompt(enum prop_type type, const char *prompt, struct expr *dep); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 0f1a6513987c..b2d8d4e11e07 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -127,8 +127,18 @@ static struct expr *rewrite_m(struct expr *e) return e; } -void menu_add_dep(struct expr *dep) +void menu_add_dep(struct expr *dep, struct expr *cond) { + if (cond) { + /* + * We have "depends on X if Y" and we want: + * Y != n --> X + * Y == n --> y + * That simplifies to: (X || (Y == n)) + */ + dep = expr_alloc_or(dep, + expr_trans_compare(cond, E_EQUAL, &symbol_no)); + } current_entry->dep = expr_alloc_and(current_entry->dep, dep); } diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 79c09b378be8..735e1de450c6 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -16,8 +16,8 @@ set -e clean_up() { - rm -f $TMP_FILE - rm -f $MERGE_FILE + rm -f "$TMP_FILE" + rm -f "$TMP_FILE.new" } usage() { @@ -43,6 +43,10 @@ STRICT=false CONFIG_PREFIX=${CONFIG_-CONFIG_} WARNOVERRIDE=echo +if [ -z "$AWK" ]; then + AWK=awk +fi + while true; do case $1 in "-n") @@ -117,11 +121,8 @@ if [ ! -r "$INITFILE" ]; then fi MERGE_LIST=$* -SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" -SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) -MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) echo "Using $INITFILE as base" @@ -129,6 +130,8 @@ trap clean_up EXIT cat $INITFILE > $TMP_FILE +PROCESSED_FILES="" + # Merge files, printing warnings on overridden values for ORIG_MERGE_FILE in $MERGE_LIST ; do echo "Merging $ORIG_MERGE_FILE" @@ -136,42 +139,138 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 exit 1 fi - cat $ORIG_MERGE_FILE > $MERGE_FILE - CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) - - for CFG in $CFG_LIST ; do - grep -q -w $CFG $TMP_FILE || continue - PREV_VAL=$(grep -w $CFG $TMP_FILE) - NEW_VAL=$(grep -w $CFG $MERGE_FILE) - BUILTIN_FLAG=false - if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then - ${WARNOVERRIDE} Previous value: $PREV_VAL - ${WARNOVERRIDE} New value: $NEW_VAL - ${WARNOVERRIDE} -y passed, will not demote y to m - ${WARNOVERRIDE} - BUILTIN_FLAG=true - elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then - ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE: - ${WARNOVERRIDE} Previous value: $PREV_VAL - ${WARNOVERRIDE} New value: $NEW_VAL - ${WARNOVERRIDE} - if [ "$STRICT" = "true" ]; then - STRICT_MODE_VIOLATED=true - fi - elif [ "$WARNREDUN" = "true" ]; then - ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: - fi - if [ "$BUILTIN_FLAG" = "false" ]; then - sed -i "/$CFG[ =]/d" $TMP_FILE - else - sed -i "/$CFG[ =]/d" $MERGE_FILE - fi - done - # In case the previous file lacks a new line at the end - echo >> $TMP_FILE - cat $MERGE_FILE >> $TMP_FILE -done + # Check for duplicate input files + case " $PROCESSED_FILES " in + *" $ORIG_MERGE_FILE "*) + ${WARNOVERRIDE} "WARNING: Input file provided multiple times: $ORIG_MERGE_FILE" + ;; + esac + + # Use awk for single-pass processing instead of per-symbol grep/sed + if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ + -v warnoverride="$WARNOVERRIDE" \ + -v strict="$STRICT" \ + -v builtin="$BUILTIN" \ + -v warnredun="$WARNREDUN" ' + BEGIN { + strict_violated = 0 + cfg_regex = "^" prefix "[a-zA-Z0-9_]+" + notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" + } + + # Extract config name from a line, returns "" if not a config line + function get_cfg(line) { + if (match(line, cfg_regex)) { + return substr(line, RSTART, RLENGTH) + } else if (match(line, notset_regex)) { + # Extract CONFIG_FOO from "# CONFIG_FOO is not set" + sub(/^# /, "", line) + sub(/ is not set$/, "", line) + return line + } + return "" + } + + function warn_builtin(cfg, prev, new) { + if (warnoverride == "true") return + print cfg ": -y passed, will not demote y to m" + print "Previous value: " prev + print "New value: " new + print "" + } + + function warn_redefined(cfg, prev, new) { + if (warnoverride == "true") return + print "Value of " cfg " is redefined by fragment " mergefile ":" + print "Previous value: " prev + print "New value: " new + print "" + } + + function warn_redundant(cfg) { + if (warnredun != "true" || warnoverride == "true") return + print "Value of " cfg " is redundant by fragment " mergefile ":" + } + + # First pass: read merge file, store all lines and index + FILENAME == ARGV[1] { + mergefile = FILENAME + merge_lines[FNR] = $0 + merge_total = FNR + cfg = get_cfg($0) + if (cfg != "") { + merge_cfg[cfg] = $0 + merge_cfg_line[cfg] = FNR + } + next + } + + # Second pass: process base file (TMP_FILE) + FILENAME == ARGV[2] { + cfg = get_cfg($0) + + # Not a config or not in merge file - keep it + if (cfg == "" || !(cfg in merge_cfg)) { + print $0 >> ARGV[3] + next + } + + prev_val = $0 + new_val = merge_cfg[cfg] + + # BUILTIN: do not demote y to m + if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) { + warn_builtin(cfg, prev_val, new_val) + print $0 >> ARGV[3] + skip_merge[merge_cfg_line[cfg]] = 1 + next + } + + # Values equal - redundant + if (prev_val == new_val) { + warn_redundant(cfg) + next + } + + # "=n" is the same as "is not set" + if (prev_val ~ /=n$/ && new_val ~ / is not set$/) { + print $0 >> ARGV[3] + next + } + + # Values differ - redefined + warn_redefined(cfg, prev_val, new_val) + if (strict == "true") { + strict_violated = 1 + } + } + + # output file, skip all lines + FILENAME == ARGV[3] { + nextfile + } + + END { + # Newline in case base file lacks trailing newline + print "" >> ARGV[3] + # Append merge file, skipping lines marked for builtin preservation + for (i = 1; i <= merge_total; i++) { + if (!(i in skip_merge)) { + print merge_lines[i] >> ARGV[3] + } + } + if (strict_violated) { + exit 1 + } + }' \ + "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then + # awk exited non-zero, strict mode was violated + STRICT_MODE_VIOLATED=true + fi + mv "$TMP_FILE.new" "$TMP_FILE" + PROCESSED_FILES="$PROCESSED_FILES $ORIG_MERGE_FILE" +done if [ "$STRICT_MODE_VIOLATED" = "true" ]; then echo "The fragment redefined a value and strict mode had been passed." exit 1 @@ -198,16 +297,91 @@ fi # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET +# Check all specified config values took effect (might have missed-dependency issues) +if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ + -v warnoverride="$WARNOVERRIDE" \ + -v strict="$STRICT" \ + -v warnredun="$WARNREDUN" ' +BEGIN { + strict_violated = 0 + cfg_regex = "^" prefix "[a-zA-Z0-9_]+" + notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" +} -# Check all specified config values took (might have missed-dependency issues) -for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do +# Extract config name from a line, returns "" if not a config line +function get_cfg(line) { + if (match(line, cfg_regex)) { + return substr(line, RSTART, RLENGTH) + } else if (match(line, notset_regex)) { + # Extract CONFIG_FOO from "# CONFIG_FOO is not set" + sub(/^# /, "", line) + sub(/ is not set$/, "", line) + return line + } + return "" +} - REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) - ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) - if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then - echo "Value requested for $CFG not in final .config" - echo "Requested value: $REQUESTED_VAL" - echo "Actual value: $ACTUAL_VAL" - echo "" - fi -done +function warn_mismatch(cfg, merged, final) { + if (warnredun == "true") return + if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) { + print "WARNING: Value requested for " cfg " not in final .config" + print "Requested value: " merged + print "Actual value: " final + } else if (final == "" && merged ~ / is not set$/) { + # not set, pass + } else if (merged == "" && final != "") { + print "WARNING: " cfg " not in merged config but added in final .config:" + print "Requested value: " merged + print "Actual value: " final + } else { + print "WARNING: " cfg " differs:" + print "Requested value: " merged + print "Actual value: " final + } +} + +# First pass: read effective config file, store all lines +FILENAME == ARGV[1] { + cfg = get_cfg($0) + if (cfg != "") { + config_cfg[cfg] = $0 + } + next +} + +# Second pass: process merged config and compare against effective config +{ + cfg = get_cfg($0) + if (cfg == "") next + + # strip trailing comment + sub(/[[:space:]]+#.*/, "", $0) + merged_val = $0 + final_val = config_cfg[cfg] + + if (merged_val == final_val) next + + if (merged_val ~ /=n$/ && final_val ~ / is not set$/) next + if (merged_val ~ /=n$/ && final_val == "") next + + warn_mismatch(cfg, merged_val, final_val) + + if (strict == "true") { + strict_violated = 1 + } +} + +END { + if (strict_violated) { + exit 1 + } +}' \ +"$KCONFIG_CONFIG" "$TMP_FILE"; then + # awk exited non-zero, strict mode was violated + STRICT_MODE_VIOLATED=true +fi + +if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then + echo "Requested and effective config differ" + exit 1 +fi diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y index 49b79dde1725..6d1bbee38f5d 100644 --- a/scripts/kconfig/parser.y +++ b/scripts/kconfig/parser.y @@ -323,7 +323,7 @@ if_entry: T_IF expr T_EOL { printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno); menu_add_entry(NULL, M_IF); - menu_add_dep($2); + menu_add_dep($2, NULL); $$ = menu_add_menu(); }; @@ -422,9 +422,9 @@ help: help_start T_HELPTEXT /* depends option */ -depends: T_DEPENDS T_ON expr T_EOL +depends: T_DEPENDS T_ON expr if_expr T_EOL { - menu_add_dep($3); + menu_add_dep($3, $4); printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno); }; diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index b84c9f2485d1..b02ead7a3f98 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -26,8 +26,6 @@ #include "lkc.h" #include "qconf.h" -#include "images.h" - static QApplication *configApp; static ConfigSettings *configSettings; @@ -1283,13 +1281,14 @@ ConfigMainWindow::ConfigMainWindow(void) move(x.toInt(), y.toInt()); // set up icons - ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); - ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); - ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); - ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); - ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); - ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); - ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); + QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/"; + ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm")); + ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm")); + ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm")); + ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm")); + ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm")); + ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm")); + ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm")); QWidget *widget = new QWidget(this); setCentralWidget(widget); @@ -1312,7 +1311,7 @@ ConfigMainWindow::ConfigMainWindow(void) configList->setFocus(); - backAction = new QAction(QPixmap(xpm_back), "Back", this); + backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this); backAction->setShortcut(QKeySequence::Back); connect(backAction, &QAction::triggered, this, &ConfigMainWindow::goBack); @@ -1322,12 +1321,12 @@ ConfigMainWindow::ConfigMainWindow(void) connect(quitAction, &QAction::triggered, this, &ConfigMainWindow::close); - QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); + QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this); loadAction->setShortcut(QKeySequence::Open); connect(loadAction, &QAction::triggered, this, &ConfigMainWindow::loadConfig); - saveAction = new QAction(QPixmap(xpm_save), "&Save", this); + saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this); saveAction->setShortcut(QKeySequence::Save); connect(saveAction, &QAction::triggered, this, &ConfigMainWindow::saveConfig); @@ -1344,15 +1343,15 @@ ConfigMainWindow::ConfigMainWindow(void) searchAction->setShortcut(QKeySequence::Find); connect(searchAction, &QAction::triggered, this, &ConfigMainWindow::searchConfig); - singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); + singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this); singleViewAction->setCheckable(true); connect(singleViewAction, &QAction::triggered, this, &ConfigMainWindow::showSingleView); - splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); + splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this); splitViewAction->setCheckable(true); connect(splitViewAction, &QAction::triggered, this, &ConfigMainWindow::showSplitView); - fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); + fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this); fullViewAction->setCheckable(true); connect(fullViewAction, &QAction::triggered, this, &ConfigMainWindow::showFullView); diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 8e23faab5d22..8677d1ca06a7 100755 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -415,7 +415,7 @@ foreach my $module (keys(%modules)) { } } else { # Most likely, someone has a custom (binary?) module loaded. - print STDERR "$module config not found!!\n"; + print STDERR "$module config not found!\n"; } } diff --git a/scripts/kconfig/tests/conditional_dep/Kconfig b/scripts/kconfig/tests/conditional_dep/Kconfig new file mode 100644 index 000000000000..2015dfbce2b1 --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/Kconfig @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0 +# Test Kconfig file for conditional dependencies. + +# Enable module support for tristate testing +config MODULES + bool "Enable loadable module support" + modules + default y + +config FOO + bool "FOO symbol" + +config BAR + bool "BAR symbol" + +config TEST_BASIC + bool "Test basic conditional dependency" + depends on FOO if BAR + default y + +config TEST_COMPLEX + bool "Test complex conditional dependency" + depends on (FOO && BAR) if (FOO || BAR) + default y + +config BAZ + tristate "BAZ symbol" + +config TEST_OPTIONAL + tristate "Test simple optional dependency" + depends on BAZ if BAZ + default y diff --git a/scripts/kconfig/tests/conditional_dep/__init__.py b/scripts/kconfig/tests/conditional_dep/__init__.py new file mode 100644 index 000000000000..ab16df6487ec --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/__init__.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Correctly handle conditional dependencies. +""" + +def test(conf): + assert conf.oldconfig('test_config1') == 0 + assert conf.config_matches('expected_config1') + + assert conf.oldconfig('test_config2') == 0 + assert conf.config_matches('expected_config2') + + assert conf.oldconfig('test_config3') == 0 + assert conf.config_matches('expected_config3') diff --git a/scripts/kconfig/tests/conditional_dep/expected_config1 b/scripts/kconfig/tests/conditional_dep/expected_config1 new file mode 100644 index 000000000000..826ed7f541b8 --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/expected_config1 @@ -0,0 +1,11 @@ +# +# Automatically generated file; DO NOT EDIT. +# Main menu +# +CONFIG_MODULES=y +CONFIG_FOO=y +CONFIG_BAR=y +CONFIG_TEST_BASIC=y +CONFIG_TEST_COMPLEX=y +CONFIG_BAZ=m +CONFIG_TEST_OPTIONAL=m diff --git a/scripts/kconfig/tests/conditional_dep/expected_config2 b/scripts/kconfig/tests/conditional_dep/expected_config2 new file mode 100644 index 000000000000..10d2354f687f --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/expected_config2 @@ -0,0 +1,9 @@ +# +# Automatically generated file; DO NOT EDIT. +# Main menu +# +CONFIG_MODULES=y +# CONFIG_FOO is not set +CONFIG_BAR=y +CONFIG_BAZ=y +CONFIG_TEST_OPTIONAL=y diff --git a/scripts/kconfig/tests/conditional_dep/expected_config3 b/scripts/kconfig/tests/conditional_dep/expected_config3 new file mode 100644 index 000000000000..b04fa6fdfeb4 --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/expected_config3 @@ -0,0 +1,11 @@ +# +# Automatically generated file; DO NOT EDIT. +# Main menu +# +CONFIG_MODULES=y +# CONFIG_FOO is not set +# CONFIG_BAR is not set +CONFIG_TEST_BASIC=y +CONFIG_TEST_COMPLEX=y +# CONFIG_BAZ is not set +CONFIG_TEST_OPTIONAL=y diff --git a/scripts/kconfig/tests/conditional_dep/test_config1 b/scripts/kconfig/tests/conditional_dep/test_config1 new file mode 100644 index 000000000000..9b05f3ce8a99 --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/test_config1 @@ -0,0 +1,6 @@ +# Basic check that everything can be configured if selected. +CONFIG_FOO=y +CONFIG_BAR=y +CONFIG_BAZ=m +# Ensure that TEST_OPTIONAL=y with BAZ=m is converted to TEST_OPTIONAL=m +CONFIG_TEST_OPTIONAL=y diff --git a/scripts/kconfig/tests/conditional_dep/test_config2 b/scripts/kconfig/tests/conditional_dep/test_config2 new file mode 100644 index 000000000000..5e66d230a836 --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/test_config2 @@ -0,0 +1,7 @@ +# If FOO is not selected, then TEST_BASIC should fail the conditional +# dependency since BAR is set. +# TEST_COMPLEX will fail dependency as it depends on both FOO and BAR +# if either of those is selected. +CONFIG_FOO=n +CONFIG_BAR=y +CONFIG_BAZ=y diff --git a/scripts/kconfig/tests/conditional_dep/test_config3 b/scripts/kconfig/tests/conditional_dep/test_config3 new file mode 100644 index 000000000000..86304f3aa557 --- /dev/null +++ b/scripts/kconfig/tests/conditional_dep/test_config3 @@ -0,0 +1,6 @@ +# If FOO is not selected, but BAR is also not selected, then TEST_BASIC +# should pass since the dependency on FOO is conditional on BAR. +# TEST_COMPLEX should be also set since neither FOO nor BAR are selected +# so it has no dependencies. +CONFIG_FOO=n +CONFIG_BAR=n diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 16d6a048e07c..f99e196abeea 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -115,6 +115,10 @@ kallsyms() kallsymopt="${kallsymopt} --all-symbols" fi + if is_enabled CONFIG_64BIT || is_enabled CONFIG_RELOCATABLE; then + kallsymopt="${kallsymopt} --pc-relative" + fi + info KSYMS "${2}.S" scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" diff --git a/scripts/make_fit.py b/scripts/make_fit.py index 1683e5ec6e67..e923cc8b05b7 100755 --- a/scripts/make_fit.py +++ b/scripts/make_fit.py @@ -10,10 +10,14 @@ Usage: make_fit.py -A arm64 -n 'Linux-6.6' -O linux -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk - @arch/arm64/boot/dts/dtbs-list -E -c gzip + -r /boot/initrd.img-6.14.0-27-generic @arch/arm64/boot/dts/dtbs-list + -E -c gzip -Creates a FIT containing the supplied kernel and a set of devicetree files, -either specified individually or listed in a file (with an '@' prefix). +Creates a FIT containing the supplied kernel, an optional ramdisk, and a set of +devicetree files, either specified individually or listed in a file (with an +'@' prefix). + +Use -r to specify an existing ramdisk/initrd file. Use -E to generate an external FIT (where the data is placed after the FIT data structure). This allows parsing of the data without loading @@ -29,12 +33,11 @@ looks at the .cmd files produced by the kernel build. The resulting FIT can be booted by bootloaders which support FIT, such as U-Boot, Linuxboot, Tianocore, etc. - -Note that this tool does not yet support adding a ramdisk / initrd. """ import argparse import collections +import multiprocessing import os import subprocess import sys @@ -48,11 +51,12 @@ import libfdt CompTool = collections.namedtuple('CompTool', 'ext,tools') COMP_TOOLS = { - 'bzip2': CompTool('.bz2', 'bzip2'), + 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'), 'gzip': CompTool('.gz', 'pigz,gzip'), 'lz4': CompTool('.lz4', 'lz4'), - 'lzma': CompTool('.lzma', 'lzma'), + 'lzma': CompTool('.lzma', 'plzip,lzma'), 'lzo': CompTool('.lzo', 'lzop'), + 'xz': CompTool('.xz', 'xz'), 'zstd': CompTool('.zstd', 'zstd'), } @@ -81,6 +85,8 @@ def parse_args(): help='Specifies the operating system') parser.add_argument('-k', '--kernel', type=str, required=True, help='Specifies the (uncompressed) kernel input file (.itk)') + parser.add_argument('-r', '--ramdisk', type=str, + help='Specifies the ramdisk/initrd input file') parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') parser.add_argument('dtbs', type=str, nargs='*', @@ -98,7 +104,7 @@ def setup_fit(fsw, name): fsw (libfdt.FdtSw): Object to use for writing name (str): Name of kernel image """ - fsw.INC_SIZE = 65536 + fsw.INC_SIZE = 16 << 20 fsw.finish_reservemap() fsw.begin_node('') fsw.property_string('description', f'{name} with devicetree set') @@ -133,7 +139,28 @@ def write_kernel(fsw, data, args): fsw.property_u32('entry', 0) -def finish_fit(fsw, entries): +def write_ramdisk(fsw, data, args): + """Write out the ramdisk image + + Writes a ramdisk node along with the required properties + + Args: + fsw (libfdt.FdtSw): Object to use for writing + data (bytes): Data to write (possibly compressed) + args (Namespace): Contains necessary strings: + arch: FIT architecture, e.g. 'arm64' + fit_os: Operating Systems, e.g. 'linux' + """ + with fsw.add_node('ramdisk'): + fsw.property_string('description', 'Ramdisk') + fsw.property_string('type', 'ramdisk') + fsw.property_string('arch', args.arch) + fsw.property_string('compression', 'none') + fsw.property_string('os', args.os) + fsw.property('data', data) + + +def finish_fit(fsw, entries, has_ramdisk=False): """Finish the FIT ready for use Writes the /configurations node and subnodes @@ -143,6 +170,7 @@ def finish_fit(fsw, entries): entries (list of tuple): List of configurations: str: Description of model str: Compatible stringlist + has_ramdisk (bool): True if a ramdisk is included in the FIT """ fsw.end_node() seq = 0 @@ -154,6 +182,8 @@ def finish_fit(fsw, entries): fsw.property_string('description', model) fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) fsw.property_string('kernel', 'kernel') + if has_ramdisk: + fsw.property_string('ramdisk', 'ramdisk') fsw.end_node() @@ -179,7 +209,12 @@ def compress_data(inf, compress): done = False for tool in comp.tools.split(','): try: - subprocess.call([tool, '-c'], stdin=inf, stdout=outf) + # Add parallel flags for tools that support them + cmd = [tool] + if tool in ('zstd', 'xz'): + cmd.extend(['-T0']) # Use all available cores + cmd.append('-c') + subprocess.call(cmd, stdin=inf, stdout=outf) done = True break except FileNotFoundError: @@ -191,15 +226,31 @@ def compress_data(inf, compress): return comp_data -def output_dtb(fsw, seq, fname, arch, compress): +def compress_dtb(fname, compress): + """Compress a single DTB file + + Args: + fname (str): Filename containing the DTB + compress (str): Compression algorithm, e.g. 'gzip' + + Returns: + tuple: (str: fname, bytes: compressed_data) + """ + with open(fname, 'rb') as inf: + compressed = compress_data(inf, compress) + return fname, compressed + + +def output_dtb(fsw, seq, fname, arch, compress, data=None): """Write out a single devicetree to the FIT Args: fsw (libfdt.FdtSw): Object to use for writing seq (int): Sequence number (1 for first) fname (str): Filename containing the DTB - arch: FIT architecture, e.g. 'arm64' + arch (str): FIT architecture, e.g. 'arm64' compress (str): Compressed algorithm, e.g. 'gzip' + data (bytes): Pre-compressed data (optional) """ with fsw.add_node(f'fdt-{seq}'): fsw.property_string('description', os.path.basename(fname)) @@ -207,9 +258,10 @@ def output_dtb(fsw, seq, fname, arch, compress): fsw.property_string('arch', arch) fsw.property_string('compression', compress) - with open(fname, 'rb') as inf: - compressed = compress_data(inf, compress) - fsw.property('data', compressed) + if data is None: + with open(fname, 'rb') as inf: + data = compress_data(inf, compress) + fsw.property('data', data) def process_dtb(fname, args): @@ -249,30 +301,27 @@ def process_dtb(fname, args): return (model, compat, files) -def build_fit(args): - """Build the FIT from the provided files and arguments + +def _process_dtbs(args, fsw, entries, fdts): + """Process all DTB files and add them to the FIT Args: - args (Namespace): Program arguments + args: Program arguments + fsw: FIT writer object + entries: List to append entries to + fdts: Dictionary of processed DTBs Returns: tuple: - bytes: FIT data - int: Number of configurations generated - size: Total uncompressed size of data + Number of files processed + Total size of files processed """ seq = 0 size = 0 - fsw = libfdt.FdtSw() - setup_fit(fsw, args.name) - entries = [] - fdts = {} - # Handle the kernel - with open(args.kernel, 'rb') as inf: - comp_data = compress_data(inf, args.compress) - size += os.path.getsize(args.kernel) - write_kernel(fsw, comp_data, args) + # First figure out the unique DTB files that need compression + todo = [] + file_info = [] # List of (fname, model, compat, files) tuples for fname in args.dtbs: # Ignore non-DTB (*.dtb) files @@ -282,24 +331,84 @@ def build_fit(args): try: (model, compat, files) = process_dtb(fname, args) except Exception as e: - sys.stderr.write(f"Error processing {fname}:\n") + sys.stderr.write(f'Error processing {fname}:\n') raise e + file_info.append((fname, model, compat, files)) + for fn in files: + if fn not in fdts and fn not in todo: + todo.append(fn) + + # Compress all DTBs in parallel + cache = {} + if todo and args.compress != 'none': + if args.verbose: + print(f'Compressing {len(todo)} DTBs...') + + with multiprocessing.Pool() as pool: + compress_args = [(fn, args.compress) for fn in todo] + # unpacks each tuple, calls compress_dtb(fn, compress) in parallel + results = pool.starmap(compress_dtb, compress_args) + + cache = dict(results) + + # Now write all DTBs to the FIT using pre-compressed data + for fname, model, compat, files in file_info: for fn in files: if fn not in fdts: seq += 1 size += os.path.getsize(fn) - output_dtb(fsw, seq, fn, args.arch, args.compress) + output_dtb(fsw, seq, fn, args.arch, args.compress, + cache.get(fn)) fdts[fn] = seq files_seq = [fdts[fn] for fn in files] - entries.append([model, compat, files_seq]) - finish_fit(fsw, entries) + return seq, size + + +def build_fit(args): + """Build the FIT from the provided files and arguments + + Args: + args (Namespace): Program arguments + + Returns: + tuple: + bytes: FIT data + int: Number of configurations generated + size: Total uncompressed size of data + """ + size = 0 + fsw = libfdt.FdtSw() + setup_fit(fsw, args.name) + entries = [] + fdts = {} + + # Handle the kernel + with open(args.kernel, 'rb') as inf: + comp_data = compress_data(inf, args.compress) + size += os.path.getsize(args.kernel) + write_kernel(fsw, comp_data, args) + + # Handle the ramdisk if provided. Compression is not supported as it is + # already compressed. + if args.ramdisk: + with open(args.ramdisk, 'rb') as inf: + data = inf.read() + size += len(data) + write_ramdisk(fsw, data, args) + + count, fdt_size = _process_dtbs(args, fsw, entries, fdts) + size += fdt_size + + finish_fit(fsw, entries, bool(args.ramdisk)) # Include the kernel itself in the returned file count - return fsw.as_fdt().as_bytearray(), seq + 1, size + fdt = fsw.as_fdt() + fdt.pack() + return fdt.as_bytearray(), count + 1 + bool(args.ramdisk), size def run_make_fit(): diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 755b842f1f9b..0c25b5ad497b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -602,6 +602,10 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) /* Special register function linked on all modules during final link of .ko */ if (strstarts(symname, "_restgpr0_") || strstarts(symname, "_savegpr0_") || + strstarts(symname, "_restgpr1_") || + strstarts(symname, "_savegpr1_") || + strstarts(symname, "_restfpr_") || + strstarts(symname, "_savefpr_") || strstarts(symname, "_restvr_") || strstarts(symname, "_savevr_") || strcmp(symname, ".TOC.") == 0) @@ -958,7 +962,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, /* symbols in data sections that may refer to any init/exit sections */ if (match(fromsec, PATTERNS(DATA_SECTIONS)) && match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && - match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) + match(fromsym, PATTERNS("*_ops", "*_console"))) return 0; /* Check for pattern 3 */ |
