[Concept,07/13] ulib: Replace CONFIG_ULIB_JUMP_TO_MAIN with runtime ulib_has_main()

Message ID 20260214021317.816170-8-sjg@u-boot.org
State New
Headers
Series ulib: Support building examples for x86 |

Commit Message

Simon Glass Feb. 14, 2026, 2:13 a.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

The Kconfig option CONFIG_ULIB_JUMP_TO_MAIN is a build-time switch that
cannot vary per-binary when multiple images share the same config.

Replace it with a weak ulib_has_main() function that returns false by
default. Example programs override it to return true, so the decision
to set GD_FLG_ULIB and jump to main() is made at link time rather than
build time. Add a weak main() fallback that enters the normal command
loop.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 Kconfig          |  9 ---------
 common/board_f.c |  2 +-
 common/board_r.c | 18 +++++++++++++++++-
 include/init.h   | 11 +++++++++++
 4 files changed, 29 insertions(+), 11 deletions(-)
  

Patch

diff --git a/Kconfig b/Kconfig
index 011f248ba03..ccd62220f0e 100644
--- a/Kconfig
+++ b/Kconfig
@@ -129,15 +129,6 @@  config ULIB_SHARED_LIB
 	  available for SANDBOX builds since shared libraries are not
 	  meaningful for bare-metal targets.
 
-config ULIB_JUMP_TO_MAIN
-	bool "Set GD_FLG_ULIB flag in early boot"
-	depends on ULIB
-	help
-	  Enable this to set the GD_FLG_ULIB flag in the global data structure
-	  during early boot (in start.S before calling board_init_f). This allows
-	  U-Boot code to detect that it's running as a library from the very
-	  beginning of initialization.
-
 config OPTIMIZE_INLINING
 	bool "Allow compiler to uninline functions marked 'inline' in full U-Boot"
 	help
diff --git a/common/board_f.c b/common/board_f.c
index 448cf2e319a..4558fdf297a 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -1031,7 +1031,7 @@  void board_init_f(ulong boot_flags)
 
 	gd->flags = boot_flags;
 	gd->flags &= ~GD_FLG_HAVE_CONSOLE;
-	if (IS_ENABLED(CONFIG_ULIB_JUMP_TO_MAIN))
+	if (ulib_has_main())
 		gd->flags |= GD_FLG_ULIB;
 
 	gd->boardf = &boardf;
diff --git a/common/board_r.c b/common/board_r.c
index 53851504c8f..ce5aa28b1e5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -771,6 +771,22 @@  static void initcall_run_r(void)
 	INITCALL(run_main_loop);
 }
 
+__weak bool ulib_has_main(void)
+{
+	return false;
+}
+
+#ifdef CONFIG_ULIB
+__weak int main(void)
+{
+	/* No example linked -- fall through to normal command loop */
+	for (;;)
+		main_loop();
+
+	return 0;
+}
+#endif
+
 void board_init_r(gd_t *new_gd, ulong dest_addr)
 {
 	/*
@@ -803,7 +819,7 @@  void board_init_r(gd_t *new_gd, ulong dest_addr)
 
 	if (gd_ulib()) {
 #ifdef CONFIG_ULIB	/* handle __noreturn attribute */
-		if (!IS_ENABLED(CONFIG_ULIB_JUMP_TO_MAIN))
+		if (!ulib_has_main())
 			return;
 #endif
 		main();
diff --git a/include/init.h b/include/init.h
index 4e2155abb22..8a4e23403cc 100644
--- a/include/init.h
+++ b/include/init.h
@@ -392,6 +392,17 @@  int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
  */
 int ulib_init_with_data(char *progname, struct global_data *data);
 
+/**
+ * ulib_has_main() - check whether an example main() is linked
+ *
+ * This weak function returns false by default.  Example programs override it
+ * to return true so that U-Boot can set GD_FLG_ULIB and jump to main() after
+ * initialisation.
+ *
+ * Return: true if an example main() is present, false otherwise
+ */
+bool ulib_has_main(void);
+
 /**
  * main() - main program called from ulib
  *