diff --git a/ChangeLog b/ChangeLog
index 36b6e689bdb0fae35f583cbc997ffa8bb549ac49..9678148caa8ffce628216b8cf424d052f0aebbf4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,10 @@
 	  use of semaphore can cause deadlock.
 	* Tasks can now accept a configurable maximum number of
 	  input parameters (argc)
+	* _task_init() was divided into separate functions that
+	  require fewer parameters.  This was necessary to keep
+	  the stack usage down for the 8051/2 (which has only
+	  256 bytes of stack).
 	* Attempts to use C5471 console from interrupt handlers
 	  can casue errors. Added a special path for this case.
 	* Refuse calls to sem_wait and sem_trywait from interrupt
@@ -20,4 +24,5 @@
 	  were calling printf-like functions.
 	* Added strtok() and strtok_r()
 	* Added a simple shell called nsh (see examples/nsh).
+	* Many changes as part of 8052 bringup
 	* Documentation updates
diff --git a/sched/Makefile b/sched/Makefile
index 375cb6a3d6e48e4b0809b89f2117f28cc1017626..7708f5d467250f3e867ec7a5fbf50904b2196635 100644
--- a/sched/Makefile
+++ b/sched/Makefile
@@ -44,7 +44,8 @@ MISC_SRCS	= os_start.c get_errno_ptr.c \
 		  sched_setupstreams.c sched_getfiles.c sched_getstreams.c \
 		  sched_setupidlefiles.c sched_setuptaskfiles.c sched_setuppthreadfiles.c \
 		  sched_releasefiles.c
-TSK_SRCS	= task_create.c task_init.c task_delete.c task_restart.c \
+TSK_SRCS	= task_create.c task_init.c task_setup.c task_activate.c \
+		  task_start.c task_delete.c task_restart.c \
 		  exit.c abort.c atexit.c getpid.c  \
 		  sched_addreadytorun.c sched_removereadytorun.c sched_addprioritized.c \
 		  sched_mergepending.c sched_addblocked.c sched_removeblocked.c \
diff --git a/sched/os_internal.h b/sched/os_internal.h
index 222e0ba880860b13587aaceffadf6da671c5ba9f..ca2222ad6b04f70d4f42f5942cc7042c908fc79c 100644
--- a/sched/os_internal.h
+++ b/sched/os_internal.h
@@ -240,9 +240,10 @@ extern const tasklist_t g_tasklisttable[NUM_TASK_STATES];
  ************************************************************/
 
 extern void    task_start(void);
-extern STATUS  _task_init(FAR _TCB *tcb, const char *name, int priority,
-                          start_t start, main_t main, boolean pthread,
-                          char *argv[]);
+extern STATUS  task_schedsetup(FAR _TCB *tcb, int priority,
+                               start_t start, main_t main);
+extern STATUS  task_argsetup(FAR _TCB *tcb, const char *name,
+                             boolean pthread, char *argv[]);
 
 extern boolean sched_addreadytorun(FAR _TCB *rtrtcb);
 extern boolean sched_removereadytorun(FAR _TCB *rtrtcb);
diff --git a/sched/pthread_create.c b/sched/pthread_create.c
index 72a5b4a81306b0011504767c04ff0ed8881337c9..33fdcf00f5934b4a8ab13aa33ad4c37de9de86f0 100644
--- a/sched/pthread_create.c
+++ b/sched/pthread_create.c
@@ -167,12 +167,12 @@ static void pthread_start(void)
  * Input Parameters:
  *    thread
  *    attr
