VxWorks Boot Sequence Notes

Ozan Ağma
18 min readJan 3, 2021

At a minimum, initializing a processor consists of providing a portion of code, and possibly some tables, that are located at the specific location in memory that the processor jumps to upon reset or power-up of the target system. This code sets the processor to a specific state, initializes memory and memory addressing, disables interrupts, and then passes control to additional bootstrapping code.

Upon power-up or reset, the processor first jumps to the entry point in ROM, _romInit( ).The assembly code at the jump destination sets up memory, initializes the processor status word, and creates a temporary stack. The processor then jumps to a C routine (romStart( ) in installDir/vxworks-6.x/target/config/ all/bootInit.c). A parameter in a register or on a temporary stack determines whether memory must be cleared (cold start) and then copies the appropriate sections of ROM into RAM. If the code in ROM is compressed, it is decompressed during the copy. Next, the processor jumps to the VxWorks entry point in RAM.

Deep Note: What Is Cold Boot?

To perform a cold boot (also called a “hard boot”) means to start up a computer that is turned off. It is often used in contrast to a warm boot, which refers to restarting a computer once it has been turned on. A cold boot is typically performed by pressing the power button on the computer.

Both a cold boot and warm boot clear the system RAM and perform the boot sequence from scratch. However, unlike a cold boot, a warm boot may not clear all system caches, which store temporary information. Additionally, a cold boot performs a “power on self test” (POST), which runs a series of system checks at the beginning of the boot sequence.

While a warm boot and cold boot are similar, a cold boot performs a more complete reset of the system than a warm boot. Therefore, if you are troubleshooting your computer, you may be asked to turn off your computer completely and perform a cold boot. This makes sure all temporary data is wiped from your system, which may help eliminate issues affecting your computer.

The VxWorks entry point is _sysInit( ) in sysALib.s. This assembly routine sets the initial hardware state (much as _romInit( ) does) and then jumps to usrInit( ) in usrConfig.c. usrInit( ) is the first C routine that runs from a VxWorks image. This routine initializes the cache, clears the block storage segment (bss) to zero (Check that: Memory Layout of C Programs — GeeksforGeeks), initializes the vector table, performs board-specific initialization, and then starts the multitasking kernel with a user-booting task.

Boot sequence when VxWorks is booted from an image
Boot Sequence Using a ROM Image(same steps with above after usrInit)

For development, the most common boot method is through the presence of a ROM-based boot loader. The purpose of this boot loader is to load the final VxWorks image from a remote development host (or possibly from a local file system) and then to start running the newly downloaded image. The boot image is a specially-crafted version of VxWorks with a boot loader as its only application. Because this boot image is largely independent of development changes, it is seldom necessary to re-program the flash, which saves development time. The boot image is referred to as bootrom; the OS image that is loaded is referred to as vxWorks.

Another alternative boot method is to put the VxWorks image into flash directly. Typically, both the core OS and the application code reside in the same image. In this case, there is no intermediate step between loading the boot loader and loading the application image. Also, no file system is needed to hold the final VxWorks image file. Although this boot method can be used for development, progress can be hindered by the need to re-program the flash often. However, this is a very common boot mechanism in final product delivery. Whether loading a VxWorks image from flash or loading a boot loader from flash, there are special requirements. The processor’s reset vector causes it to start execution of the code in flash memory. This flash-resident code can do one of several things. It can:

■ Continue running from flash (that is, fetch instructions from the flash memory and execute them).

■ Copy itself from flash to RAM and branch to an appropriate place in the RAM copy.

■ Decompress a compressed image contained in flash and put the image into RAM, then branch to an appropriate place in the RAM copy.

An image that continues running from flash and is built from a project is normally called vxWorks_romResident. Such an image built from the command line is typically called one of the following image types:

■vxWorks.res_rom

■ vxWorks.res_rom_res_low

■ vxWorks.res_rom_nosym

■ vxWorks.res_rom_nosym_res_low

■ bootrom_res

■ bootrom_res_high

