MVME162 FLASH RAM Resident Bootable VxWorks System

Kevin Ryan
National Radio Astronomy Observatory
Socorro, NM
May 22, 2002

The purpose of this document is to provide the information necessary to:


The MVME162 contains an onboard-programmable FLASH RAM device that behaves similar to a ROM or EPROM in that it retains its data even with no power, but unlike ROM, can be written to without the need for an external programming device. These features make the FLASH RAM ideal for holding bootable program code such as the VxWorks operating system and associated application code to make a true 'turn-key' system in which the application can be up and running within seconds after power-up or reset.

Normally, a small bootstrap program is contained in the processor's ROM and is executed upon reset or power-up. This bootstrap program loads the VxWorks OS from across the network or from an onboard disk if available. It is possible to contain the VxWorks OS itself (and application code) in the ROM so that bootstrapping from an external device is not necessary. This can be quite beneficial in terms of speed (booting is done in a few seconds not minutes) and reliability (booting will still take place even if the network is down).

This document will describe how to build a VxWorks OS image that can reside in ROM or, in this case, FLASH RAM and how to put that image into the MVME162's FLASH RAM. The information provided is specific to the MVME162-412 processor used in the NRAO's EVLA Interim Control and Monitor system but will contain enough generic information to apply to any processor with similar capabilities.


Summary of Parameters used for this Project

The following summarizes the various parameters such as IP addresses, processor names, etc. used for this particular application. The term 'host' refers to the Unix system used for software development purposes. The term 'target' refers to the computer that the VxWorks OS will run in.

Host Name:                 magnolia
Target Name:               buckwheat
Host IP Address: 
Target IP Address:
Target Board:              MVME162-412(CE) or MVME162-FX
VxWorks BSP:               mv162lc
VxWorks Installation Area: /opt/local/WindRiver/Tornado/2.0
VxWorks Build Area:        /home/asg/vxworks/evla/cmp

Description of the MVME162

The Motorola MVME162-412 Embedded Controller is a 6U VME single board computer utilizing a MM68LC040 processor. The 'LC' means this processor does not contain an integral hardware Floating Point Unit (FPU). The MVME162 contains 4 Industry Pack (IP) mezzanine card slots, an IPChip2 device for communications between the IP Modules and the main circuit board and a VMEChip2 for communications between the main circuit board and the VME chassis. The '162 contains various memories as follows:

The various memories are explained in more detail here:


This board contains a 512KByte EPROM that is loaded with the Motorola debug/monitor program called 162Bug. 162Bug allows the user to perform basic operations such as read/modify memory contents, load programs/data either manually or over a network via TFTP and other low level operations.

On our other VME processor boards, MVME147s & MVME167s, the EPROM is normally replaced (or rewritten) with a version containing the VxWorks bootrom image so that we can load VxWorks. Since the 162 also has FLASH RAM which is non-volatile, we can keep the 162Bug program on EPROM and use FLASH for our VxWorks needs.


This board contains 1 MB of non-volatile RAM which can easily be programmed in-circuit from the operator's console using the 162Bug's PFLASH command. FLASH is erased/written in 64K blocks.

FLASH/EPROM address mapping

Jumper GP13 (J22 pins 9/10) is used to determine where FLASH RAM and the EPROM reside as follows:

GP13 IN  - FLASH at 0xFF800000, EPROM at 0xFFA00000
GP13 OUT - EPROM at 0xFF800000, FLASH at 0xFFA00000.

Since Power-up/Reset code is loaded from address 0xFF80000, booting can take place from either EPROM or FLASH depending on which one is mapped to address 0xFF800000.


This RAM can be written to just like regular RAM but retains the data during power off. It is mapped to address space 0xFFFC0000 - 0xFFFC1FFF. The first 4K (FFFC00000 - FFFC0FFF) is available for the user and is used by VxWorks to store the boot string (configuration information such as host/target IP addresses, startup script file names, etc.). This area is also used by Motorola's monitor/debug program (162Bug) for the same purpose. Unfortunately the data are stored differently so VxWorks cannot read the data when it is in 162Bug format and vice-versa. If network operations are to be used with 162Bug, (i.e. TFTP transfers to get a VxWorks image that will be written to FLASH RAM), NVRAM should first be updated with the correct data using the NIOT utility. When using VxWorks, NVRAM can be loaded in the proper format using 'bootParamsPrompt()'.