- *    startRoutine
+ *    start_routine
  *    arg
  ************************************************************/
 
 int pthread_create(pthread_t *thread, pthread_attr_t *attr,
-                   pthread_startroutine_t startRoutine,
+                   pthread_startroutine_t start_routine,
                    pthread_addr_t arg)
 {
   FAR _TCB *ptcb;
@@ -268,12 +268,10 @@ int pthread_create(pthread_t *thread, pthread_attr_t *attr,
 #endif
     }
 
-  /* Initialize the task */
+  /* Initialize the task control block */
 
-  argv[0] = (char *)arg;
-  argv[1] = NULL;
-  status  = _task_init(ptcb, NULL, priority, pthread_start,
-                       (main_t)startRoutine, TRUE, argv);
+  status  = task_schedsetup(ptcb, priority, pthread_start,
+                            (main_t)start_routine);
   if (status != OK)
     {
 
@@ -282,6 +280,14 @@ int pthread_create(pthread_t *thread, pthread_attr_t *attr,
       return ERROR;
     }
 
+  /* Configure the TCB for a pthread receiving on parameter
+   * passed by value
+   */
+
+  argv[0] = (char *)arg;
+  argv[1] = NULL;
+  (void)task_argsetup(ptcb, NULL, TRUE, argv);
+
   /* Attach the join info to the TCB. */
 
   ptcb->joininfo = (void*)pjoin;
diff --git a/sched/task_activate.c b/sched/task_activate.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce574428af0acac0b19788a92a68ca445409a7c4
--- /dev/null
+++ b/sched/task_activate.c
@@ -0,0 +1,117 @@
+/************************************************************
+ * task_activate.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name Gregory Nutt nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************/
+
+/************************************************************
+ * Included Files
+ ************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <sched.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+
+/************************************************************
+ * Definitions
+ ************************************************************/
+
+/************************************************************
+ * Private Type Declarations
+ ************************************************************/
+
+/************************************************************
+ * Global Variables
+ ************************************************************/
+
+/************************************************************
+ * Private Variables
+ ************************************************************/
+
+/************************************************************
+ * Private Function Prototypes
+ ************************************************************/
+
+/************************************************************
+ * Private Functions
+ ************************************************************/
+
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+/************************************************************
+ * Name: task_activate
+ *
+ * Description:
+ *   This function activates tasks initialized by
+ *   task_schedsetup(). Without activation, a task is
+ *   ineligible for execution  by the scheduler.
+ *
+ * Input Parameters:
+ *   tcb - The TCB for the task for the task (same as the
+ *         task_init argument.
+ *
+ * Return Value:
+ *  Always returns OK
+ *
+ ************************************************************/
+
+STATUS task_activate(FAR _TCB *tcb)
+{
+#ifdef CONFIG_SCHED_INSTRUMENTATION
+  irqstate_t flags = irqsave();
+
+  /* Check if this is really a re-start */
+
+  if (tcb->task_state != TSTATE_TASK_INACTIVE)
+    {
+      /* Inform the instrumentation layer that the task
+       * has stopped
+       */
+
+      sched_note_stop(tcb);
+    }
+
+  /* Inform the instrumentation layer that the task
+   * has started
+   */
+
+  sched_note_start(tcb);
+  irqrestore(flags);
+#endif
+
+  up_unblock_task(tcb);
+  return OK;
+}
diff --git a/sched/task_create.c b/sched/task_create.c
index 07a6cab22233b97beec8643254e8b125c02d44eb..c3d1b453b4b1244ed30faccdb25c1f238413c7f4 100644
--- a/sched/task_create.c
+++ b/sched/task_create.c
@@ -37,13 +37,12 @@
  * Included Files
  ************************************************************/
 
+#include <nuttx/config.h>
 #include <sys/types.h>
 #include <sched.h>
-#include <string.h>
 #include <errno.h>
 #include <debug.h>
 #include <nuttx/arch.h>
-#include <nuttx/os_external.h>
 #include "os_internal.h"
 
 /************************************************************
@@ -62,323 +61,14 @@
  * Private Variables
  ************************************************************/
 
-/* This is the name for un-named tasks */
-
-static FAR char g_noname[] = "no name";
-
 /************************************************************
  * Private Function Prototypes
  ************************************************************/
 
-static STATUS   task_assignpid(FAR _TCB* tcb);
-
 /************************************************************
  * Private Functions
  ************************************************************/
 
-/************************************************************
- * Name: task_assignpid
- *
- * Description:
- *   This function assigns the next unique task ID to a task.
- *
- * Inputs:
- *   tcb - TCB of task
- *
- * Return:
- *   OK on success; ERROR on failure (errno is not set)
- *
- ************************************************************/
-
-static STATUS task_assignpid(FAR _TCB *tcb)
-{
-  pid_t next_pid;
-  int   hash_ndx;
-  int   tries = 0;
-
-  /* Disable pre-emption.  This should provide sufficient protection
-   * for the following operation.
-   */
-
-  (void)sched_lock();
-
-  /* We'll try every allowable pid */
-
-  for (tries = 0; tries < CONFIG_MAX_TASKS; tries++)
-    {
-      /* Get the next process ID candidate */
-
-      next_pid = ++g_lastpid;
-
-      /* Verify that the next_pid is in the valid range */
-
-      if (next_pid <= 0)
-        {
-          g_lastpid = 1;
-          next_pid  = 1;
-        }
-
-      /* Get the hash_ndx associated with the next_pid */
-
-      hash_ndx = PIDHASH(next_pid);
-
-      /* Check if there is a (potential) duplicate of this pid */
-
-      if (!g_pidhash[hash_ndx].tcb)
-        {
-          g_pidhash[hash_ndx].tcb = tcb;
-          g_pidhash[hash_ndx].pid = next_pid;
-          tcb->pid = next_pid;
-          (void)sched_unlock();
-          return OK;
-        }
-    }
-
-  /* If we get here, then the g_pidhash[] table is completely full.
-   * We cannot allow another task to be started.
-   */
-
-  (void)sched_unlock();
-  return ERROR;
-}
-
-/************************************************************
- * Public Functions
- ************************************************************/
-
-/************************************************************
- * Name: task_start
- *
- * Description:
- *   This function is the low level entry point
- *   into the main thread of execution of a task.  It receives
- *   initial control when the task is started and calls main
- *   entry point of the newly started task.
- *
- * Inputs:
- *   None
- *
- * Return:
- *   None
- *
- ************************************************************/
-
-void task_start(void)
-{
-  FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
-  int argc;
-
-  /* Count how many non-null arguments we are passing */
-
-  for (argc = 1; argc <= CONFIG_MAX_TASK_ARGS; argc++)
-    {
-       /* The first non-null argument terminates the list */
-
-       if (!tcb->argv[argc])
-         {
-           break;
-         }
-    }
-
-  /* Call the 'main' entry point passing argc and argv.  If/when
-   * the task returns,  */
-
-  exit(tcb->entry.main(argc, tcb->argv));
-}
-
-/************************************************************
- * Name: _task_init 
- *
- * Description:
- *   This functions initializes a Task Control Block (TCB)
- *   in preparation for starting a new thread.  _task_init()
- *   is an internal version of the task_init() function that
- *   has some  additional control arguments and task_init()
- *   is a wrapper function that creates a VxWorks-like user
- *   API. task_init() is, otherwise, not used by the OS.
- *
- *   _task_init() is called from task_init() and task_start().\
- *   It is also called from pthread_create() to create a 
- *   a pthread (distinguished by the pthread argument).
- *
- *   Unlike task_create(), task_init() does not activate the
- *   task.  This must be done by calling task_activate()
- *   afterward.
- *
- * Input Parameters:
- *   tcb        - Address of the new task's TCB
- *   name       - Name of the new task (not used)
- *   priority   - Priority of the new task
- *   entry      - Entry point of a new task
- *   main       - Application start point of the new task
- *   pthread    - TRUE is the task emulates pthread behavior
- *   argv       - A pointer to an array of input parameters.
- *                Up to CONFIG_MAX_TASK_ARG parameters may be
- *                provided. If fewer than CONFIG_MAX_TASK_ARG
- *                parameters are passed, the list should be
- *                terminated with a NULL argv[] value.
- *                If no parameters are required, argv may be NULL.
- *
- * Return Value:
- *  OK on success; ERROR on failure.
- *
- *  This function can only failure is it is unable to assign
- *  a new, unique task ID to the TCB (errno is not set).
- *
- ************************************************************/
-
-STATUS _task_init(FAR _TCB *tcb, const char *name, int priority,
-                  start_t start, main_t main, boolean pthread,
-                  char *argv[])
-{
-  STATUS ret;
-  int i;
-
-  /* Assign a unique task ID to the task. */
-
-  ret = task_assignpid(tcb);
-  if (ret == OK)
-    {
-      /* Save task priority and entry point in the TCB */
-
-      tcb->init_priority  = (ubyte)priority;
-      tcb->sched_priority = (ubyte)priority;
-      tcb->start          = start;
-      tcb->entry.main     = main;
-
-#if CONFIG_TASK_NAME_SIZE > 0
-      /* Give a name to the unnamed threads */
-
-      if (!name)
-        {
-          name = g_noname;
-        }
-
-      /* copy the name into the TCB */
-
-      strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE);
-#endif /* CONFIG_TASK_NAME_SIZE */
-
-      /* Save the arguments in the TCB */
-
-#if CONFIG_TASK_NAME_SIZE > 0
-      tcb->argv[0] = tcb->name;
-#else
-      tcb->argv[0] = g_noname;
-#endif
-
-      /* For pthreads, args are strictly pass-by-value; the char*
-       * arguments wrap some unknown value cast to char*.  However,
-       * for tasks, the life of the argument must be as long as
-       * the life of the task and the arguments must be strings.
-       * So for tasks, we have to to dup the strings.
-       */
-
-      if (!pthread)
-        {
-          /* The first NULL argument terminates the list of 
-           * arguments.  The argv pointer may be NULL if no
-           * parameters are passed.
-           */
-
-          i = 1;
-          if (argv)
-            {
-              for (; i < CONFIG_MAX_TASK_ARGS+1 && argv[i-1]; i++)
-                {
-                  tcb->argv[i] = strdup(argv[i-1]);
-                }
-            }
-        }
-      else
-        {
-          /* Mark this task as a pthread */
-
-          tcb->flags   |= TCB_FLAG_PTHREAD;
-
-          /* And just copy the argument. For pthreads, there
-           * is really only a single argument, argv[0].  It is
-           * copy as a value -- NOT duplicated.
-           */
-
-          i = 2;
-          tcb->argv[1]  = argv[0];
-        }
-
-      /* Nullify any unused argument storage */
-
-      for (; i < CONFIG_MAX_TASK_ARGS+1; i++)
-        {
-          tcb->argv[i] = NULL;
-        }
-
-      /* Initialize other (non-zero) elements of the TCB */
-
-#ifndef CONFIG_DISABLE_SIGNALS
-      tcb->sigprocmask  = ALL_SIGNAL_SET;
-#endif
-      tcb->task_state   = TSTATE_TASK_INVALID;
-
-      /* Initialize the processor-specific portion of the TCB */
-
-      up_initial_state(tcb);
-
-      /* Add the task to the inactive task list */
-
-      sched_lock();
-      dq_addfirst((FAR dq_entry_t*)tcb, &g_inactivetasks);
-      tcb->task_state = TSTATE_TASK_INACTIVE;
-      sched_unlock();
-    }
-
- return ret;
-}
-
-/************************************************************
- * Name: task_activate
- *
- * Description:
- *   This function activates tasks initialized by _task_init().
- *   Without activation, a task is ineligible for execution
- *   by the scheduler.
- *
- * Input Parameters:
- *   tcb - The TCB for the task for the task (same as the
- *         task_init argument.
- *
- * Return Value:
- *  Always returns OK
- *
- ************************************************************/
-
-STATUS task_activate(FAR _TCB *tcb)
-{
-#ifdef CONFIG_SCHED_INSTRUMENTATION
-  irqstate_t flags = irqsave();
-
-  /* Check if this is really a re-start */
-
-  if (tcb->task_state != TSTATE_TASK_INACTIVE)
-    {
-      /* Inform the instrumentation layer that the task
-       * has stopped
-       */
-
-      sched_note_stop(tcb);
-    }
-
-  /* Inform the instrumentation layer that the task
-   * has started
-   */
-
-  sched_note_start(tcb);
-  irqrestore(flags);
-#endif
-
-  up_unblock_task(tcb);
-  return OK;
-}
-
 /************************************************************
  * Name: task_create
  *
@@ -401,7 +91,13 @@ STATUS task_activate(FAR _TCB *tcb)
  *   priority   - Priority of the new task
  *   stack_size - size (in bytes) of the stack needed
  *   entry      - Entry point of a new task
- *   arg*       - Ten required task arguments to pass to func
+ *   arg        - A pointer to an array of input parameters.
+ *                Up to  CONFIG_MAX_TASK_ARG parameters may
+ *                be provided.  If fewer than CONFIG_MAX_TASK_ARG
+ *                parameters are passed, the list should be
+ *                terminated with a NULL argv[] value.
+ *                If no parameters are required, argv may be
+ *                NULL.
  *
  * Return Value:
  *   Returns the non-zero process ID of the new task or
@@ -452,29 +148,32 @@ int task_create(const char *name, int priority,
     }
 #endif
 
-   /* Initialize the task control block */
+  /* Initialize the task control block */
 
-   status = _task_init(tcb, name, priority, task_start, entry,
-                       FALSE, argv);
-   if (status != OK)
-     {
-       sched_releasetcb(tcb);
-       return ERROR;
-     }
+  status = task_schedsetup(tcb, priority, task_start, entry);
+  if (status != OK)
+    {
+      sched_releasetcb(tcb);
+      return ERROR;
+    }
+
+  /* Setup to pass parameters to the new task */
 
-   /* Get the assigned pid before we start the task */
+  (void)task_argsetup(tcb, name, FALSE, argv);
 
-   pid = (int)tcb->pid;
+  /* Get the assigned pid before we start the task */
 
-   /* Activate the task */
+  pid = (int)tcb->pid;
 
-   status = task_activate(tcb);
-   if (status != OK)
+  /* Activate the task */
+
+  status = task_activate(tcb);
+  if (status != OK)
     {
       dq_rem((FAR dq_entry_t*)tcb, &g_inactivetasks);
       sched_releasetcb(tcb);
       return ERROR;
     }
 
-   return pid;
+  return pid;
 }