An image that copies itself from flash to RAM and is built from a project is normally called vxWorks_rom. Such an image built from the command line is normally called vxWorks.st or bootrom_uncmp.

An image that decompresses itself and puts the results in RAM, and is built from a project, is generally called vxWorks_romCompress. Such an image built from the command line is called vxWorks.st_rom or bootrom.

If a boot loader loads a VxWorks image, whether from a local file system or from a remote host, the image is referred to as vxWorks, regardless of how it is built.

A more detailed description of each image type is listed below. Much of this information can be found in the file

installDir/vxworks-6.x/target/h/make/rules.bsp

in your installation.

vxWorks: The primary VxWorks image that is loaded by a boot loader from a local file system or from a remote host. If a downloaded symbol table is configured, vxWorks requires the vxWorks.sym file. vxWorks.sym A symbol table that is loaded from the same file system and directory as the vxWorks image itself.

vxWorks_rom: A VxWorks standalone ROM image programmed into flash that copies itself to RAM for execution. This format is typically used when making an application in ROM that does not include the shell or the symbol table. Because these images are usually smaller, this version does not use ROM compression.

vxWorks.st: A VxWorks standalone image that is loaded by a boot loader from a local file system or from a remote host. This VxWorks image has a symbol table already linked in, so it does not need to load vxWorks.sym from a local file system or over the network. This image requires a large ROM space and a large RAM space. This image can not be run from ROM.

vxWorks.st_rom: A VxWorks standalone image programmed into flash that decompresses itself to RAM for execution. This image includes a linked-in symbol table so that a complete VxWorks image with shell and symbol table is put into ROM. Because these systems tend to be large, ROM compression is used. This rule also creates vxImage.o for use as a “core” file (to provide a symbol table) for the target server or other host-based debugger. This image uses less ROM than a vxWorks image and requires a large RAM space.

vxWorks.res_rom: A VxWorks image programmed into flash. This image copies the data segment from flash into RAM, but continues to fetch instructions from flash. This image includes a linked-in symbol table so that a complete VxWorks image with shell and symbol table is put into ROM. This type of image uses less RAM than a vxWorks image and requires a large ROM space. In general, execution is slow for all ROM-resident images, as compared to RAM-resident images.

vxWorks.res_rom_res_low: This image is similar to vxWorks.res_rom, but sometimes starts the data segment in RAM closer to RAM_LOW_ADRS on some architectures.

vxWorks.res_rom_nosym: A VxWorks image programmed into flash. This image copies the data segment from flash into RAM, but continues to fetch instructions from flash. This image does not include a symbol table. This image uses a small amount of RAM and requires a large ROM space. This type of image has a quick start time but executes more slowly than a RAM image.

vxWorks.res_rom_nosym_res_low :This image is similar to vxWorks.res_rom_nosym, but sometimes starts the data segment in RAM closer to RAM_LOW_ADRS for some architectures.

bootrom: A VxWorks image with a boot loader application that is programmed into flash. This image decompresses itself into RAM for execution. This image requires a minimal amount of ROM space and a large RAM space.

bootrom_uncmp: A VxWorks image with a boot loader application that is programmed into flash. This image copies itself into RAM for execution. This image requires a large amount of both RAM and ROM but executes quickly.

bootrom_res: A image with a boot loader application that is programmed into flash. This image copies its data segment into RAM for execution, but continues fetching instructions from flash. This image requires a large ROM space and little RAM space.

bootrom_res_high: A VxWorks image with a boot loader application that is programmed into flash. This image copies its data segment into RAM for execution, but continues fetching instructions from flash. This image loads the VxWorks image into a higher location in RAM.

Detailed Boot Sequence

Execute romInit( )