The Boot Process Explained

On power-up or reset, the processor loads the Stack Pointer (SP) with the contents of address 0xFF800000 and the Program Counter (PC) with the contents of address 0xFF800004 which causes program execution to resume at the PC's new address. To take control of the processor on power-up or reset we want to do the following:

In our case we configure the GP13 jumper so that FLASH RAM is at address 0xFF800000, and our program is loaded starting at address xFF800008. We put the value 0xFF800008 (our starting address) into location 0xFF800004. When power-up or reset occurs, the starting address is loaded into the PC and execution begins at that address.

VxWorks Image Types Explained

A VxWorks image is the actual VxWorks Operating System program in non-relocatable object format that is loaded in and runs on the target processor (the VME board). There are two forms of VxWorks programs; one that operates in the Tornado development environment and one that operates in a stand-alone fashion. The difference between the two is that the stand-alone version includes the symbol table whereas under Tornado, the symbol table remains on the host processor. We will be building a stand-alone version that will run on the target independent of the host.

Additionally, if you want your VxWorks image to reside in ROM you have two more choices; you can make it so the whole image (both the code and data segments) are copied into RAM before execution takes place, or you can have it so only the data segment is copied into RAM and the program is executed out of ROM. The latter is called ROM-resident by the VxWorks documentation which is rather confusing terminology because BOTH versions reside in ROM, the difference is that one also executes out of ROM. The advantage of executing in ROM (ROM-resident) is that less RAM is taken up by the OS (leaves more for applications); the disadvantage is that program execution from ROM will be slower.

Finally, if the program does not execute out of ROM and if it is the stand-alone version, it will be compressed at build time and uncompressed while it is being copied from ROM to RAM. Programs that execute in ROM and non ROM-resident Tornado versions are not compressed.

The following summarizes the VxWorks build options available at make time (these are done by specifying the build name when invoking the Makefile):

Uploaded images:
vxWorks               - basic Tornado, host-based shell and symbol table            - stand-alone image, target-based shell and symbol table

ROM based images:
vxWorks_rom           - Tornado in ROM, uncompressed, executes in RAM
vxWorks.res_rom_nosym - Tornado in ROM, uncompressed, executes in ROM
vxWorks.st_rom        - Stand-alone in ROM, compressed, executes in RAM
vxWorks.res_rom       - Stand-alone in ROM, uncompressed, executes in ROM

Build a Customized VxWorks Image

This procedure is done using the following steps:

Make a build directory in our VxWorks Build Area

Our VxWorks Build Area is '/home/asg/vxworks'. For the EVLA project it is further refined to 'home/asg/vxworks/evla' and finally for the CMP subsystem of the EVLA it is '/home/asg/vxworks/evla/cmp'. In here we want to make a subdirectory called 'target'. The 'target' directory is where all the files specific to our particular build as well as links to generic files will reside.


Make links to unmodified files/directories back to VxWorks Installation Area

The VxWorks Installation Area is the directory in which the VxWorks deliverable software is installed. This is a non-writable area that contains all of the core VxWorks software plus all of the BSPs that we hold license to. Since most of the Installation Area files will not be modified for our build - but may still need access to by our 'make' process, we can simply make links to them.

Make links to the files in the Installation Area that will not be modified for our build.


SETUP       -> /opt/local/WindRiver/Tornado/2.0/SETUP/
docs        -> /opt/local/WindRiver/Tornado/2.0/docs/
host        -> /opt/local/WindRiver/Tornado/2.0/host/
share       -> /opt/local/WindRiver/Tornado/2.0/share/

Many of the sub-directories in the new 'target' directory can also be linked back to the installation area as follows:


h           -> /opt/local/WindRiver/Tornado/2.0/target/h/
lib         -> /opt/local/WindRiver/Tornado/2.0/target/lib/
proj        -> /opt/local/WindRiver/Tornado/2.0/target/proj/
src         -> /opt/local/WindRiver/Tornado/2.0/target/src/
unsupported -> /opt/local/WindRiver/Tornado/2.0/target/unsupported/

Copy the directories whose contents will be modified to our build directory.

