History

Merge 7.0 Kbuild changes into kbuild-fixes

kbuild-fixes needs to be based on 6.19 to apply some fixes for 62089b804895 ("kbuild: rpm-pkg: Generate debuginfo package manually") which landed in 6.19-rc1 but the new material of 7.0 needs fixes merged as well.

Nathan Chancellor committed 9 months ago

Commit df989b02 parents 05f7e89 d8ad80a63 files · +1515 −626Browse files

Showing the changes to scripts (41 of 63 files). Show all

Unified · Split

41 files
  1. scripts/Kconfig.include +0 −2
  2. scripts/Makefile.lib +1 −1
  3. scripts/Makefile.package +0 −1
  4. scripts/Makefile.warn +13 −14
  5. scripts/container +199 −0
  6. scripts/dummy-tools/python3 +4 −0
  7. scripts/kallsyms.c +17 −47
  8. scripts/kconfig/Makefile +2 −2
  9. scripts/kconfig/gconf.c +28 −7
  10. scripts/kconfig/icons/back.xpm +29 −0
  11. scripts/kconfig/icons/choice_no.xpm +18 −0
  12. scripts/kconfig/icons/choice_yes.xpm +18 −0
  13. scripts/kconfig/icons/load.xpm +31 −0
  14. scripts/kconfig/icons/menu.xpm +18 −0
  15. scripts/kconfig/icons/menuback.xpm +18 −0
  16. scripts/kconfig/icons/save.xpm +31 −0
  17. scripts/kconfig/icons/single_view.xpm +28 −0
  18. scripts/kconfig/icons/split_view.xpm +28 −0
  19. scripts/kconfig/icons/symbol_mod.xpm +18 −0
  20. scripts/kconfig/icons/symbol_no.xpm +18 −0
  21. scripts/kconfig/icons/symbol_yes.xpm +18 −0
  22. scripts/kconfig/icons/tree_view.xpm +28 −0
  23. scripts/kconfig/images.c +0 −328
  24. scripts/kconfig/images.h +0 −33
  25. scripts/kconfig/lkc.h +1 −1
  26. scripts/kconfig/menu.c +11 −1
  27. scripts/kconfig/merge_config.sh +225 −51
  28. scripts/kconfig/parser.y +3 −3
  29. scripts/kconfig/qconf.cc +14 −15
  30. scripts/kconfig/streamline_config.pl +1 −1
  31. scripts/kconfig/tests/conditional_dep/Kconfig +32 −0
  32. scripts/kconfig/tests/conditional_dep/__init__.py +14 −0
  33. scripts/kconfig/tests/conditional_dep/expected_config1 +11 −0
  34. scripts/kconfig/tests/conditional_dep/expected_config2 +9 −0
  35. scripts/kconfig/tests/conditional_dep/expected_config3 +11 −0
  36. scripts/kconfig/tests/conditional_dep/test_config1 +6 −0
  37. scripts/kconfig/tests/conditional_dep/test_config2 +7 −0
  38. scripts/kconfig/tests/conditional_dep/test_config3 +6 −0
  39. scripts/link-vmlinux.sh +4 −0
  40. scripts/make_fit.py +144 −35
  41. scripts/mod/modpost.c +5 −1