At power-up (cold start), the processor begins execution at the romInit( ) entry point, located in romInit.s. For resets (warm starts), the processor begins execution at romInit( ) plus a small offset (see sysToMonitor( ) in installDir/vxworks-6.x/target/config/bspname/sysLib.c). The romInit( ) routine must be written in assembly language. The purpose of this routine is to initialize the CPU and some portion of memory. It does the absolute minimum amount of initialization — that is, the initialization of essential hardware only — before jumping to romStart( ). If romInit( ) is working correctly, the memory from LOCAL_MEM_LOCAL_ADRS through (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE) should be readable and writable. If this is not the case, romInit( ) is not working properly. In addition to initializing memory as described above, the romInit( ) routine must also disable interrupts and clear caches. romInit( ) then configures the boot type (cold or warm) to be a subroutine argument and branches to romStart( ) in bootInit.c. romInit( ) must do only as much device setup as is required to start executing C code. Hardware initialization is the responsibility of the sysHwInit( ) routine in installDir/vxworks-6.x/target/config/sysLib.c, which is called later during the boot sequence.

Execute romStart()

The purpose of the romStart( ) routine is to move all further bootstrap code from ROM into RAM and then, if necessary, jump to the VxWorks image. Because this implementation depends only on the CPU architecture, the romStart( ) routine is provided by Wind River and is located in the file bootInit.c. Typically, romStart( ) jumps to the usrInit( ) routine in RAM. The required execution steps are as follows:

  1. Copy the data segment from flash to ROM. Depending on the image type, you may also need to copy the text segment. If necessary, decompress the data during the copy.
  2. Clear unused RAM.
  3. The romStart( ) routine then jumps to the RAM entry point, sysInit( ), which is located in sysALib.s. The boot type (cold or warm) is passed as an argument to sysInit( ).

Execute sysInit( )

FUNC_LABEL(_sysInit)
FUNC_BEGIN(sysInit)
li r29, BOOT_CLEAR // load imm
bl cold //branch
li r29, BOOT_NORMAL
cold:
#ifdef _WRS_CONFIG_STANDALONE_DTB
/* save IMA size */
lis r31, HI(IMA_SIZE) // load imm, shifted left by 16 bits
ori r31, r31, LO(IMA_SIZE) // or imm
#else /* !_WRS_CONFIG_STANDALONE_DTB */
/* save DTB address and IMA size */
mr r30, r3 //move r3 to r30
mr r31, r7 //move r7 to r31
#endif /* _WRS_CONFIG_STANDALONE_DTB */
#ifdef INCLUDE_WARM_BOOT
cmpwi r29, BOOT_CLEAR //compare with imm
bne skipBackup //
bl vxSdaInit
/* get frame stack */
LOADPTR(sp, RAM_LOW_ADRS)
LOADPTR(r3, KERNEL_SYS_MEM_RGN_BASE)
sub sp, sp, r3
addi sp, sp, -FRAMEBASESZ
bl warmBootBackupskipBackup:
#endif /* INCLUDE_WARM_BOOT */
/* initialize CPU */
bl vxCpuInit
/* obtain runtime address */
bl rtAddr
rtAddr:
mflr r3 /* runtime address */ //copies the contents of lr to r3
/* calculate offset from link address */
LOADPTR(r4, LOCAL_MEM_LOCAL_ADRS)
LOADPTR(r5, rtAddr)
sub r5, r5, r4
/* calculate runtime address base */
sub r3, r3, r5
/* adjust DTB address */
#ifndef _WRS_CONFIG_STANDALONE_DTB
sub r30, r30, r3 /* get offset */
add r30, r30, r4
#endif /* !_WRS_CONFIG_STANDALONE_DTB */
/* initialize MMU early */
mr r5, r31
bl vxMmuEarlyInit
/* save DTB address */
#ifdef _WRS_CONFIG_STANDALONE_DTB
LOADPTR(r30, dt_blob_start)
#endif /* _WRS_CONFIG_STANDALONE_DTB */
STOREVAR_LP(r30, r6, gpDtbInit)/* get frame stack */ LOADPTR(sp, RAM_LOW_ADRS)
addi sp, sp, -FRAMEBASESZ
/* jump to C routine */
mr r3, r29 /* resotre the boot type */
b usrInit
FUNC_END(sysInit)

