Notes for installing Tornado 2.0.2

Written by Zach Pfeffer

 

Keywords

 

VxWorks, Etherlink III, network boot, Tornado 2.0.2, 3Com, Etherlink III 3c509 based ISA Ethernet card, target server, WTX Error 0x100de (AGENT_COMMUNICATION_ERROR), PCI_CONFIG, pci

 

 

Installation

 

Install the Tornado 2.0.2 development environment.

 

Please consult ‘C:\Tornado\docs\vxworks\bsp\pcPentium\pc.html’ for Pentium specific issues (questions such as, “which Ethernet card will work?”)

 

This tutorial relies heavily on client host communication over an Ethernet. Please disable any Firewalls running on the host. After everything works go back and punch specific holes for VxWorks to communicate through.

 

Copy C:\Tornado\target\config\pcPentium to C:\Tornado\target\config\pcPentium_orig This will be a backup tree. Should the instructions prove inadequate, simply copy the ‘orig’ copy back and start over.

 

 

Configuring the Ethernet Device

 

The following instructions will bring up a Pentium board with an Etherlink III 3c509 based ISA Ethernet card. The card’s device name is ‘elt’. Do a search in ‘C:\Tornado\target\config\pcPentium’ for ‘elt’. The hope is to support other cards in further revisions of this document.

 

Google 3C5X9CFG.EXE and download it. It’s a DOS configuration utility. Make a DOS boot floppy and copy 3C5X9CFG.EXE to it. Try’ ftp://ftp.epson.it/pub/it/pc/5x9diag.zip’ for the download.

 

In configuration set the I/O Base Address to 300h and the interrupt level to 5.

 

These may conflict. When you press OK the computer will prompt you to choose another IRQ, I/O Base Address or both. Find two that don’t conflict. Remember these values because you’ll use them in a later configuration step.

 

Boot the target into the BIOS configuration screen. You may have to do this step before running the configuration program.

 

In the BIOS enter the PnP/PCI screen. You need to set the IRQ line used by the Ethernet device to “Legacy” or equivalent. Doing this tells the BIOS that it can’t use this IRQ when it’s assigning IRQ’s, I/O space and memory to its PCI devices. If you have the option, set the I/O memory used by the device to “Legacy” or its equivalent.

 

Reboot again and run 3C5X9CFG.EXE.

 

Download 3C5x9cfg.exe

 

Building the Boot ROM (Boot Floppy)

 

Run ‘ipconfig /all’ on the host machine and note the Host name and the IP Address.

 

The first thing to do is update some files in the tree.

 

Open C:\Tornado\target\config\pcPentium\sysLib.c.

 

Change:

 

STATUS sysIntEnablePIC

    (

    int irqNo                   /* IRQ(PIC) or INTIN(APIC) number to enable */

    )

    {

 

#if        defined(VIRTUAL_WIRE_MODE)

    return (i8259IntEnable (irqNo));

#elif      defined(SYMMETRIC_IO_MODE)

    return (ioApicIntEnable (irqNo));

#else

    return (i8259IntEnable (irqNo));

#endif   /* defined(VIRTUAL_WIRE_MODE) */

    }

 

To:

 

STATUS sysIntEnablePIC

    (

    int irqNo                   /* IRQ(PIC) or INTIN(APIC) number to enable */

    )

    {

 

#if        defined(VIRTUAL_WIRE_MODE)

    return (i8259IntEnable (irqNo));

#elif      defined(SYMMETRIC_IO_MODE)

    return (ioApicIntEnable (irqNo));

#else

    return (i8259IntEnable (irqNo));

#endif   /* defined(VIRTUAL_WIRE_MODE) */

    }

 

STATUS sysIntEnable

    (

    int irqNo                   /* IRQ(PIC) or INTIN(APIC) number to enable */

    )

    {

 

#if        defined(VIRTUAL_WIRE_MODE)

    return (i8259IntEnable (irqNo));

#elif      defined(SYMMETRIC_IO_MODE)

    return (ioApicIntEnable (irqNo));

#else

    return (i8259IntEnable (irqNo));

#endif   /* defined(VIRTUAL_WIRE_MODE) */

    }

 

