pts/kvikdos
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
kvikdos: a very fast headless DOS emulator for Linux
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
kvikdos is a very fast emulator for running noninteractive DOS programs on
Linux. Such programs are old compilers, assemblers and other build tools.
kvikdos implements a very small subset of DOS, BIOS and IBM PC harware, so
it can keep the overhead low, so it can be very fast. It uses Linux KVM
under the hood for emulating the CPU, which is also very fast.
kvikdos is free software, GNU GPL >=2.0. There is NO WARRANTY. Use at your risk.
kvikdos should be pronunced as ``quick DOS''. the initials ``kv'' refers to
KVM, the underlying virtualization technology.
Requirements:
* Linux operating system running on i386 (x86, i686) or amd64 (x86_64)
architecture.
* Hardware virtualization (Intel VT-x or AMD-V) enabled on the host.
Modern CPUs (even some in 2008) support it.
* KVM enabled for your Linux user (see below).
Limitations:
* kvikdos needs a Linux i386 or amd64 system with KVM. It has been tested
and found working with both: Linux compiled for i386 and Linux compiled
for amd64. (Windows and macOS have similar virtualization technologies,
but kvikdos hasn't been ported to them yet. Alternatively, on old Linux
i386 systems, the vm86(2) system call could be used, but that's not
implemented in kvikdos either.) macOS users should use udosrun instead of
kvikdos, others should use DOSBox or DOSBox-X.
* kvikdos can run 16-bit DOS programs (written for the 8086, 186 or 286
processors, but not 16-bit 286 protected mode), it can't run 32-bit DOS
programs (written for 386, 486, Pentium processors or above) or 64-bit
programs. Use udosrun if you want to run 32-bit DOS programs.
* kvikdos can run a single DOS program at a time. (But you can run multiple
independent instances of kvikdos in parallel.) Use udosrun (with the
`-text' or `-gui' flag) or DOSBox if you want to run multiple DOS programs
after each other or nested.
* The DOS program can use up to 635 KiB of (conventional) memory, including
the program code and the variables (data and BSS). The 635 KiB excludes:
environment variables, command-line arguments (in the Program Segment
Prefix), Interrupt Vector Table, Program Segment Prefix, program stack
(last 768 bytes), BIOS Data Area, helper code, the user code written for
Linux.
kvikdos doesn't support memory types UMB (up to 384 KiB more), HMA (63
KiB more), XMS (up to hundreds of megabytes more) or EMS (also up to
hundres of megabytes, overlapping with XMS).
If your DOS programs need mre memory, use udosrun or DOSBox instead.
* kvikdos doesn't support graphics. Use udosrun or DOSBox instead.
* kvikdos doesn't support interactive text mode (moving the cursor, changing
the cursor shape, changing the font), so e.g. Volkov Commander doesn't
work. Something could be emulated using ncurses, but it's not the focus of
kvikdos. However, kvikdos can supply line-based input (terminated by
<Enter>) from the terminal to DOS programs. For interactive text mode
programs in DOS, use udosrun or DOSBox.
* kvikdos doesn't emulate any special hardware (e.g. sound card, MIDI,
joystick, mouse, CD-ROM). Use DOSBox instead.
* kvikdos implements a tiny subset of the DOS ABI (int 21h etc.), PC BIOS
ABI (int 10h etc.) and IBM PC hardware interfaces (in and out
instructions). Thus random DOS programs won't work out of the box. Simple
API calls can be added on the fly to kvikdos.c. However, many famous build
tools (e.g. compilers and assemblers) released in the 1980s and 1990s
already work, see the compatibility list below. To get good chances for
running any random DOS program, use udosrun or DOSBox instead.
Features and advantages:
* kvikdos is very fast, it runs CPU-intensive code at almost native speeds
with Linux KVM. For I/O-intensive code, kvikdos tries to satisfy DOS I/O
calls using the corresponding Linux system calls (mapping as directly as
possible), thus it has less overhead than other emulators. See
benchmark/benchmark.md for a comparison between kvikdos, DOSBox and QEMU.
For CPU-intensive worklad, kvikdos and QEMU + KVM are on par, each of them
is about 11.49 times faster than the next emulator. For mixed CPU and I/O
workload, kvikdos is 4.507 times faster than anything else.
* All features of a modern Intel CPU (such as floating point instructions
and 32-bit registers), except for protected mode and using more than 1 MiB
of memory, are available for DOS programs, because the host CPU features
are used directly
* Since very little hardware is emulated, kvikdos starts up very quickly,
it's possible to run dozens of short-lived kvikdos instances per second.
* After installation (and enabling KVM for the Linux user), kvikdos doesn't
need special privileges (i.e. root or sudo not needed).
* kvikdos integrates DOS command-line tools to the Linux (Unix) command-line:
its standard input, output etc. can be redirected, it propagatates the DOS
exit code to Unix, it can pass environment variables to DOS etc. It also
works very well headless (i.e. without GUI or interactive text UI), e.g.
as part of continous build pipelines.
How to install kvikdos:
* (You don't have to install QEMU, kvikdos doesn't need it.)
* To check for hardware virtualization (Intel VT-x or AMD-V),
run this command on your Linux system (without the leading `$'):
$ awk '/^flags/&&/( vmx | svm)/{print"OK";exit}' </proc/cpuinfo
OK
If it doesn't display OK (as indicated above), then consult this
tutorial: https://www.linux-kvm.org/page/FAQ#How_can_I_tell_if_I_have_Intel_VT_or_AMD-V.3F
. You may have to enable it in the BIOS.
* To check that KVM works on your Linux system,
run (just the line starting with `$', without the `$'):
$ cat /dev/kvm
cat: /dev/kvm: Invalid argument
If you get `Invalid argument' (as above), then it's OK.
If you get `No such file or directory' instead, then your kernel doesn't
have KVM. Ubuntu and mainstream Linux distributions have it. Consult the
support channels of your Linux distribution about enabling KVM.
If you get `Permission denied' instead, then you need to give permissions
for your Linux user to /dev/kvm. Typically, on Ubuntu, run the following,
and reboot:
$ sudo adduser "$(id -nu)" kvm
* Download the precompiled kvikdos binary (kvikdos.linux.i386). Rename the
file to kvikdos, and make it executable:
$ mv kvikdos.linux.i386 kvikdos
$ chmod 755 kvikdos
* Download a test DOS program (guest.com) to the same directory, and run it:
$ ./kvikdos guest.com
.
Hello, World!
If it displays the dot and the `Hello, World!' message, then it's OK.
About making Linux files available for DOS programs:
* kvikdos emulates DOS drives A: .. F: by exposing directories on the Linux
filesystem as mount points for these DOS drives.
* Use the `--mount=<drive><case><dirname>/' command-line flag to make
DOS drive <drive>: point to Linux directory named <dirname>. Use `:' as
<case> for uppercase (see below), and use `-' for lowercase.
* Use the `--mount=<drive>0' command-line flag to make <drive>: invisible
to DOS programs. This is useful to override some default mounts.
* Use the `--mount=<drive><case>' command-line flag to override case folding
for default mounts.
* The following drives are visible to DOS by default (i.e. default mounts):
* C: points to the current directory (.) of the kvikdos Linux process.
* D: points to the directory containing the kvikdos executable program
(taken from argv[0]).
* E: points to the directory containing the <dos-executable-file>
specified in the command-line, if it was specified as a Linux pathname.
* A:, B: and F: are not mounted by default.
* The default drive is C:, but if it was disabled (`--mount=C0'), then the
default drive is E:.
* If you don't specify `--env=PATH=...', then the DOS PATH environment
variable is set to the directory containing <dos-executable-file>
(i.e. `--env=PATH=E:\' most of the time).
* The defaults are set up in way that most of the time you don't need to
specify `--mount=...', and you don't need to specify any directory name in
DOS pathnames. That's because the current Linux directory is visible as
C:\ in DOS, and that's the default within DOS as well.
About uppercase and lowercase filenames:
* Filenames in Linux are case sensitive, but in DOS they are case
insensitive. Thus if a DOS program wants to open or access a file, kvikdos
has to decide how to case fold the letters in the pathname.
* Only unaccented Latin letters a .. z (and A .. Z) are targets of case
folding. International characters (typically with code >= 128) are kept
intact.
* When the DOS program tries to open or access a file, kvikdos generates an
uppercase or lowercase Linux filename based on the mount flags of the
emulated drive the DOS file is on. (DOSBox does it differently: on a per
file basis, it uses uppercase iff the lowercase variant doesn't already
exists on the filesystem.)
* To specify an uppercase drive, use the `--mount=<drive>:<dirname>' flag.
To specify a lowercase drive, replace the `:' with `-' above. For
example, to mount the current Linux directory as C: lowercase,
specify `--mount=C-' .
* For drives C:, D: and E:, if not explicitly specified as
`--mount=<drive>...', kvikdos autodetects lowercase based on the
on the <dos-executable-file>: if there is at least
one lowercase character, the drive becomes lowercase. For drives D: and E:
only the last pathname component is considered, for C:, if
<dos-executable-file> is under C:, then the entire pathname is considered.
To override autodetection, specify e.g. `--mount=E:' for uppercase and
`-mount=E-' for lowercase.
Software compatibility, i.e. DOS programs known to work in kvikdos:
* Turbo Pascal 7.0 compiler tpc.exe. It produces .exe program files
directly.
* A86 macro assembler 3.14 .. 4.05 (practically all popular versions)
a86.com. It produces .com program files directly or OMF .obj files.
* Turbo Assembler (TASM) 2.51, 3.0, 3.1, 3.2 and 4.0 tasm.exe.
There is no newer 16-bit real mode TASM, packages 5.0 and 5.2 contain the
tasm.exe of TASM 4.1. It produces OMF .obj files.
* Turbo Link (TLINK) linker 3.01 and 4.0 tlink.exe. There is no newer 16-bit
real mode TLINK, newer versions of tlink.exe use 16-bit 286 protected
mode, which kvikdos doesn't support. It reads OMF .obj and .lib files,
and it produces .exe and .com program files.
* TLIB library builder 3.01 and 3.02 tlib.exe. There is no newer 16-bit
real mode TLIB, newer versions of tlib.exe use 32-bit protected
mode, which kvikdos doesn't support. It produces OBF .lib files
from OMF .obj files.
* Sphinx C-- compiler 1.04 c--.exe: It produces .com program files.
* Microsoft QuickBASIC compiler 4.50 bc.exe and the corresponding linker
link.exe. The compiler produces OMF .obj files, and the linker reads
OMF .obj and .lib files, and it produces .exe program files.
Please note that the generated .exe files are correct (they are identical
to those generated in DOSBox by the same tools), but they don't work yet
in kvikdos, even the hello-world doesn't work yet.
* Microsoft BASIC Professional Development System compiler 7.10 bc.exe and
the corresponding linker link.exe. The compiler produces OMF .obj files,
and the linker reads OMF .obj and .lib files, and it produces .exe program
files.
Please note that the generated .exe files are correct (they are identical
to those generated in DOSBox by the same tools), but they don't work yet
in kvikdos, even the hello-world doesn't work yet.
* BAssPasC Compiler v3.0pre2 bapc3.exe. It produces .asm (TASM) assembly
source files from .bp3 source files.
* Netwide Assembler (NASM) 0.98.39. The 16-bit versions downloaded from
here:
https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/nasm/0.98.39/
This is the last version of nasm which uses 32-bit integers internally
(thus it compiles on 16-bit systems), newer versions use 64-bit integers
or even longer.
It produces OMF .obj files, .com program files or others (use `nasm -hf'
to get a list of output formats).
Download links:
* https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/nasm/0.98.39/8086host/nasm-0.98.39-16bit-8086-12oct2019-Rugxulo.zip
* https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/nasm/0.98.39/8086host/nasm16.zip
* https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/nasm/0.98.39/8086host/nasmlite.zip
* https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/nasm/0.98.39/nsm09839.zip
* Turbo C, Turbo C++ and Borland C++ compilers haven't been tested.
(TODO(pts): Test them.)
* (TODO(pts): Add tutorial for compiling hello-world with the tools above.)
* (Please note that installers typically don't work. So you should run the
installer in `udosrun -gui' or DOSBox, and then run the installed programs
in kvikdos.)
Protected mode support for running 32-bit DOS programs in kvikdos:
* The CPU emulation in KVM makes it possible to switch to various types of
protected modes (16-bit and 32-bit data and code segments) and even 64-bit
long mode (not supported by most existing DOS programs).
* However, to take advantage of protected modes, DOS extenders and/or DPMI
hosts are needed, and most of the existing ones don't run in kvikdos.
* These programs work:
* flat assembler 1.73.30 fasmlite.exe.
* pmode.asm 3.07 example.exe.
* Most existing 32-bit DOS programs don't work.
* Currently programs running in kvikdos can use less than 640 KiB of memory,
and this also applies to protected mode. (This restriction should be easy
to lift.)
* Currently there is no XMS, EMS, VCPI or DPMI support implemented in
kvikdos.
Alternatives of kvikdos:
* udosrun (unreleased): A wrapper around pts-fast-dosbox and DOSBox to run
DOS command-line tools conveniently and directly within the Linux
terminal. It has fast startup time, because it doesn't open a separate
window, and it doesn't emulate most of the hardware. It supports 63 MiB of
memory and it can run 32-bit programs (just like DOSBox).
* DOSBox or DOSBox-X: It can run 32-bit programs, can display graphics,
emulates lots of hardware (sound card, MIDI, joystick, mouse, CD-ROM etc.)
Can run many games. It works out of the box, no need to install FreeDOS,
MS-DOS etc. It supports up to 63 MiB of memory. Disadvantage: it doesn't
support headless operation or running DOS command-line tools directly
within the Linux terminal.
* pts-fast-dosbox (unreleased): a fork of DOSBox 0.74 for Linux, optimized
for fast startup and fast operation (both faster than regular DOSBox, but
not as fast as kvikdos). By default it doesn't open a separate window, it
doesn't emulate most of the hardware, and it has an embedded dosbox.conf
file optimized for (CPU) speed. It also features a command prompt (`C:\>')
within the Linux terminal. You can use it most conveniently by driving it
with udosrun (see above).
* EMU2: https://github.com/dmsc/emu2 . It works on the Unix terminal,
including interactive text-mode DOS programs. It emulates more hardware
and more DOS functionality than kvikdos. It contains a slow and
architecture-independent 80286 emulator, without protected mode. It is
able to run MASM 1.00. It is quite close to kvikdos in the sense that it
maps DOS standard handles to Unix standard file descriptors (stdin, stdout
and stderr).
Unix Makefile example using EMU2 headless:
https://gist.github.com/dmsc/28d7f4900e7adaf60427a95f9b471813
* MS-DOS Player: https://github.com/cracyc/msdos-player . Uses CPU
emulation, implements quote a large subset of the MS-DOS API, including
EMS, XMS, VCPI and long filenames. It can also convert a DOS program to a
Win32 program by embedding the emulator .exe.
* !! doscmd
* !! dosrun and dosrunner
* !! dosemu (how does it work on amd64?)
DOSEMU2 also supports KVM: https://github.com/stsp/dosemu2/blob/42bc36c8adee504db92e5de9c6db95633c76813d/src/base/emu-i386/kvm.c
It would be very interesting to see this supported in DOSBox-X. It would probably enable very good Windows 9x support. DOSEMU2 runs up to Windows 3.x and QEMU with KVM has difficulty with Windows 9x (was quite unstable when I tried it).
!! Is KVM 64-bit only?
Recommendations on using DOSBox interactively, in a GUI:
* Create a directory, and copy everything relevant (e.g. the DOS program)
there.
* In your terminal window, cd into that directory.
* Run `dosbox .'.
* Use DOSBox in the appearing (black) window. All programs and files of the
work directory are there. (Use `dir' to see them.)
* Run `exit' in DOSBox to exit (and destroy the black window).
Future work:
* Embed an alternative (but slow) CPU emulator, to make kvikdos
system-independent (i.e. no KVM) on the host. Example such emulators:
* https://github.com/ecm-pushbx/8086tiny
* https://github.com/adriancable/8086tiny (base of ecm-pushbx/8086tiny)
* https://github.com/retrohun/8086tiny
* The CPU emulator of DOSBox. It supports 386, 486, Pentium etc.
* https://sourceforge.net/projects/fake86/
* http://ioccc.org/2013/cable3/
* https://github.com/koutheir/i8086sim
* https://github.com/DispatchCode/NaTE
* https://github.com/moesay/Elegant86
* https://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu
* https://github.com/zsteve/hard86
* https://github.com/Thraetaona/EXACT (written in WebAssembly)
* https://github.com/Mati365/ts-c99-compiler (written in TypeScript)
* As an alternative to KVM, use Virtual 8086 mode (vm86(2) system call) on
Linux i386. Known limitations:
* It doesn't work if the Linux kernel is targeted to amd64 (i.e. most
modern systems), because it's not possible to switch back from 64-bit
mode (long mode) to 32-bit mode, except using virtualization (as done by
KVM).
* It won't be able to run protected mode DOS programs (i.e. most 32-bit
DOS programs), except possibly with a DPMI server. It's not obvious if a
DPMI server is possible in Linux userspace code (especially the `int
0x21' remapping within the host process).
* vm86(2) needs to use the first 1 MiB of the Linux process address space,
but Linux disallows the mmap(2) of the first 64 KiB for non-root users.
There may be (slow) workarounds. This effectively redues the memory
available for the DOS program from 635 KiB to 575 KiB.
!! Speed measurements.
__END__