The sysInit( ) routine is the RAM entry point. sysInit( ) — which should be the first routine defined in sysALib.s invalidates caches if applicable, initializes the system interrupt tables with default stubs, initializes the system fault tables with default stubs, and initializes all processor registers to known default values. The routine also enables tracing, clears all pending interrupts, and finally invokes usrInit( ) with the argument bootType. This routine must duplicate much of the hardware initialization done by romInit( ) in order to set the run-time state rather than the boot state. Keep in mind that the board may have been booted using a ROM monitor or hardware debugger. In this case, the VxWorks boot ROM code, where romInit( ) is located, is not executed and VxWorks system initialization is not performed. Therefore, failure to duplicate the initialization code from romInit( ) may result in BSP failure.

Execute usrInit( )

void usrInit (int startType){sysStart (startType);               /* clear BSS and set up the vector table base address. */_func_kprintf = kprintf;            /* formatted kernel print facility */usrFdtInit ((void*)DTB_RELOC_ADDR, (int)DTB_MAX_LEN); /* Flat Device Tree library */usrBoardLibInit();                  /* initialize board subsystem to supply BSP access APIs */usrAimCpuInit ();                   /* include CPU library support */cacheLibInit (USER_I_CACHE_MODE, USER_D_CACHE_MODE); /* include cache support */excShowInit ();                     /* exception show routines */excVecInit ();                      /* exception handling */vxCpuLibInit ();                    /* Enable the initialization of CPU identification routines */usrCacheEnable ();                  /* optionally enable caches */objOwnershipInit ();                /* object management ownership */objInfoInit ();                     /* object management routines that requires lookup in a    list of objects, such as the objNameToId() routine. */objLibInit ((OBJ_ALLOC_FUNC)FUNCPTR_OBJ_MEMALLOC_RTN,         (OBJ_FREE_FUNC)FUNCPTR_OBJ_MEMFREE_RTN,           OBJ_MEM_POOL_ID,                  OBJ_LIBRARY_OPTIONS); /* object management */vxMemProbeInit ();                  /* Initialize vxMemProbe exception handler support */wvLibInit ();                       /* low-level kernel instrumentation needed by System Viewer */classListLibInit ();                /* object class list management */semLibInit ();                      /* semaphore support infrastructure *//* mutex semaphores *//* mutex semaphore creation routine */condVarLibInit ();                  /* condition variables */classLibInit ();                    /* object class management */kernelBaseInit ();                  /* required component DO NOT REMOVE. */taskCreateHookInit ();              /* user callouts on task creation/deletion *//* __thread variables support */sysDebugModeInit ();                /* a flag indicating the system is in 'debug' mode */umaskLibInit(UMASK_DEFAULT);        /* This component adds support for POSIX file mode creation mask                 in the kernel environment */usrKernelInit (VX_GLOBAL_NO_STACK_FILL); /* context switch and interrupt handling (DO NOT REMOVE). */}

The purpose of the usrInit( ) routine is to completely initialize the CPU and shut down any other hardware, thus preparing the way for the kernel to initialize and start itself. This routine is located in prjConfig.c but calls routines in several other files, some of which you must provide and some of which are provided by Wind River. Normally, it is not necessary to modify the usrInit( ) routine provided by Wind River. However, the sysHwInit( ) routine that must be called from usrInit( ) typically does require modification. The sysHwInit( ) routine ensures that the board-dependent hardware is quiescent. sysHwInit( ) is provided in the reference BSP or template and is located in sysLib.c. The usrInit( ) routine (in prjConfig.c) saves information about the boot type, handles all initialization that must be performed before the kernel is actually started, and then starts the kernel execution. It is the first C code to run in VxWorks. This routine is invoked in supervisor mode with all hardware interrupts locked out. Many facilities cannot be invoked from this routine. There is no task context yet — that is, no task control block (TCB) and no thread stack — therefore, facilities that require a task context cannot be invoked. This includes any facility that can cause the caller to be preempted (such as semaphores) or any facility that itself uses a facility of this type, such as printf( ). Instead, the usrInit( ) routine does only what is necessary to create the initial thread, usrRoot( ). usrRoot( ) then completes the startup. The initialization operations performed in usrInit( ) include the following:

■ Initializing cache.

The code at the beginning of usrInit( ) initializes the caches, sets the mode of the caches, and puts the caches in a safe state. At the end of usrInit( ), the instruction and data caches are enabled by default.

■ Zeroing out the system BSS segment.

C language specifies that all uninitialized variables (stored in bss) must have initial values of 0. Because usrInit( ) is the first C code to execute, it clears the section of memory containing bss.

■ Initializing interrupt vectors.

The exception vectors must be initialized before enabling interrupts and starting the kernel. First, intVecBaseSet( ) is called to establish the vector table base address.

After intVecBaseSet( ) is called, the routine excVecInit( ) initializes all exception vectors to default handlers. These handlers safely trap and report exceptions caused by program errors or unexpected hardware interrupts.

■ Initializing system hardware to a quiescent state.

Calling the system-dependent routine sysHwInit( ) initializes the system hardware. Initialization mainly consists of resetting and disabling hardware devices. Otherwise, when the kernel is started and interrupts are enabled, these devices can cause unexpected interrupts. In VxWorks, ISRs (for I/O devices, system clocks, and so on) are not connected to their interrupt vectors until system initialization is completed by the usrRoot( ) task. This is a requirement because the memory pool is not yet initialized. You must not connect an interrupt handler to an interrupt during the sysHwInit( ) call; doing so requires memory allocation, which is not available at this time. Most interrupt connection occurs later in the sysHwInit2( ) routine located in sysLib.c.

■ Calling kernelInit( ).

The VxWorks libraries contain the code for kernelInit( ). Therefore, it is not normally available to BSP developers in source form. The kernelInit( ) routine initiates the multitasking environment and never returns. It takes the following parameters:

typedef struct kernelInit_params
{
FUNCPTR rootRtn; /* function to run as tRootTask */
size_t rootMemSize; /* memory for TCB and root stack */
char *pMemPoolStart; /* beginning of memory pool */
char *pMemPoolEnd; /* end of memory pool */
size_t intStackSize; /* interrupt stack size */
size_t vmPageSize; /* configuration's VM_PAGE_SIZE */
size_t intStackOverflowSize; /* int stack overflow region size */
size_t intStackUnderflowSize; /* int stack underflow region size */
size_t idleTaskExcepStkSize; /* SMP idle task exc. stack size */
size_t idleTaskExcepStkOverflowSize; /* ... overflow region size */size_t idleTaskExcepStkUnderflowSize; /* ... underflow region size */
int lockOutLevel; /* interrupt lock-out level (1-7) */
} _KERNEL_INIT_PARAMS; //defined in kernelLib.hvoid usrKernelInit(BOOL noStackFill)
{
_KERNEL_INIT_PARAMS kIP;
* start the kernel specifying usrRoot as the root task */
bfill ((char *)&kIP, sizeof(kIP), 0);
kIP.rootRtn = (FUNCPTR) usrRoot;
kIP.rootMemSize = ROOT_STACK_SIZE;
kIP.pMemPoolStart = MEM_POOL_START;
kIP.pMemPoolEnd = memPoolEndAdrs;
kIP.intStackSize = ISR_STACK_SIZE;
kIP.lockOutLevel = INT_LOCK_LEVEL;
kIP.vmPageSize = VM_PAGE_SIZE;
kIP.idleTaskExcepStkSize = KERNEL_TASK_EXC_STACK_SIZE;
kernelInit (_KERNEL_INIT_PARAMS_VN_AND_SIZE, &kIP);/* we do not return from kernelInit() */}
  • address of the routine to be spawned as the root task, typically usrRoot()
  • stack size
  • start of usable memory; that is, the memory after the main text, data, and bss segments of the VxWorks image. All memory after this area is allocated to the system memory pool, which is managed by memPartLib. All cached dynamic allocations are derived from this memory pool.
  • top of cached memory as indicated by sysMemTop( )
  • interrupt stack size. The interrupt stack corresponds to the largest amount of stack space that can be used by any interrupt-level routine that may be called, plus a safety margin for the nesting of interrupts.
  • interrupt lockout level. For architectures that have a level concept, it is the maximum level. For architectures that do not have a level concept, it is a mask to disable interrupts. For more details, see the appropriate VxWorks Architecture Supplement.

