Skip to main content

VxWorks memDrv vs ramDrv: Key Differences and Use Cases

·1901 words·9 mins
VxWorks MemDrv RamDrv VxWorks Filesystem Embedded Systems VxWorks Boot RAM Disk NOR Flash RTOS
Table of Contents

VxWorks memDrv vs ramDrv: Key Differences and Use Cases

VxWorks provides several storage and memory-oriented device drivers that can appear similar at first glance. Two commonly confused components are INCLUDE_MEMDRV (memDrv) and INCLUDE_RAMDRV (ramDrv).

Both can expose memory-backed storage through the VxWorks I/O subsystem, but they represent fundamentally different device models.

The key distinction is:

  • memDrv exposes an absolute memory region as a pseudo-I/O device and can operate on RAM or memory-mapped Flash.
  • ramDrv emulates a block disk in RAM and is intended to be used with a VxWorks filesystem.

Understanding this distinction is particularly important when implementing boot-from-Flash mechanisms, RAM disks, filesystem-backed storage, or persistent image loading.

🧩 INCLUDE_MEMDRV: Memory as a Pseudo-I/O Device
#

The VxWorks component definition for memDrv is typically structured as follows:

Component INCLUDE_MEMDRV {
        NAME MEM disk driver
        SYNOPSIS allows a filesystem to be put on top of memory
        MODULES memDrv.o
        INIT_RTN memDrv ();
        HDR_FILES memDrv.h
}

The corresponding initialization code is commonly guarded by:

#ifdef INCLUDE_MEMDRV
memDrv ();
#endif

Internally, the device maintains information such as:

typedef struct
{
    DEV_HDR devHdr;
    MEM_DRV_DIRENTRY dir;
    off_t allowOffset;
} MEM_DEV;

The important architectural point is that memDrv integrates memory into the VxWorks I/O system as a pseudo-device.

How memDrv Works
#

Wind River describes memDrv as a mechanism for allowing the I/O system to access memory directly as a pseudo-I/O device.

The memory location and size are specified when the device is created:

STATUS memDevCreate
(
    char *name,
    char *base,
    int length
);

For example:

memDevCreate("/mem/", (char *)0xFF800000, 0x1F6FA0);

Here:

  • /mem/ is the device name.
  • 0xFF800000 is the starting address of the memory region.
  • 0x1F6FA0 specifies the accessible size.

The memory region is treated as a device that can be accessed through normal VxWorks I/O mechanisms.

This makes memDrv particularly useful when software needs to access a fixed physical or memory-mapped region without introducing a conventional block-storage layer.

💾 memDrv and NOR Flash
#

One of the most useful characteristics of memDrv is that the underlying address range does not have to be ordinary system RAM.

If NOR Flash is memory-mapped into the processor address space, it can be exposed through memDevCreate() in a similar way.

For example:

NOR Flash
    │ memory mapped
0xFF800000
memDevCreate()
/mem/
VxWorks I/O subsystem

This is particularly useful for boot-image storage.

A VxWorks image can be programmed into a known Flash address and subsequently accessed through the /mem/ device.

Example: Booting a VxWorks Image from NOR Flash
#

Assume a VxWorks image is stored at:

0xFF800000

and its size is:

0x1F6FA0

The configuration can include:

#define INCLUDE_BOOT_FILESYSTEMS
#define INCLUDE_MEMDRV

After memDrv() initialization, create the memory device:

memDevCreate("/mem/", (char *)0xFF800000, 0x1F6FA0);

The size must cover the entire image region that will be accessed. It should not be configured smaller than the actual image.

After the image has been programmed into Flash, the bootloader can access it through the memory device.

A typical VxWorks boot configuration might therefore use:

boot device          : fs
unit number          : 0
file name            : /mem/0

The bootloader can then load the image directly from the memory-backed device:

Loading /mem/0...
Starting at 0x10000...

This is one of the practical reasons memDrv is useful in systems where network-based image loading is inconvenient or unavailable.

🧱 INCLUDE_RAMDRV: A RAM-Based Block Device
#

The corresponding ramDrv component is defined as:

Component INCLUDE_RAMDRV {
        NAME RAM disk driver
        SYNOPSIS allows a filesystem to be put on top of RAM
        MODULES ramDrv.o
        INIT_RTN ramDrv ();
        HDR_FILES ramDrv.h
}

The initialization code is typically:

#ifdef INCLUDE_RAMDRV
ramDrv ();
#endif

The device structure is fundamentally different from memDrv:

typedef struct
{
    BLK_DEV ram_blkdev;
    off_t ram_blkOffset;
    char *ram_addr;
} RAM_DEV;

The presence of BLK_DEV is the important clue.

ramDrv behaves like a block storage device, rather than simply exposing a memory range as a pseudo-I/O device.

📦 How ramDrv Works
#

The primary creation API is:

BLK_DEV *ramDevCreate
(
    char *ramAddr,
    int bytesPerBlk,
    int blksPerTrack,
    int nBlocks,
    off_t blkOffset
);

For example:

BLK_DEV *pBlkDev;

pBlkDev = ramDevCreate
(
    NULL,
    512,
    32,
    416,
    0
);

The resulting BLK_DEV must then be connected to the VxWorks block-device framework.

With newer XBD-based configurations, this can be done using:

xbdBlkDevCreate(pBlkDev, "/ramDrv");

A filesystem can then be formatted on top of the resulting block device.

For example:

dosFsVolFormat("/ramDrv:0", DOS_OPT_BLANK, NULL);

The architecture becomes:

RAM
ramDrv
BLK_DEV
XBD
dosFs / hrFs / rawFs
File Operations

This layered architecture is the fundamental difference between ramDrv and memDrv.

🗂️ ramDrv Requires a Filesystem Layer
#

Unlike memDrv, ramDrv is designed to act as a disk.

Consequently, it normally works together with a filesystem such as:

  • dosFs
  • hrFs
  • rawFs

For example:

BLK_DEV *pBlkDev;

pBlkDev = ramDevCreate(NULL, 512, 32, 416, 0);

xbdBlkDevCreate(pBlkDev, "/ramDrv");

dosFsVolFormat("/ramDrv:0", DOS_OPT_BLANK, NULL);

The filesystem provides the higher-level file and directory semantics.

Without that filesystem layer, ramDrv is simply providing the block-device abstraction.

🔄 Reusing an Existing RAM Disk Image
#

ramDrv can also use a predefined memory region instead of automatically allocating memory.

For example:

pBlkDev = ramDevCreate
(
    (char *)0xC0000,
    512,
    32,
    416,
    0
);

In this configuration, the RAM region is expected to contain an existing disk image.

The block geometry must match the parameters used when the image was originally created.

If the existing filesystem can be detected, the VxWorks filesystem framework can automatically reinstantiate it.

This makes the technique useful when a RAM disk needs to persist across a reboot without being reformatted.

🧠 The Most Important Difference
#

The easiest way to remember the distinction is to look at the abstraction each driver provides.

memDrv
#

Memory Address
   memDrv
Pseudo-I/O Device
Read / Write Operations

memDrv essentially tells VxWorks:

Treat this memory range as an I/O device.

The underlying address can represent system RAM or a memory-mapped device region such as NOR Flash.

ramDrv
#

RAM
ramDrv
BLK_DEV
XBD
Filesystem
Files / Directories

ramDrv instead tells VxWorks:

Treat this RAM region as a disk.

The block-device and filesystem layers are therefore central to its design.

⚖️ memDrv vs ramDrv
#

The differences can be summarized as follows:

Feature memDrv ramDrv
Component INCLUDE_MEMDRV INCLUDE_RAMDRV
Primary abstraction Pseudo-I/O device Block device
Creation API memDevCreate() ramDevCreate()
Uses DEV_HDR Yes Indirectly through block-device infrastructure
Uses BLK_DEV No Yes
Requires filesystem No Typically yes
Designed for RAM Yes Yes
Designed for memory-mapped Flash Yes No
Typical use Direct memory access through I/O RAM disk
Files/directories Not inherently provided Provided through filesystem
Persistent storage Possible with nonvolatile memory RAM contents normally disappear on reset
Typical filesystem stack Not required XBD + dosFs / hrFs / rawFs

The distinction can therefore be reduced to one sentence:

memDrv exposes memory as an I/O device, while ramDrv emulates a disk in RAM.

🚀 Using ramDrv with hrFs
#

A practical ramDrv configuration can be used to create a RAM-backed filesystem and store a VxWorks image there.

For example, the required configuration may include:

#define INCLUDE_RAMDRV
#define INCLUDE_DISK_UTIL
#define INCLUDE_DEVICE_MANAGER
#define INCLUDE_XBD
#define INCLUDE_XBD_BLK_DEV
#define INCLUDE_XBD_PART_LIB
#define INCLUDE_FS_MONITOR
#define INCLUDE_ERF
#define INCLUDE_FS_EVENT_UTIL
#define INCLUDE_BOOT_FILESYSTEMS

#define INCLUDE_HRFS
#define INCLUDE_HRFS_FORMAT
#define INCLUDE_HRFS_CHKDSK

The exact component set depends on the VxWorks release and filesystem configuration.

Reserving RAM for the Disk
#

If the RAM disk must survive a warm reset, its memory should not simply be treated as ordinary dynamically allocated application memory.

A reserved memory region can be configured, for example:

#define USER_RESERVED_MEM 0x600000

The reserved area can then be used for the RAM disk.