Open C:\Tornado\target\config\pcPentium\config.h.

 

Change:

 

#elif      (CPU_VARIANT == PENTIUM)

#define DEFAULT_BOOT_LINE \

            "fd=0,0(0,0)host:/fd0/vxWorks.st h=90.0.0.3 e=90.0.0.50 u=target"

 

To:

 

#elif      (CPU_VARIANT == PENTIUM)

#define DEFAULT_BOOT_LINE \

                        "elt(0,0) oracle:vxWorks h=128.138.244.15 \

e=128.138.244.27:0xFFFFFFC0 u=target pw=target g=128.138.129.12"

 

In this statement, ‘h’ is the host’s IP, ‘e’ is the target’s IP, ‘u’ is the ftp user name, ‘pw’ is the ftp password and g is an optional gateway. There is a ‘gotcha’ here. If you don’t supply a user name a password, VxWorks will attempt to use RSH instead of FTP to get its image (done in a later step), so make sure both are present. You’ll use IP addresses appropriate to your circumstance.

 

See C:\Tornado\docs\vxworks\netguide\c-booting.html or C:\Tornado\docs\tornado\winguide\c-start5.html for more info on the ‘boot line’

 

Change:

 

#   ifdef INCLUDE_ELT

#          undef INCLUDE_ELT /* don't use BSD driver */

#          define INCLUDE_ELT_3C509_END /* Use END driver instead */

#   endif

 

To:

 

#ifdef INCLUDE_ELT

#undef INCLUDE_ELT           /* don't use BSD driver */

#define INCLUDE_ELT_3C509_END /* Use END driver instead */

#endif

 

Change:

 

#define IO_ADRS_ELT           0x240

#define INT_LVL_ELT            0x0b

#define NRF_ELT                    0x00

#define CONFIG_ELT            0          /* 0=EEPROM 1=AUI  2=BNC  3=RJ45 */

 

To:

 

#define IO_ADRS_ELT           0x300

#define INT_LVL_ELT            0x05

#define NRF_ELT                    0x00

#define CONFIG_ELT            3          /* 0=EEPROM 1=AUI  2=BNC  3=RJ45 */

 

Or whatever didn’t conflict when you set these using 3Com’s utility program.

 

Change:

 

#undef  INCLUDE_ELT                      /* include 3COM EtherLink III interface */

#undef  INCLUDE_ESMC                  /* include SMC 91c9x Ethernet interface */

#define INCLUDE_FEI                       /* include Intel Ether Express PRO100B PCI */

 

To:

 

#define INCLUDE_ELT                      /* include 3COM EtherLink III interface */

#undef  INCLUDE_ESMC                  /* include SMC 91c9x Ethernet interface */

#undef  INCLUDE_FEI                       /* include Intel Ether Express PRO100B PCI */

 

Next, Select Build -> Build Boot ROM. Select pcPentium under ‘Select a BSP:’ Select bootrom_uncmp under ‘Select an Image to build:’. Click OK

 

Get a disk.

 

Open a cygwin term and ‘cd C:/Tornado/host/x86-win32/bin/

 

Run ‘./mkboot.bat a: C:/Tornado/target/config/pcPentium/bootrom_uncmp’

 

After it finishes insert the floppy in the target and reboot the target. You should see a blue VxWorks screen and the following lines at the bottom of the screen:

 

Attached TCP/IP interface to elt0.

Attaching network interface lo0… done.

Loading…

 

The target will either hang or time out to a prompt at this point.

 

You have just built a bootrom. The next step is to build a VxWorks kernel.

 

 

Building the VxWorks Kernel

 

To build a basic VxWorks kernel, using Tornado 2.0.2, open a new project from the ‘File’ menu. Click ‘Create a bootable VxWorks image (custom configured). Save your project in a location other than under the Tornado tree. Rename the wsp file to correspond with the project’s name. Click ‘Next.’ Base the project on an existing BSP, the ‘pcPentium’, and click next. Click ‘Finish’.

 

