Skip to content
Gregory Haerr edited this page Jan 19, 2022 · 84 revisions

How to use ELKS

Following is a quick-start guide for learning how to set up and use ELKS quickly, with a table of contents.

If something is missing you'd like to know about, please let us know.

  1. Binaries

  2. Installation

  3. Building

  4. Booting

  5. Logins

  6. Serial Connectivity

  7. Networking

  8. Processes and Memory

  9. Filesystems

  10. Useful Commands

Binaries

The ELKS system must be booted up on PC-compatible hardware, or a PC emulator. There are a variety of binary images available, which are copied onto physical floppy disks or USB thumb drives for booting. The recommended image to use for first time users is a 1.44M floppy image intended for 3.5" disks, but can also be used with a PC emulator, such as qemu. This image is named fd1440.img. Following is the full list of binary images produced by the ELKS build (in the images/ directory), and will also be available for direct download:

Size   Format Filename          Description
-----  ------ ----------------  --------------------------------------------------------
1440k  Minix  fd1440.img        Build-configuration specific (usually Minix 3.5" floppy)

360k   Minix  fd360-minix.img   5.25" floppy, 9 sectors, 2 heads
720k   Minix  fd720-minix.img   3.5" floppy, 9 sectors, 2 heads
1440k  Minix  fd1440-minix.img  3.5" floppy, 18 sectors, 2 heads
2880k  Minix  fd2880-minix.img  3.5" floppy, 36 sectors, 2 heads
32MB   Minix  hd32-minix.img    32MB flat hard disk, CHS=63,16,63
32MB   Minix  hd32mbr-minix.img 32MB partitioned hd, CHS=63,16,63

360k   FAT    fd360-fat.img    5.25" floppy, 9 sectors, 2 heads
720k   FAT    fd720-fat.img     3.5" floppy, 9 sectors, 2 heads
1440k  FAT    fd1440-fat.img    3.5" floppy, 18 sectors, 2 heads
2880k  FAT    fd2880-fat.img    3.5" floppy, 36 sectors, 2 heads
32MB   FAT    hd32-fat.img      32MB flat hard disk, CHS=63,16,63
32MB   FAT    hd32mbr-fat.img   32MB partitioned hd, CHS=63,16,63

To copy a 1440k image onto a floppy from Linux, one could use dd if=fd1440.img of=/dev/fd0 bs=1024 count=1440. Please note that ELKS is built with certain parameters compiled in the kernel. An example is the network card's parameters. If you need to change these you will need to recompile the kernel.

Installation

ELKS can be installed on a hdd or floppy. The installation process supports the following filesystems: MINIX, FAT16 and FAT32. The basic stages are:

  • Boot a binary image of ELKS
  • Create a partition using fdisk command
  • Format the partition
  • Execute the sys command to transfer ELKS kernel and commands
  • Reboot into your new installation

Example installation on /dev/hda1:

  • Start fdisk from a floppy binary image: fdisk /dev/hda Use the n command to create a partition /dev/hda1 of size 200MB. Make it bootable with b. Save everything with w. Exit with q.

  • Format the partition as FAT32 of size 180MB: mkfat -fat32 /dev/hda1 180000 To create a MINIX partition use mkfs instead.

  • Copy the kernel and all basic files required to boot ELKS with the sys commande: sys /dev/hda1. Use the -M option to put ELKS boot loader in the MBR. This is required if you are using an empty hard drive and you do not have another boot loader.

  • reboot

Remarks

For partitions less than 32MB FAT16 will be selected automatically by mkfat. Once you booted into your new installation you will need to copy yourself some additional commands to the hdd. If the ELKS boot manager does not know where is your new installation you can instruct it to boot from /dev/hda1 by pressing 1. You can also format a partition as FAT16 or FAT32 using Windows 10. Windows puts extra hidden files on the formatted drive such as the folder "System Volume Information". Normally ELKS sys tool is capable of installing ELKS on a drive with "System Volume Information", but in case of failed install, you can try formatting the partition under Linux to remove this folder. Dual boot of ELKS and DOS might also be possible.

Building

Building ELKS from source code requires downloading and building a gcc cross-compiler for 8086, and then cloning the source repository from GitHub. Full instructions are here.

Configuration options

The ELKS system compilation is configured using make menuconfig, which allows a variety of technical options to be specified.

Booting

ELKS is booted by copying one of the floppy or hard disk images produced during the build directly to the media (usually using 'dd'), and can also be booted virtually using a PC emulator such as qemu. Both the native filesystem formats Minix (v1) as well as MSDOS FAT are supported, for both floppy disk, USB FAT and hard disks. The ELKS build process automatically adds the appropriate boot sector onto the created image.

Boot options

When ELKS boots, the boot sector searches for /Linux on the root filesystem and loads it. It also searches for the file /bootopts, which contains boot options. A variety of boot options can be set in the /bootopts file, without requiring kernel recompilation.

ELKS boot options are parsed from a Linux 2.0-style multiple command lines stored in the root file /bootopts, and parsed at boot time to enable a variety of configurations without having to recompile anything. Very useful for debugging and quick configuration changes.

Allows setting the console to be serial (or any other device, such as virtual Alt2 /dev/tty2), root mount device (FAT and Minix), read-only/read-write, alternative startup process & args, init run level, network start, and set environment variables for the initial startup process, such as a shell or shell script. Note: if the kernel is compiled with serial console ON, console= redirection will have no effect.

Here's an example of the distribution /bootopts file, with everything commented out:

##      
#console=ttyS0 root=fd0 net=eth 3 # condensed
#TZ=MDT7            # timezone
#QEMU=1             # to use ftp/ftpd in qemu
#init=/bin/init 3   # multiuser serial
#init=/bin/sh       # singleuser shell
#netirq=9 netport=0x300 # NIC
#bufs=128           # number of kernel buffers (XMS or External/main memory)
#console=ttyS0,19200 # serial console
#console=tty2       # alt2 console
#root=hda1          # hd partition 1
#ro                 # read-only root
#net=slip

For validation, the /bootopts file must start with ## and file size less be than 512 bytes. # = comment, options are space separated, multiple lines ok. Devices can be specified by /dev/ prefix or without. Non-reserved options without '=' inside them are treated as arguments to /bin/init or init=, and options with '=' are passed as environment variables to the init (or other init=) process.

Here's some more examples, hopefully self-explanatory:

init=/bin/init 3 or just 3
init=/bin/sh HOME=/ TERM=ansi
console=ttyS0, console=/dev/tty2, etc
console=ttyS0,38400
console=tty1
root=fd1, root=/dev/fd1, root=hda[1-4], hdb[1-4], hdc[1-4]
net=eth, net=slip, net=cslip  starts predefined network configurations
ro, rw
netirq=9

To use, edit the file elkscmd/rootfs_template/bootopts and run "make" to create another image, or edit /bootopts when running ELKS and reboot. More about runtime configuration options for network interface cards below.

The entire process can be configured in or out by selecting "Boot Options in /bootopts" in the Kernel section of make menuconfig, and is by default ON.

QEMU boot

The provided shell script qemu.sh can be used to boot ELKS with any of the ELKS-produced disk images. This script is also used to redirect the serial port to the shell as well as provide additional images to mount after boot. See qemu.sh for more details, and uncomment the desired IMAGE= for the desired disk image. Running ./qemu.sh will run QEMU with the default options and boot the file 'images/fd1440.img'.

Logins

ELKS supports single-user operation, as well as allowing multiple logins over the serial ports as well as virtual consoles. Virtual consoles all run on the main system display and can be switched between by using the ALT-Fnkey keyboard sequence, for instance ALT-F2 will switch to virtual console 2, which will have another login, if running in a multiuser run level.

Each mode of operation is called a run level and is assigned a number from 1 through 6, and the file /etc/inittab specifies which serial port or virtual console should be used for the login, along with some other parameters. The ELKS run levels are:

Run Level Description Device(s)
1 Single User Console tty1 only
2 Single User Serial ttyS0 only
3 Multiuser Console and Serial tty1,ttyS0
4 Multiuser Serial ttyS0,ttyS1
5 Multiuser Console tty1,tty2,tty3
6 Multiuser All tty1,tty2,tty3,ttyS0,ttyS1

Switching run levels

The system can be switched to a new run level by specifying the new run level to init, e.g. init 3 will switch to multiuser serial.

Initial startup run level

The first line in the file /etc/inittab specifies the boot run level. By default, it is set to single user console (run level 1):

id:1:initdefault:

Login Device Management

Additional lines in /etc/inittab specify which commands to run for a series of run levels. For instance, the following line specifies to run /bin/getty (the program that prints 'login:') on /dev/ttyS1 at 9600 baud, for run levels 4 and 6:

s1:46:respawn:/bin/getty /dev/ttyS1 9600

sh vs sash shells

Two shells are available on ELKS. The standard shell sh is used when logging in as 'root', and provides a BASH-compatible scripting shell with modern capabilities including line editing using the arrow keys and TAB command completion. An alternative shell, sash (Stand Alone Shell), is provided for smaller-footprint use and is available when logging in as 'toor'. sash supports csh-like command-line history and editing, and has a number of builtin commands (such as ls, rm, mkdir, ...) for fast execution. The file /etc/passwd specifies which shell to run based on login name.

Serial-Connectivity

ELKS supports two serial ports, /dev/ttyS0 and /dev/ttyS1 (COM1 and COM2) for use as logins, outbound terminal emulation to other systems, network connections (slip/cslip, see the Networking section below) and mouse connections for the Nano-X graphical window system. It is possible to increase the number of serial ports to 4 - if the required interrupt lines are available - by manually editing the kernel configuration file elks/include/arch/ports.h.

Hardware flow Control is not supported. Serial speed up to 115200 is possible if the hardware can handle it. Speeds 38400 and 57600 have been found to work on vintage 286 and 386 based systems.

Serial Logins

As discussed above in Logins, the serial ports can be turned on for logins by setting run level 3 by running init 3 at shell prompt.

Serial Mouse

The serial ports are exclusive use, so they cannot be used simultaneously for login or terminal emulation and a mouse. If a mouse is connected, running init 1 will turn off serial logins so the mouse can be used.

Serial with QEMU

The first serial port, /dev/ttyS0, can be used for logins with QEMU by uncommenting one of the following lines in qemu.sh:

# Uncomment this to route ELKS /dev/ttyS0 to host terminal
CONSOLE="-serial stdio"
# Hides qemu window also
#CONSOLE="-serial stdio -nographic"

If the second line is also uncommented, QEMU won't display the graphical console.

Serial logins must be enabled by setting run level 3, either by editing the first line of /etc/inittab as follows, or running init 3 after boot:

id:3:initdefault:

To use the mouse with QEMU for ELKS, uncomment the following line in qemu.sh:

SERIAL="-chardev msmouse,id=chardev1 -device isa-serial,chardev=chardev1,id=serial1"

The host mouse will be setup as a serial mouse connected to /dev/ttyS0, which is the default for running the Nano-X graphical demos, such as nxlandmine, nxdemo or nxclock.

Networking

ELKS supports TCP/IP networking via a sockets library in the kernel and a user mode networking stack ktcp. NE2K-compatible network cards, and SMC are supported for ethernet networking, and serial connectivity via SLIP and CSLIP. Networking is started via the net script either at system start in /etc/rc.d/rc.sys or via the command line. If 'net=eth' is present in /bootopts (MINIX FS only), networking will be started at boot time. Networking IP address and daemon configuration is specified in the /etc/net.cfg file.

Kernel config

Only one active network driver can be selected (NE2K or SMC) in the kernel. There are three parameters to configure: IO base address, IRQ and RAM base address. Default values are used and they might differ from your network card configuration. Check the dip-switches on your card (for soft-configured (PnP) cards, it may be necessary to run a DOS-based configuration utility in order to find the current settings). For the NE2K card, IRQ and IO Base address may be configured at runtime via the /bootopts file, see below. To change the IRQ and IO base address(PORT) for a SMC card go to: elks/include/arch/ports.h and replace the following values:

/* wd, wd.c*/
#define WD_IRQ          2
#define WD_PORT         0x240

The RAM base address is configured in: #define WD_SHMEMSEG 0xce00U in elks/arch/i86/drivers/net/wd.c

Recompile and use the new kernel.

Runtime configuration of the NE2K-driver is available via the /bootopts file. Use netirq= and netport= to enter the correct values. The IRQ is a decimal number, the port address is hexadecimal and may be preceded by '0x'. Make sure the changes don't cause the size of the bootopts file to exceed 511 bytes. Also keep an eye on the boot messages while booting the system, to verify that the card is found and configured correctly.

Starting networking with net start

Ethernet, SLIP and CSLIP link layers and the networking stack can be started quickly using the /bin/net shell script, which allows for specifying the link layer, and serial port and baud rate for SLIP/CSLIP. The default addresses of IP 10.0.2.15, gateway 10.0.2.2 and net mask 255.255.255.0 are used, but can be modified in the /bin/net script, as well as the default serial device and baud rate. Following is the usage for net as well as several examples:

net [start|stop] [eth|slip|cslip] [baud] [device]

$ net start eth                           [starts ethernet networking]
$ net start slip                          [starts slip networking on /dev/ttyS0 at 57600 baud]
$ net start slip 19200 /dev/ttyS1         [starts slip networking on /dev/ttyS1 at 19200 baud]
$ net start cslip 4800                    [starts cslip networking on /dev/ttyS0 at 4800 baud]

The net start command also starts two daemons, telnetd and httpd, for TELNET port 23 and HTTP port 80 remote access.

Ktcp options

The net script runs ktcp which is the actual user mode TCP/IP networking stack. For more direct control, ktcp can be run directly from the command line, as follows:

ktcp [-b] [-d] [-p eth|slip|cslip] [-m mtu] [-s baud] [-l device] [localip] [gateway] [netmask]
   -b  run in background
   -d  debug mode
   -p  link layer eth, slip or cslip
   -m  specify MTU (default 1024)
   -s  baud rate
   -l  device for SLIP or CSLIP

# ktcp -b -p eth 10.0.2.15 10.0.2.2 255.255.255.0     [start ethernet networking as IP 10.0.2.15]
# ktcp -b -p slip 10.0.2.15 10.0.2.2 255.255.255.0    [start slip networking]
# telnetd                                             [start telnetd]

A shell script 'slattach.sh' is provided to help configure a remote Linux system for SLIP or CSLIP connectivity with ELKS.

Netstat and Arp

After starting networking, the netstat and arp commands will display networking connections/statistics, and the ARP cache, respectively.

Networking with QEMU

QEMU needs specific options to forward incoming packets to the emulated system, but will forward outgoing packets by default.

The qemu.sh script sets up incoming IP packet forwarding for telnet on port 2323 and http on port 8080. This is configured using the following lines in qemu.sh, which also sets up the NE2K emulation network interface card to IRQ 12:

# Simultaneous telnet and http forwarding
FWD="hostfwd=tcp:127.0.0.1:8080-10.0.2.15:80,hostfwd=tcp:127.0.0.1:2323-10.0.2.15:23"
NET="-netdev user,id=mynet,$FWD -device ne2k_isa,irq=12,netdev=mynet"

To access ELKS from Linux, use the following after starting networking using net start as described above:

$ telnet 10.0.2.15 2323                   [telnet to ELKS from Linux]
or input "10.0.2.15:8080" in your browser [http to ELKS]

To access ELKS from macOS, use "localhost" rather than the QEMU default gateway 10.0.2.15:

$ telnet localhost 2323                   [telnet to ELKS from macOS]

To telnet out from ELKS on QEMU to Linux or macOS, no host forwarding is needed as QEMU will auto-forward all outgoing packets, so use telnet as normal, and specify the IP address of your system and port, e.g.:

# telnet 192.168.179.176 23               [telnet from ELKS to host]

In some cases, your system may not have a telnetd server running. On macOS, homebrew can be used to download a telnetd server, which is sometimes easier to setup on port 2424. Here it is being setup on port 23:

/usr/local/opt/telnetd/sbin/telnetd -debug 23 &     (start homebrew telnetd on port 23 on macOS)

To telnet to ELKS telnetd from within ELKS, which now works great and supports multiple connections, connect to the ELKS IP (10.0.2.15) directly, since gethostbyname localhost is not yet implemented:

$ telnet 10.0.2.15              (telnet to ELKS from ELKS)

Processes-and-Memory

ps

Details on ELKS internal process status can be seen by running the ps command:

# ps
  PID   GRP  TTY USER STAT CSEG DSEG  HEAP   FREE   SIZE COMMAND
    1     0      root    S 2eb2 305c  3072   2016  15584 /bin/init 
    7     7    1 root    S 36c8 3865     0   1967  13056 /bin/getty /dev/tty1 
    8     8   S0 root    S 3d06 484f  1166   6818  64896 -/bin/sh 
    9     8   S0 root    R 39f8 3280  1024   5952  18624 ps 

This display shows process 1 /bin/init, which reads the /etc/inittab file and controls ELKS run levels. A getty process is running on /dev/tty1 (the console), which displays a 'login:' prompt and is awaiting a login. A login shell '-/bin/sh' is running on ttyS0.

The labels are PID and GRP for process ID and group, TTY shows the controlling terminal, USER is the user ID of the process, and the STAT column shows the process run status:

R running
S sleeping (waiting on read or child exit, etc)
s uninterruptible sleeping
T stopped
Z zombie (exited with saved exit status for parent)
E exiting

The HEAP and FREE columns show the process heap usage and (free) stack available, which are useful for tuning using the chmem command, explained below.

meminfo

ELKS internal memory usage is displayed via meminfo:

# meminfo
  HEAP   TYPE  SIZE    SEG   TYPE    SIZE  CNT
  eb8a   SEG     12   1eb2   BUF    65536    1
  eb9e   SEG     12   2eb2   CSEG    6816    1
  ebb2   SEG     12   305c   DSEG    8768    1
  ebc6   SEG     12   3280   DSEG   12112    1
  ebda   free    12
  ebee   SEG     12   36c8   CSEG    6608    1
  ec02   TTY    128
  ec8a   TTY     64
  ecd2   SEG     12   3865   DSEG    6448    1
  ece6   SEG     12   39f8   CSEG    4576    1
  ecfa   TTY   1024
  f102   TTY     64
  f14a   SEG     12   3b16   free    7936    0
  f15e   SEG     12   3d06   CSEG   46224    1
  f172   SEG     12   484f   DSEG   18672    1
  f186   SEG     12   4cde   free  339488    0
  f19a   SEG     12   3575   free    5424    0
  f1ae   free  3666
  Total heap   5246     Total mem  528608
  Memory usage  517KB total,  172KB used,  345KB free

The HEAP column shows the kernel local heap address, memory segment type and size. Type SEG is a main memory segment, used for code (CSEG) and data (DSEG), and BUF (level 2 cache external file buffers). TTY segments are the variable-sized TTY (console, serial and PTY) input/output queues. The last lines show the total kernel local heap use, total memory installed, used and free.

chmem

ELKS is designed to use small, separate heap and stack areas for minimum RAM usage. The default heap and stack sizes are 2k bytes. The chmem command is useful for working with ps output to set and show the heap and stack usage for any process. To show the a programs settings, run chmem with no arguments:

# chmem /bin/vi
 TEXT   DATA    BSS   HEAP  STACK  TOTDATA  TOTAL
62400   7008  26336      0      0    41536 103936 /bin/vi

The HEAP and STACK displayed as 0 indicate the system should use the default settings (2k each) for those values.

The following shows telnetd using a smaller heap and stack of 1k bytes:

# chmem /bin/telnetd
 TEXT   DATA    BSS   HEAP  STACK  TOTDATA  TOTAL
 5856    368   3568   1024   1024     5984  11840 /bin/telnetd

Filesystems

The native filesystem for ELKS is Minix v1, which support 14 character filenames. In addition, MSDOS FAT12, FAT16 and FAT32 filesystems are supported, with VFAT long filename support. The block device for mounting filesystems is /dev/hda for the first hard drive, and /dev/hdb for the second. Partitioned filesystems 1-4 are accessed by appending the digit to the block device, e.g. partition 2 on the first drive would be /dev/hda2. Floppy drives are /dev/fd0 for first floppy, and /dev/fd1 the second.

Mounting file systems

To mount a filesystem after booting ELKS, use the mount command and specify the filesystem type, e.g.:

# mount /dev/fd1 /mnt          [mount MINIX floppy B on /mnt]
# mount /dev/hda1 /mnt         [mount MINIX hard drive partition 1 on /mnt]
# mount -t msdos /dev/fd1 /mnt [mount FAT floppy B on /mnt]

Be sure to sync the data on drives before rebooting, and use umount /dev/fd1 to unmount (eject) the floppy after use.

Device Names

Here's a useful list of block device names, useful for mounting, or using the root= option in /bootopts:

/dev/hda       first hard drive, no partitions
/dev/hda1      first hard drive, partition 1
/dev/hda2      first hard drive, partition 2
/dev/hda3      first hard drive, partition 3
/dev/hda4      first hard drive, partition 4
/dev/hdb       second hard drive, no partitions
/deb/hdb1      second hard drive, partition 1
/dev/hdc       usually USB drive
/dev/fd0       floppy A
/dev/fd1       floppy B
/dev/rd0       ramdisk A
/dev/rd1       ramdisk B
/dev/ssd       SSD (ram or flash) disk

Useful-Commands-and-Directories

The following programs are useful for getting the most out of ELKS:

arp                             [display ARP cache]
ls /bin                         [list all commands]
grep                            [search a file for a string]
hd                              [hex dumper]
init 1                          [turn off serial logins, use mouse]
init 3                          [turn on serial logins]
kilo                            [visual editor]
meminfo                         [show memory usage]
miniterm -s 19200               [login via serial to remote system at 19200 baud]
more                            [screen paginate through a file]
mount                           [attach a floppy or HD filesystem]
mouse                           [test mouse]
net start                       [start networking]
netstat                         [show networking statistics and connections]
printenv                        [show environment variables]
ps                              [display running processes]
reboot                          [reboot system in 3 seconds]
sync                            [write unwritten data to disk]
telnet                          [login via network to remote system]
vi                              [UNIX vi editor]

The following files and directories are used for ELKS configuration:

/etc/inittab                    [initial run level and login devices]
/etc/rc.d/rc.sys                [startup shell script, sets date and starts networking]
/etc/net.cfg                    [network configuration]
/etc/mount.cfg                  [auto-mounted or checked filesystems]
/etc/passwd                     [sets login users, user IDs and shells]
/etc/motd                       [build version message displayed at boot]
/etc/issue                      [ELKS version message displayed at login]
/etc/profile                    [global shell settings]
/root/.profile                  [root shell settings]
/bootopts                       [boot options]