We copy the BSP specific files into our VxWorks build area so that we may modify files for our customized build without changing the originals. The files that we will be changing reside in a subdirectory of the 'target' directory called 'config'. We must first create the 'config' subdirectory in our 'target' directory :


The BSP that we are using for this project is 'mv162lc' which is for the MVME162 without the hardware FPU. Since we will also be modifying 'usrConfig.c' which resides in 'all' we must obtain our own copy of that directory as well:

cd config
cp -r /opt/local/WindRiver/Tornado/2.0/target/config/mv162lc .
cp -r /opt/local/WindRiver/Tornado/2.0/target/config/all .

If we were not going to modify anything in the 'all' directory, then we would link it back to the VxWorks Installation Area, but we are going to modify it so we need our own copy.

Modify 'Makefile'

If necessary, make changes to point to the new 'all' directory. This step is used only when two or more builds share the same target build area and but need to use different 'all' files. It is possible to control 'make' to use different 'all' files. The Makefile file contains an area reserved for user modifications and there are comments that describe where this area is. The user can add a pointer called CONFIG_ALL to the Makefile that will point to his customized 'all' area by adding the following line:

CONFIG_ALL = /myAllPath/myAllDir

Since we are the only build using the 'all' directory, we do not need to perform the above step.

Change the ROM_SIZE to 1M from 256K. Since our FLASH RAM can hold 1M we need to let the Makefile know so we don't get warnings that our file size being too big.

# ROM_SIZE         = 00040000 # number of bytes of ROM space  
ROM_SIZE         = 000100000 # number of bytes of ROM space

Modify config.h to add/remove various services and functionality

VxWorks provides many optional features that can be included or removed from a build; examples of these features are C++ support, networking support, debug facilities and etc.. The mechanism for adding or removing these features is by defining or undefining them in the 'bsp/config.h' file or in the 'all/configAll.h' file by using the #define and #undef compiler directives.

Each BSP has its own 'config.h' file and there is a 'configAll.h' file common to all BSPs. The 'configAll.h' file contains all the possible available build option choices but some have been included and others excluded. If all the BSPs want the same options, the 'configAll.h' can be modified. If not all the BSPs use the same options, then 'configAll.h' should NOT be modified and each 'config.h' should be changed instead. The 'config.h' file has the 'final say' at build time so items defined or undefined there will take precedence over what is in 'configAll.h'.

To make option changes using config.h, if an option that was originally included in 'configAll.h' is to be removed, it should be undefined in config.h using the '#undef' directive. If an option is to be added then it should be defined with the '#define' directive. If an option is to be modified such as the console BAUD rate, then it must first be undefined then redefined with the new value (this is necessary to prevent compiler warnings that an item was defined more than once).

Changes made to the config.h file for this project are listed here.

Modify usrConfig.c to customize the way the system starts up

The boot program that is normally used to load the VxWorks image from over the network or disk device provides the operator the ability to modify parameters pertaining to the network such as the host and target names and IP addresses. Even though we do not need the network for our VxWorks (since it will be resident on board the processor) it is necessary to be able to set up the network parameters for further application program loading.

Since we are not using the normal boot program we must add the parameter change ability to our startup process. 'usrConfig.c' in the 'all' directory is where this done. The parameter change routines were borrowed from the boot program (bootConfig.c) and added to 'usrConfig.c'

Changes made to the usrConfig.c file for this project are listed here.

Setup the environment variables.

setenv WIND_BASE /home/asg/vxworks/evla/cmp
setenv WIND_HOST_TYPE sun4-solaris2
setenv PATH ${WIND_BASE}/host/sun4-solaris2/bin:${PATH}

Use the supplied VxWorks Makefile to build a Stand-alone, ROM-based, compressed VxWorks image

We use the make system supplied with VxWorks by specifying the type of build we wish to create. In our case we want the build that will create a VxWorks image that is stand-alone (not Tornado), will be loaded into ROM, is compressed and executes totally in RAM (both code and data segments). The name of this build is 'vxWorks.st_rom'.

cd /home/asg/vxworks/evla/cmp/target/config/mv162lc
make vxWorks.st_rom

This will create a file called 'vxWorks.st_rom'. This file needs to be converted to a .bin file as follows:

/opt/local/WindRiver/Tornado/2.0/host/sun4-solaris2/bin/aoutToBin < vxWorks.st_rom > vxWorks.st_rom.bin

This will create a file called 'vxWorks.st_rom.bin'. This file is ready to be loaded into the MVME162's FLASH RAM.

Program the VxWorks Image into FLASH RAM

This process consists of using TFTP to load our VxWorks image into the MVME162 main memory from over the network, then writing this image into the 162's FLASH RAM. The steps for doing this are as follows:

Boot the target from EPROM to run the 162 Debugger.

The MVME162 contains a debug/monitor program (a very low-level operating system), called 162-Bug, in the onboard EPROM device. This program provides several utilities for manipulating memory, loading programs, an inline assembler for writing programs directly into memory, network configuration, etc.
We will use 162-Bug to upload our VxWorks image from the host into the MVME162. To enter 162-Bug we must boot from EPROM by following these steps:

Setup the Server/Client IP Addresses for the TFTP Transfer.

We will use the NIOT command for this. Follow the prompts; we are only concerned with the client and server IP addresses, press return to ignore all the other parameters. When all parameters have been entered (or ignored), you will be prompted to answer if NVRAM should be updated. If you say YES to this it will write over the VxWorks parameters that may have been stored there from a previous time and you will have to re-enter them at boot time. If you answer NO, the changes you made will not be saved but will still work for this one time. Unless you plan on doing several TFTP transfers before rebooting under VxWorks, answer NO to the question.

The NIOT command goes something like this (notice the only things we change are the Client/Server IP Addresses and the Update Non-Volatile RAM question at the bottom, for all other prompts we just press return):

162-Bug> NIOT 
Controller LUN =00?
Device LUN     =00?
Node Control Memory Address =FFE10000?
Client IP Address      = 
Server IP Address      = 
Subnet IP Address Mask =
Broadcast IP Address   =
Boot File Name ("NULL" for None)     =?
Argument File Name ("NULL" for None) =?
Boot File Load Address         =001F0000?
Boot File Execution Address    =001F0000?
Boot File Execution Delay      =00000000?
Boot File Length               =00000000?
Boot File Byte Offset          =00000000?
BOOTP/RARP Request Retry       =00?
TFTP/ARP Request Retry         =00?
Trace Character Buffer Address =00000000?
BOOTP/RARP Request Control: Always/When-Needed (A/W)=W?
BOOTP/RARP Reply Update Control: Yes/No (Y/N)       =Y?

Update Non-Volatile RAM (Y/N)? N 

Load the VxWorks image file into RAM at address 0x10008.

We will use the NIOP command for this. Follow the prompts to add the File Name and Memory Address; all other parameters can be left as is by pressing return after each. The File Name starts at the directory path of the pre-configured TFTP directory (usually called '/myhost/tftpboot/' and must be setup before-hand by a system administrator).

The NIOP command goes like this (Note that File Name assumes a TFTP directory of '/home/asg/vxworks/'):

162-Bug> NIOP 
Controller LUN =00?
Device LUN     =00?
Get/Put        =G?
File Name      =? evla/cmp/target/config/mv162lc/vxWorks.st_rom.bin
Memory Address =0000E000? 00010008
Length         =00000000?
Byte Offset    =00000000?
Bytes Received =&300992, Bytes Loaded =&300992
Bytes/Second   =&75248, Elapsed Time =4 Second(s)


Configure the Stack Pointer (SP) and Program Counter (PC) Values

As explained in the Boot Process description above, the SP and PC are first obtained from the 8-byte area preceeding the VxWorks image. We must set up this area with the proper values.

We will use the MM (Memory Modify) command for this as follows:

162-Bug> MM 10000;l 
00010000 00000000? 00001000
00010004 00000000? FF800008
00010008 46FC3700? .

Write the VxWorks image along with the SP and PC values to FLASH RAM

The monitor/debug program contains a facility to 'program' FLASH RAM; it is called PFLASH. The arguments to PFLASH are the source starting address, length, and destination starting address. To determine length round the VxWorks image size up to the nearest 64k block (to the nearest 0x10000 hex). The file size can be obtained from the NIOP command results above. In this case the size is 300992 (0x497C0) which rounds up to 327680 (0x50000).

The PFLASH command is as follows:

162-Bug> PFLASH 10000:50000 FFA00000 
Source Starting/Ending Address      =00010000/0005FFFF
Destination Starting/Ending Address =FFA00000/FFA4FFFF
Number of Effective Bytes           =00050000 (&327680)

Program FLASH Memory (Y/N)? Y
Erasing Block Number     =00 ($FFA00000)
Erasing Block Number     =01 ($FFA10000)
Erasing Block Number     =02 ($FFA20000)
Erasing Block Number     =03 ($FFA30000)
Erasing Block Number     =04 ($FFA40000)
Programming Block Number =00 ($FFA00000)
Programming Block Number =01 ($FFA10000)
Programming Block Number =02 ($FFA20000)
Programming Block Number =03 ($FFA30000)
Programming Block Number =04 ($FFA40000)
FLASH Memory Programming Complete

Boot the MVME162 from FLASH RAM

This step places the FLASH RAM back at the boot start address so when the machine is restarted, it will execute from FLASH RAM.

Changes Made to 'config.h' for this Project

diff /home/asg/vxworks/evla/cmp/target/config/mv162lc/config.h \

< /* ----------------   changes to configAll  -- K.Ryan 7/26/01 -------------- */
< /* remove these guys */
< #undef  INCLUDE_BOOTP 		/* we'll get ours from NVRAM */
< #undef  INCLUDE_CPLUS		        /* no like-um C++ */
< #undef  HOST_NAME_DEFAULT             /* we'll redefine our own later */
< #undef  CONSOLE_BAUD_RATE             /* same here */
< /* add these */
< #define CONSOLE_BAUD_RATE	9600	/* console baud rate */
< #define INCLUDE_CONFIGURATION_5_2 /* pre-tornado tools */
< #define INCLUDE_DEBUG           /* pre-tornado debugging */
< #define INCLUDE_FTP_SERVER	/* ftp server */
< #define INCLUDE_INSTRUMENTATION /* windView instrumentation */
< #define INCLUDE_LOADER          /* object module loading */
< #define INCLUDE_MIB2_ALL        /* All of MIB 2 */
< #define INCLUDE_NET_SHOW        /* network info and status facilities */
< #define INCLUDE_NET_SYM_TBL     /* load symbol table from network */
< #define INCLUDE_NFS             /* nfs package */
< #define INCLUDE_NFS_SERVER      /* nfs server */
< #define INCLUDE_NFS_MOUNT_ALL	/* automatically mount all NFS file systems */
< #define INCLUDE_PING		/* ping() utility */
< #define INCLUDE_RLOGIN          /* remote login */
< #define INCLUDE_RPC		/* rpc package */
< #define INCLUDE_SECURITY	/* shell security for network access */
< #define INCLUDE_SHELL           /* interactive c-expression interpreter */
< #define INCLUDE_SHOW_ROUTINES   /* show routines for system facilities*/
< #define INCLUDE_SPY             /* spyLib for task monitoring */
< #define INCLUDE_STANDALONE_SYM_TBL /* compiled-in symbol table */
< #define INCLUDE_STARTUP_SCRIPT  /* execute start-up script */
< #define INCLUDE_STAT_SYM_TBL    /* create user-readable error status */
< #define INCLUDE_SYM_TBL         /* symbol table package */
< #define	INCLUDE_TCP_DEBUG	/* TCP debug facility */
< #define INCLUDE_TELNET          /* telnet-style remote login */
< #define INCLUDE_TFTP_SERVER	/* tftp server */
< #define INCLUDE_UNLOADER        /* object module unloading */
< #define INCLUDE_WINDVIEW	/* WindView command server */
< #define	INCLUDE_ZBUF_SOCK	/* zbuf socket interface */
< /* ----------------   End changes to configAll  ------------------------- */
< /* ------------------ Changes to support new INCLUDES ------------------- */
< /* Login security initial user name and password.
<  * Use vxencrypt on host to find encrypted password.
<  * Default password provided here is "password".
<  */
< #define LOGIN_USER_NAME		"aaa"
< #define LOGIN_PASSWORD          "rrrrrrrr"
< #endif	/* INCLUDE_SECURITY */
< #ifdef INCLUDE_NFS
< /* Default NFS parameters - constants may be changed here, variables
<  * may be changed in usrConfig.c at the point where NFS is included.
<  */
< #define NFS_USER_ID		1041	  /* for vlbsoft - get it from ...  */
< #define NFS_GROUP_ID		49	  /*   ... zia:/etc/passwd   [kjr]  */
< #endif /* INCLUDE_NFS */
< /* [kjr] 
<  * To allow network initialization in standalone (non tornado) mode. 
<  * See page 366 of VxWorks 5.4 Programmers Guide.
<  */
< "ei(0, 2)\
<  magnolia:/home/magnolia2/evla/vxWorks\
<  tn=gumby\
<  u=vlbsoft"
< #define HOST_NAME_DEFAULT    "magnolia"
< #define TARGET_NAME_DEFAULT  "gumby"
< #define HOST_USER_DEFAULT    "vlbsoft"
< /* --------------  End Changes to support new INCLUDES ------------------- */
> "ei(0,0)host:/usr/vw/config/mv162/vxWorks h= e= u=target"
< #define ROM_SIZE                0x00100000     /* 1M ROM space */
< /* Changed ROM_SIZE from 0x00040000	( 256K ROM space ) K.Ryan 07/26/01 */
> #define ROM_SIZE		0x00040000	/* 256K ROM space */