You must configure the Ethernet card again. Select the VxWorks tab in the Workspace window. Expand ‘network components’, then ‘network devices’, then ‘BSD Ethernet drivers’ and click on ‘ELT netif driver’. Click the ‘Params’ tab and change CONFIG_ELT, INT_LVL_ELT and IO_ADRS_ELT to the same values used in the previous steps. Right click on ELT netif drivers and select ‘Include ELT netif driver …’ and click ‘OK’.

 

Next expand ‘development tool components’ then expand ‘WDB agent components’, then expand ‘select WDB connection’. Right click and include ‘WDB network connection’. All the other options under ‘select WDB connection’ should be excluded. Expand ‘select WDB mode’ and include ‘WDB task debugging’; exclude ‘WDB system debugging’ if it’s selected.

 

It’s useful to have a shell as well. Right click ‘target shell components’ and click ‘include …’. There are words after ‘include’ but they’ve been removed for brevity. This practice is done through out the document. A window will pop up. Make sure the top three items are checked and click through the OKs.

 

Also include all the show routines. Under ‘development tool components’ right click ‘show routines’. Click ‘include…’ and check each box except ‘ata show routine’ and ‘pci show routine’. Click through the error and expand from the top level (they’ll all be highlighted in red) ‘hardware’, ‘memory’, ‘MMU’, and ‘MMU Mode’. Exclude basic MMU support by right clicking on it.

 

After this under ‘development tool components’ right click ‘symbol table components’ and click ‘include…’, checking each component in the list that pops up. Click ‘symbol table initialization components’ then ‘select symbol table initialization’ and exclude ‘downloaded symbol table’. Including the symbol table makes the image very large, but not having it is a pain when trying to debug problems.

 

For Windview debugging using real time marks instead of ticks expand ‘development tool components’ then expand ‘Windview components’ expand ‘select timestamping’ and right click include ‘system-defined timestamping.’ Exclude ‘sequential timestamping.’ In addition expand ‘network components’, ‘basic network initialization components’, ‘bootline processing components’ and exclude ‘DHCP client timestamp setup.’ 

 

In these steps you may have noticed that Tornado highlights incompatible selections in red. To find out more about a specific incompatibility, right click on the deepest red link in the tree and select properties. A brief note will tell you what’s wrong.

 

Notice in these steps that a designer can add and delete things from the VxWorks image they want to run. We’ll play with this more in a later tutorial.

 

Select Build -> Build from the menu. You’ve just built VxWorks. Now the ftp server and the task debugger have to be started.

 

 

Configuring and Starting the FTP Server

 

To start the FTP server go to Start -> All Programs -> Tornado 2 -> FTP Server. Click Security -> Users/rights. Click ‘New User’ and name the user ‘target’. Set the password to ‘target’. Make sure user ‘target’ is selected and paste the absolute path to ‘vxWorks’ under the directory you created for the project (its typically under the directory ‘default’) into the ‘Home Directory:’ space. My path is ‘‘C:\pfefferz\vxworks\labbench\default’ for instance. There is a major ‘gotcha’ here. Make sure there’s isn’t a ‘\’ at the end of the path. If its there the download will fail. So if my path to my image is C:\vxworks\target\vxWorks I would enter, ‘C:\vxworks\target’ in the field. Click Done. Click Logging -> Log Options, and check every box except ‘Winsock Calls’. Reset the target and watch the FTP dialog screen to ensure that the file gets downloaded. Use Ethereal to debug. Remember the boot line needs both a user name and password to make an FTP request.

 

At this point the terminal hooked up to the target will be displaying the VxWorks logo. Type ‘i’. This will list the currently running task. For more information on these tasks please see file:///C:/Tornado/docs/vxworks/guide/c-basic3.html#84899

 

 

Setting up the Target Server

 

