FreeDOS DEVLOAD: Loading DOS Device Drivers After Boot Without Guesswork
How DEVLOAD emulates DEVICE and DEVICEHIGH at runtime, assigns block devices, reports memory use, and reveals which drivers still require boot-time setup.
DOS normally initializes character and block device drivers from CONFIG.SYS before the command interpreter starts. That timing lets a driver reserve memory, hook interrupts, publish device headers, and influence later boot steps. It is also inconvenient when testing a USB storage stack or optional device would otherwise require repeated edits and reboots.
FreeDOS DEVLOAD emulates DEVICE= from the command line and can attempt a DEVICEHIGH=-style load into an Upper Memory Block. It supports character and block drivers, including COM and EXE style driver files documented by the project. Runtime loading is valuable, but it cannot reproduce every assumption a driver makes about early boot.
Establish a recoverable test environment
Before loading anything, save open files and work from a boot configuration that can be selected again after reset. Record memory and device state with the tools available on the system, and keep the driver binary plus its documentation on known-good local media.
Start in verbose mode and load low before optimizing memory:
DEVLOAD /V DRIVER.SYS parameter1 parameter2
IF ERRORLEVEL 255 GOTO LOADFAIL
Pass driver parameters after the filename exactly as that driver documents. DEVLOAD cannot validate a private option string. A driver can hang the machine before any friendly error message, so test unknown binaries in an emulator or disposable system first.
DEVICE emulation has a defined boundary
The basic form is DEVLOAD filename [params]. DEVLOAD prepares the environment a DOS device-driver initialization entry point expects, lets the driver install its device header or hooks, and retains the required resident memory when installation succeeds.
This is not equivalent to executing a normal utility. A loaded driver becomes part of DOS’s global device chain and may receive requests from every process. There is generally no universal safe unload operation. Plan on reboot as the rollback mechanism unless the specific driver provides and documents its own removal procedure.
Drivers that patch boot-only structures, expect to be first in a chain, or must precede filesystem and redirector initialization may reject runtime loading or behave incorrectly. In that case, use DEVICE= in a controlled CONFIG.SYS menu entry.
Use /H only after a low-memory load works
/H asks DEVLOAD to load into an Upper Memory Block, like DEVICEHIGH. The DEVLOAD guide explains that it falls back to low memory if it cannot find a sufficiently large UMB. A driver can also reject a block that DEVLOAD considered large enough because its own initialization needs differ.
First prove the driver works without /H. Then inspect the UMB layout, reboot to restore a clean baseline, and retry with /H /V. Compare conventional memory before and after and confirm verbose output says where the resident portion remained.
DEVLOAD /H /V USBASPI.SYS /V /W
DEVLOAD /H /V DI1000DD.SYS
These are examples from the DEVLOAD guide, not universal USB parameters. Driver order matters: a disk driver depending on an ASPI manager must load after that manager initializes successfully.
/D controls block-device letter assignment
For a block driver, /D requests the first drive letter to try. /DS, for example, asks for S: or the next available letter through LASTDRIVE. The default is equivalent to starting at C:.
Check whether the requested letter is already used by a local drive, CD-ROM extension, network redirector, RAM disk, or substitution. A successful fallback to a later letter can break a batch file that assumes the request was exact. Read the returned code and verify the resulting device table or directory access.
LASTDRIVE in CONFIG.SYS limits the range DOS prepared. DEVLOAD cannot allocate beyond that structural limit at runtime. If the desired range is unavailable, update the boot configuration deliberately rather than forcing CDS flags.
Exit status identifies the installed result
The project documents exit code 255 for an error or a driver that was not loaded. Character devices return zero on success. Block devices return 1 through 26 for the first assigned drive, where 1 is A: and 26 is Z:.
That means a nonzero result is not automatically failure. A batch file that branches on any nonzero status will misclassify every successfully loaded block device. Check 255 first, then interpret 1 through 26 according to the expected driver type.
DOS IF ERRORLEVEL comparisons are inclusive and should be written from high to low. For important installation logic, use a helper or explicit branch table and then verify the actual letter by accessing a marker or querying the relevant DOS state.
/A resolves one narrow residency question
Some drivers request to stay resident even though DEVLOAD sees no interrupt hook and no published character or block device. DEVLOAD normally asks whether to retain them. /A automatically answers yes.
Do not use /A to force an arbitrary failed driver into memory. It addresses only that residency prompt. Understand why the driver has a useful resident role that DEVLOAD cannot detect, then use /A for unattended repeatability.
If documentation does not explain the behavior, reject the load. Resident code with no visible integration point is difficult to monitor and can consume scarce conventional memory indefinitely.
Confirm the driver, not just DEVLOAD
After a successful return, exercise the smallest safe operation. For a character device, check that its name is present and use its documented query. For a block driver, list the assigned drive read-only, confirm expected geometry or files, and only then attempt a write.
Run MEM /C or an equivalent memory report to record resident usage. Check interrupt or device-chain diagnostics where available. Keep verbose DEVLOAD output with driver version, hash, parameters, DOS version, and emulator or hardware model.
A loaded USB mass-storage stack also depends on controller support, media partitioning, BIOS state, and filesystem support. DEVLOAD success proves only that its driver initialization path accepted the environment.
Promote stable drivers to boot configuration when appropriate
DEVLOAD is excellent for discovery and optional hardware. A driver required on every boot may be clearer and safer in a named CONFIG.SYS menu profile, where dependency order and memory managers are established consistently.
Move it only after repeated cold-boot tests. Preserve the working DEVLOAD command as a diagnostic profile, translate /H to DEVICEHIGH= only if UMB placement was reliable, and keep a boot-menu option that omits the driver for recovery.
Test missing hardware, removed media, unavailable UMBs, occupied drive letters, warm reboot, cold boot, and application workloads that stress the device. DEVLOAD removes the reboot from each experiment, not the need for disciplined driver validation. When a driver truly requires early boot, the correct outcome is to learn that limit and configure it there.
Related:
- FreeDOS SWSUBST: Mapping Paths and Drive Letters Through the CDS Table
- Device Drivers on FreeDOS: How .SYS Files Extend the Kernel
Sources: