01403 784500 sales@harmonicss.co.uk

1 Introduction

VxWorks is a Real Time Operating System built by Wind River, and U-Boot is a boot loader, known as the Universal Boot
Loader. This is the first bit of code that runs when an embedded system is powered on. U-Boot is typically used for
Embedded Systems, such as PowerPC or ARM devices, where there is no X86 BIOS.

Although VxWorks can have its’ own bootloader (the VxWorks Bootrom or Bootapp), U-Boot tends to be much more feature
rich, and if it is already supplied with the board, it makes much more sense to make use of it.

U-boot : http://www.denx.de/wiki/U-Boot/WebHome

VxWorks : https://www.windriver.com/products/vxworks/

Now, recent versions of VxWorks (that is VxWorks-7) have made the VxWorks / U-Boot integration alot easier than for past
VxWorks versions (ugh – the problems I had with VxWorks 6.9).

This blog details the setup that we used for a recent VxWorks-7 BSP. We elected to use the option to have a seperate DTB
file from the VxWorks image, as opposed to having the DTB file embedded within the VxWorks Image. This gives greater
flexibility, as the bootline can be changed from U-Boot, rather than having to rebuild the DTB to do this.

Specifically, the VxWorks image needs to be built to embed a U-Boot header, and then U-Boot needs to be configured to
pass the bootline, and the MAC addresses through to VxWorks.

2 Build VxWorks Image

A U-Boot specific VxWorks image needs to be built (this will add a U-Boot header to the VxWorks binary).

Build the uVxWorks target from Workbench or from the command line:

Open a DOS shell, configure the build environment and then build the project.

cd <WIND_HOME>              // your installation directory
wrenv -p vxworks-7
cd <YOUR_VIP>               // your VxWorks Image Project
vxprj vip build uVxWorks

This will create two files that will be uploaded by U-Boot using tftp:

uVxWorks VxWorks image with U-Boot header
<yourboard>.dtb the device tree binary

3 Configure U-Boot for VxWorks

U-Boot needs some environment variables setting up to load VxWorks, the bootargs
(bootline) for VxWorks:

=> setenv bootargs memac(2,0)host:vxWorks h=192.168.1.101 e=192.168.1.50:ffffff00 
        g=192.168.1.254 u=vxworks pw=harmonic f=0x0

=> saveenv

=> printenv bootargs
   bootargs=memac(2,0)host:vxWorks h=192.168.1.101 e=192.168.1.50:ffffff00
        g=192.168.1.254 u=vxworks pw=harmonic f=0x0

And optionally, to change the MAC addresses for the Ethernet Devices:

setenv ethaddr 00:00:13:3a:ad:00
setenv eth1add 00:00:13:3a:ad:01
setenv eth1add 00:00:13:3a:ad:02
setenv eth1add 00:00:13:3a:ad:03
saveenv

4 Loading and Executing the VxWorks Image

Configure a tftp server to load the VxWorks Image and the DTB file.

You can download an excellent Windows TFTP server from here: http://tftpd32.jounin.net/

4.1 Load the VxWorks Image

=> tftp 0x100000 uVxWorks
Using FM1@DTSEC3 device
TFTP from server 192.168.1.101; our IP address is 192.168.1.50
Filename 'uVxWorks'.
Load address: 0x100000
Loading: #################################################################
         #################################################################
         #################################################################

         1.5 MiB/s
done
Bytes transferred = 2861632 (2baa40 hex)

4.2 Load the dtb blob

=> tftp 0xe00000 t4240qds.dtb
Using FM1@DTSEC3 device
TFTP from server 192.168.1.101; our IP address is 192.168.1.50
Filename 't4240qds.dtb'.
Load address: 0xe00000
Loading: ##
         1.4 MiB/s

4.3 Boot the VxWorks Image

=> bootm 0x100000 - 0xe00000
WARNING: adjusting available memory to 30000000
## Booting kernel from Legacy Image at 00100000 ...
   Image Name:   vxWorks
   Image Type:   PowerPC VxWorks Kernel Image (uncompressed)
   Data Size:    2861568 Bytes = 2.7 MiB

4.4 Create U-boot Command

To create a new U-Boot command to run the above steps:

setenv vxboot 'tftp 0x100000 uVxWorks; tftp 0xe00000 t4240qds.dtb; bootm 0x100000 - 0xe00000'
saveenv

To run the command:

run vxboot

5 Configuring U-Boot To Pass The MAC Addresses Through

This is crutial for any hardware developer. The MAC addresses are assigned in the factory, and these need to be re used
in the VxWorks image. Otherwise each board shipped will need to have a seperate VxWorks image built and loaded – an
absolute nightmare scenario.

Luckily we figured out how to do this. Because we are using a seperate dtb file, as opposed to dtb file built into
VxWorks, U-Boot will overwrite the MAC address in the dts file, with the MAC address in the ethaddr environment
variable.

Not only is U-Boot able to overwrite the local-mac-address property, but if you store additional ethaddr variables in
the U-Boot environment and add aliases to your devicetree for your ethernet interfaces, U-Boot can pass those MAC
addresses via the devicetree into VxWorks. So all MAC addresses for all Ethernet devices can be overwritten.

For Example from a T4240 PowerPC Board:

/*
 * U-boot only fixes up MAC Adrress (ethernet0 - n) if <ethaddr, eth1addr, ..> 
 * environment variable is set.
 * aliases simplyfies the path to the property i.e <ethernet0> by using a 
 * label <&enet0> to assign a path to a particular node
 */

aliases{
     ethernet0 = &enet0; 
     ethernet1 = &enet1;
     ethernet2 = &enet2;
     ethernet3 = &enet3;
};

....

    fman0: fman@400000 {
          #address-cells = <1>;
            #size-cells = <1>;
            cell-index = <0>;
            compatible = "fsl,fman";
            ranges = <0 0x400000 0x100000>;
            reg = <0x400000 0x100000>;
            interrupts = <
                    96 2 0 0
                    16 2 1 1>;

        clocks = <&hwac1>;
        clock-names = "fman0-clk";

        /* FDT dummyMdio driver : memac0*/
        enet0: ethernet@e0000 {
                 compatible = "fsl,fman-memac";
                 reg = <0xe0000 0x1000>;
                 phy-handle = <&dummy_phy0>;
                 phy-connection-type = "sgmii";
                 cell-index = <0>;
                 local-mac-address = [ 00 04 9F 03 0A 5C ];
                };

        /* FDT dummyMdio driver : memac1*/
        enet1: ethernet@e2000 {
                ....
                };
        ....
        };