Changes Made to 'usrConfig.c' for this Project

diff /home/asg/vxworks/evla/cmp/target/config/all/usrConfig.c \

< /* 
< * EVLA Interim CMP Modified File 
< * 
< * This file has been modified to facilitate starting up from a VxWorks 
< * image that was booted from ROM. 
< * 
< * Normally when booting from ROM the user is not given the chance to 
< * modify the boot parameters like when booting from over the network. 
< * The countdown to allow the user the chance to stop the process and 
< * and modify boot parameters was adapted from bootConfig.c (which is 
< * the ROM based boot-only program used to boot VxWorks from a file 
< * over the network) and added to this file. 
< * 
< * Also, code was added to execute startup commands (like those normally 
< * found in a 'startup.cmd' script file) from within the program 
< * instead of having to load a file from across network. File loading 
< * at this stage still takes a considerable amount of time because 
< * they must use FTP or RSH which requires a login. Once the startup 
< * commands are executed to mount the NFS devices, network access 
< * becomes very much faster. A that point a startup script with a 
< * hard-coded name is executed to start the CMP if desired. 
< * 
< * Changes to this file are marked with 'Begin [ROM Boot Modification]' 
< * and 'End [ROM Boot Modification]' 
< * 
< * K.Ryan 08/03/01 
< * 
< */ 
< /* [kev - 08/01/01] set serial port backspace character to delete */ 
< tyBackspaceSet ('\177'); 
< /* Begin [ROM Boot Modification] */ 
< /* 
< * The following code was added to provide parameter (such as IP 
< * addresses) changing before network initialization takes place. 
< * 
< * Much of this code was adapted (stolen) from bootConfig.c and 
< * behaves similar to when booting over the network by providing 
< * a countdown timer that the user can stop by pressing any key. 
< * If he stops the process he will be given a chance to change 
< * the boot parameters which will then be saved in NVRAM and used 
< * for future initializations. If he doesn't stop the process, the 
< * old parameters will be use to initialize the network facilities. 
< */ 
< /* First let him see the current parameters */ 
< bootParamsShow (BOOT_LINE_ADRS); 
< /* perform countdown to let op change boot params if he wants */ 
< { 
< int timeout = 7; /* timeout time in seconds */ 
< ULONG autoBootTime; 
< int timeLeft; 
< UINT timeMarker; 
< int bytesRead = 0; 
< printf ("\nPress any key to stop auto-boot...\n"); 
< /* take console out of line mode */ 
< (void) ioctl (consoleFd, FIOSETOPTIONS, 
< /* Loop looking for a char, or timeout after specified seconds */ 
< autoBootTime = tickGet () + sysClkRateGet () * timeout; 
< timeMarker = tickGet () + sysClkRateGet (); 
< timeLeft = timeout; 
< printf ("%2d\r", timeLeft); 
< while ((tickGet () < autoBootTime) && (bytesRead == 0)) { 
< (void) ioctl (consoleFd, FIONREAD, (int) &bytesRead); 
< if (tickGet () == timeMarker) { 
< timeMarker = tickGet () + sysClkRateGet (); 
< printf ("%2d\r", --timeLeft); 
< } 
< } 
< /* flush standard input to get rid of any garbage */ 
< (void) ioctl (STD_IN, FIOFLUSH, 0 /*XXX*/); 
< /* 
< * Put the console back in line mode so it echoes (so's you 
< * can bang on it to see if it's still alive) 
< */ 
< (void) ioctl (consoleFd, FIOSETOPTIONS, OPT_TERMINAL); 
< if (bytesRead > 0) { /* he wants to make changes */ 
< /* change boot params */ 
< bootParamsPrompt (BOOT_LINE_ADRS); 
< /* set NVRAM with the new parameters */ 
< (void) sysNvRamSet (BOOT_LINE_ADRS, strlen (BOOT_LINE_ADRS) + 1, 0); 
< } 
< } /* end (perform countdown) */ 
< /* We should now be ready to initialize the network stuff. */ 
< /* end [ROM Boot Modification] */ 
< /* Begin [ROM Boot Modification] */ 
< /* 
< * DO_TELL is a macro to echo a command to the console, execute it and 
< * print the info if an error is returned. 
< * An example of how it works: 
< * DO_TELL (netDevCreate("magnolia:","magnolia",0)); 
< * might return: 
< * netDevCreate("magnolia:","magnolia",0) 
< * DO_ECHO does is similar except that it doesn't check and report 
< * errors - it is used where a command returns a void. 
< */ 
< #define DO_TELL(cmd) printf (" -> "); \ 
< printf (#cmd); \ 
< printf ("\n"); \ 
< if((cmd)==ERROR) { perror (" -- ERROR "); } 
< #define DO_ECHO(cmd) printf (" -> "); \ 
< printf (#cmd); \ 
< printf ("\n"); \ 
< cmd; 
< /* End [ROM Boot Modification] */ 
< /* Begin [ROM Boot Modification] */ 
< else { /* use built-in startup info */ 
< /* 
< * If the boot parameter 'startupScript' field is left blank the 
< * following built-in startup script will execute. These commands 
< * will be executed many times faster than if we had to FTP a 
< * startup scipt from over the net (we're talking from dozens of 
< * seconds to less than one second). Since the whole idea of ROM 
< * boot is speed by not having to wait on network transfers, it makes 
< * sense to apply it to the startup script as well. 
< * 
< * Once the NFS system is setup, file transfers become very fast since 
< * they don't have to do FTP or RSH logins anymore. For this reason 
< * a startup script with the name "/home/asg/evla/cmp/goCmp" is 
< * executed. It is executed almost instantaneously if the network is 
< * operating properly. 
< * 
< */ 
< char prompt[20]; 
< printf ("\n\n-- Executing 'Built-in' startup script ... \n"); 
< DO_TELL (iam ("vlbsoft", NULL)); 
< DO_ECHO (nfsIdSet (1041)); 
< DO_ECHO (nfsAuthUnixSet ("magnolia", 1049, 49, 0, 0)); 
< /* DO_TELL (loginUserDelete ("target", "password")); */ 
< DO_TELL (loginUserAdd ("aaa", "rrrrrrrr")); 
< /* DO_TELL (netDevCreate ("magnolia:", "magnolia", 0)); */ 
< DO_TELL (hostAdd ("filehost-gw2","")); 
< DO_TELL (routeAdd ("", "")); 
< DO_TELL (routeAdd ("", "")); 
< DO_TELL (nfsMount("magnolia","/export/home/magnolia2","/home/magnolia2")); 
< DO_TELL (nfsMount ("filehost-gw2","/home","/users")); 
< /* customize shell prompt to <host name>-> */ 
< DO_TELL (gethostname (prompt, 15)); 
< DO_ECHO (strcat (prompt, "-> ")); 
< DO_ECHO (shellPromptSet (prompt)); 
< /* go to delivery directory */ 
< DO_ECHO (cd ("/home/magnolia2/evla/icms")); 
< printf ("-- 'Built-in' startup script complete \n "); 
< printf ("\n-- Launching CMP startup script \n"); 
< usrStartupScript ("/home/magnolia2/evla/icms/goCmp"); 
< } /* end (else - execute built-in startup commands) */ 
< /* End [ROM Boot Modification] */