Skip to content

Instantly share code, notes, and snippets.

@fcicq
Created July 12, 2019 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fcicq/5124a64d106ff47bfbbf2b539ee6dd18 to your computer and use it in GitHub Desktop.
Save fcicq/5124a64d106ff47bfbbf2b539ee6dd18 to your computer and use it in GitHub Desktop.
From 9d0992d35ddd1532b9be9defbe201316e6b93b13 Mon Sep 17 00:00:00 2001
From: Stephen Warren <swarren@nvidia.com>
Date: Mon, 16 Oct 2017 12:04:05 -0600
Subject: [PATCH] kconfig: implement overlays
Kernel overlays allow the kernel source tree to be sharded into separate
directories, referred to as overlays, which are combined into a single
kernel image during the build process. The overlays can be used e.g. to
house different sets of IP that are released on different schedules. This
approach doesn't require the base kernel Kconfig files and Makefiles to
manually specify when to reference source from the overlays; rather the
build system automatically combines the overlays.
Bug 1978395
Change-Id: Ic2de5fd3c56a7037dcc6996b990b356050077fe1
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1579977
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
---
Makefile | 13 +++
scripts/Makefile.build | 2 -
scripts/Makefile.fwinst | 2 -
scripts/Makefile.modbuiltin | 2 -
scripts/Makefile.tegra | 16 ++-
scripts/kconfig/confdata.c | 6 +-
scripts/kconfig/expr.h | 2 +
scripts/kconfig/lkc.h | 4 +-
scripts/kconfig/util.c | 12 ++-
scripts/kconfig/zconf.l | 154 +++++++++++++++++++++-------
scripts/kconfig/zconf.lex.c_shipped | 153 +++++++++++++++++++++------
11 files changed, 271 insertions(+), 95 deletions(-)
diff --git a/Makefile b/Makefile
index 35bc1685a095c..c50e790d5915f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,15 @@
+ifeq ($(KERNEL_OVERLAYS),)
+KERNEL_OVERLAYS :=
+KERNEL_OVERLAYS += $(CURDIR)/../nvidia
+KERNEL_OVERLAYS += $(CURDIR)/../t19x
+KERNEL_OVERLAYS += $(CURDIR)/../nvgpu
+KERNEL_OVERLAYS += $(CURDIR)/../nvgpu-t19x
+else
+override KERNEL_OVERLAYS := $(subst :, ,$(KERNEL_OVERLAYS))
+endif
+override KERNEL_OVERLAYS := $(abspath $(KERNEL_OVERLAYS))
+export KERNEL_OVERLAYS
+
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 52
@@ -216,6 +228,7 @@ src := $(srctree)
obj := $(objtree)
VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
+VPATH += $(foreach overlay,$(KERNEL_OVERLAYS),:$(overlay))
export srctree objtree VPATH
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 8778d63d33a7a..16b16175b6ced 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -67,14 +67,12 @@ ifneq ($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(h
include scripts/Makefile.host
endif
-ifneq ($(KBUILD_SRC),)
# Create output directory if not already present
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
# Create directories for object files if directory does not exist
# Needed when obj-y := dir/file.o syntax is used
_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
-endif
ifndef obj
$(warning kbuild: Makefile.build is included improperly)
diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst
index b272900352532..a06ab999acd8b 100644
--- a/scripts/Makefile.fwinst
+++ b/scripts/Makefile.fwinst
@@ -24,14 +24,12 @@ ifndef CONFIG_FIRMWARE_IN_KERNEL
mod-fw += $(fw-shipped-y)
endif
-ifneq ($(KBUILD_SRC),)
# Create output directory if not already present
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all))))
# Create directories for firmware in subdirectories
_dummy := $(foreach d,$(firmware-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
-endif
installed-mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(mod-fw))
diff --git a/scripts/Makefile.modbuiltin b/scripts/Makefile.modbuiltin
index 1dcbb4569015e..2012adbe41ab9 100644
--- a/scripts/Makefile.modbuiltin
+++ b/scripts/Makefile.modbuiltin
@@ -14,10 +14,8 @@ __modbuiltin:
include scripts/Kbuild.include
-ifneq ($(KBUILD_SRC),)
# Create output directory if not already present
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
-endif
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
diff --git a/scripts/Makefile.tegra b/scripts/Makefile.tegra
index 77ba411fcef7f..6fa3c461fd0cb 100644
--- a/scripts/Makefile.tegra
+++ b/scripts/Makefile.tegra
@@ -9,14 +9,10 @@
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
-#
-define tegra_include
- ifneq ("$(wildcard $(kbuild-dir)/Makefile.$(1))", "")
- include $(kbuild-dir)/Makefile.$(1)
- EXTRA_CFLAGS += -I$(srctree)/../$(1)/include
- endif
-endef
-$(foreach suffix, \
- nvgpu nvidia t19x, \
- $(eval $(call tegra_include,$(suffix))))
+define include_overlay
+ ovl_file := $(if $(wildcard $(overlay)/$(src)/Kbuild),$(overlay)/$(src)/Kbuild,$(overlay)/$(src)/Makefile)
+ -include $(ovl_file)
+ EXTRA_CFLAGS += -I$(overlay)/include
+endef
+$(foreach overlay,$(KERNEL_OVERLAYS),$(eval $(value include_overlay)))
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 297b079ae4d9f..a9790d406263f 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -258,12 +258,12 @@ int conf_read_simple(const char *name, int def)
int i, def_flags;
if (name) {
- in = zconf_fopen(name);
+ in = zconf_fopen(name, 0, NULL, NULL);
} else {
struct property *prop;
name = conf_get_configname();
- in = zconf_fopen(name);
+ in = zconf_fopen(name, 0, NULL, NULL);
if (in)
goto load;
sym_add_change_count(1);
@@ -275,7 +275,7 @@ int conf_read_simple(const char *name, int def)
prop->expr->type != E_SYMBOL)
continue;
name = conf_expand_value(prop->expr->left.sym->name);
- in = zconf_fopen(name);
+ in = zconf_fopen(name, 0, NULL, NULL);
if (in) {
conf_message(_("using defaults found in %s"),
name);
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 973b6f7333682..83925a448418a 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -21,6 +21,8 @@ struct file {
struct file *next;
struct file *parent;
const char *name;
+ int overlay_id;
+ const char *logical_name;
int lineno;
};
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 134a89bcb15a3..f2c2aae45d6d2 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -70,7 +70,7 @@ struct kconf_id {
void zconfdump(FILE *out);
void zconf_starthelp(void);
-FILE *zconf_fopen(const char *name);
+FILE *zconf_fopen(const char *name, int init_overlay_id, int *found_overlay_id, const char **found_name);
void zconf_initscan(const char *name);
void zconf_nextfile(const char *name);
int zconf_lineno(void);
@@ -111,7 +111,7 @@ void menu_finalize(struct menu *parent);
void menu_set_type(int type);
/* util.c */
-struct file *file_lookup(const char *name);
+struct file *file_lookup(const char *name, int overlay_id, const char *logical_name);
int file_write_dep(const char *name);
void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size);
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 9bf2f4db160c4..8175fd161fa36 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -11,21 +11,23 @@
#include "lkc.h"
/* file already present in list? If not add it */
-struct file *file_lookup(const char *name)
+struct file *file_lookup(const char *name, int overlay_id, const char *logical_name)
{
struct file *file;
- const char *file_name = sym_expand_string_value(name);
for (file = file_list; file; file = file->next) {
- if (!strcmp(name, file->name)) {
- free((void *)file_name);
+ if (!strcmp(name, file->name) && overlay_id == file->overlay_id) {
+ free((void *)name);
+ free((void *)logical_name);
return file;
}
}
file = xmalloc(sizeof(*file));
memset(file, 0, sizeof(*file));
- file->name = file_name;
+ file->name = name;
+ file->overlay_id = overlay_id;
+ file->logical_name = logical_name;
file->next = file_list;
file_list = file;
return file;
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index c410d257da060..45a345b887bc8 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -265,6 +265,43 @@ static void zconf_endhelp(void)
BEGIN(INITIAL);
}
+char **overlays;
+int overlay_count;
+
+static void zconf_init_overlays(void)
+{
+ static int initialized;
+ char *env, *elem;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ overlays = xmalloc(2 * sizeof(*overlays));
+ overlays[0] = "";
+ overlays[1] = NULL;
+ overlay_count = 2;
+
+ env = getenv(SRCTREE);
+ if (env && strcmp(env, "."))
+ overlays[1] = env;
+
+ env = getenv("KERNEL_OVERLAYS");
+ if (!env)
+ return;
+ env = xstrdup(env);
+
+ for (;;) {
+ elem = strtok(env, " ");
+ if (!elem)
+ break;
+ env = NULL;
+
+ overlays = xrealloc(overlays, (overlay_count + 1) * sizeof(*overlays));
+ overlays[overlay_count] = elem;
+ overlay_count++;
+ }
+}
/*
* Try to open specified file with following names:
@@ -274,25 +311,46 @@ static void zconf_endhelp(void)
* when compiling the kernel.
* Return NULL if file is not found.
*/
-FILE *zconf_fopen(const char *name)
+FILE *zconf_fopen(const char *name, int init_overlay_id, int *found_overlay_id, const char **found_name)
{
- char *env, fullname[PATH_MAX+1];
- FILE *f;
-
- f = fopen(name, "r");
- if (!f && name != NULL && name[0] != '/') {
- env = getenv(SRCTREE);
- if (env) {
- sprintf(fullname, "%s/%s", env, name);
- f = fopen(fullname, "r");
+ int i;
+ char fullname[PATH_MAX+1];
+ FILE *fp;
+
+ zconf_init_overlays();
+
+ for (i = init_overlay_id; i < overlay_count; i++) {
+ if (!overlays[i])
+ continue;
+ if (overlays[i][0])
+ sprintf(fullname, "%s/%s", overlays[i], name);
+ else
+ strcpy(fullname, name);
+ fp = fopen(fullname, "r");
+ if (fp) {
+ if (found_overlay_id)
+ *found_overlay_id = i;
+ if (found_name) {
+ if (i < 2)
+ *found_name = name;
+ else
+ *found_name = fullname;
+ *found_name = xstrdup(*found_name);
+ }
+ return fp;
}
}
- return f;
+
+ return NULL;
}
void zconf_initscan(const char *name)
{
- yyin = zconf_fopen(name);
+ int found_overlay_id;
+
+ zconf_init_overlays();
+
+ yyin = zconf_fopen(name, 0, &found_overlay_id, NULL);
if (!yyin) {
printf("can't find file %s\n", name);
exit(1);
@@ -301,56 +359,79 @@ void zconf_initscan(const char *name)
current_buf = xmalloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
- current_file = file_lookup(name);
+ /*
+ * file_lookup can't find name, so won't free it, so no need to
+ * duplicate the allocation
+ */
+ current_file = file_lookup(name, found_overlay_id, name);
current_file->lineno = 1;
}
-void zconf_nextfile(const char *name)
+static void zconf_nextfile_imp(int init_overlay_id, const char *name, int must_exist)
{
- struct file *iter;
- struct file *file = file_lookup(name);
- struct buffer *buf = xmalloc(sizeof(*buf));
- memset(buf, 0, sizeof(*buf));
-
- current_buf->state = YY_CURRENT_BUFFER;
- yyin = zconf_fopen(file->name);
- if (!yyin) {
- printf("%s:%d: can't open file \"%s\"\n",
- zconf_curname(), zconf_lineno(), file->name);
- exit(1);
+ FILE *fp;
+ struct file *file;
+ struct buffer *buf;
+ int found_overlay_id;
+ const char *found_name;
+
+ if (current_buf)
+ current_buf->state = YY_CURRENT_BUFFER;
+
+ fp = zconf_fopen(name, init_overlay_id, &found_overlay_id, &found_name);
+ if (!fp) {
+ if (must_exist) {
+ printf("%s:%d: can't open file \"%s\"\n",
+ zconf_curname(), zconf_lineno(), name);
+ exit(1);
+ }
+ return;
}
+
+ yyin = fp;
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+
+ buf = xmalloc(sizeof(*buf));
+ memset(buf, 0, sizeof(*buf));
buf->parent = current_buf;
current_buf = buf;
- for (iter = current_file->parent; iter; iter = iter->parent ) {
- if (!strcmp(current_file->name,iter->name) ) {
+ file = file_lookup(found_name, found_overlay_id, name);
+ file->lineno = 1;
+ file->parent = current_file;
+ current_file = file;
+}
+
+void zconf_nextfile(const char *name)
+{
+ const char *file_name = sym_expand_string_value(name);
+ struct file *iter;
+
+ for (iter = current_file; iter; iter = iter->parent ) {
+ if (!strcmp(file_name, iter->logical_name) ) {
printf("%s:%d: recursive inclusion detected. "
"Inclusion path:\n current file : '%s'\n",
zconf_curname(), zconf_lineno(),
zconf_curname());
iter = current_file->parent;
- while (iter && \
- strcmp(iter->name,current_file->name)) {
+ while (iter) {
printf(" included from: '%s:%d'\n",
iter->name, iter->lineno-1);
iter = iter->parent;
}
- if (iter)
- printf(" included from: '%s:%d'\n",
- iter->name, iter->lineno+1);
exit(1);
}
}
- file->lineno = 1;
- file->parent = current_file;
- current_file = file;
+
+ zconf_nextfile_imp(0, file_name, 1);
}
static void zconf_endfile(void)
{
struct buffer *parent;
+ struct file *prev_file;
+ prev_file = current_file;
current_file = current_file->parent;
parent = current_buf->parent;
@@ -361,6 +442,9 @@ static void zconf_endfile(void)
}
free(current_buf);
current_buf = parent;
+
+ if (prev_file->overlay_id < overlay_count - 1)
+ zconf_nextfile_imp(prev_file->overlay_id + 1, xstrdup(prev_file->logical_name), 0);
}
int zconf_lineno(void)
diff --git a/scripts/kconfig/zconf.lex.c_shipped b/scripts/kconfig/zconf.lex.c_shipped
index 37fdf61235058..01d757400956b 100644
--- a/scripts/kconfig/zconf.lex.c_shipped
+++ b/scripts/kconfig/zconf.lex.c_shipped
@@ -2364,6 +2364,44 @@ static void zconf_endhelp(void)
BEGIN(INITIAL);
}
+char **overlays;
+int overlay_count;
+
+static void zconf_init_overlays(void)
+{
+ static int initialized;
+ char *env, *elem;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ overlays = xmalloc(2 * sizeof(*overlays));
+ overlays[0] = "";
+ overlays[1] = NULL;
+ overlay_count = 2;
+
+ env = getenv(SRCTREE);
+ if (env && strcmp(env, "."))
+ overlays[1] = env;
+
+ env = getenv("KERNEL_OVERLAYS");
+ if (!env)
+ return;
+ env = xstrdup(env);
+
+ for (;;) {
+ elem = strtok(env, " ");
+ if (!elem)
+ break;
+ env = NULL;
+
+ overlays = xrealloc(overlays, (overlay_count + 1) * sizeof(*overlays));
+ overlays[overlay_count] = elem;
+ overlay_count++;
+ }
+}
+
/*
* Try to open specified file with following names:
* ./name
@@ -2372,25 +2410,46 @@ static void zconf_endhelp(void)
* when compiling the kernel.
* Return NULL if file is not found.
*/
-FILE *zconf_fopen(const char *name)
+FILE *zconf_fopen(const char *name, int init_overlay_id, int *found_overlay_id, const char **found_name)
{
- char *env, fullname[PATH_MAX+1];
- FILE *f;
+ int i;
+ char fullname[PATH_MAX+1];
+ FILE *fp;
+
+ zconf_init_overlays();
- f = fopen(name, "r");
- if (!f && name != NULL && name[0] != '/') {
- env = getenv(SRCTREE);
- if (env) {
- sprintf(fullname, "%s/%s", env, name);
- f = fopen(fullname, "r");
+ for (i = init_overlay_id; i < overlay_count; i++) {
+ if (!overlays[i])
+ continue;
+ if (overlays[i][0])
+ sprintf(fullname, "%s/%s", overlays[i], name);
+ else
+ strcpy(fullname, name);
+ fp = fopen(fullname, "r");
+ if (fp) {
+ if (found_overlay_id)
+ *found_overlay_id = i;
+ if (found_name) {
+ if (i < 2)
+ *found_name = name;
+ else
+ *found_name = fullname;
+ *found_name = xstrdup(*found_name);
+ }
+ return fp;
}
}
- return f;
+
+ return NULL;
}
void zconf_initscan(const char *name)
{
- zconfin = zconf_fopen(name);
+ int found_overlay_id;
+
+ zconf_init_overlays();
+
+ zconfin = zconf_fopen(name, 0, &found_overlay_id, NULL);
if (!zconfin) {
printf("can't find file %s\n", name);
exit(1);
@@ -2399,56 +2458,79 @@ void zconf_initscan(const char *name)
current_buf = xmalloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
- current_file = file_lookup(name);
+ /*
+ * file_lookup can't find name, so won't free it, so no need to
+ * duplicate the allocation
+ */
+ current_file = file_lookup(name, found_overlay_id, name);
current_file->lineno = 1;
}
-void zconf_nextfile(const char *name)
+static void zconf_nextfile_imp(int init_overlay_id, const char *name, int must_exist)
{
- struct file *iter;
- struct file *file = file_lookup(name);
- struct buffer *buf = xmalloc(sizeof(*buf));
- memset(buf, 0, sizeof(*buf));
-
- current_buf->state = YY_CURRENT_BUFFER;
- zconfin = zconf_fopen(file->name);
- if (!zconfin) {
- printf("%s:%d: can't open file \"%s\"\n",
- zconf_curname(), zconf_lineno(), file->name);
- exit(1);
+ FILE *fp;
+ struct file *file;
+ struct buffer *buf;
+ int found_overlay_id;
+ const char *found_name;
+
+ if (current_buf)
+ current_buf->state = YY_CURRENT_BUFFER;
+
+ fp = zconf_fopen(name, init_overlay_id, &found_overlay_id, &found_name);
+ if (!fp) {
+ if (must_exist) {
+ printf("%s:%d: can't open file \"%s\"\n",
+ zconf_curname(), zconf_lineno(), name);
+ exit(1);
+ }
+ return;
}
+
+ zconfin = fp;
zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
+
+ buf = xmalloc(sizeof(*buf));
+ memset(buf, 0, sizeof(*buf));
buf->parent = current_buf;
current_buf = buf;
- for (iter = current_file->parent; iter; iter = iter->parent ) {
- if (!strcmp(current_file->name,iter->name) ) {
+ file = file_lookup(found_name, found_overlay_id, name);
+ file->lineno = 1;
+ file->parent = current_file;
+ current_file = file;
+}
+
+void zconf_nextfile(const char *name)
+{
+ const char *file_name = sym_expand_string_value(name);
+ struct file *iter;
+
+ for (iter = current_file; iter; iter = iter->parent ) {
+ if (!strcmp(file_name, iter->logical_name) ) {
printf("%s:%d: recursive inclusion detected. "
"Inclusion path:\n current file : '%s'\n",
zconf_curname(), zconf_lineno(),
zconf_curname());
iter = current_file->parent;
- while (iter && \
- strcmp(iter->name,current_file->name)) {
+ while (iter) {
printf(" included from: '%s:%d'\n",
iter->name, iter->lineno-1);
iter = iter->parent;
}
- if (iter)
- printf(" included from: '%s:%d'\n",
- iter->name, iter->lineno+1);
exit(1);
}
}
- file->lineno = 1;
- file->parent = current_file;
- current_file = file;
+
+ zconf_nextfile_imp(0, file_name, 1);
}
static void zconf_endfile(void)
{
struct buffer *parent;
+ struct file *prev_file;
+ prev_file = current_file;
current_file = current_file->parent;
parent = current_buf->parent;
@@ -2459,6 +2541,9 @@ static void zconf_endfile(void)
}
free(current_buf);
current_buf = parent;
+
+ if (prev_file->overlay_id < overlay_count - 1)
+ zconf_nextfile_imp(prev_file->overlay_id + 1, xstrdup(prev_file->logical_name), 0);
}
int zconf_lineno(void)
--
2.21.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment