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(-) 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 * -- 2.43.0