diff --git a/sched/task_init.c b/sched/task_init.c
index b603ddc805130fe67f12855ba6429c82ce0daf01..92fd53fb2b7d970dfcf7d422c7c0d84f6af30ba3 100644
--- a/sched/task_init.c
+++ b/sched/task_init.c
@@ -37,6 +37,7 @@
  * Included Files
  ************************************************************/
 
+#include <nuttx/config.h>
 #include <sys/types.h>
 #include <sched.h>
 #include <nuttx/arch.h>
@@ -74,22 +75,31 @@
  * Name: task_init
  *
  * Description:
- *   This is a wrapper around the internal _task_init() that
- *   provides a VxWorks-like API.  See _task_init() for
- *   further information.
+ *   This function initializes a Task Control Block (TCB)
+ *   in preparation for starting a new thread.  It performs a
+ *   subset of the functionality of task_create()
+ *
+ *   Unlike task_create(), task_init() does not activate the
+ *   task. This must be done by calling task_activate().
  *
  * Input Parameters:
  *   tcb        - Address of the new task's TCB
  *   name       - Name of the new task (not used)
  *   priority   - Priority of the new task
- *   stack      - start of the pre-allocated stack
- *   stack_size - size (in bytes) of the stack allocated
+ *   stack      - Start of the pre-allocated stack
+ *   stack_size - Size (in bytes) of the stack allocated
  *   entry      - Application start point of the new task
