diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-08-30 13:27:23 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-08-30 13:27:23 -0600 |
commit | 6589a0ca8924c1166152a5386e30ea49cd266f51 (patch) | |
tree | 5c4eb249cbbee7db43a5ea13779d3dc72825612d /nuttx/sched/init | |
parent | 7af9398910df9a007a16856956fd7754fa6e89ff (diff) | |
download | nuttx-6589a0ca8924c1166152a5386e30ea49cd266f51.tar.gz nuttx-6589a0ca8924c1166152a5386e30ea49cd266f51.tar.bz2 nuttx-6589a0ca8924c1166152a5386e30ea49cd266f51.zip |
Add configuration options to start the system from a program on a file system
Diffstat (limited to 'nuttx/sched/init')
-rw-r--r-- | nuttx/sched/init/os_bringup.c | 274 |
1 files changed, 216 insertions, 58 deletions
diff --git a/nuttx/sched/init/os_bringup.c b/nuttx/sched/init/os_bringup.c index 150aa4481..b084bd1b0 100644 --- a/nuttx/sched/init/os_bringup.c +++ b/nuttx/sched/init/os_bringup.c @@ -52,6 +52,7 @@ #include <nuttx/wqueue.h> #include <nuttx/kthread.h> #include <nuttx/userspace.h> +#include <nuttx/binfmt/binfmt.h> #ifdef CONFIG_PAGING # include "paging/paging.h" @@ -62,6 +63,59 @@ * Pre-processor Definitions ****************************************************************************/ +/* Configuration */ + +#if defined(CONFIG_INIT_NONE) + /* Kconfig logic will set CONFIG_INIT_NONE if dependencies are not met */ + +# error No initialization mechanism selected (CONFIG_INIT_NONE) + +#else +# if !defined(CONFIG_INIT_ENTRYPOINT) && !defined(CONFIG_INIT_FILEPATH) + /* For backward compatibility with older defconfig files when this was + * the way things were done. + */ + +# define CONFIG_INIT_ENTRYPOINT 1 +# endif + +# if defined(CONFIG_INIT_ENTRYPOINT) + /* Initialize by starting a task at an entry point */ + +# ifndef CONFIG_USER_ENTRYPOINT + /* Entry point name must have been provided */ + +# error CONFIG_USER_ENTRYPOINT must be defined +# endif + +# elif defined(CONFIG_INIT_FILEPATH) + /* Initialize by running an initialization program in the file system. + * Presumably the user has configured a board initialization function + * that will mount the file system containing the initialization + * program. + */ + +# ifndef CONFIG_BOARD_INITIALIZE +# warning You probably need CONFIG_BOARD_INITIALIZE to mount the file system +# endif + +# ifndef CONFIG_USER_INITPATH + /* Path to the initialization program must have been provided */ + +# error CONFIG_USER_INITPATH must be defined +# endif + +# if !defined(CONFIG_INIT_SYMTAB) || !defined(CONFIG_INIT_NEXPORTS) + /* No symbol information... assume no symbol table is available */ + +# undef CONFIG_INIT_SYMTAB +# undef CONFIG_INIT_NEXPORTS +# define CONFIG_INIT_SYMTAB NULL +# define CONFIG_INIT_NEXPORTS 0 +# endif +# endif +#endif + /* If NuttX is built as a separately compiled module, then the config.h header * file should contain the address of the entry point (or path to the file) * that will perform the application-level initialization. @@ -103,28 +157,12 @@ ****************************************************************************/ /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: os_bringup + * Name: os_pgworker * * Description: - * Start all initial system tasks. This does the "system bring-up" after - * the conclusion of basic OS initialization. These initial system tasks - * may include: - * - * - pg_worker: The page-fault worker thread (only if CONFIG_PAGING is - * defined. - * - work_thread: The work thread. This general thread can be used to - * perform most any kind of queued work. Its primary - * function is to serve as the "bottom half" of device - * drivers. - * - * And the main application entry point: - * symbols: - * - * - USER_ENTRYPOINT: This is the default user application entry point. + * Start the page fill worker kernel thread that will resolve page faults. + * This should always be the first thread started because it may have to + * resolve page faults in other threads * * Input Parameters: * None @@ -134,42 +172,49 @@ * ****************************************************************************/ -int os_bringup(void) +#ifdef CONFIG_PAGING +static inline void os_pgworker(void) { - int taskid; - - /* Setup up the initial environment for the idle task. At present, this - * may consist of only the initial PATH variable. The PATH variable is - * (probably) not used by the IDLE task. However, the environment - * containing the PATH variable will be inherited by all of the threads - * created by the IDLE task. - */ - -#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL) - (void)setenv("PATH", CONFIG_PATH_INITIAL, 1); -#endif - /* Start the page fill worker kernel thread that will resolve page faults. * This should always be the first thread started because it may have to * resolve page faults in other threads */ -#ifdef CONFIG_PAGING svdbg("Starting paging thread\n"); g_pgworker = KERNEL_THREAD("pgfill", CONFIG_PAGING_DEFPRIO, CONFIG_PAGING_STACKSIZE, (main_t)pg_worker, (FAR char * const *)NULL); DEBUGASSERT(g_pgworker > 0); -#endif +} - /* Start the worker thread that will serve as the device driver "bottom- - * half" and will perform misc garbage clean-up. - */ +#else /* CONFIG_PAGING */ +# define os_pgworker() + +#endif /* CONFIG_PAGING */ + +/**************************************************************************** + * Name: os_workqueues + * + * Description: + * Start the worker threads that service the work queues. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ #ifdef CONFIG_SCHED_WORKQUEUE -#ifdef CONFIG_SCHED_HPWORK +static inline void os_workqueues(void) +{ +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_SCHED_USRWORK) + int taskid; +#endif +#ifdef CONFIG_SCHED_HPWORK #ifdef CONFIG_SCHED_LPWORK svdbg("Starting high-priority kernel worker thread\n"); #else @@ -178,7 +223,8 @@ int os_bringup(void) g_work[HPWORK].pid = KERNEL_THREAD(HPWORKNAME, CONFIG_SCHED_WORKPRIORITY, CONFIG_SCHED_WORKSTACKSIZE, - (main_t)work_hpthread, (FAR char * const *)NULL); + (main_t)work_hpthread, + (FAR char * const *)NULL); DEBUGASSERT(g_work[HPWORK].pid > 0); /* Start a lower priority worker thread for other, non-critical continuation @@ -191,7 +237,8 @@ int os_bringup(void) g_work[LPWORK].pid = KERNEL_THREAD(LPWORKNAME, CONFIG_SCHED_LPWORKPRIORITY, CONFIG_SCHED_LPWORKSTACKSIZE, - (main_t)work_lpthread, (FAR char * const *)NULL); + (main_t)work_lpthread, + (FAR char * const *)NULL); DEBUGASSERT(g_work[LPWORK].pid > 0); #endif /* CONFIG_SCHED_LPWORK */ @@ -203,29 +250,40 @@ int os_bringup(void) DEBUGASSERT(USERSPACE->work_usrstart != NULL); taskid = USERSPACE->work_usrstart(); DEBUGASSERT(taskid > 0); + UNUSED(taskid); #endif +} -#endif /* CONFIG_SCHED_WORKQUEUE */ +#else /* CONFIG_SCHED_WORKQUEUE */ +# define os_workqueues() - /* Once the operating system has been initialized, the system must be - * started by spawning the user init thread of execution. This is the - * first user-mode thead. - */ +#endif /* CONFIG_SCHED_WORKQUEUE */ - svdbg("Starting init thread\n"); +/**************************************************************************** + * Name: os_init_thread + * + * Description: + * Start the application initialization thread. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ - /* Perform any last-minute, board-specific initialization, if so - * configured. - */ +#if defined(CONFIG_INIT_ENTRYPOINT) +static inline void os_init_thread(void) +{ + int taskid; -#ifdef CONFIG_BOARD_INITIALIZE - board_initialize(); -#endif + svdbg("Starting init thread\n"); - /* Start the default application. In a flat build, this is entrypoint - * is given by the definitions, CONFIG_USER_ENTRYPOINT. In the kernel - * build, however, we must get the address of the entrypoint from the - * header at the beginning of the user-space blob. + /* Start the application initialization ask. In a flat build, this is + * entrypoint is given by the definitions, CONFIG_USER_ENTRYPOINT. In + * the protected build, however, we must get the address of the + * entrypoint from the header at the beginning of the user-space blob. */ #ifdef CONFIG_BUILD_PROTECTED @@ -240,6 +298,106 @@ int os_bringup(void) (FAR char * const *)NULL); #endif ASSERT(taskid > 0); +} + +#elif defined(CONFIG_INIT_FILEPATH) +static inline void os_init_thread(void) +{ + int ret; + + svdbg("Starting init task: %s\n", CONFIG_USER_INITPATH); + + ret = exec(CONFIG_USER_INITPATH, NULL, CONFIG_INIT_SYMTAB, + CONFIG_INIT_NEXPORTS); + ASSERT(ret >= 0); +} + +#elif defined(CONFIG_INIT_NONE) +# define os_init_thread() + +#else +# error "Cannot start initialization thread" + +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: os_bringup + * + * Description: + * Start all initial system tasks. This does the "system bring-up" after + * the conclusion of basic OS initialization. These initial system tasks + * may include: + * + * - pg_worker: The page-fault worker thread (only if CONFIG_PAGING is + * defined. + * - work_thread: The work thread. This general thread can be used to + * perform most any kind of queued work. Its primary + * function is to serve as the "bottom half" of device + * drivers. + * + * And the main application entry point: + * symbols, either: + * + * - CONFIG_USER_ENTRYPOINT: This is the default user application entry + * point, or + * - CONFIG_USER_INITPATH: The full path to the location in a mounted + * file system where we can expect to find the + * initialization program. Presumably, this file system + * was mounted by board-specific logic when + * board_initialize() was called. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +int os_bringup(void) +{ + /* Setup up the initial environment for the idle task. At present, this + * may consist of only the initial PATH variable. The PATH variable is + * (probably) not used by the IDLE task. However, the environment + * containing the PATH variable will be inherited by all of the threads + * created by the IDLE task. + */ + +#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL) + (void)setenv("PATH", CONFIG_PATH_INITIAL, 1); +#endif + + /* Start the page fill worker kernel thread that will resolve page faults. + * This should always be the first thread started because it may have to + * resolve page faults in other threads + */ + + os_pgworker(); + + /* Start the worker thread that will serve as the device driver "bottom- + * half" and will perform misc garbage clean-up. + */ + + os_workqueues(); + + /* Perform any last-minute, board-specific initialization, if so + * configured. + */ + +#ifdef CONFIG_BOARD_INITIALIZE + board_initialize(); +#endif + + /* Once the operating system has been initialized, the system must be + * started by spawning the user initialization thread of execution. This + * is the first user-mode thread. + */ + + os_init_thread(); /* We an save a few bytes by discarding the IDLE thread's environment. */ |