FreeDOS INSTALL and INSTALLHIGH: Resident-Program Loading Contracts
Trace FreeDOS INSTALL and INSTALLHIGH from CONFIG.SYS parsing through executable startup, UMB-first allocation, fallback, and failure reporting.
FreeDOS INSTALL= and INSTALLHIGH= are kernel-owned CONFIG.SYS directives for starting executable programs during boot, commonly programs designed to terminate and remain resident (TSRs). They are not the FreeDOS operating-system installer, and they are not alternate spellings of DEVICE= or DEVICEHIGH=. This article follows the released FreeDOS kernel 2046 (tag ke2046, version 2.46); other DOS kernels and older FreeDOS builds may implement different contracts.
The distinction matters operationally. A device driver is initialized through the DOS device-driver protocol and its header/request entry points. The kernel’s INSTALL path instead invokes DOS executable loading for a program. A .SYS suffix alone does not tell you which interface a file implements: use the directive and load procedure documented for that exact program.
CONFIG.SYS records the request; it does not execute the program inline
In kernel 2046, the CONFIG.SYS command table assigns both directives to configuration pass 2. When a selected line reaches its handler, INSTALL or INSTALLHIGH stores the command text and a load-mode flag in an internal queue. The executable is not launched at that point in the line-by-line parser.
The boot call sequence explains the timing: the kernel processes configuration passes 0 and 1, initializes allocation structures, processes pass 2 (including device lines), finalizes configuration, and returns from kernel initialization. Only then does the main startup path call DoInstall(), immediately before starting the shell. Queued programs run in their original directive order. Consequently, an INSTALL line is not a hook that runs between adjacent DEVICE= lines, and its program does not run from AUTOEXEC.BAT.
There is an important boundary in this exact kernel snapshot: the internal queue has ten entries, but its parser check rejects a count only when it is greater than the queue length. After ten entries are queued, an eleventh passes that guard and attempts index ten, one past the array. Treat this as a source-level bounds defect in the cited build, not as support for an eleventh directive or a claim about runtime exploitability. Keep this exact build’s configuration to at most ten INSTALL/INSTALLHIGH records, and re-check other kernel versions rather than generalizing the finding.
The pass-2 menu/conditional filter still matters: a line skipped by the selected configuration is not queued. Keep profile-specific installers under the same numeric condition as the TSRs they belong to, and preserve a known-good boot choice that omits optional residents.
Syntax, filename parsing, and program arguments
The documented forms are:
INSTALL=[drive:][path]program [program-options]
INSTALLHIGH=[drive:][path]program [program-options]
The text after the program name belongs to that program; it is not an option set for the kernel directive. Kernel 2046 extracts the executable name up to whitespace or a slash, then builds a DOS command tail from the remainder. It does not invoke a command shell to expand variables or interpret a batch command. Use a real DOS executable path with simple, unquoted DOS syntax; the handler has no quoting layer for paths containing spaces. Consult the resident program’s own manual for each switch rather than borrowing options from another TSR.
There is a conflict in the FreeDOS help: the general INSTALL reference lists NANSI.SYS as an example, but NANSI’s own manual identifies it as a console driver and documents DEVICE[HIGH]= or DEVLOAD as its load path. The pinned kernel’s INSTALL path invokes DOS executable loading; it is not the device-driver initialization protocol. Do not treat the generic example as verified for kernel 2046. Use the NANSI-specific driver instructions for NANSI, and reserve INSTALL for an executable whose own documentation supports DOS EXEC startup and TSR retention. The sources establish conflicting guidance and different loader contracts; without testing the exact binary on the target kernel, do not predict whether that particular NANSI image will crash, hang, or appear to load.
This schematic CONFIG.SYS excerpt keeps the two interfaces separate. MYTSR.COM is a placeholder, not a file supplied by FreeDOS; replace it only with a real COM/EXE program documented to start as a TSR through DOS EXEC:
; NANSI's documented device-driver initialization path.
DEVICE=C:\FDOS\BIN\NANSI.SYS /X /P
; Schematic executable-TSR example; verify the actual program's options.
INSTALL=C:\FDOS\BIN\MYTSR.COM /OPTION
An executable that exits normally is not made resident by the directive; a program must implement its own stay-resident behavior if it is expected to remain after startup. Conversely, do not feed a device-driver binary to INSTALL just because a generic example or its .SYS suffix suggests it might work. The correct interface is determined by the program’s format and documented initialization path, not its filename extension.
INSTALLHIGH requests an upper-memory-first executable load
INSTALL uses the normal executable allocation path, documented for conventional memory. INSTALLHIGH sets the kernel’s high-load flag. In kernel 2046’s executable loader, that flag temporarily links upper-memory blocks into the allocation search and tries to satisfy the program’s memory requirement high first. When the high region is unavailable or too small, the allocator can retry in conventional memory. The request is therefore an attempt, not proof that the resident portion ended up in a UMB.
High loading depends on the actual boot profile and available UMBs. Install a compatible memory manager before relying on it, and check the resulting memory map after boot. For a machine where JEMMEX is the selected UMB provider, a configuration can look like this:
DOS=HIGH,UMB
DEVICE=C:\FDOS\BIN\JEMMEX.EXE NOEMS
DEVICEHIGH=C:\FDOS\BIN\NANSI.SYS /X /P
INSTALLHIGH=C:\FDOS\BIN\MYTSR.COM /OPTION
The NANSI line remains a device-driver load, while the schematic INSTALLHIGH line is a separate executable-TSR request. To compare low placement, replace INSTALLHIGH with INSTALL for that verified program; do not include both unless intentionally starting it twice. Adjust paths and memory-manager options to the installed versions. The HIGH suffix in INSTALLHIGH concerns the executable’s allocation in the upper-memory area; it is not a promise to place arbitrary code in XMS or the High Memory Area, and it does not turn a driver into a protected module. Do not confuse it with DOS=HIGH, the separate request concerning DOS kernel placement in the High Memory Area.
Environment is inherited through the boot process
The FreeDOS help describes these directives as using a minimal environment. The kernel 2046 handler sets the EXEC block’s environment segment to zero rather than building a per-line environment. In the DOS loader, zero means to create the child environment from the current parent PSP’s environment. That is a narrower and more precise contract than assuming that the eventual interactive shell has already processed its startup batch file.
INSTALL programs run before the shell is started, so they cannot rely on variables that would only be established later in FDAUTO.BAT or AUTOEXEC.BAT. CONFIG.SYS SET commands are processed during the same configuration pass before the queued programs execute, but that is still not the shell’s later environment. If a TSR’s documented options depend on environment variables, verify the actual value in the exact kernel/build and boot profile. Do not infer it from an interactive prompt after startup.
Failure reporting and fallback boundaries
Configuration parsing and program execution are separate failure points. A malformed or unrecognized line is reported as a CONFIG.SYS error during parsing. A queued filename that cannot be executed also calls the kernel’s CONFIG.SYS error reporter when INT 21h EXEC returns an error, and the DoInstall() loop then advances to the next queued entry; the failed program is not repaired, and the kernel does not roll back earlier TSRs. There is a diagnostic limitation in the pinned build: the reporter calculates its caret position from the currently parsed CONFIG.SYS line, but queued INSTALL text is passed from a copied command buffer. Its source-line and caret details can therefore be misleading or malformed; do not rely on that message to identify which queued directive failed.
The INSTALLHIGH low-memory fallback covers memory-placement failure. It does not make a missing file, invalid executable, unsupported command-line switch, or incompatible TSR valid. If a high request succeeds only after falling back low, startup can continue without an error even though conventional memory was consumed. Inspect the memory report and test the target workload rather than treating a clean boot as proof of UMB placement.
Keep the first trial reversible: copy the active FDCONFIG.SYS or CONFIG.SYS, add one resident program, and retain a menu entry that skips it. Validate the executable interactively where its own documentation permits, then test the exact boot path with the intended memory manager and all required predecessor TSRs. Compare memory before and after; confirm the program’s documented resident check or function; and reboot to verify that disabling the line restores the baseline. Do not stack several new residents at once, because their interrupt hooks and retained allocations can make both failures and memory use difficult to attribute.
The kernel’s own history records INSTALL/INSTALLHIGH as implemented in build 2029 and notes both an environment correction and an INSTALLHIGH correction in build 2031. That history is another reason to check the actual FreeDOS kernel version on a machine rather than extrapolate from MS-DOS syntax or a generic DOS guide.
Related:
- Upper Memory Blocks and Loading TSRs High
- FreeDOS INT 21h AH=58h: Allocation Strategy and UMB Routing
Sources:
- FreeDOS kernel 2046 release notes
- FreeDOS INSTALL / INSTALLHIGH command reference
- FreeDOS kernel 2046 CONFIG.SYS command table, parser, and INSTALL handlers
- FreeDOS kernel 2046 INSTALL execution queue and EXEC block
- FreeDOS kernel 2046
LENGTHarray-element-count macro - FreeDOS kernel 2046 CONFIG.SYS error reporting
- FreeDOS kernel 2046 queued INSTALL execution loop
- FreeDOS kernel 2046 CONFIG.SYS pass and finalization order
- FreeDOS kernel 2046 pre-shell DoInstall call
- FreeDOS kernel 2046 executable allocation path, including UMB-first fallback
- FreeDOS kernel 2046 COM/EXE dispatch for DOS EXEC
- FreeDOS kernel 2046 COM loader UMB-link handling
- FreeDOS kernel 2046 EXE loader UMB-link handling
- FreeDOS kernel 2046 executable loader and child-environment behavior
- FreeDOS kernel 2046 CONFIG.SYS SET handling
- FreeDOS kernel 2046 documented CONFIG.SYS options
- FreeDOS NANSI command reference and documented switches
- FreeDOS JEMMEX options and UMB behavior
- FreeDOS boot overview: the shell starts after kernel initialization
- FreeDOS kernel history: INSTALL and INSTALLHIGH implementation in build 2029
- FreeDOS kernel history: INSTALL environment and INSTALLHIGH corrections in build 2031