Creating the RAM Disk
#

After ramDrv() initialization:

BLK_DEV *pBlkDev1;

pBlkDev1 = ramDevCreate
(
    (char *)sysMemTop(),
    512,
    6144,
    6144,
    0
);

xbdBlkDevCreateSync(pBlkDev1, "/ram");

This creates the block-device layer and exposes it through the /ram device.

After formatting and populating the filesystem, a boot configuration can point to an image stored inside the RAM disk.

For example:

boot device          : fs
unit number          : 0
file name            : /ram:0/vxWorks

The resulting boot sequence can then load the image from the RAM-backed filesystem:

Loading /ram:0/vxWorks...
Starting at 0x100000...

This is fundamentally different from the NOR Flash example using memDrv.

💡 Choosing the Correct Driver
#

The choice depends primarily on what abstraction the application needs.

Use memDrv when
#

Use memDrv when the requirement is to expose a specific memory address range through the VxWorks I/O system.

Typical scenarios include:

  • Accessing a fixed RAM region
  • Accessing memory-mapped NOR Flash
  • Sharing data through a predefined memory region
  • Preserving data between boots when backed by nonvolatile memory
  • Loading a VxWorks image from a fixed Flash address
  • Providing direct read/write access without a filesystem

For example:

memDevCreate("/mem/", (char *)0xFF800000, imageSize);

is appropriate when /mem/ represents a known memory-mapped image region.

Use ramDrv when
#

Use ramDrv when the requirement is to create a disk-like storage device in RAM.

Typical scenarios include:

  • Temporary file storage
  • RAM-backed filesystems
  • High-speed temporary data storage
  • Testing filesystem behavior without physical storage
  • Loading or preserving a filesystem image in a reserved RAM region

The architecture is then:

RAM → ramDrv → BLK_DEV → XBD → Filesystem

🔬 Practical Architecture Comparison
#

Consider two different requirements.

Scenario A: Boot image stored in NOR Flash
#

NOR Flash
Memory-Mapped Address
memDevCreate()
/mem/
VxWorks Bootloader
VxWorks Image

Here, the memory region already exists as a physical storage resource. A filesystem is not necessary merely to expose the image.

memDrv is therefore a natural fit.

Scenario B: VxWorks image stored in a RAM filesystem
#

Reserved RAM
ramDevCreate()
BLK_DEV
XBD
hrFs / dosFs
/ram:0/vxWorks
VxWorks Bootloader

Here, the application wants a disk-like filesystem containing files.

ramDrv is therefore the appropriate abstraction.

⚠️ Common Misunderstanding
#

A common mistake is to assume that both drivers are interchangeable because both ultimately operate on memory.

They are not.

The fact that ramDrv uses memory does not make it a general-purpose replacement for memDrv.

Likewise, the fact that memDrv can expose memory does not make it a complete RAM-disk implementation.

The difference is not primarily the physical storage medium. It is the software abstraction presented to the VxWorks I/O subsystem.

In simplified terms:

memDrv → "This address range is an I/O device."

ramDrv → "This RAM region is a block disk."

That distinction becomes especially important when designing the filesystem and boot architecture.

🧭 Final Takeaway
#

INCLUDE_MEMDRV and INCLUDE_RAMDRV solve different problems despite their similar names.

memDrv is a pseudo-I/O memory driver. It exposes a specified memory region through VxWorks I/O interfaces and can be used with both RAM and memory-mapped Flash. It does not inherently require a filesystem.

ramDrv is a RAM-based block driver. It emulates a disk in RAM and is normally combined with the VxWorks XBD and filesystem layers such as dosFs or hrFs.

The practical distinction is:

memDrv
  ├─ RAM
  ├─ Memory-mapped Flash
  ├─ Direct memory-region access
  └─ No filesystem required

ramDrv
  ├─ RAM only
  ├─ Block-device abstraction
  ├─ XBD integration
  └─ Filesystem such as dosFs / hrFs / rawFs

For booting an image directly from a fixed NOR Flash address, memDrv is the more appropriate mechanism.

For creating a filesystem-backed RAM disk, ramDrv is the appropriate choice.

Once this abstraction difference is understood, the roles of memDevCreate() and ramDevCreate() become much clearer, and selecting the correct VxWorks storage architecture becomes considerably easier.

Related

QNX vs VxWorks: Key Differences for Real-Time Systems
·500 words·3 mins
VxWorks QNX RTOS Embedded Systems
Deploying Containers in a VxWorks Environment: A Practical Guide
·732 words·4 mins
VxWorks Containers RTOS Embedded Systems DevOps
Writing VxWorks Device Drivers: Architecture, DMA, ISR, and Porting
·1826 words·9 mins
VxWorks Device Drivers RTOS Embedded Systems DMA Interrupts VME PCI Driver Development