- *   arg1-4     - Four required task arguments to pass to
- *                the task when it is started.
+ *   arg        - A pointer to an array of input parameters.
+ *                Up to  CONFIG_MAX_TASK_ARG parameters may
+ *                be provided.  If fewer than CONFIG_MAX_TASK_ARG
+ *                parameters are passed, the list should be
+ *                terminated with a NULL argv[] value.
+ *                If no parameters are required, argv may be
+ *                NULL.
  *
  * Return Value:
- *   see _task_init()
+ *   OK on success; ERROR on failure.  (See task_schedsetup()
+ *   for possible failure conditions).
  *
  ************************************************************/
 
@@ -97,16 +107,27 @@
 STATUS task_init(FAR _TCB *tcb, const char *name, int priority,
                  FAR uint32 *stack, uint32 stack_size,
                  main_t entry, char *argv[])
-{
-  up_use_stack(tcb, stack, stack_size);
-  return _task_init(tcb, name, priority, task_start, entry,
-                    FALSE, argv);
-}
 #else
 STATUS task_init(FAR _TCB *tcb, const char *name, int priority,
                  main_t entry, char *argv[])
+#endif
 {
-  return _task_init(tcb, name, priority, task_start, entry,
-                    FALSE, argv);
-}
+  STATUS ret;
+
+  /* Configure the user provided stack region */
+
+#ifndef CONFIG_CUSTOM_STACK
+  up_use_stack(tcb, stack, stack_size);
 #endif