■ Execute kernelInit( )

The kernelInit( ) routine is provided by Wind River in a VxWorks library archive file. The purpose of this routine is to get the kernel up and running so that all further initialization can be done as a task running under the kernel. The name of this task is tRootTask, and the routine it executes is typically usrRoot( ). The kernelInit( ) routine calls intLockLevelSet( ), disables round-robin scheduling mode, and creates an interrupt stack (if supported by the architecture). The routine then creates a root stack and a task control block (TCB) from the top of the memory pool, spawns the root thread usrRoot( ), and terminates the usrInit( ) thread of execution. At this time, interrupts are enabled. It is critical that all interrupt sources be disabled by usrInit( ), and that all pending interrupts be cleared.

Execute usrRoot( ) as a task

void usrRoot (char *pMemPoolStart, unsigned memPoolSize){usrKernelCoreInit ();               /* core kernel facilities */poolLibInit();                      /* memory pools of fixed size items */memInit (pMemPoolStart, memPoolSize,      MEM_PART_DEFAULT_OPTIONS); /* full featured memory allocator */memPartLibInit (pMemPoolStart, memPoolSize); /* core memory partition manager */kProxHeapInit (pMemPoolStart, memPoolSize); /* Kernel proximity heap */pgPoolLibInit();                    /* Generic Page Pool Allocator */pgPoolVirtLibInit();                /* Page Pool Allocator for Virtual Space */pgPoolPhysLibInit();                /* Page Pool Allocator for Physical Space *//* basic MMU component */usrMmuInit ();                      /* MMU global map support */pmapInit();                         /* provides the functionality to map or unmap physical                         addresss to the kernel/RTP context. */kCommonHeapInit (KERNEL_COMMON_HEAP_INIT_SIZE, KERNEL_COMMON_HEAP_INCR_SIZE); /* kernel common heap */usrKernelCreateInit ();             /* object creation routines */usrNetApplUtilInit ();              /* Stack and Application Logging Utility */memInfoInit ();                     /* memory allocator info routines */envLibInit (ENV_VAR_USE_HOOKS);     /* unix compatible environment variables */edrStubInit ();                     /* ED&R error-injection stub */usrSecHashInit ();                  /* Initialize the secHash providers */boardInit();                        /* call the boardInit() routine during system startup */usrDebugAgentBannerInit ();         /* Toggles agent specific elements in banner */usrShellBannerInit ();              /* Toggles shell specific elements in banner */usrSmaBannerInit ();                /* Add stop mode debug agent specific elements in banner */excOsmInit (TASK_USER_EXC_STACK_OVERFLOW_SIZE, VM_PAGE_SIZE); /* Handler for Exception Stack Overflow */taskStackGuardPageEnable();         /* insert underflow and overflow guard pages to kernel task stacks */taskStackNoExecEnable();            /* enable non-executable kernel task stacks */usrSysctlInit();                    /* System control function */erfLibInit (ERF_MAX_USR_CATEGORIES, ERF_MAX_USR_TYPES, ERF_TASK_STACK_SIZE); /* Event Reporting Framework */kernelIdleTaskActivate();           /* Add Idle Tasks Support (SMP Only) */usrIosCoreInit ();                  /* core I/O system */usrNetworkInit0 ();                 /* Initialize the network subsystem for drivers */usrHwSysctlInit();                  /* System control hardware info registration */vxbClkLibInit();                    /* vxBus device clock subsystem */vxbDmaLibInit();                    /* vxBus DMA subsystem */vxbGpioLibInit();                   /* vxBus GPIO subsystem */vxbIsrHandlerInit (VXB_MAX_INTR_VEC, VXB_MAX_INTR_CHAIN); /* VxBus ISR handler module initialization */vxbIntLibInit (VXB_MAX_INTR_DEFER); /* VxBus interrupt library initialization */vxIpiLibInit ();                    /* Inter Processor Interrupts for SMP and AMP */miiBusFdtLibInit();                 /* MII FDT subsystem */miiBusLibInit();                    /* MII subsystem */vxbParamLibInit ();                 /* VxBus driver parameter utilities */vxbLibInit ();                      /* VxBus subsystem */excIntNestLogInit();                     vxMsrSet(vxMsrGet() | taskMsrDefault);                     sysIntEnableFlagSet (); /* Enable interrupts at appropriate point in root task */usrSerialInit ();                   /* Serial IO component */usrClkInit ();                      /* clock system initialization */cpcInit ();                         /* CPUs Cross-Processor Call (SMP Only) */vxdbgCpuLibInit ();                 /* CPU control support for VxDBG *//* Architecture common modules for hardware floating point */pgMgrBaseLibInit();                 /* Basic Page Manager Library */pgMgrLibInit();                     /* Page Manager Library */usrRtpInit ();                      /* RTP init routines */mmanLibInit ();                     /* Memory mapping and unmapping routines */usrKernelExtraInit ();              /* extended kernel facilities */usrIosExtraInit ();                 /* extended I/O system */sockLibInit ();                     /* Socket API */selTaskDeleteHookAdd ();            /* selectInit, part 2, install task delete hook */cplusCtorsLink ();                  /* run compiler generated initialization functions at system startup */usrCplusLibInit ();                 /* Basic support for C++ applications */cplusDemanglerInit ();              /* Support library for kernel shell and loader: provides human readable forms of C++ identifiers */usrScInit ();                       /* The system call initialization sequence */usrSmpInit ();                      /* Enable multi-processor capability of the kernel */miiBusMonitorTaskInit();            /* This component will spawn the MII bus monitor task */usrNetworkInit ();                  /* Initialize the reset of the network subsystem */usrBanner ();                       /* Display the WRS banner on startup */usrToolsInit ();                    /* software development tools */usrAppInit ();                      /* call usrAppInit() (in your usrAppInit.c project file) after startup. */usrRtpAppInit ();                   /* Launch RTP from a user-defined function. */usrRtpAppInitBootline ();           /* Launch RTP from a string-encoded list in the boot parameters. */}

