Skip to content

Commit

Permalink
kernel: add bootargs support
Browse files Browse the repository at this point in the history
Add support for passing args to main(). The
content of bootargs is taken from get_bootargs()
which should be implemented for each loader and
then its split into args and passed to main.

(cherry picked from commit 49fc106)

Original-Signed-off-by: Jakub Michalski <jmichalski@internships.antmicro.com>
Original-Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
GitOrigin-RevId: 49fc106
Cr-Build-Id: 8737098476786990081
Cr-Build-Url: https://cr-buildbucket.appspot.com/build/8737098476786990081
Copybot-Job-Name: zephyr-main-copybot-downstream
Change-Id: I7557853aa0f84f845c0d9e88aabb431cc0bea9be
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/zephyr/+/5842088
Tested-by: Keith Short <keithshort@chromium.org>
Commit-Queue: Keith Short <keithshort@chromium.org>
Reviewed-by: Keith Short <keithshort@chromium.org>
Reviewed-by: Tristan Honscheid <honscheid@google.com>
  • Loading branch information
jmichalski-ant authored and Chromeos LUCI committed Sep 11, 2024
1 parent 0a959ed commit e298fd8
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 3 deletions.
25 changes: 25 additions & 0 deletions kernel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,31 @@ config STATIC_INIT_GNU
Note the option CMAKE_LINKER_GENERATOR does not yet support this feature
or CPP.

config BOOTARGS
bool "Support bootargs"
help
Enables bootargs support and passing them to main().

config DYNAMIC_BOOTARGS
bool "Support dynamic bootargs"
depends on BOOTARGS
help
Enables dynamic bootargs support.

config BOOTARGS_STRING
string "static bootargs string"
depends on BOOTARGS && !DYNAMIC_BOOTARGS
help
Static bootargs string. It includes argv[0], so if its expected that it
contains executable name it should be put at the beginning of this string.

config BOOTARGS_ARGS_BUFFER_SIZE
int "Size of buffer containing main arguments in bytes"
default 1024
depends on BOOTARGS
help
Configures size of buffer containing all arguments passed to main.

endmenu

rsource "Kconfig.device"
Expand Down
102 changes: 99 additions & 3 deletions kernel/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
* This module contains routines that are used to initialize the kernel.
*/

#include <ctype.h>
#include <stdbool.h>
#include <string.h>
#include <offsets_short.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
Expand All @@ -24,13 +27,11 @@
#include <zephyr/linker/linker-defs.h>
#include <ksched.h>
#include <kthread.h>
#include <string.h>
#include <zephyr/sys/dlist.h>
#include <kernel_internal.h>
#include <zephyr/drivers/entropy.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/tracing/tracing.h>
#include <stdbool.h>
#include <zephyr/debug/gcov.h>
#include <kswap.h>
#include <zephyr/timing/timing.h>
Expand All @@ -42,7 +43,7 @@
* TODO(b/272518464): Work around coreboot GCC preprocessor bug.
* #line marks the *next* line, so it is off by one.
*/
#line 46
#line 47

LOG_MODULE_REGISTER(os, CONFIG_KERNEL_LOG_LEVEL);

Expand Down Expand Up @@ -410,6 +411,93 @@ static inline int z_vrfy_device_init(const struct device *dev)

extern void boot_banner(void);

#ifdef CONFIG_BOOTARGS
extern const char *get_bootargs(void);
static char **prepare_main_args(int *argc)
{
#ifdef CONFIG_DYNAMIC_BOOTARGS
const char *bootargs = get_bootargs();
#else
const char bootargs[] = CONFIG_BOOTARGS_STRING;
#endif

/* beginning of the buffer contains argument's strings, end of it contains argvs */
static char args_buf[CONFIG_BOOTARGS_ARGS_BUFFER_SIZE];
char *strings_end = (char *)args_buf;
char **argv_begin = (char **)WB_DN(
args_buf + CONFIG_BOOTARGS_ARGS_BUFFER_SIZE - sizeof(char *));
int i = 0;

*argc = 0;
*argv_begin = NULL;

#ifdef CONFIG_DYNAMIC_BOOTARGS
if (!bootargs) {
return argv_begin;
}
#endif

while (1) {
while (isspace(bootargs[i])) {
i++;
}

if (bootargs[i] == '\0') {
return argv_begin;
}

if (strings_end + sizeof(char *) >= (char *)argv_begin) {
LOG_WRN("not enough space in args buffer to accommodate all bootargs"
" - bootargs truncated");
return argv_begin;
}

argv_begin--;
memmove(argv_begin, argv_begin + 1, *argc * sizeof(char *));
argv_begin[*argc] = strings_end;

bool quoted = false;

if (bootargs[i] == '\"' || bootargs[i] == '\'') {
char delimiter = bootargs[i];

for (int j = i + 1; bootargs[j] != '\0'; j++) {
if (bootargs[j] == delimiter) {
quoted = true;
break;
}
}
}

if (quoted) {
char delimiter = bootargs[i];

i++; /* strip quotes */
while (bootargs[i] != delimiter
&& strings_end < (char *)argv_begin) {
*strings_end++ = bootargs[i++];
}
i++; /* strip quotes */
} else {
while (!isspace(bootargs[i])
&& bootargs[i] != '\0'
&& strings_end < (char *)argv_begin) {
*strings_end++ = bootargs[i++];
}
}

if (strings_end < (char *)argv_begin) {
*strings_end++ = '\0';
} else {
LOG_WRN("not enough space in args buffer to accommodate all bootargs"
" - bootargs truncated");
argv_begin[*argc] = NULL;
return argv_begin;
}
(*argc)++;
}
}
#endif

/**
* @brief Mainline for kernel's background thread
Expand Down Expand Up @@ -463,9 +551,17 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3)
z_mem_manage_boot_finish();
#endif /* CONFIG_MMU */

#ifdef CONFIG_BOOTARGS
extern int main(int, char **);

int argc = 0;
char **argv = prepare_main_args(&argc);
(void)main(argc, argv);
#else
extern int main(void);

(void)main();
#endif /* CONFIG_BOOTARGS */

/* Mark non-essential since main() has no more work to do */
z_thread_essential_clear(&z_main_thread);
Expand Down

0 comments on commit e298fd8

Please sign in to comment.