+
+  /* Initialize the task control block */
+
+  ret = task_schedsetup(tcb, priority, task_start, entry);
+  if (ret == OK)
+    {
+      /* Setup to pass parameters to the new task */
+
+      (void)task_argsetup(tcb, name, FALSE, argv);
+    }
+  return ret;
+ }
diff --git a/sched/task_setup.c b/sched/task_setup.c
new file mode 100644
index 0000000000000000000000000000000000000000..3573e72d9fd04d9e409ed97bc4427f0749a6ac8d
--- /dev/null
+++ b/sched/task_setup.c
@@ -0,0 +1,312 @@
+/************************************************************
+ * task_setup.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name Gregory Nutt nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************/
+
+/************************************************************
+ * Included Files
+ ************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <sched.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <nuttx/arch.h>
+#include "os_internal.h"
+
+/************************************************************
+ * Definitions
+ ************************************************************/
+
+/************************************************************
+ * Private Type Declarations
+ ************************************************************/
+
+/************************************************************
+ * Global Variables
+ ************************************************************/
+
+/************************************************************
+ * Private Variables
+ ************************************************************/
+
+/* This is the name for un-named tasks */
+
+static FAR char g_noname[] = "no name";
+
+/************************************************************
+ * Private Function Prototypes
+ ************************************************************/
+
+static STATUS   task_assignpid(FAR _TCB* tcb);
+
+/************************************************************
+ * Private Functions
+ ************************************************************/
+
+/************************************************************
+ * Name: task_assignpid
+ *
+ * Description:
+ *   This function assigns the next unique task ID to a task.
+ *
+ * Inputs:
+ *   tcb - TCB of task
+ *
+ * Return:
+ *   OK on success; ERROR on failure (errno is not set)
+ *
+ ************************************************************/
+
+static STATUS task_assignpid(FAR _TCB *tcb)
+{
+  pid_t next_pid;
+  int   hash_ndx;
+  int   tries = 0;
+
+  /* Disable pre-emption.  This should provide sufficient protection
+   * for the following operation.
+   */
+
+  (void)sched_lock();
+
+  /* We'll try every allowable pid */
+
+  for (tries = 0; tries < CONFIG_MAX_TASKS; tries++)
+    {
+      /* Get the next process ID candidate */
+
+      next_pid = ++g_lastpid;
+
+      /* Verify that the next_pid is in the valid range */
+
+      if (next_pid <= 0)
+        {
+          g_lastpid = 1;
+          next_pid  = 1;
+        }
+
+      /* Get the hash_ndx associated with the next_pid */
+
+      hash_ndx = PIDHASH(next_pid);
+
+      /* Check if there is a (potential) duplicate of this pid */
+
+      if (!g_pidhash[hash_ndx].tcb)
+        {
+          g_pidhash[hash_ndx].tcb = tcb;
+          g_pidhash[hash_ndx].pid = next_pid;
+          tcb->pid = next_pid;
+          (void)sched_unlock();
+          return OK;
+        }
+    }
+
+  /* If we get here, then the g_pidhash[] table is completely full.
+   * We cannot allow another task to be started.
+   */
+
+  (void)sched_unlock();
+  return ERROR;
+}
+
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+/************************************************************
+ * Name: task_schedsetup
+ *
+ * Description:
+ *   This functions initializes a Task Control Block (TCB)
+ *   in preparation for starting a new thread.
+ *
+ *   task_schedsetup() is called from task_init(),
+ *   task_start(), and pthread_create();
+ *
+ * Input Parameters:
+ *   tcb        - Address of the new task's TCB
+ *   priority   - Priority of the new task
+ *   entry      - Entry point of a new task
+ *   main       - Application start point of the new task
+ *
+ * Return Value:
+ *   OK on success; ERROR on failure.
+ *
+ *   This function can only failure is it is unable to assign
+ *   a new, unique task ID to the TCB (errno is not set).
+ *
+ ************************************************************/
+
+STATUS task_schedsetup(FAR _TCB *tcb, int priority,
+                       start_t start, main_t main)
+{
+  STATUS ret;
+
+  /* Assign a unique task ID to the task. */
+
+  ret = task_assignpid(tcb);
+  if (ret == OK)
+    {
+      /* Save task priority and entry point in the TCB */
+
+      tcb->init_priority  = (ubyte)priority;
+      tcb->sched_priority = (ubyte)priority;
+      tcb->start          = start;
+      tcb->entry.main     = main;
+
+      /* Initialize other (non-zero) elements of the TCB */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+      tcb->sigprocmask  = ALL_SIGNAL_SET;
+#endif
+      tcb->task_state   = TSTATE_TASK_INVALID;
+
+      /* Initialize the processor-specific portion of the TCB */
+
+      up_initial_state(tcb);
+
+      /* Add the task to the inactive task list */
+
+      sched_lock();
+      dq_addfirst((FAR dq_entry_t*)tcb, &g_inactivetasks);
+      tcb->task_state = TSTATE_TASK_INACTIVE;
+      sched_unlock();
+    }
+
+  return ret;
+}
+
+/************************************************************
+ * Name: task_argsetup
+ *
+ * Description:
+ *   This functions sets up parameters in the Task Control
+ *   Block (TCB) in preparation for starting a new thread.
+ *
+ *   task_argsetup() is called from task_init() and task_start()
+ *   to create a new task (with arguments cloned via strdup)
+ *   or pthread_create() which has one argument passed by
+ *   value (distinguished by the pthread boolean argument).
+ *
+ * Input Parameters:
+ *   tcb        - Address of the new task's TCB
+ *   name       - Name of the new task (not used)
+ *   pthread    - TRUE is the task emulates pthread behavior
+ *   argv       - A pointer to an array of input parameters.
+ *                Up to CONFIG_MAX_TASK_ARG parameters may be
+ *                provided. If fewer than CONFIG_MAX_TASK_ARG
+ *                parameters are passed, the list should be
+ *                terminated with a NULL argv[] value.
+ *                If no parameters are required, argv may be NULL.
+ *
+ * Return Value:
+ *  OK
+ *
+ ************************************************************/
+
+STATUS task_argsetup(FAR _TCB *tcb, const char *name,
+                     boolean pthread, char *argv[])
+{
+  int i;
+
+#if CONFIG_TASK_NAME_SIZE > 0
+  /* Give a name to the unnamed threads */
+
+  if (!name)
+    {
+      name = g_noname;
+    }
+
+  /* copy the name into the TCB */
+
+  strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE);
+#endif /* CONFIG_TASK_NAME_SIZE */
+
+  /* Save the arguments in the TCB */
+
+#if CONFIG_TASK_NAME_SIZE > 0
+  tcb->argv[0] = tcb->name;
+#else
+  tcb->argv[0] = g_noname;
+#endif
+
+  /* For pthreads, args are strictly pass-by-value; the char*
+   * arguments wrap some unknown value cast to char*.  However,
+   * for tasks, the life of the argument must be as long as
+   * the life of the task and the arguments must be strings.
+   * So for tasks, we have to to dup the strings.
+   */
+
+  if (!pthread)
+    {
+      /* The first NULL argument terminates the list of 
+       * arguments.  The argv pointer may be NULL if no
+       * parameters are passed.
+       */
+
+      i = 1;
+      if (argv)
+        {
+          for (; i < CONFIG_MAX_TASK_ARGS+1 && argv[i-1]; i++)
+            {
+              tcb->argv[i] = strdup(argv[i-1]);
+            }
+        }
+    }
+  else
+    {
+      /* Mark this task as a pthread */
+
+      tcb->flags   |= TCB_FLAG_PTHREAD;
+
+      /* And just copy the argument. For pthreads, there
+       * is really only a single argument, argv[0].  It is
+       * copy as a value -- NOT duplicated.
+       */
+
+      i = 2;
+      tcb->argv[1]  = argv[0];
+    }
+
+  /* Nullify any unused argument storage */
+
+  for (; i < CONFIG_MAX_TASK_ARGS+1; i++)
+    {
+      tcb->argv[i] = NULL;
+    }
+
+  return OK;
+}
diff --git a/sched/task_start.c b/sched/task_start.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e2a013bf604fb984538951ea0172860d24bd6b2
--- /dev/null
+++ b/sched/task_start.c
@@ -0,0 +1,113 @@
+/************************************************************
+ * task_start.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name Gregory Nutt nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************/
+
+/************************************************************
+ * Included Files
+ ************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <debug.h>
+#include "os_internal.h"
+
+/************************************************************
+ * Definitions
+ ************************************************************/
+
+/************************************************************
+ * Private Type Declarations
+ ************************************************************/
+
+/************************************************************
+ * Global Variables
+ ************************************************************/
+
+/************************************************************
+ * Private Variables
+ ************************************************************/
+
+/************************************************************
+ * Private Function Prototypes
+ ************************************************************/
+
+/************************************************************
+ * Private Functions
+ ************************************************************/
+
+/************************************************************
+ * Public Functions
+ ************************************************************/
+
+/************************************************************
+ * Name: task_start
+ *
+ * Description:
+ *   This function is the low level entry point
+ *   into the main thread of execution of a task.  It receives
+ *   initial control when the task is started and calls main
+ *   entry point of the newly started task.
+ *
+ * Inputs:
+ *   None
+ *
+ * Return:
+ *   None
+ *
+ ************************************************************/
+
+void task_start(void)
+{
+  FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
+  int argc;
+
+  /* Count how many non-null arguments we are passing */
+
+  for (argc = 1; argc <= CONFIG_MAX_TASK_ARGS; argc++)
+    {
+       /* The first non-null argument terminates the list */
+
+       if (!tcb->argv[argc])
+         {
+           break;
+         }
+    }
+
+  /* Call the 'main' entry point passing argc and argv.  If/when
+   * the task returns,  */
+
+  exit(tcb->entry.main(argc, tcb->argv));
+}