The only remaining task to complete is starting a target server so that the host and target can talk to each other (opening command line windows, windview, etc…). Open Tools -> Target Server -> Configure… Click ‘New’. At the ‘Target Server Properties’ drop down box select ‘Back End’. Under ‘Available Back Ends’ select ‘wdbrpc’. Go back to the ‘Target Server Properties’ drop down box and select ‘Core File and Symbols’. Click the radio button next to ‘File’ and enter in the path to the VxWorks file you built. This file will be located in the place you saved the workspace. For instance, ‘C:\pfefferz\vxworks\labbench\default\vxWorks’ is where my VxWorks file lives. Click the radio button next to ‘All Symbols’. Return to ‘Target Server Properties’ and select ‘Target Server File System’. Check ‘Enable File System’. Copy a directory into the Root. I used ‘C:\pfefferz\vxworks\labbench\default\target’. The directory ‘target’ is a normal directory I want to use so the target can read and write to a file. Finally. click the Read/Write radio button. Leave everything else. Enter the targets IP address in the ‘Target Name/IP Address’ field. Click ‘Launch’.

 

That’s it. If everything worked great, if not I need to add to this tutorial.

 

 

Adding Support For PCI

 

If you need to access the PCI library code you need to make a change to C:\Tornado\target\config\pcPentium. Add the following lines to the end of the file:

 

#define INCLUDE_PCI

 

#ifndef INCLUDE_PCI

#define INCLUDE_PCI

#endif

 

You need to rebuild the bootrom and the kernel.

 

 

Solving the Insidious WTX Error 0x100de (AGENT_COMMUNICATION_ERROR)

 

This error sucks. If you’ve installed a VPN client (like the University of Colorado’s VPN client) you have had your MTU changed. MTU or maximum transfer unit is usually set to 1500 for Ethernet, but the VPN client changes this for the whole system to 1300 or what ever it says in your registry. Fortunately you should be able to reset this to 1500 using the VPN’s software.  

 

 

Concerning the ‘Loading…’ Timeout

 

I’ve finally figured this one out, sort of. In essence everything is working, but due to the I/O address and IRQ level chosen for the ISA 3Com card the thing just hangs (even if the system says there isn’t a conflict). One solution, which sucks, is to keep choosing a different I/O address and IRQ level that doesn’t conflict and allows the loading to progress.

 

How I came to this conclusion:

 

Searched the source tree for the string “Loading…”

 

Found the printf in C:\Tornado\target\config\all\bootConfig.c

 

Found that the next function that gets called is ftpXfer()

 

Looked up this function, which is only distributed in binary, and found a description of the steps it takes to perform the ftp transaction.

 

The first step was to establish the ftp connection and the second step was to log into the server.

 

Since the ftp log was empty, I surmised that the connection never got made.

 

I had already turned off the firewall for my Windows box. I had also seen the arp requests using Ethereal.

 

I therefore concluded that the driver was having some sort of problem. I changed the I/O address to 280h and the IRQ to 10 and everything worked.

 

 

Something else to check

 

Make sure that you’re using numbers of the right base when you’re configuring config.h and the vxworks image. For instance, if the IRQ request level is 10 don’t use 0x10; which is actually 16!

 

 

Changing PCI Memory Mapped Areas and Accessing them from the CPU

 

In addition to the configuration space registers, PCI cards implement decoders that will respond to IO and memory accesses. Many programmers know what memory is and how to read it, but they don’t “know” what memory is, let me explain:

 

int x;

x = 1;

x = x + 2;

 

Here’s a simple piece of code. The compiler allocates (associates a piece of memory with) the variable x. This piece of memory has an address, but C programmers never really care what this address is, they just take it for granted that it exists. In the next line a write of ‘1’ to x occurs. Stop and think about this for a second, the CPU performs a write on the memory bus to the address represented by x. The value written is ‘1’. In the next line x gets read and then written. Again, the CPU performs a read on the bus and then, having updated the value of ‘x’ performs a write transaction on the bus back to ‘x’. Programmers don’t care about where this value x actually gets written, but driver writers do.

 

Suppose that x is given a specific address

 

  int *x;

  int y;

  x = 0x8000000;

  y = *x;

  printf("Value read from 0x%x is: 0x%x \n", x, y);

 

In this example y will get the value stored at 0x8000000. The astute reader will see an apparent error: there is no actual variable with its storage at 0x8000000; dereference of x should fail. This is indeed the case except when a device is configured to respond to accesses from a specific address, enter memory mapped IO.

 

