Introduction #
Asymmetric Multi-Processing (AMP) allows a multi-core system to run multiple independent operating systems (OSs) concurrently. In this model, each CPU has its own private memory region containing its OS and applications, although shared memory regions can also be used for inter-CPU communication. This is in contrast to Symmetric Multi-Processing (SMP), where a single OS spans multiple CPUs using a common memory space.
This guide is based on work with the Freescale P4080, an 8-core processor in the PowerPC family. The P4080 is a powerful and complex chip—with documentation exceeding 3500 pages.
The diagram below (not shown here) represents a typical AMP system. CPU0 boots first, and the wrload
utility is used to load VxWorks images into the memory regions of the remaining CPUs. Typically, CPU0 is allocated more memory than the others.
We focus here on unsupervised AMP. (Supervised AMP using a hypervisor is outside the scope of this article.)
Why Use AMP? #
AMP is especially useful for:
- Modular application design: e.g., separating control plane and data plane tasks in a router.
- Enhanced security: isolating secure applications and I/O to specific CPUs via the MMU.
- Mixed OS environments: each CPU can run a different OS instance, such as a mix of Linux and VxWorks.
- Legacy system consolidation: old applications from separate boards can be ported individually to CPUs in a single multi-core board. Existing Ethernet-based connections can be preserved using MIPC Network Devices (MND), avoiding codebase mergers.
Building AMP Images in VxWorks #
There are two options:
- Workbench GUI (tedious for 8 CPUs)
- Command-line Makefile (recommended)
Here’s a sample Makefile for the Vadatech AMC718 board (Freescale P4080):
###############################################################################
#
# makefile for AMC718 AMP builds
#
# Kontronn
#
# https://www.kontronn.com
#
# This makefile demonstrates how to build an AMP system for the
# Kontronn AMC718 board. This board uses an 8 core Freescale P4080 Chip
#
# From a vxWorks development shell, type make amp. VxWorks images will be copied
# into FTP_DIR
#
# for Windows hosts, fix slashes
WIND_HOME := $(subst \,/,$(WIND_HOME))
WIND_BASE := $(subst \,/,$(WIND_BASE))
WIND_USR := $(subst \,/,$(WIND_USR))
TOOL = gnu
# all vxWorks images will get copied here for pickup
FTP_DIR = C:/temp/incoming
AMP0_DIR = amc718_gnu_amp0
AMP0_PROJ = $(AMP0_DIR)/$(AMP0_DIR).wpj
AMP1_DIR = amc718_gnu_amp1
AMP1_PROJ = $(AMP1_DIR)/$(AMP1_DIR).wpj
AMP2_DIR = amc718_gnu_amp2
AMP2_PROJ = $(AMP2_DIR)/$(AMP2_DIR).wpj
AMP3_DIR = amc718_gnu_amp3
AMP3_PROJ = $(AMP3_DIR)/$(AMP3_DIR).wpj
AMP4_DIR = amc718_gnu_amp4
AMP4_PROJ = $(AMP4_DIR)/$(AMP4_DIR).wpj
AMP5_DIR = amc718_gnu_amp5
AMP5_PROJ = $(AMP5_DIR)/$(AMP5_DIR).wpj
AMP6_DIR = amc718_gnu_amp6
AMP6_PROJ = $(AMP6_DIR)/$(AMP6_DIR).wpj
AMP7_DIR = amc718_gnu_amp7
AMP7_PROJ = $(AMP7_DIR)/$(AMP7_DIR).wpj
amp: amp0 amp1 amp2 amp3 amp4 amp5 amp6 amp7
amp0:
vxprj create -force $(BSP) $(TOOL) $(AMP0_PROJ)
vxprj bundle add $(AMP0_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP0_PROJ) BUNDLE_AMP_PRI
vxprj component add $(BSP_PROJ) INCLUDE_PCI_BUS
vxprj build $(AMP0_PROJ)
cp $(AMP0_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.0
amp1:
vxprj create -force $(BSP) $(TOOL) $(AMP1_PROJ)
vxprj bundle add $(AMP1_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP1_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP1_PROJ) INCLUDE_AMP_CPU_01
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP1_PROJ) INCLUDE_WDB_SYS
vxprj build $(AMP1_PROJ)
cp $(AMP1_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.1
amp2:
vxprj create -force $(BSP) $(TOOL) $(AMP2_PROJ)
vxprj bundle add $(AMP2_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP2_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP2_PROJ) INCLUDE_AMP_CPU_02
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP2_PROJ) INCLUDE_WDB_SYS
# remove networking. No devices
vxprj component remove $(AMP2_PROJ) INCLUDE_NETWORK
vxprj build $(AMP2_PROJ)
cp $(AMP2_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.2
amp3:
vxprj create -force $(BSP) $(TOOL) $(AMP3_PROJ)
vxprj bundle add $(AMP3_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP3_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP3_PROJ) INCLUDE_AMP_CPU_03
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP3_PROJ) INCLUDE_WDB_SYS
# remove networking. No devices
vxprj component remove $(AMP3_PROJ) INCLUDE_NETWORK
vxprj build $(AMP3_PROJ)
cp $(AMP3_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.3
amp4:
vxprj create -force $(BSP) $(TOOL) $(AMP4_PROJ)
vxprj bundle add $(AMP4_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP4_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP4_PROJ) INCLUDE_AMP_CPU_04
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP4_PROJ) INCLUDE_WDB_SYS
# remove networking. No devices.
vxprj component remove $(AMP4_PROJ) INCLUDE_NETWORK
vxprj build $(AMP4_PROJ)
cp $(AMP4_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.4
amp5:
vxprj create -force $(BSP) $(TOOL) $(AMP5_PROJ)
vxprj bundle add $(AMP5_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP5_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP5_PROJ) INCLUDE_AMP_CPU_05
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP5_PROJ) INCLUDE_WDB_SYS
# remove networking. No devices.
vxprj component remove $(AMP5_PROJ) INCLUDE_NETWORK
vxprj build $(AMP5_PROJ)
cp $(AMP5_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.5
amp6:
vxprj create -force $(BSP) $(TOOL) $(AMP6_PROJ)
vxprj bundle add $(AMP6_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP6_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP6_PROJ) INCLUDE_AMP_CPU_06
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP6_PROJ) INCLUDE_WDB_SYS
# remove networking. No devices.
vxprj component remove $(AMP6_PROJ) INCLUDE_NETWORK
vxprj build $(AMP6_PROJ)
cp $(AMP6_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.6
amp7:
vxprj create -force $(BSP) $(TOOL) $(AMP7_PROJ)
vxprj bundle add $(AMP7_PROJ) BUNDLE_STANDALONE_SHELL
vxprj bundle add $(AMP7_PROJ) BUNDLE_AMP_SEC
vxprj component add $(AMP7_PROJ) INCLUDE_AMP_CPU_07
# need to remove INCLUDE_WDB_SYS, incompatible with AMP
vxprj component remove $(AMP7_PROJ) INCLUDE_WDB_SYS
# remove networking. No devices.
vxprj component remove $(AMP7_PROJ) INCLUDE_NETWORK
vxprj build $(AMP7_PROJ)
cp $(AMP7_DIR)/default/vxWorks $(FTP_DIR)/vxWorks.7
This Makefile automates the creation and building of separate VxWorks images for each CPU, reducing manual effort and ensuring consistent configuration.
Using wrload
to Launch Images
#
wrload
runs on CPU0’s VxWorks shell. It loads the VxWorks image for each target CPU from the mounted filesystem, initializes memory, and sets up the .bss
segment. Be aware:
- Insert
taskDelay()
betweenwrload
calls to avoid timing issues. - Provide a valid bootline using
-tsym
or boot may fail.
Example:
wrload ("-file host:/vxWorks.1 -cpu 1 -tsym \"*sysBootLine=dtsec(1,1) host:/vxWorks.1 h=192.168.1.100 e=192.168.1.51\"");
taskDelay (60);
wrload ("-file host:/vxWorks.2 -cpu 2 -tsym \"*sysBootLine=dtsec(2,2)\"");
taskDelay (60);
Using tip
to Access Shells on Other CPUs
#
When physical serial connections are unavailable, tip
connects to other CPUs via MIPC Serial Devices (MSDs). The BSP auto-generates /ttyMsdX
entries.
Example output from devs
:
-> devs
drv name
0 /null
1 /tyCo/0
1 /ttyMsd0
1 /ttyMsd1
...
To open a shell on CPUs 1 and 2:
tip ("dev=/ttyMsd0", "dev=/ttyMsd1")
~?
# Available commands:
# ~.: Exit
# ~l: List sessions
# ~s: Switch session
# ~?: Help
Conclusion #
This article introduced key concepts and setup procedures for running AMP systems using VxWorks 6.9. If you need help configuring multiprocessor BSPs, MIPC/MSD setup, or working with the P4080 architecture, feel free to reach out.