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:
memDrvexposes an absolute memory region as a pseudo-I/O device and can operate on RAM or memory-mapped Flash.ramDrvemulates 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.0xFF800000is the starting address of the memory region.0x1F6FA0specifies 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:
dosFshrFsrawFs
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.