In memory mapped IO memory decoders beside the main memory decoder for RAM logically sit on the same bus as the RAM decoder, i.e. they see the same reads and writes come across the bus. If the address for reading or writing falls within the range of a memory decoder on the memory bus, it will respond with the value to be read or write the value to be written, just like RAM. These extra memory decoders are 1/3rd of the story, how read and write transactions get onto the bus is another 1/3rd.

 

Most processors contain a memory management unit (MMU). MMU’s are devices that help kernels manage memory. These MMU’s are great in mid to large scale systems with complex memory needs, but they tend to get in the way in small systems where virtual memory addresses are usually equivalent to actual addresses. If the MMU is not programmed, the address will not be output on the bus and in the case of the x86 an exception is generated reminding you of that fact (exception 14, page fault). Fortunately, VxWorks provides an architecturally independent way of programming the MMU. Assuming the user is using the pcPentium BSP the file that must be updated is located at C:\Tornado\target\config\pcPentium\syslib.c. This file contains an array of PHYS_MEM_DESC structs named sysPhysMemDesc. For each decoder a PCI device implements an entry must be placed in the struct. Using a monkey-see-monkey-do approach (also known as an engineering approach) the user locates the string DUMMY_MMU_ENTRY for each entry and replaces it with something like this:

 

    {

    (void *) 0x8000000,

    (void *) 0x8000000,

    0x1000,      

    VM_STATE_MASK_FOR_ALL,

    VM_STATE_FOR_PCI

    }

 

This struct is documented very poorly (Tornado documents this struct at docs\vxworks\guide\c-vm3.html). Here’s the break down: The first value is the base of the virtual address space. This address corresponds with the addresses the C programmer programs to. The second value is the base of the actual address space the base of the virtual address space maps to. It does not have to be the same, but in small embedded systems it typically is. The third entry is the length of the decodable space IN BYTES. This is typically in given in pages in architecturally specific MMU code, but Windriver uses bytes to support architectures that have configurable MMU page sizes. The next two entry’s refer to Page States. The first state is a mask of all the bits that can be changed; the second entry is the mask for the initial page attributes. These attributes are:

 

Valid/Invalid

Writable/Write Protected

Cacheable/Not-Cacheable

 

These attributes are defined in config.h (BSP specfic)

 

VM_STATE_MASK_FOR_ALL is defined as

 

#define VM_STATE_MASK_FOR_ALL \

VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | \

VM_STATE_MASK_CACHEABLE | VM_STATE_MASK_WBACK | VM_STATE_MASK_GLOBAL

 

#define VM_STATE_FOR_PCI \

VM_STATE_VALID | VM_STATE_WRITABLE | \

VM_STATE_CACHEABLE_NOT | VM_STATE_WBACK_NOT | VM_STATE_GLOBAL_NOT

 

The last 1/3rd of the PCI memory mapped story answers the question, how do you find out how big the decodable address space for a PCI device is and how do you program it? Each PCI device has a configuration space that you can read and write with IO transactions. This is all encapsulated by Windriver into their pci library of functions. A PCI device contains 6 base address registers (BAR). Each BAR is a separate decoder. To find out how much decodable space a PCI device needs for each decodable space, the user writes 32 bits of 1’s to the register and reads it back. When a specific BAR register comes back with a value of all zeros, it means that the particular BAR doesn’t implement at decodable space. A non zero value means that a decodable space does exist. The return value tells the user:

 

Is the Base Address Register Implemented?

Memory or IO decodable space?

If it’s a memory decoder is it a 32-bit or 64-bit BAR?

If its memory is the memory Prefetchable or non-Prefetchable?

How much space and with what alignment?

 

 All these can be looked up, but the important thing is how to tell how much memory is decoded. Not counting the first 3 bits [2:0] the user looks for the first bit that’s a 1. Taking 2^(bit position of first 1) gives the size of the decodable space.

 

 

 

 

For more information regarding starting and configuring a target server under Windows, reference file:///C:/Tornado/docs/tornado/winguide/c-tools2.html#84049

 

Please email me at pfefferz@colorado.edu with any questions.

 

© 08 23 2004 Zach Pfeffer