scripts/Kconfig.include+0−2
@@ -73,8 +73,6 @@ rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC)) · 72 unmodified lines
7373
7474 # $(rustc-option,<flag>)
7575 # Return y if the Rust compiler supports <flag>, n otherwise
76−# Calls to this should be guarded so that they are not evaluated if
77−# CONFIG_RUST_IS_AVAILABLE is not set.
7876 # If you are testing for unstable features, consider testing RUSTC_VERSION
7977 # instead, as features may have different completeness while available.
8078 rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib)
scripts/Makefile.lib+1−1
@@ -400,7 +400,7 @@ FIT_COMPRESSION ?= gzip · 399 unmodified lines
400400
401401 quiet_cmd_fit = FIT $@
402402 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \
403− --name '$(UIMAGE_NAME)' \
403+ --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \
404404 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \
405405 $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \
406406 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
scripts/Makefile.package+0−1
@@ -201,7 +201,6 @@ quiet_cmd_cpio = CPIO $@ · 200 unmodified lines
201201 cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $<
202202
203203 modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio
204− $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio
205204 $(call cmd,cpio)
206205
207206 PHONY += modules-cpio-pkg
scripts/Makefile.warn+13−14
@@ -16,7 +16,7 @@ KBUILD_CFLAGS += -Werror=return-type · 15 unmodified lines
1616 KBUILD_CFLAGS += -Werror=strict-prototypes
1717 KBUILD_CFLAGS += -Wno-format-security
1818 KBUILD_CFLAGS += -Wno-trigraphs
19−KBUILD_CFLAGS += $(call cc-option, -Wno-frame-address)
19+KBUILD_CFLAGS += -Wno-frame-address
2020 KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member)
2121 KBUILD_CFLAGS += -Wmissing-declarations
2222 KBUILD_CFLAGS += -Wmissing-prototypes
@@ -55,6 +55,9 @@ else · 32 unmodified lines
5555 KBUILD_CFLAGS += -Wno-main
5656 endif
5757
58+# Too noisy on range checks and in macros handling both signed and unsigned.
59+KBUILD_CFLAGS += -Wno-type-limits
60+
5861 # These result in bogus false positives
5962 KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer)
6063
@@ -72,7 +75,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign · 11 unmodified lines
7275 # In order to make sure new function cast mismatches are not introduced
7376 # in the kernel (to avoid tripping CFI checking), the kernel should be
7477 # globally built with -Wcast-function-type.
75−KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type)
78+KBUILD_CFLAGS += -Wcast-function-type
7679
7780 # Currently, disable -Wstringop-overflow for GCC 11, globally.
7881 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) · 20 unmodified lines
99102 KBUILD_CFLAGS += -Werror=date-time
100103
101104 # enforce correct pointer usage
102−KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
105+KBUILD_CFLAGS += -Werror=incompatible-pointer-types
103106
104107 # Require designated initializers for all marked structures
105108 KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
@@ -116,7 +119,7 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) · 10 unmodified lines
116119
117120 KBUILD_CFLAGS += -Wmissing-format-attribute
118121 KBUILD_CFLAGS += -Wmissing-include-dirs
119−KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable)
122+KBUILD_CFLAGS += -Wunused-const-variable
120123
121124 KBUILD_CPPFLAGS += -Wundef
122125 KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1
@@ -125,12 +128,12 @@ else · 2 unmodified lines
125128
126129 # Some diagnostics enabled by default are noisy.
127130 # Suppress them by using -Wno... except for W=1.
128−KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable)
129−KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable)
131+KBUILD_CFLAGS += -Wno-unused-but-set-variable
132+KBUILD_CFLAGS += -Wno-unused-const-variable
130133 KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned)
131134 KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow)
132135 ifdef CONFIG_CC_IS_GCC
133−KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation)
136+KBUILD_CFLAGS += -Wno-format-truncation
134137 endif
135138 KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation)
136139
@@ -145,14 +148,11 @@ KBUILD_CFLAGS += -Wno-format · 8 unmodified lines
145148 # problematic.
146149 KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier
147150 KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull
148−# Requires clang-12+.
149−ifeq ($(call clang-min-version, 120000),y)
150151 KBUILD_CFLAGS += -Wformat-insufficient-args
151152 endif
152−endif
153−KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast)
153+KBUILD_CFLAGS += -Wno-pointer-to-enum-cast
154154 KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
155−KBUILD_CFLAGS += $(call cc-option, -Wno-unaligned-access)
155+KBUILD_CFLAGS += -Wno-unaligned-access
156156 KBUILD_CFLAGS += -Wno-enum-compare-conditional
157157 endif
158158
@@ -166,7 +166,7 @@ ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) · 7 unmodified lines
166166 KBUILD_CFLAGS += -Wdisabled-optimization
167167 KBUILD_CFLAGS += -Wshadow
168168 KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
169−KBUILD_CFLAGS += $(call cc-option, -Wunused-macros)
169+KBUILD_CFLAGS += -Wunused-macros
170170
171171 KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2
172172
@@ -174,7 +174,6 @@ else · 1 unmodified line
174174
175175 # The following turn off the warnings enabled by -Wextra
176176 KBUILD_CFLAGS += -Wno-missing-field-initializers
177−KBUILD_CFLAGS += -Wno-type-limits
178177 KBUILD_CFLAGS += -Wno-shift-negative-value
179178
180179 ifdef CONFIG_CC_IS_CLANG
scripts/container+199−0
@@ -0,0 +1,199 @@
1+#!/usr/bin/env python3
2+# SPDX-License-Identifier: GPL-2.0-only
3+# Copyright (C) 2025 Guillaume Tucker
4+
5+"""Containerized builds"""
6+
7+import abc
8+import argparse
9+import logging
10+import os
11+import pathlib
12+import shutil
13+import subprocess
14+import sys
15+import uuid
16+
17+
18+class ContainerRuntime(abc.ABC):
19+ """Base class for a container runtime implementation"""
20+
21+ name = None # Property defined in each implementation class
22+
23+ def __init__(self, args, logger):
24+ self._uid = args.uid or os.getuid()
25+ self._gid = args.gid or args.uid or os.getgid()
26+ self._env_file = args.env_file
27+ self._shell = args.shell
28+ self._logger = logger
29+
30+ @classmethod
31+ def is_present(cls):
32+ """Determine whether the runtime is present on the system"""
33+ return shutil.which(cls.name) is not None
34+
35+ @abc.abstractmethod
36+ def _do_run(self, image, cmd, container_name):
37+ """Runtime-specific handler to run a command in a container"""
38+
39+ @abc.abstractmethod
40+ def _do_abort(self, container_name):
41+ """Runtime-specific handler to abort a running container"""
42+
43+ def run(self, image, cmd):
44+ """Run a command in a runtime container"""
45+ container_name = str(uuid.uuid4())
46+ self._logger.debug("container: %s", container_name)
47+ try:
48+ return self._do_run(image, cmd, container_name)
49+ except KeyboardInterrupt:
50+ self._logger.error("user aborted")
51+ self._do_abort(container_name)
52+ return 1
53+
54+
55+class CommonRuntime(ContainerRuntime):
56+ """Common logic for Docker and Podman"""
57+
58+ def _do_run(self, image, cmd, container_name):
59+ cmdline = [self.name, 'run']
60+ cmdline += self._get_opts(container_name)
61+ cmdline.append(image)
62+ cmdline += cmd
63+ self._logger.debug('command: %s', ' '.join(cmdline))
64+ return subprocess.call(cmdline)
65+
66+ def _get_opts(self, container_name):
67+ opts = [
68+ '--name', container_name,
69+ '--rm',
70+ '--volume', f'{pathlib.Path.cwd()}:/src',
71+ '--workdir', '/src',
72+ ]
73+ if self._env_file:
74+ opts += ['--env-file', self._env_file]
75+ if self._shell:
76+ opts += ['--interactive', '--tty']
77+ return opts
78+
79+ def _do_abort(self, container_name):
80+ subprocess.call([self.name, 'kill', container_name])
81+
82+
83+class DockerRuntime(CommonRuntime):
84+ """Run a command in a Docker container"""
85+
86+ name = 'docker'
87+
88+ def _get_opts(self, container_name):
89+ return super()._get_opts(container_name) + [
90+ '--user', f'{self._uid}:{self._gid}'
91+ ]
92+
93+
94+class PodmanRuntime(CommonRuntime):
95+ """Run a command in a Podman container"""
96+
97+ name = 'podman'
98+
99+ def _get_opts(self, container_name):
100+ return super()._get_opts(container_name) + [
101+ '--userns', f'keep-id:uid={self._uid},gid={self._gid}',
102+ ]
103+
104+
105+class Runtimes:
106+ """List of all supported runtimes"""
107+
108+ runtimes = [PodmanRuntime, DockerRuntime]
109+
110+ @classmethod
111+ def get_names(cls):
112+ """Get a list of all the runtime names"""
113+ return list(runtime.name for runtime in cls.runtimes)
114+
115+ @classmethod
116+ def get(cls, name):
117+ """Get a single runtime class matching the given name"""
118+ for runtime in cls.runtimes:
119+ if runtime.name == name:
120+ if not runtime.is_present():
121+ raise ValueError(f"runtime not found: {name}")
122+ return runtime
123+ raise ValueError(f"unknown runtime: {name}")
124+
125+ @classmethod
126+ def find(cls):
127+ """Find the first runtime present on the system"""
128+ for runtime in cls.runtimes:
129+ if runtime.is_present():
130+ return runtime
131+ raise ValueError("no runtime found")
132+
133+
134+def _get_logger(verbose):
135+ """Set up a logger with the appropriate level"""
136+ logger = logging.getLogger('container')
137+ handler = logging.StreamHandler()
138+ handler.setFormatter(logging.Formatter(
139+ fmt='[container {levelname}] {message}', style='{'
140+ ))
141+ logger.addHandler(handler)
142+ logger.setLevel(logging.DEBUG if verbose is True else logging.INFO)
143+ return logger
144+
145+
146+def main(args):
147+ """Main entry point for the container tool"""
148+ logger = _get_logger(args.verbose)
149+ try:
150+ cls = Runtimes.get(args.runtime) if args.runtime else Runtimes.find()
151+ except ValueError as ex:
152+ logger.error(ex)
153+ return 1
154+ logger.debug("runtime: %s", cls.name)
155+ logger.debug("image: %s", args.image)
156+ return cls(args, logger).run(args.image, args.cmd)
157+
158+
159+if __name__ == '__main__':
160+ parser = argparse.ArgumentParser(
161+ 'container',
162+ description="See the documentation for more details: "
163+ "https://docs.kernel.org/dev-tools/container.html"
164+ )
165+ parser.add_argument(
166+ '-e', '--env-file',
167+ help="Path to an environment file to load in the container."
168+ )
169+ parser.add_argument(
170+ '-g', '--gid',
171+ help="Group ID to use inside the container."
172+ )
173+ parser.add_argument(
174+ '-i', '--image', required=True,
175+ help="Container image name."
176+ )
177+ parser.add_argument(
178+ '-r', '--runtime', choices=Runtimes.get_names(),
179+ help="Container runtime name. If not specified, the first one found "
180+ "on the system will be used i.e. Podman if present, otherwise Docker."
181+ )
182+ parser.add_argument(
183+ '-s', '--shell', action='store_true',
184+ help="Run the container in an interactive shell."
185+ )
186+ parser.add_argument(
187+ '-u', '--uid',
188+ help="User ID to use inside the container. If the -g option is not "
189+ "specified, the user ID will also be set as the group ID."
190+ )
191+ parser.add_argument(
192+ '-v', '--verbose', action='store_true',
193+ help="Enable verbose output."
194+ )
195+ parser.add_argument(
196+ 'cmd', nargs='+',
197+ help="Command to run in the container"
198+ )
199+ sys.exit(main(parser.parse_args(sys.argv[1:])))
scripts/dummy-tools/python3+4−0
@@ -0,0 +1,4 @@
1+#!/bin/sh
2+# SPDX-License-Identifier: GPL-2.0-only
3+
4+true
scripts/kallsyms.c+17−47
@@ -46,7 +46,6 @@ struct addr_range { · 45 unmodified lines
4646 };
4747
4848 static unsigned long long _text;
49−static unsigned long long relative_base;
5049 static struct addr_range text_ranges[] = {
5150 { "_stext", "_etext" },
5251 { "_sinittext", "_einittext" },
@@ -57,6 +56,7 @@ static struct addr_range text_ranges[] = { · 4 unmodified lines
5756 static struct sym_entry **table;
5857 static unsigned int table_size, table_cnt;
5958 static int all_symbols;
59+static int pc_relative;
6060
6161 static int token_profit[0x10000];
6262
@@ -280,7 +280,7 @@ static void read_map(const char *in) · 217 unmodified lines
280280 static void output_label(const char *label)
281281 {
282282 printf(".globl %s\n", label);
283− printf("\tALGN\n");
283+ printf("\t.balign 4\n");
284284 printf("%s:\n", label);
285285 }
286286
@@ -343,15 +343,6 @@ static void write_src(void) · 56 unmodified lines
343343 unsigned int *markers, markers_cnt;
344344 char buf[KSYM_NAME_LEN];
345345
346− printf("#include <asm/bitsperlong.h>\n");
347− printf("#if BITS_PER_LONG == 64\n");
348− printf("#define PTR .quad\n");
349− printf("#define ALGN .balign 8\n");
350− printf("#else\n");
351− printf("#define PTR .long\n");
352− printf("#define ALGN .balign 4\n");
353− printf("#endif\n");
354−
355346 printf("\t.section .rodata, \"a\"\n");
356347
357348 output_label("kallsyms_num_syms");
@@ -434,34 +425,24 @@ static void write_src(void) · 76 unmodified lines
434425 output_label("kallsyms_offsets");
435426
436427 for (i = 0; i < table_cnt; i++) {
437− /*
438− * Use the offset relative to the lowest value
439− * encountered of all relative symbols, and emit
440− * non-relocatable fixed offsets that will be fixed
441− * up at runtime.
442− */
443−
444− long long offset;
445−
446− offset = table[i]->addr - relative_base;
447− if (offset < 0 || offset > UINT_MAX) {
448− fprintf(stderr, "kallsyms failure: "
449− "relative symbol value %#llx out of range\n",
450− table[i]->addr);
451− exit(EXIT_FAILURE);
428+ if (pc_relative) {
429+ long long offset = table[i]->addr - _text;
430+
431+ if (offset < INT_MIN || offset > INT_MAX) {
432+ fprintf(stderr, "kallsyms failure: "
433+ "relative symbol value %#llx out of range\n",
434+ table[i]->addr);
435+ exit(EXIT_FAILURE);
436+ }
437+ printf("\t.long\t_text - . + (%d)\t/* %s */\n",
438+ (int)offset, table[i]->sym);
439+ } else {
440+ printf("\t.long\t%#x\t/* %s */\n",
441+ (unsigned int)table[i]->addr, table[i]->sym);
452442 }
453− printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym);
454443 }
455444 printf("\n");
456445
457− output_label("kallsyms_relative_base");
458− /* Provide proper symbols relocatability by their '_text' relativeness. */
459− if (_text <= relative_base)
460− printf("\tPTR\t_text + %#llx\n", relative_base - _text);
461− else
462− printf("\tPTR\t_text - %#llx\n", _text - relative_base);
463− printf("\n");
464−
465446 sort_symbols_by_name();
466447 output_label("kallsyms_seqs_of_names");
467448 for (i = 0; i < table_cnt; i++)
@@ -701,22 +682,12 @@ static void sort_symbols(void) · 233 unmodified lines
701682 qsort(table, table_cnt, sizeof(table[0]), compare_symbols);
702683 }
703684
704−/* find the minimum non-absolute symbol address */
705−static void record_relative_base(void)
706−{
707− /*
708− * The table is sorted by address.
709− * Take the first symbol value.
710− */
711− if (table_cnt)
712− relative_base = table[0]->addr;
713−}
714−
715685 int main(int argc, char **argv)
716686 {
717687 while (1) {
718688 static const struct option long_options[] = {
719689 {"all-symbols", no_argument, &all_symbols, 1},
690+ {"pc-relative", no_argument, &pc_relative, 1},
720691 {},
721692 };
722693
@@ -734,7 +705,6 @@ int main(int argc, char **argv) · 11 unmodified lines
734705 read_map(argv[optind]);
735706 shrink_table();
736707 sort_symbols();
737− record_relative_base();
738708 optimize_token_table();
739709 write_src();
740710
scripts/kconfig/Makefile+2−2
@@ -201,7 +201,7 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags · 200 unmodified lines
201201 # qconf: Used for the xconfig target based on Qt
202202 hostprogs += qconf
203203 qconf-cxxobjs := qconf.o qconf-moc.o
204−qconf-objs := images.o $(common-objs)
204+qconf-objs := $(common-objs)
205205
206206 HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs)
207207 HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags)
@@ -219,7 +219,7 @@ targets += qconf-moc.cc · 11 unmodified lines
219219
220220 # gconf: Used for the gconfig target based on GTK+
221221 hostprogs += gconf
222−gconf-objs := gconf.o images.o $(common-objs)
222+gconf-objs := gconf.o $(common-objs)
223223
224224 HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs)
225225 HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags)
scripts/kconfig/gconf.c+28−7
@@ -5,7 +5,6 @@ · 4 unmodified lines
55
66 #include <stdlib.h>
77 #include "lkc.h"
8−#include "images.h"
98
109 #include <gtk/gtk.h>
1110
@@ -951,12 +950,24 @@ static void fixup_rootmenu(struct menu *menu) · 939 unmodified lines
951950 }
952951
953952 /* Main Window Initialization */
954−static void replace_button_icon(GtkWidget *widget, const char * const xpm[])
953+static void replace_button_icon(GtkWidget *widget, const char *filename)
955954 {
956955 GdkPixbuf *pixbuf;
957956 GtkWidget *image;
957+ GError *err = NULL;
958+
959+ char *env = getenv(SRCTREE);
960+ gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL);
961+
962+ pixbuf = gdk_pixbuf_new_from_file(path, &err);
963+ g_free(path);
964+
965+ if (err) {
966+ g_warning("Failed to load icon %s: %s", filename, err->message);
967+ g_error_free(err);
968+ return;
969+ }
958970
959− pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm);
960971 image = gtk_image_new_from_pixbuf(pixbuf);
961972 g_object_unref(pixbuf);
962973
@@ -1078,17 +1089,17 @@ static void init_main_window(const gchar *glade_file) · 115 unmodified lines
10781089 single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4"));
10791090 g_signal_connect(single_btn, "clicked",
10801091 G_CALLBACK(on_single_clicked), NULL);
1081− replace_button_icon(single_btn, xpm_single_view);
1092+ replace_button_icon(single_btn, "single_view.xpm");
10821093
10831094 split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5"));
10841095 g_signal_connect(split_btn, "clicked",
10851096 G_CALLBACK(on_split_clicked), NULL);
1086− replace_button_icon(split_btn, xpm_split_view);
1097+ replace_button_icon(split_btn, "split_view.xpm");
10871098
10881099 full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6"));
10891100 g_signal_connect(full_btn, "clicked",
10901101 G_CALLBACK(on_full_clicked), NULL);
1091− replace_button_icon(full_btn, xpm_tree_view);
1102+ replace_button_icon(full_btn, "tree_view.xpm");
10921103
10931104 widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7"));
10941105 g_signal_connect(widget, "clicked",
@@ -1269,7 +1280,17 @@ static void init_right_tree(void) · 174 unmodified lines
12691280 g_signal_connect(G_OBJECT(renderer), "edited",
12701281 G_CALLBACK(renderer_edited), tree2_w);
12711282
1272− pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu);
1283+ char *env = getenv(SRCTREE);
1284+ gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL);
1285+ GError *err = NULL;
1286+
1287+ pix_menu = gdk_pixbuf_new_from_file(path, &err);
1288+ g_free(path);
1289+
1290+ if (err) {
1291+ g_warning("Failed to load menu icon: %s", err->message);
1292+ g_error_free(err);
1293+ }
12731294
12741295 for (i = 0; i < COL_VALUE; i++) {
12751296 column = gtk_tree_view_get_column(view, i);
scripts/kconfig/icons/back.xpm+29−0
@@ -0,0 +1,29 @@
1+/* XPM */
2+static char * back_xpm[] = {
3+"22 22 3 1",
4+". c None",
5+"# c #000083",
6+"a c #838183",
7+"......................",
8+"......................",
9+"......................",
10+"......................",
11+"......................",
12+"...........######a....",
13+"..#......##########...",
14+"..##...####......##a..",
15+"..###.###.........##..",
16+"..######..........##..",
17+"..#####...........##..",
18+"..######..........##..",
19+"..#######.........##..",
20+"..########.......##a..",
21+"...............a###...",
22+"...............###....",
23+"......................",
24+"......................",
25+"......................",
26+"......................",
27+"......................",
28+"......................"
29+};
scripts/kconfig/icons/choice_no.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * choice_no_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .... ",
8+" .. .. ",
9+" . . ",
10+" . . ",
11+" . . ",
12+" . . ",
13+" . . ",
14+" . . ",
15+" .. .. ",
16+" .... ",
17+" "
18+};
scripts/kconfig/icons/choice_yes.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * choice_yes_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .... ",
8+" .. .. ",
9+" . . ",
10+" . .. . ",
11+" . .... . ",
12+" . .... . ",
13+" . .. . ",
14+" . . ",
15+" .. .. ",
16+" .... ",
17+" "
18+};
scripts/kconfig/icons/load.xpm+31−0
@@ -0,0 +1,31 @@
1+/* XPM */
2+static char * load_xpm[] = {
3+"22 22 5 1",
4+". c None",
5+"# c #000000",
6+"c c #838100",
7+"a c #ffff00",
8+"b c #ffffff",
9+"......................",
10+"......................",
11+"......................",
12+"............####....#.",
13+"...........#....##.##.",
14+"..................###.",
15+".................####.",
16+".####...........#####.",
17+"#abab##########.......",
18+"#babababababab#.......",
19+"#ababababababa#.......",
20+"#babababababab#.......",
21+"#ababab###############",
22+"#babab##cccccccccccc##",
23+"#abab##cccccccccccc##.",
24+"#bab##cccccccccccc##..",
25+"#ab##cccccccccccc##...",
26+"#b##cccccccccccc##....",
27+"###cccccccccccc##.....",
28+"##cccccccccccc##......",
29+"###############.......",
30+"......................"
31+};
scripts/kconfig/icons/menu.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * menu_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .......... ",
8+" . . ",
9+" . .. . ",
10+" . .... . ",
11+" . ...... . ",
12+" . ...... . ",
13+" . .... . ",
14+" . .. . ",
15+" . . ",
16+" .......... ",
17+" "
18+};
scripts/kconfig/icons/menuback.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * menuback_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .......... ",
8+" . . ",
9+" . .. . ",
10+" . .... . ",
11+" . ...... . ",
12+" . ...... . ",
13+" . .... . ",
14+" . .. . ",
15+" . . ",
16+" .......... ",
17+" "
18+};
scripts/kconfig/icons/save.xpm+31−0
@@ -0,0 +1,31 @@
1+/* XPM */
2+static char * save_xpm[] = {
3+"22 22 5 1",
4+". c None",
5+"# c #000000",
6+"a c #838100",
7+"b c #c5c2c5",
8+"c c #cdb6d5",
9+"......................",
10+".####################.",
11+".#aa#bbbbbbbbbbbb#bb#.",
12+".#aa#bbbbbbbbbbbb#bb#.",
13+".#aa#bbbbbbbbbcbb####.",
14+".#aa#bbbccbbbbbbb#aa#.",
15+".#aa#bbbccbbbbbbb#aa#.",
16+".#aa#bbbbbbbbbbbb#aa#.",
17+".#aa#bbbbbbbbbbbb#aa#.",
18+".#aa#bbbbbbbbbbbb#aa#.",
19+".#aa#bbbbbbbbbbbb#aa#.",
20+".#aaa############aaa#.",
21+".#aaaaaaaaaaaaaaaaaa#.",
22+".#aaaaaaaaaaaaaaaaaa#.",
23+".#aaa#############aa#.",
24+".#aaa#########bbb#aa#.",
25+".#aaa#########bbb#aa#.",
26+".#aaa#########bbb#aa#.",
27+".#aaa#########bbb#aa#.",
28+".#aaa#########bbb#aa#.",
29+"..##################..",
30+"......................"
31+};
scripts/kconfig/icons/single_view.xpm+28−0
@@ -0,0 +1,28 @@
1+/* XPM */
2+static char * single_view_xpm[] = {
3+"22 22 2 1",
4+". c None",
5+"# c #000000",
6+"......................",
7+"......................",
8+"..........#...........",
9+"..........#...........",
10+"..........#...........",
11+"..........#...........",
12+"..........#...........",
13+"..........#...........",
14+"..........#...........",
15+"..........#...........",
16+"..........#...........",
17+"..........#...........",
18+"..........#...........",
19+"..........#...........",
20+"..........#...........",
21+"..........#...........",
22+"..........#...........",
23+"..........#...........",
24+"..........#...........",
25+"..........#...........",
26+"......................",
27+"......................"
28+};
scripts/kconfig/icons/split_view.xpm+28−0
@@ -0,0 +1,28 @@
1+/* XPM */
2+static char * split_view_xpm[] = {
3+"22 22 2 1",
4+". c None",
5+"# c #000000",
6+"......................",
7+"......................",
8+"......#......#........",
9+"......#......#........",
10+"......#......#........",
11+"......#......#........",
12+"......#......#........",
13+"......#......#........",
14+"......#......#........",
15+"......#......#........",
16+"......#......#........",
17+"......#......#........",
18+"......#......#........",
19+"......#......#........",
20+"......#......#........",
21+"......#......#........",
22+"......#......#........",
23+"......#......#........",
24+"......#......#........",
25+"......#......#........",
26+"......................",
27+"......................"
28+};
scripts/kconfig/icons/symbol_mod.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * symbol_mod_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .......... ",
8+" . . ",
9+" . . ",
10+" . .. . ",
11+" . .... . ",
12+" . .... . ",
13+" . .. . ",
14+" . . ",
15+" . . ",
16+" .......... ",
17+" "
18+};
scripts/kconfig/icons/symbol_no.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * symbol_no_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .......... ",
8+" . . ",
9+" . . ",
10+" . . ",
11+" . . ",
12+" . . ",
13+" . . ",
14+" . . ",
15+" . . ",
16+" .......... ",
17+" "
18+};
scripts/kconfig/icons/symbol_yes.xpm+18−0
@@ -0,0 +1,18 @@
1+/* XPM */
2+static char * symbol_yes_xpm[] = {
3+"12 12 2 1",
4+" c white",
5+". c black",
6+" ",
7+" .......... ",
8+" . . ",
9+" . . ",
10+" . . . ",
11+" . .. . ",
12+" . . .. . ",
13+" . .... . ",
14+" . .. . ",
15+" . . ",
16+" .......... ",
17+" "
18+};
scripts/kconfig/icons/tree_view.xpm+28−0
@@ -0,0 +1,28 @@
1+/* XPM */
2+static char * tree_view_xpm[] = {
3+"22 22 2 1",
4+". c None",
5+"# c #000000",
6+"......................",
7+"......................",
8+"......#...............",
9+"......#...............",
10+"......#...............",
11+"......#...............",
12+"......#...............",
13+"......########........",
14+"......#...............",
15+"......#...............",
16+"......#...............",
17+"......#...............",
18+"......#...............",
19+"......########........",
20+"......#...............",
21+"......#...............",
22+"......#...............",
23+"......#...............",
24+"......#...............",
25+"......########........",
26+"......................",
27+"......................"
28+};
scripts/kconfig/images.c+0−328
@@ -1,328 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−/*
3− * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4− */
5−
6−#include "images.h"
7−
8−const char * const xpm_load[] = {
9−"22 22 5 1",
10−". c None",
11−"# c #000000",
12−"c c #838100",
13−"a c #ffff00",
14−"b c #ffffff",
15−"......................",
16−"......................",
17−"......................",
18−"............####....#.",
19−"...........#....##.##.",
20−"..................###.",
21−".................####.",
22−".####...........#####.",
23−"#abab##########.......",
24−"#babababababab#.......",
25−"#ababababababa#.......",
26−"#babababababab#.......",
27−"#ababab###############",
28−"#babab##cccccccccccc##",
29−"#abab##cccccccccccc##.",
30−"#bab##cccccccccccc##..",
31−"#ab##cccccccccccc##...",
32−"#b##cccccccccccc##....",
33−"###cccccccccccc##.....",
34−"##cccccccccccc##......",
35−"###############.......",
36−"......................"};
37−
38−const char * const xpm_save[] = {
39−"22 22 5 1",
40−". c None",
41−"# c #000000",
42−"a c #838100",
43−"b c #c5c2c5",
44−"c c #cdb6d5",
45−"......................",
46−".####################.",
47−".#aa#bbbbbbbbbbbb#bb#.",
48−".#aa#bbbbbbbbbbbb#bb#.",
49−".#aa#bbbbbbbbbcbb####.",
50−".#aa#bbbccbbbbbbb#aa#.",
51−".#aa#bbbccbbbbbbb#aa#.",
52−".#aa#bbbbbbbbbbbb#aa#.",
53−".#aa#bbbbbbbbbbbb#aa#.",
54−".#aa#bbbbbbbbbbbb#aa#.",
55−".#aa#bbbbbbbbbbbb#aa#.",
56−".#aaa############aaa#.",
57−".#aaaaaaaaaaaaaaaaaa#.",
58−".#aaaaaaaaaaaaaaaaaa#.",
59−".#aaa#############aa#.",
60−".#aaa#########bbb#aa#.",
61−".#aaa#########bbb#aa#.",
62−".#aaa#########bbb#aa#.",
63−".#aaa#########bbb#aa#.",
64−".#aaa#########bbb#aa#.",
65−"..##################..",
66−"......................"};
67−
68−const char * const xpm_back[] = {
69−"22 22 3 1",
70−". c None",
71−"# c #000083",
72−"a c #838183",
73−"......................",
74−"......................",
75−"......................",
76−"......................",
77−"......................",
78−"...........######a....",
79−"..#......##########...",
80−"..##...####......##a..",
81−"..###.###.........##..",
82−"..######..........##..",
83−"..#####...........##..",
84−"..######..........##..",
85−"..#######.........##..",
86−"..########.......##a..",
87−"...............a###...",
88−"...............###....",
89−"......................",
90−"......................",
91−"......................",
92−"......................",
93−"......................",
94−"......................"};
95−
96−const char * const xpm_tree_view[] = {
97−"22 22 2 1",
98−". c None",
99−"# c #000000",
100−"......................",
101−"......................",
102−"......#...............",
103−"......#...............",
104−"......#...............",
105−"......#...............",
106−"......#...............",
107−"......########........",
108−"......#...............",
109−"......#...............",
110−"......#...............",
111−"......#...............",
112−"......#...............",
113−"......########........",
114−"......#...............",
115−"......#...............",
116−"......#...............",
117−"......#...............",
118−"......#...............",
119−"......########........",
120−"......................",
121−"......................"};
122−
123−const char * const xpm_single_view[] = {
124−"22 22 2 1",
125−". c None",
126−"# c #000000",
127−"......................",
128−"......................",
129−"..........#...........",
130−"..........#...........",
131−"..........#...........",
132−"..........#...........",
133−"..........#...........",
134−"..........#...........",
135−"..........#...........",
136−"..........#...........",
137−"..........#...........",
138−"..........#...........",
139−"..........#...........",
140−"..........#...........",
141−"..........#...........",
142−"..........#...........",
143−"..........#...........",
144−"..........#...........",
145−"..........#...........",
146−"..........#...........",
147−"......................",
148−"......................"};
149−
150−const char * const xpm_split_view[] = {
151−"22 22 2 1",
152−". c None",
153−"# c #000000",
154−"......................",
155−"......................",
156−"......#......#........",
157−"......#......#........",
158−"......#......#........",
159−"......#......#........",
160−"......#......#........",
161−"......#......#........",
162−"......#......#........",
163−"......#......#........",
164−"......#......#........",
165−"......#......#........",
166−"......#......#........",
167−"......#......#........",
168−"......#......#........",
169−"......#......#........",
170−"......#......#........",
171−"......#......#........",
172−"......#......#........",
173−"......#......#........",
174−"......................",
175−"......................"};
176−
177−const char * const xpm_symbol_no[] = {
178−"12 12 2 1",
179−" c white",
180−". c black",
181−" ",
182−" .......... ",
183−" . . ",
184−" . . ",
185−" . . ",
186−" . . ",
187−" . . ",
188−" . . ",
189−" . . ",
190−" . . ",
191−" .......... ",
192−" "};
193−
194−const char * const xpm_symbol_mod[] = {
195−"12 12 2 1",
196−" c white",
197−". c black",
198−" ",
199−" .......... ",
200−" . . ",
201−" . . ",
202−" . .. . ",
203−" . .... . ",
204−" . .... . ",
205−" . .. . ",
206−" . . ",
207−" . . ",
208−" .......... ",
209−" "};
210−
211−const char * const xpm_symbol_yes[] = {
212−"12 12 2 1",
213−" c white",
214−". c black",
215−" ",
216−" .......... ",
217−" . . ",
218−" . . ",
219−" . . . ",
220−" . .. . ",
221−" . . .. . ",
222−" . .... . ",
223−" . .. . ",
224−" . . ",
225−" .......... ",
226−" "};
227−
228−const char * const xpm_choice_no[] = {
229−"12 12 2 1",
230−" c white",
231−". c black",
232−" ",
233−" .... ",
234−" .. .. ",
235−" . . ",
236−" . . ",
237−" . . ",
238−" . . ",
239−" . . ",
240−" . . ",
241−" .. .. ",
242−" .... ",
243−" "};
244−
245−const char * const xpm_choice_yes[] = {
246−"12 12 2 1",
247−" c white",
248−". c black",
249−" ",
250−" .... ",
251−" .. .. ",
252−" . . ",
253−" . .. . ",
254−" . .... . ",
255−" . .... . ",
256−" . .. . ",
257−" . . ",
258−" .. .. ",
259−" .... ",
260−" "};
261−
262−const char * const xpm_menu[] = {
263−"12 12 2 1",
264−" c white",
265−". c black",
266−" ",
267−" .......... ",
268−" . . ",
269−" . .. . ",
270−" . .... . ",
271−" . ...... . ",
272−" . ...... . ",
273−" . .... . ",
274−" . .. . ",
275−" . . ",
276−" .......... ",
277−" "};
278−
279−const char * const xpm_menu_inv[] = {
280−"12 12 2 1",
281−" c white",
282−". c black",
283−" ",
284−" .......... ",
285−" .......... ",
286−" .. ...... ",
287−" .. .... ",
288−" .. .. ",
289−" .. .. ",
290−" .. .... ",
291−" .. ...... ",
292−" .......... ",
293−" .......... ",
294−" "};
295−
296−const char * const xpm_menuback[] = {
297−"12 12 2 1",
298−" c white",
299−". c black",
300−" ",
301−" .......... ",
302−" . . ",
303−" . .. . ",
304−" . .... . ",
305−" . ...... . ",
306−" . ...... . ",
307−" . .... . ",
308−" . .. . ",
309−" . . ",
310−" .......... ",
311−" "};
312−
313−const char * const xpm_void[] = {
314−"12 12 2 1",
315−" c white",
316−". c black",
317−" ",
318−" ",
319−" ",
320−" ",
321−" ",
322−" ",
323−" ",
324−" ",
325−" ",
326−" ",
327−" ",
328−" "};
scripts/kconfig/images.h+0−33
@@ -1,33 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−/*
3− * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4− */
5−
6−#ifndef IMAGES_H
7−#define IMAGES_H
8−
9−#ifdef __cplusplus
10−extern "C" {
11−#endif
12−
13−extern const char * const xpm_load[];
14−extern const char * const xpm_save[];
15−extern const char * const xpm_back[];
16−extern const char * const xpm_tree_view[];
17−extern const char * const xpm_single_view[];
18−extern const char * const xpm_split_view[];
19−extern const char * const xpm_symbol_no[];
20−extern const char * const xpm_symbol_mod[];
21−extern const char * const xpm_symbol_yes[];
22−extern const char * const xpm_choice_no[];
23−extern const char * const xpm_choice_yes[];
24−extern const char * const xpm_menu[];
25−extern const char * const xpm_menu_inv[];
26−extern const char * const xpm_menuback[];
27−extern const char * const xpm_void[];
28−
29−#ifdef __cplusplus
30−}
31−#endif
32−
33−#endif /* IMAGES_H */
scripts/kconfig/lkc.h+1−1
@@ -82,7 +82,7 @@ void menu_warn(const struct menu *menu, const char *fmt, ...); · 81 unmodified lines
8282 struct menu *menu_add_menu(void);
8383 void menu_end_menu(void);
8484 void menu_add_entry(struct symbol *sym, enum menu_type type);
85−void menu_add_dep(struct expr *dep);
85+void menu_add_dep(struct expr *dep, struct expr *cond);
8686 void menu_add_visibility(struct expr *dep);
8787 struct property *menu_add_prompt(enum prop_type type, const char *prompt,
8888 struct expr *dep);
scripts/kconfig/menu.c+11−1
@@ -127,8 +127,18 @@ static struct expr *rewrite_m(struct expr *e) · 126 unmodified lines
127127 return e;
128128 }
129129
130−void menu_add_dep(struct expr *dep)
130+void menu_add_dep(struct expr *dep, struct expr *cond)
131131 {
132+ if (cond) {
133+ /*
134+ * We have "depends on X if Y" and we want:
135+ * Y != n --> X
136+ * Y == n --> y
137+ * That simplifies to: (X || (Y == n))
138+ */
139+ dep = expr_alloc_or(dep,
140+ expr_trans_compare(cond, E_EQUAL, &symbol_no));
141+ }
132142 current_entry->dep = expr_alloc_and(current_entry->dep, dep);
133143 }
134144
scripts/kconfig/merge_config.sh+225−51
@@ -16,8 +16,8 @@ · 15 unmodified lines
1616 set -e
1717
1818 clean_up() {
19− rm -f $TMP_FILE
20− rm -f $MERGE_FILE
19+ rm -f "$TMP_FILE"
20+ rm -f "$TMP_FILE.new"
2121 }
2222
2323 usage() {
@@ -43,6 +43,10 @@ STRICT=false · 19 unmodified lines
4343 CONFIG_PREFIX=${CONFIG_-CONFIG_}
4444 WARNOVERRIDE=echo
4545
46+if [ -z "$AWK" ]; then
47+ AWK=awk
48+fi
49+
4650 while true; do
4751 case $1 in
4852 "-n")
@@ -117,11 +121,8 @@ if [ ! -r "$INITFILE" ]; then · 68 unmodified lines
117121 fi
118122
119123 MERGE_LIST=$*
120−SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p"
121−SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p"
122124
123125 TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
124−MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX)
125126
126127 echo "Using $INITFILE as base"
127128
@@ -129,6 +130,8 @@ trap clean_up EXIT · 1 unmodified line
129130
130131 cat $INITFILE > $TMP_FILE
131132
133+PROCESSED_FILES=""
134+
132135 # Merge files, printing warnings on overridden values
133136 for ORIG_MERGE_FILE in $MERGE_LIST ; do
134137 echo "Merging $ORIG_MERGE_FILE"
@@ -136,42 +139,138 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do · 1 unmodified line
136139 echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2
137140 exit 1
138141 fi
139− cat $ORIG_MERGE_FILE > $MERGE_FILE
140− CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE)
141−
142− for CFG in $CFG_LIST ; do
143− grep -q -w $CFG $TMP_FILE || continue
144− PREV_VAL=$(grep -w $CFG $TMP_FILE)
145− NEW_VAL=$(grep -w $CFG $MERGE_FILE)
146− BUILTIN_FLAG=false
147− if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then
148− ${WARNOVERRIDE} Previous value: $PREV_VAL
149− ${WARNOVERRIDE} New value: $NEW_VAL
150− ${WARNOVERRIDE} -y passed, will not demote y to m
151− ${WARNOVERRIDE}
152− BUILTIN_FLAG=true
153− elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
154− ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE:
155− ${WARNOVERRIDE} Previous value: $PREV_VAL
156− ${WARNOVERRIDE} New value: $NEW_VAL
157− ${WARNOVERRIDE}
158− if [ "$STRICT" = "true" ]; then
159− STRICT_MODE_VIOLATED=true
160− fi
161− elif [ "$WARNREDUN" = "true" ]; then
162− ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE:
163− fi
164− if [ "$BUILTIN_FLAG" = "false" ]; then
165− sed -i "/$CFG[ =]/d" $TMP_FILE
166− else
167− sed -i "/$CFG[ =]/d" $MERGE_FILE
168− fi
169− done
170− # In case the previous file lacks a new line at the end
171− echo >> $TMP_FILE
172− cat $MERGE_FILE >> $TMP_FILE
173−done
174142
143+ # Check for duplicate input files
144+ case " $PROCESSED_FILES " in
145+ *" $ORIG_MERGE_FILE "*)
146+ ${WARNOVERRIDE} "WARNING: Input file provided multiple times: $ORIG_MERGE_FILE"
147+ ;;
148+ esac
149+
150+ # Use awk for single-pass processing instead of per-symbol grep/sed
151+ if ! "$AWK" -v prefix="$CONFIG_PREFIX" \
152+ -v warnoverride="$WARNOVERRIDE" \
153+ -v strict="$STRICT" \
154+ -v builtin="$BUILTIN" \
155+ -v warnredun="$WARNREDUN" '
156+ BEGIN {
157+ strict_violated = 0
158+ cfg_regex = "^" prefix "[a-zA-Z0-9_]+"
159+ notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$"
160+ }
161+
162+ # Extract config name from a line, returns "" if not a config line
163+ function get_cfg(line) {
164+ if (match(line, cfg_regex)) {
165+ return substr(line, RSTART, RLENGTH)
166+ } else if (match(line, notset_regex)) {
167+ # Extract CONFIG_FOO from "# CONFIG_FOO is not set"
168+ sub(/^# /, "", line)
169+ sub(/ is not set$/, "", line)
170+ return line
171+ }
172+ return ""
173+ }
174+
175+ function warn_builtin(cfg, prev, new) {
176+ if (warnoverride == "true") return
177+ print cfg ": -y passed, will not demote y to m"
178+ print "Previous value: " prev
179+ print "New value: " new
180+ print ""
181+ }
182+
183+ function warn_redefined(cfg, prev, new) {
184+ if (warnoverride == "true") return
185+ print "Value of " cfg " is redefined by fragment " mergefile ":"
186+ print "Previous value: " prev
187+ print "New value: " new
188+ print ""
189+ }
190+
191+ function warn_redundant(cfg) {
192+ if (warnredun != "true" || warnoverride == "true") return
193+ print "Value of " cfg " is redundant by fragment " mergefile ":"
194+ }
195+
196+ # First pass: read merge file, store all lines and index
197+ FILENAME == ARGV[1] {
198+ mergefile = FILENAME
199+ merge_lines[FNR] = $0
200+ merge_total = FNR
201+ cfg = get_cfg($0)
202+ if (cfg != "") {
203+ merge_cfg[cfg] = $0
204+ merge_cfg_line[cfg] = FNR
205+ }
206+ next
207+ }
208+
209+ # Second pass: process base file (TMP_FILE)
210+ FILENAME == ARGV[2] {
211+ cfg = get_cfg($0)
212+
213+ # Not a config or not in merge file - keep it
214+ if (cfg == "" || !(cfg in merge_cfg)) {
215+ print $0 >> ARGV[3]
216+ next
217+ }
218+
219+ prev_val = $0
220+ new_val = merge_cfg[cfg]
221+
222+ # BUILTIN: do not demote y to m
223+ if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) {
224+ warn_builtin(cfg, prev_val, new_val)
225+ print $0 >> ARGV[3]
226+ skip_merge[merge_cfg_line[cfg]] = 1
227+ next
228+ }
229+
230+ # Values equal - redundant
231+ if (prev_val == new_val) {
232+ warn_redundant(cfg)
233+ next
234+ }
235+
236+ # "=n" is the same as "is not set"
237+ if (prev_val ~ /=n$/ && new_val ~ / is not set$/) {
238+ print $0 >> ARGV[3]
239+ next
240+ }
241+
242+ # Values differ - redefined
243+ warn_redefined(cfg, prev_val, new_val)
244+ if (strict == "true") {
245+ strict_violated = 1
246+ }
247+ }
248+
249+ # output file, skip all lines
250+ FILENAME == ARGV[3] {
251+ nextfile
252+ }
253+
254+ END {
255+ # Newline in case base file lacks trailing newline
256+ print "" >> ARGV[3]
257+ # Append merge file, skipping lines marked for builtin preservation
258+ for (i = 1; i <= merge_total; i++) {
259+ if (!(i in skip_merge)) {
260+ print merge_lines[i] >> ARGV[3]
261+ }
262+ }
263+ if (strict_violated) {
264+ exit 1
265+ }
266+ }' \
267+ "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then
268+ # awk exited non-zero, strict mode was violated
269+ STRICT_MODE_VIOLATED=true
270+ fi
271+ mv "$TMP_FILE.new" "$TMP_FILE"
272+ PROCESSED_FILES="$PROCESSED_FILES $ORIG_MERGE_FILE"
273+done
175274 if [ "$STRICT_MODE_VIOLATED" = "true" ]; then
176275 echo "The fragment redefined a value and strict mode had been passed."
177276 exit 1
@@ -198,16 +297,91 @@ fi · 20 unmodified lines
198297 # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set
199298 make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
200299
300+# Check all specified config values took effect (might have missed-dependency issues)
301+if ! "$AWK" -v prefix="$CONFIG_PREFIX" \
302+ -v warnoverride="$WARNOVERRIDE" \
303+ -v strict="$STRICT" \
304+ -v warnredun="$WARNREDUN" '
305+BEGIN {
306+ strict_violated = 0
307+ cfg_regex = "^" prefix "[a-zA-Z0-9_]+"
308+ notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$"
309+}
201310
202−# Check all specified config values took (might have missed-dependency issues)
203−for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do
311+# Extract config name from a line, returns "" if not a config line
312+function get_cfg(line) {
313+ if (match(line, cfg_regex)) {
314+ return substr(line, RSTART, RLENGTH)
315+ } else if (match(line, notset_regex)) {
316+ # Extract CONFIG_FOO from "# CONFIG_FOO is not set"
317+ sub(/^# /, "", line)
318+ sub(/ is not set$/, "", line)
319+ return line
320+ }
321+ return ""
322+}
204323
205− REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
206− ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true)
207− if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
208− echo "Value requested for $CFG not in final .config"
209− echo "Requested value: $REQUESTED_VAL"
210− echo "Actual value: $ACTUAL_VAL"
211− echo ""
212− fi
213−done
324+function warn_mismatch(cfg, merged, final) {
325+ if (warnredun == "true") return
326+ if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) {
327+ print "WARNING: Value requested for " cfg " not in final .config"
328+ print "Requested value: " merged
329+ print "Actual value: " final
330+ } else if (final == "" && merged ~ / is not set$/) {
331+ # not set, pass
332+ } else if (merged == "" && final != "") {
333+ print "WARNING: " cfg " not in merged config but added in final .config:"
334+ print "Requested value: " merged
335+ print "Actual value: " final
336+ } else {
337+ print "WARNING: " cfg " differs:"
338+ print "Requested value: " merged
339+ print "Actual value: " final
340+ }
341+}
342+
343+# First pass: read effective config file, store all lines
344+FILENAME == ARGV[1] {
345+ cfg = get_cfg($0)
346+ if (cfg != "") {
347+ config_cfg[cfg] = $0
348+ }
349+ next
350+}
351+
352+# Second pass: process merged config and compare against effective config
353+{
354+ cfg = get_cfg($0)
355+ if (cfg == "") next
356+
357+ # strip trailing comment
358+ sub(/[[:space:]]+#.*/, "", $0)
359+ merged_val = $0
360+ final_val = config_cfg[cfg]
361+
362+ if (merged_val == final_val) next
363+
364+ if (merged_val ~ /=n$/ && final_val ~ / is not set$/) next
365+ if (merged_val ~ /=n$/ && final_val == "") next
366+
367+ warn_mismatch(cfg, merged_val, final_val)
368+
369+ if (strict == "true") {
370+ strict_violated = 1
371+ }
372+}
373+
374+END {
375+ if (strict_violated) {
376+ exit 1
377+ }
378+}' \
379+"$KCONFIG_CONFIG" "$TMP_FILE"; then
380+ # awk exited non-zero, strict mode was violated
381+ STRICT_MODE_VIOLATED=true
382+fi
383+
384+if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then
385+ echo "Requested and effective config differ"
386+ exit 1
387+fi
scripts/kconfig/parser.y+3−3
@@ -323,7 +323,7 @@ if_entry: T_IF expr T_EOL · 322 unmodified lines
323323 {
324324 printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno);
325325 menu_add_entry(NULL, M_IF);
326− menu_add_dep($2);
326+ menu_add_dep($2, NULL);
327327 $$ = menu_add_menu();
328328 };
329329
@@ -422,9 +422,9 @@ help: help_start T_HELPTEXT · 92 unmodified lines
422422
423423 /* depends option */
424424
425−depends: T_DEPENDS T_ON expr T_EOL
425+depends: T_DEPENDS T_ON expr if_expr T_EOL
426426 {
427− menu_add_dep($3);
427+ menu_add_dep($3, $4);
428428 printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno);
429429 };
430430
scripts/kconfig/qconf.cc+14−15
@@ -26,8 +26,6 @@ · 25 unmodified lines
2626 #include "lkc.h"
2727 #include "qconf.h"
2828
29−#include "images.h"
30−
3129
3230 static QApplication *configApp;
3331 static ConfigSettings *configSettings;
@@ -1283,13 +1281,14 @@ ConfigMainWindow::ConfigMainWindow(void) · 1249 unmodified lines
12831281 move(x.toInt(), y.toInt());
12841282
12851283 // set up icons
1286− ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1287− ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1288− ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1289− ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1290− ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1291− ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1292− ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1284+ QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/";
1285+ ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm"));
1286+ ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm"));
1287+ ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm"));
1288+ ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm"));
1289+ ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm"));
1290+ ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm"));
1291+ ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm"));
12931292
12941293 QWidget *widget = new QWidget(this);
12951294 setCentralWidget(widget);
@@ -1312,7 +1311,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 16 unmodified lines
13121311
13131312 configList->setFocus();
13141313
1315− backAction = new QAction(QPixmap(xpm_back), "Back", this);
1314+ backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this);
13161315 backAction->setShortcut(QKeySequence::Back);
13171316 connect(backAction, &QAction::triggered,
13181317 this, &ConfigMainWindow::goBack);
@@ -1322,12 +1321,12 @@ ConfigMainWindow::ConfigMainWindow(void) · 3 unmodified lines
13221321 connect(quitAction, &QAction::triggered,
13231322 this, &ConfigMainWindow::close);
13241323
1325− QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this);
1324+ QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this);
13261325 loadAction->setShortcut(QKeySequence::Open);
13271326 connect(loadAction, &QAction::triggered,
13281327 this, &ConfigMainWindow::loadConfig);
13291328
1330− saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
1329+ saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this);
13311330 saveAction->setShortcut(QKeySequence::Save);
13321331 connect(saveAction, &QAction::triggered,
13331332 this, &ConfigMainWindow::saveConfig);
@@ -1344,15 +1343,15 @@ ConfigMainWindow::ConfigMainWindow(void) · 10 unmodified lines
13441343 searchAction->setShortcut(QKeySequence::Find);
13451344 connect(searchAction, &QAction::triggered,
13461345 this, &ConfigMainWindow::searchConfig);
1347− singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
1346+ singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this);
13481347 singleViewAction->setCheckable(true);
13491348 connect(singleViewAction, &QAction::triggered,
13501349 this, &ConfigMainWindow::showSingleView);
1351− splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
1350+ splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this);
13521351 splitViewAction->setCheckable(true);
13531352 connect(splitViewAction, &QAction::triggered,
13541353 this, &ConfigMainWindow::showSplitView);
1355− fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
1354+ fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this);
13561355 fullViewAction->setCheckable(true);
13571356 connect(fullViewAction, &QAction::triggered,
13581357 this, &ConfigMainWindow::showFullView);
scripts/kconfig/streamline_config.pl+1−1
@@ -415,7 +415,7 @@ foreach my $module (keys(%modules)) { · 414 unmodified lines
415415 }
416416 } else {
417417 # Most likely, someone has a custom (binary?) module loaded.
418− print STDERR "$module config not found!!\n";
418+ print STDERR "$module config not found!\n";
419419 }
420420 }
421421
scripts/kconfig/tests/conditional_dep/Kconfig+32−0
@@ -0,0 +1,32 @@
1+# SPDX-License-Identifier: GPL-2.0
2+# Test Kconfig file for conditional dependencies.
3+
4+# Enable module support for tristate testing
5+config MODULES
6+ bool "Enable loadable module support"
7+ modules
8+ default y
9+
10+config FOO
11+ bool "FOO symbol"
12+
13+config BAR
14+ bool "BAR symbol"
15+
16+config TEST_BASIC
17+ bool "Test basic conditional dependency"
18+ depends on FOO if BAR
19+ default y
20+
21+config TEST_COMPLEX
22+ bool "Test complex conditional dependency"
23+ depends on (FOO && BAR) if (FOO || BAR)
24+ default y
25+
26+config BAZ
27+ tristate "BAZ symbol"
28+
29+config TEST_OPTIONAL
30+ tristate "Test simple optional dependency"
31+ depends on BAZ if BAZ
32+ default y
scripts/kconfig/tests/conditional_dep/__init__.py+14−0
@@ -0,0 +1,14 @@
1+# SPDX-License-Identifier: GPL-2.0
2+"""
3+Correctly handle conditional dependencies.
4+"""
5+
6+def test(conf):
7+ assert conf.oldconfig('test_config1') == 0
8+ assert conf.config_matches('expected_config1')
9+
10+ assert conf.oldconfig('test_config2') == 0
11+ assert conf.config_matches('expected_config2')
12+
13+ assert conf.oldconfig('test_config3') == 0
14+ assert conf.config_matches('expected_config3')
scripts/kconfig/tests/conditional_dep/expected_config1+11−0
@@ -0,0 +1,11 @@
1+#
2+# Automatically generated file; DO NOT EDIT.
3+# Main menu
4+#
5+CONFIG_MODULES=y
6+CONFIG_FOO=y
7+CONFIG_BAR=y
8+CONFIG_TEST_BASIC=y
9+CONFIG_TEST_COMPLEX=y
10+CONFIG_BAZ=m
11+CONFIG_TEST_OPTIONAL=m
scripts/kconfig/tests/conditional_dep/expected_config2+9−0
@@ -0,0 +1,9 @@
1+#
2+# Automatically generated file; DO NOT EDIT.
3+# Main menu
4+#
5+CONFIG_MODULES=y
6+# CONFIG_FOO is not set
7+CONFIG_BAR=y
8+CONFIG_BAZ=y
9+CONFIG_TEST_OPTIONAL=y
scripts/kconfig/tests/conditional_dep/expected_config3+11−0
@@ -0,0 +1,11 @@
1+#
2+# Automatically generated file; DO NOT EDIT.
3+# Main menu
4+#
5+CONFIG_MODULES=y
6+# CONFIG_FOO is not set
7+# CONFIG_BAR is not set
8+CONFIG_TEST_BASIC=y
9+CONFIG_TEST_COMPLEX=y
10+# CONFIG_BAZ is not set
11+CONFIG_TEST_OPTIONAL=y
scripts/kconfig/tests/conditional_dep/test_config1+6−0
@@ -0,0 +1,6 @@
1+# Basic check that everything can be configured if selected.
2+CONFIG_FOO=y
3+CONFIG_BAR=y
4+CONFIG_BAZ=m
5+# Ensure that TEST_OPTIONAL=y with BAZ=m is converted to TEST_OPTIONAL=m
6+CONFIG_TEST_OPTIONAL=y
scripts/kconfig/tests/conditional_dep/test_config2+7−0
@@ -0,0 +1,7 @@
1+# If FOO is not selected, then TEST_BASIC should fail the conditional
2+# dependency since BAR is set.
3+# TEST_COMPLEX will fail dependency as it depends on both FOO and BAR
4+# if either of those is selected.
5+CONFIG_FOO=n
6+CONFIG_BAR=y
7+CONFIG_BAZ=y
scripts/kconfig/tests/conditional_dep/test_config3+6−0
@@ -0,0 +1,6 @@
1+# If FOO is not selected, but BAR is also not selected, then TEST_BASIC
2+# should pass since the dependency on FOO is conditional on BAR.
3+# TEST_COMPLEX should be also set since neither FOO nor BAR are selected
4+# so it has no dependencies.
5+CONFIG_FOO=n
6+CONFIG_BAR=n
scripts/link-vmlinux.sh+4−0
@@ -143,6 +143,10 @@ kallsyms() · 142 unmodified lines
143143 kallsymopt="${kallsymopt} --all-symbols"
144144 fi
145145
146+ if is_enabled CONFIG_64BIT || is_enabled CONFIG_RELOCATABLE; then
147+ kallsymopt="${kallsymopt} --pc-relative"
148+ fi
149+
146150 info KSYMS "${2}.S"
147151 scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S"
148152
scripts/make_fit.py+144−35
@@ -10,10 +10,14 @@ · 9 unmodified lines
1010 Usage:
1111 make_fit.py -A arm64 -n 'Linux-6.6' -O linux
1212 -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk
13− @arch/arm64/boot/dts/dtbs-list -E -c gzip
13+ -r /boot/initrd.img-6.14.0-27-generic @arch/arm64/boot/dts/dtbs-list
14+ -E -c gzip
1415
15−Creates a FIT containing the supplied kernel and a set of devicetree files,
16−either specified individually or listed in a file (with an '@' prefix).
16+Creates a FIT containing the supplied kernel, an optional ramdisk, and a set of
17+devicetree files, either specified individually or listed in a file (with an
18+'@' prefix).
19+
20+Use -r to specify an existing ramdisk/initrd file.
1721
1822 Use -E to generate an external FIT (where the data is placed after the
1923 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. · 9 unmodified lines
2933
3034 The resulting FIT can be booted by bootloaders which support FIT, such
3135 as U-Boot, Linuxboot, Tianocore, etc.
32−
33−Note that this tool does not yet support adding a ramdisk / initrd.
3436 """
3537
3638 import argparse
3739 import collections
40+import multiprocessing
3841 import os
3942 import subprocess
4043 import sys
@@ -48,11 +51,12 @@ import libfdt · 7 unmodified lines
4851 CompTool = collections.namedtuple('CompTool', 'ext,tools')
4952
5053 COMP_TOOLS = {
51− 'bzip2': CompTool('.bz2', 'bzip2'),
54+ 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'),
5255 'gzip': CompTool('.gz', 'pigz,gzip'),
5356 'lz4': CompTool('.lz4', 'lz4'),
54− 'lzma': CompTool('.lzma', 'lzma'),
57+ 'lzma': CompTool('.lzma', 'plzip,lzma'),
5558 'lzo': CompTool('.lzo', 'lzop'),
59+ 'xz': CompTool('.xz', 'xz'),
5660 'zstd': CompTool('.zstd', 'zstd'),
5761 }
5862
@@ -81,6 +85,8 @@ def parse_args(): · 22 unmodified lines
8185 help='Specifies the operating system')
8286 parser.add_argument('-k', '--kernel', type=str, required=True,
8387 help='Specifies the (uncompressed) kernel input file (.itk)')
88+ parser.add_argument('-r', '--ramdisk', type=str,
89+ help='Specifies the ramdisk/initrd input file')
8490 parser.add_argument('-v', '--verbose', action='store_true',
8591 help='Enable verbose output')
8692 parser.add_argument('dtbs', type=str, nargs='*',
@@ -98,7 +104,7 @@ def setup_fit(fsw, name): · 11 unmodified lines
98104 fsw (libfdt.FdtSw): Object to use for writing
99105 name (str): Name of kernel image
100106 """
101− fsw.INC_SIZE = 65536
107+ fsw.INC_SIZE = 16 << 20
102108 fsw.finish_reservemap()
103109 fsw.begin_node('')
104110 fsw.property_string('description', f'{name} with devicetree set')
@@ -133,7 +139,28 @@ def write_kernel(fsw, data, args): · 28 unmodified lines
133139 fsw.property_u32('entry', 0)
134140
135141
136−def finish_fit(fsw, entries):
142+def write_ramdisk(fsw, data, args):
143+ """Write out the ramdisk image
144+
145+ Writes a ramdisk node along with the required properties
146+
147+ Args:
148+ fsw (libfdt.FdtSw): Object to use for writing
149+ data (bytes): Data to write (possibly compressed)
150+ args (Namespace): Contains necessary strings:
151+ arch: FIT architecture, e.g. 'arm64'
152+ fit_os: Operating Systems, e.g. 'linux'
153+ """
154+ with fsw.add_node('ramdisk'):
155+ fsw.property_string('description', 'Ramdisk')
156+ fsw.property_string('type', 'ramdisk')
157+ fsw.property_string('arch', args.arch)
158+ fsw.property_string('compression', 'none')
159+ fsw.property_string('os', args.os)
160+ fsw.property('data', data)
161+
162+
163+def finish_fit(fsw, entries, has_ramdisk=False):
137164 """Finish the FIT ready for use
138165
139166 Writes the /configurations node and subnodes
@@ -143,6 +170,7 @@ def finish_fit(fsw, entries): · 3 unmodified lines
143170 entries (list of tuple): List of configurations:
144171 str: Description of model
145172 str: Compatible stringlist
173+ has_ramdisk (bool): True if a ramdisk is included in the FIT
146174 """
147175 fsw.end_node()
148176 seq = 0
@@ -154,6 +182,8 @@ def finish_fit(fsw, entries): · 5 unmodified lines
154182 fsw.property_string('description', model)
155183 fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii"))
156184 fsw.property_string('kernel', 'kernel')
185+ if has_ramdisk:
186+ fsw.property_string('ramdisk', 'ramdisk')
157187 fsw.end_node()
158188
159189
@@ -179,7 +209,12 @@ def compress_data(inf, compress): · 19 unmodified lines
179209 done = False
180210 for tool in comp.tools.split(','):
181211 try:
182− subprocess.call([tool, '-c'], stdin=inf, stdout=outf)
212+ # Add parallel flags for tools that support them
213+ cmd = [tool]
214+ if tool in ('zstd', 'xz'):
215+ cmd.extend(['-T0']) # Use all available cores
216+ cmd.append('-c')
217+ subprocess.call(cmd, stdin=inf, stdout=outf)
183218 done = True
184219 break
185220 except FileNotFoundError:
@@ -191,15 +226,31 @@ def compress_data(inf, compress): · 5 unmodified lines
191226 return comp_data
192227
193228
194−def output_dtb(fsw, seq, fname, arch, compress):
229+def compress_dtb(fname, compress):
230+ """Compress a single DTB file
231+
232+ Args:
233+ fname (str): Filename containing the DTB
234+ compress (str): Compression algorithm, e.g. 'gzip'
235+
236+ Returns:
237+ tuple: (str: fname, bytes: compressed_data)
238+ """
239+ with open(fname, 'rb') as inf:
240+ compressed = compress_data(inf, compress)
241+ return fname, compressed
242+
243+
244+def output_dtb(fsw, seq, fname, arch, compress, data=None):
195245 """Write out a single devicetree to the FIT
196246
197247 Args:
198248 fsw (libfdt.FdtSw): Object to use for writing
199249 seq (int): Sequence number (1 for first)
200250 fname (str): Filename containing the DTB
201− arch: FIT architecture, e.g. 'arm64'
251+ arch (str): FIT architecture, e.g. 'arm64'
202252 compress (str): Compressed algorithm, e.g. 'gzip'
253+ data (bytes): Pre-compressed data (optional)
203254 """
204255 with fsw.add_node(f'fdt-{seq}'):
205256 fsw.property_string('description', os.path.basename(fname))
@@ -207,9 +258,10 @@ def output_dtb(fsw, seq, fname, arch, compress): · 1 unmodified line
207258 fsw.property_string('arch', arch)
208259 fsw.property_string('compression', compress)
209260
210− with open(fname, 'rb') as inf:
211− compressed = compress_data(inf, compress)
212− fsw.property('data', compressed)
261+ if data is None:
262+ with open(fname, 'rb') as inf:
263+ data = compress_data(inf, compress)
264+ fsw.property('data', data)
213265
214266
215267 def process_dtb(fname, args):
@@ -249,30 +301,27 @@ def process_dtb(fname, args): · 33 unmodified lines
249301
250302 return (model, compat, files)
251303
252−def build_fit(args):
253− """Build the FIT from the provided files and arguments
304+
305+def _process_dtbs(args, fsw, entries, fdts):
306+ """Process all DTB files and add them to the FIT
254307
255308 Args:
256− args (Namespace): Program arguments
309+ args: Program arguments
310+ fsw: FIT writer object
311+ entries: List to append entries to
312+ fdts: Dictionary of processed DTBs
257313
258314 Returns:
259315 tuple:
260− bytes: FIT data
261− int: Number of configurations generated
262− size: Total uncompressed size of data
316+ Number of files processed
317+ Total size of files processed
263318 """
264319 seq = 0
265320 size = 0
266− fsw = libfdt.FdtSw()
267− setup_fit(fsw, args.name)
268− entries = []
269− fdts = {}
270321
271− # Handle the kernel
272− with open(args.kernel, 'rb') as inf:
273− comp_data = compress_data(inf, args.compress)
274− size += os.path.getsize(args.kernel)
275− write_kernel(fsw, comp_data, args)
322+ # First figure out the unique DTB files that need compression
323+ todo = []
324+ file_info = [] # List of (fname, model, compat, files) tuples
276325
277326 for fname in args.dtbs:
278327 # Ignore non-DTB (*.dtb) files
@@ -282,24 +331,84 @@ def build_fit(args): · 3 unmodified lines
282331 try:
283332 (model, compat, files) = process_dtb(fname, args)
284333 except Exception as e:
285− sys.stderr.write(f"Error processing {fname}:\n")
334+ sys.stderr.write(f'Error processing {fname}:\n')
286335 raise e
287336
337+ file_info.append((fname, model, compat, files))
338+ for fn in files:
339+ if fn not in fdts and fn not in todo:
340+ todo.append(fn)
341+
342+ # Compress all DTBs in parallel
343+ cache = {}
344+ if todo and args.compress != 'none':
345+ if args.verbose:
346+ print(f'Compressing {len(todo)} DTBs...')
347+
348+ with multiprocessing.Pool() as pool:
349+ compress_args = [(fn, args.compress) for fn in todo]
350+ # unpacks each tuple, calls compress_dtb(fn, compress) in parallel
351+ results = pool.starmap(compress_dtb, compress_args)
352+
353+ cache = dict(results)
354+
355+ # Now write all DTBs to the FIT using pre-compressed data
356+ for fname, model, compat, files in file_info:
288357 for fn in files:
289358 if fn not in fdts:
290359 seq += 1
291360 size += os.path.getsize(fn)
292− output_dtb(fsw, seq, fn, args.arch, args.compress)
361+ output_dtb(fsw, seq, fn, args.arch, args.compress,
362+ cache.get(fn))
293363 fdts[fn] = seq
294364
295365 files_seq = [fdts[fn] for fn in files]
296−
297366 entries.append([model, compat, files_seq])
298367
299− finish_fit(fsw, entries)
368+ return seq, size
369+
370+
371+def build_fit(args):
372+ """Build the FIT from the provided files and arguments
373+
374+ Args:
375+ args (Namespace): Program arguments
376+
377+ Returns:
378+ tuple:
379+ bytes: FIT data
380+ int: Number of configurations generated
381+ size: Total uncompressed size of data
382+ """
383+ size = 0
384+ fsw = libfdt.FdtSw()
385+ setup_fit(fsw, args.name)
386+ entries = []
387+ fdts = {}
388+
389+ # Handle the kernel
390+ with open(args.kernel, 'rb') as inf:
391+ comp_data = compress_data(inf, args.compress)
392+ size += os.path.getsize(args.kernel)
393+ write_kernel(fsw, comp_data, args)
394+
395+ # Handle the ramdisk if provided. Compression is not supported as it is
396+ # already compressed.
397+ if args.ramdisk:
398+ with open(args.ramdisk, 'rb') as inf:
399+ data = inf.read()
400+ size += len(data)
401+ write_ramdisk(fsw, data, args)
402+
403+ count, fdt_size = _process_dtbs(args, fsw, entries, fdts)
404+ size += fdt_size
405+
406+ finish_fit(fsw, entries, bool(args.ramdisk))
300407
301408 # Include the kernel itself in the returned file count
302− return fsw.as_fdt().as_bytearray(), seq + 1, size
409+ fdt = fsw.as_fdt()
410+ fdt.pack()
411+ return fdt.as_bytearray(), count + 1 + bool(args.ramdisk), size
303412
304413
305414 def run_make_fit():
scripts/mod/modpost.c+5−1
@@ -602,6 +602,10 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) · 601 unmodified lines
602602 /* Special register function linked on all modules during final link of .ko */
603603 if (strstarts(symname, "_restgpr0_") ||
604604 strstarts(symname, "_savegpr0_") ||
605+ strstarts(symname, "_restgpr1_") ||
606+ strstarts(symname, "_savegpr1_") ||
607+ strstarts(symname, "_restfpr_") ||
608+ strstarts(symname, "_savefpr_") ||
605609 strstarts(symname, "_restvr_") ||
606610 strstarts(symname, "_savevr_") ||
607611 strcmp(symname, ".TOC.") == 0)
@@ -958,7 +962,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 350 unmodified lines
958962 /* symbols in data sections that may refer to any init/exit sections */
959963 if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
960964 match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
961− match(fromsym, PATTERNS("*_ops", "*_probe", "*_console")))
965+ match(fromsym, PATTERNS("*_ops", "*_console")))
962966 return 0;
963967
964968 /* Check for pattern 3 */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t