The purpose of the usrRoot( ) routine is to complete the initialization of the kernel and all hardware, then launch any application code. This routine is supplied by Wind River in the prjConfig.c file, and the original copy should not be changed. During development, prjConfig.c is often temporarily copied to the BSP directory, and debugging changes are made to the temporary copy. prjConfig.c is also configurable with the macros defined in config.h.

The usrRoot( ) routine calls the memInit( ) routine. Optionally, usrRoot( ) can call the memShowInit( ) and usrMmuInit( ) routines. Once the system is multitasking, the BSP calls its first routine, sysClkConnect( ). sysClkConnect( ) immediately calls the sysHwInit2( ) routine. sysHwInit2( ) is responsible for any board initialization not completed in sysHwInit( ), such as the connection of interrupt sources using intConnect( ). Next, the usrRoot( ) routine continues the clock initialization. It sets the default clock rate to the value of the macro SYS_CLK_RATE, typically 60 Hz. usrRoot( ) then enables the system clock with a call to sysClkEnable( ).Once the clock is initialized and running, several kernel modules, such as selectLib, the I/O subsystem, and the console, are initialized. For details, see the source code in usrConfig.c as well as the macros defined in configAll.h and config.h. If INCLUDE_WDB is defined, wdbConfig( ) in installDir/vxworks-6.x/target/src/config/usrWdb.c is called. This routine initializes the agent’s communication interface, and then starts the debug agent. The debug agent is the portion of VxWorks that connects to and serves the Workbench tools such as the shell and the debugger. If the INCLUDE_USR_APPL macro is defined, the default usrRoot( ) code executes the USER_APPL_INIT macro. This macro allows you to start your application automatically at boot time. The BSP assumes that the USER_APPL_INIT macro is a valid C statement. For more information on USER_APPL_INIT, see the appropriate VxWorks programmer’s guide.

--

--