-
Notifications
You must be signed in to change notification settings - Fork 108
Virtual ELKS: A How To
ELKS runs fine in many, probably most x86/PC virtualisation tools. Actually most of ELKS development is done that way, with QEMU
, which is the preferred and most capable virtual environment for the system. How to run ELKS in QEMU
is discussed in the main Wiki.
While QEMU
is capable, efficient and very fast, there are things it cannot do. Such as provide real 8086 emulation (QEMU starts at the 386-level [32 bit]). Or deliver the (slow) speed of the original, which at times is important in order to simulate how ELKS will perform on a real system.
Thus other emulators are not only interesting, but important. This document describes how to run ELKS in some of these emulators. You are invited to add experience, hints, bugs and other information that may be valuable to other ELKS users.
Oracle's VirtualBox is one of the most capable and widespread X86 emulators out there – extremely capable, wide platform coverage and an excellent GUI. For good results with ELKS, configure a DOS-type virtual machine with minimal resources (more than minimal resources is a waste). VB will boot just about any floppy image, including the 2.88MB variant which is very practical because it holds the entire system including manpages and extra tools.
Like QEMU, VB is very fast. You can slow it down by setting an execution cap, but unless your host machine is very slow, you're not getting close to 'real' speed for an old clunker.
Here a sample VB configuration:
VB does not emulate any of the Ethernet interfaces supported by ELKS, so networking is not available unless you can figure out how to use slip
.
If you want to use one of the auto built ELKS HD images with VB, you need to convert the raw .img image to virtual box format .vdi
. The command example below is for Windows. If you're running on a different platform, you'll have to translate the command to the actual dialect:
VBoxManage.exe convertfromraw --format VDI "d:\temp\hdd.bin" "d:\temp\hdd_vb.vdi"
Attach the newly created drive as hdd. You will be able to boot it directly or mount it if you booted from floppy.
86Box is a comprehensive x86 emulator covering a wide range of specific hardware components and systems. Its level of hardware specificity distinguishes it from most other platforms which makes is well suited as a development environment. The price to pay is complexity. Getting the various components - CPUs, sockets, main boards, interfaces, peripherals and more to work together may be challenging. IOW - you have to know what you're doing unless you're using a prepackaged configuration - or are willing to spend time trying and failing.
86Box emulates the selected systems extremely well, including realistic speed. E.g. if you choose Compaq Portable III as your system and use the built-in graphics, you'll get an amber screen that looks exactly like the real thing, including the (very slow) memory test as you power it up. Actually, at least when running on a Mac, the speed is significantly slower than the real thing, so choose a higher clock speed than you would otherwise do unless you have a really big coffee pot around. Part of the true-to-the-real-thing magic is the use of BIOS/Firmware from the original systems.
86Box has a decent GUI which speeds up testing various configurations tremendously. What it doesn't do is warn you if you're making selected that are physically impossible or just bad choices. You have been warned.
While many different floppy types and sizes are supported, there is limited auto detection in 86Box. Make sure you configure the system to exactly match the floppy image you're using.
Beware that in some configurations, there is no blinking text cursor on the screen. 86Box also get confused as to whether you're using caps lock or not some times. Using the shift button to get lower case for a while is painful but works, and suddenly the issue goes away.
ELKS works well with many different 86Box combos. It emulates the ne2k ethernet card, so ELKS can communicate with the host and the outside world via slirp
. It keeps a configuration file in its home (installation) directory (86Box.cfg
), and changing configurations may some times be faster via the config file than via the GUI - when you know what you're doing.
Here's a configuration that works:
[General]
vid_renderer = qt_software
confirm_save = 0
confirm_exit = 0
confirm_reset = 0
[Machine]
machine = portableiii
cpu_family = 286
cpu_speed = 25000000
cpu_multi = 1
cpu_use_dynarec = 0
time_sync = local
cpu = 6
mem_size = 640
[Video]
gfxcard = internal
[Input devices]
mouse_type = none
[Storage controllers]
hdc = st506_xt_dtc5150x
cassette_enabled = 0
cassette_mode = load
[Novell NE2000]
base = 0300
irq = 11
bios_addr = 00000
mac = 90:e0:22
[Sound]
sound_type = int16
[Network]
net_card = ne2k
net_host_device = en0
[Ports (COM & LPT)]
lpt1_enabled = 0
[Floppy and CD-ROM drives]
fdd_01_turbo = 1
fdd_02_type = 525_2hd_dualrpm
fdd_02_turbo = 1
fdd_01_type = 35_2hd
fdd_01_fn = /Users/helge/tmp/fd1440.img
[Hard disks]
hdd_01_parameters = 17, 5, 979, 0, mfm
hdd_01_fn = /Users/helge/tmp/venix.raw.disk.oct2020.img
hdd_01_mfm_channel = 0
[SLiRP Port Forwarding]
0_external = 8080
0_internal = 80
1_protocol = udp
1_external = 5555
2_protocol = tcp
2_external = 8323
2_internal = 23
3_protocol = tcp
3_external = 8321
3_internal = 21
[Compaq Plasma]
display_type = 0
composite_type = 0
rgb_type = 0
[Trident TVGA 8900B]
memory = 256
[CGA]
display_type = 0
composite_type = 0
rgb_type = 0
snow_enabled = 1
[Cirrus Logic GD5426 (ISA)]
memory = 512
[WD1004A-WX1 MFM Fixed Disk Adapter]
bios_addr = C8000
base = 0320
irq = 5
[DTC 5150X MFM Fixed Disk Adapter]
bios_addr = C8000
The ELKS boot screen looks like this:
In this example the HD is configured as a MFM (very old style) disk. It might as well be configured as IDE, using the XTIDE controller option.
TBD
PCE is a lot simpler than most of the alternatives. It covers numerous platforms - MacPlus, AtariST and more - in addition to the IBMPC. X86 emulation is limited to the oldest variants: 8086/88, 80186/88 - which for all practical purposes means the original PC (5150) and the PC/XT (5160).
Within these limitations, the emulator is quite capable, not the least thanks to 'custom' BIOS enhancements that may be loaded at boot time. To add support for XMS and EMS - for example.
Lie 86Box, PCE uses BIOS-roms from the original systems, many variants of which are included in the 'package'. The 'package' being either the source code or a selection of ready-to-run configurations, complete with binaries, hard disks and floppy disk images. The complete systems are made for Windows, but as it turns out, they are great starting points regardless of platform.
Thus if your platform is Windows, just choose one of the complete systems, add in an ELKS floppy or hard drive and you're up and running. If you're on MacOS or Linux, you'll have to download and compile the system first. The following instructions are for MacOS:
- Make sure you have
sdl
andsdl2
installed (runbrew sdl
andbrew sdl2
-- assuming you havehomebrew
installed). - Of course, Apple Xcode w/command line tools must also be present on the system.
- Download the latest PCE source from http://www.hampa.ch/pub/pce/pre/
- Run the usual
./config; make; make install
- your installation directory becomes/usr/local
, binaries inbin
, configs etc. inetc
and more. - Download and uncompress the system package of choice, recommended is Minix2: http://www.hampa.ch/pub/pce/pce-0.2.2-xt-minix-2.0.2.zip
-
cd
to the package directory. Since we're not running windows, delete or rename the bin directory and add a symbolic link to your own binaries:ln -s /usr/local/bin bin
. - Copy and edit the
.bat
file to something that suits you, such as run.sh, which may look like this:
#!/bin/bash
bin/pce-ibmpc -v -c pce-5160.cfg -l pce.log -g cga
- You will notice the
-r
option gone compared to the-bat
file, which means that upon startup you'll get the text guide of PCE, which is very useful for experimentation. - The config-file holds the magic of the emulator, you should read it carefully to become acquainted with it for later experimentation. Maybe change processor from 8088 to 8086 and speed factor to something decent unless slow speed is important right away. The default config file now in
/usr/local/etc/pce/pce-ibmpc.cfg
has much more documentation about the various choices than the one included with the package. Use it to understand disk configurations in particular. For example: The disk controllers (there are 3-4 different to choose from) have switch settings indicating the disk 'type' connected, which means 'geometry' or CHS-values. Quite confusing, but when you specify a disk image in the config file, you can specify c=, h= and s= - and the values will be recognized by the system but not by the controller, which will report the CHS values form the switches. (There is something called 'visual_c', 'visual_h', 'visual_s' which may fix this, it remains untested. The disk types (i.e. sizes) support by each controller are listed in the master config file. - The ROM files included in this config works for ELKS, many others (such as the Minix1 package) don't.
- The beauty of the UI is that it enables easy configuration changes - and debugging, even breakpoints. The important commands for initial testing are
di file drive --> ´di ../../tmp/fd144.img 0' <--- 0 is floppy 0, 1 is floppy 1, 128 is hd0, 129 is hd1 etc.
boot 0 <----- set which drive to boot from, see above
g <----- go, run start whatever
h <----- Help
- Type
control option
to release the cursor from the terminal window - Type
ESC Q
in the terminal window to exit - There are many important commands and functions for testing and debugging, these are needed to get started.
- As a first run - with the setup above, just type 'g' to boot Minix 2, see how it runs. Then quit, change the floppy manually and boot from a ELKS floppy.
A working config file for ELKS (booting from floppy):
# pce-5160.cfg
path = "."
path = "rom"
system {
model = "5160"
boot = 0
rtc = 1
memtest = 0
floppy_disk_drives = 2
patch_bios_init = 1
patch_bios_int19 = 1
}
cpu {
model = "8086"
speed = 4
}
ram {
address = 0
#size = 704K
size = 640K
}
load {
format = "binary"
address = 0xf0000
file = "ibm-xt-1986-05-09.rom"
}
load {
format = "binary"
address = 0xc8000
file = "sms-hdc-1986.rom"
#file = "ibm-hdc-1985-10-28.rom"
#file = "dtc-hdc-1988-05-31.rom"
}
rom {
address = 0xf0000
size = 64K
}
rom {
address = 0xc8000
size = 32K
}
terminal {
driver = "sdl"
# escape = "CtrlRight"
scale = 1
border = 0
fullscreen = 0
mouse_mul_x = 1
mouse_div_x = 1
mouse_mul_y = 1
mouse_div_y = 1
}
terminal {
driver = "x11"
# escape = "CtrlRight"
scale = 1
mouse_mul_x = 1
mouse_div_x = 1
mouse_mul_y = 1
mouse_div_y = 1
}
terminal {
driver = "null"
}
video {
device = "cga"
font = 0
blink = 30
}
video {
device = "mda"
color = "green"
blink = 30
}
speaker {
volume = 250
lowpass = 8000
sample_rate = 44100
# driver = "oss:dev=/dev/dsp:lowpass=0:wav=speaker.wav:wavfilter=0"
driver = "sdl:lowpass=0"
}
serial {
uart = "8250"
address = 0x3f8
irq = 4
multichar = 1
# driver = "null"
# driver = "posix:file=ser1.out:read=ser1.out:write=ser1.out"
# driver = "pty:symlink=ser1"
driver = "stdio:file=ser1.out:flush=1"
# driver = "tcp:port=5556"
# driver = "tios:file=/dev/ttyS0"
# driver = "ppp:if=tun0:host-ip=192.168.2.1:guest-ip=192.168.2.10"
}
serial {
uart = "8250"
address = 0x2f8
irq = 3
multichar = 1
driver = "stdio:file=ser2.out:flush=1"
}
parport {
address = 0x378
driver = "stdio:file=par1.out:flush=1"
}
parport {
address = 0x278
driver = "stdio:file=par2.out:flush=1"
}
fdc {
address = 0x3f0
irq = 6
drive0 = 0x00
drive1 = 0x01
drive2 = 0x02
drive3 = 0x03
accurate = 1
}
hdc {
address = 0x320
irq = 5
drive0 = 0x80
drive1 = 0x81
switches = 0xf
# 0x0f is good for SMS 10MB 305/4/17 (type 15)
switches = 0x0
# 0 is good for the IBM HDC BIOS
#switches = 0x61
# 61 set drive 0 to type 4 with the DTC HDC BIOS
#switches = 0xa5
}
disk {
drive = 0x00
type = "auto"
file = "../../tmp/fd1440.img"
file = "fd0.pfdc"
file = "fd0.img"
optional = 1
}
disk {
drive = 0x01
type = "auto"
file = "fd1.pfdc"
file = "fd1.img"
optional = 1
}
disk {
drive = 0x02
type = "auto"
file = "fd2.pfdc"
file = "fd2.img"
optional = 1
}
disk {
drive = 0x80
type = "image"
file = "../../tmp/venix.raw.disk.oct2020.img"
c = 980
h = 5
s = 17
#file = "hd0.pimg"
#file = "hd0.qed"
#file = "hd0.img"
#cow = "hd0.cow"
optional = 1
}
disk {
drive = 0x81
type = "auto"
file = "hd1.pimg"
file = "hd1.qed"
file = "hd1.img"
# cow = "hd1.cow"
optional = 1
}