ELKS Executable Formats



Compiling the kernel

ELKS C source code is compiled by GCC for the IA16 platform ('ia16-elf-gcc ') and object & static library files are worked
with the BINUTILS ('binutils-ia16'), so using the ELF format.

Linking the kernel

At link time, custom 'ld' scripts (see '*.ld' files) convert ELF format to legacy 'a.out' format, and drop out all that is not 'code', '
data', 'bss' and 'rodata'. So the final executable contains neither symbol nor comment.

Compiling and linking application programs

Application programs in C for the ELKS operating system can also be compiled with GCC for the IA16 platform ('ia16-elf-gcc ')
and linked with the 'ld' scripts. A typical command line would be:

ia16-elf-gcc hello.c -o hello -melks-libc -mcmodel=small

The '-mcmodel=small' parameter specifies an executable with the splitted I/D option, this means code and data are in separate segments.

Alternatively application programs can be compiled with the bcc compiler. A command line for that would be:

bcc -ansi hello.c -o hello

A.OUT executable

Executables are still using the legacy A.OUT format defined for Minix1 with splitted I/D option:

The data section contains initialized data, uninitialized data (bss) and the stack. The default size for uninitialized data (bss) is 4Kbytes
and for the stack 4Kbytes as well. With the ia16-elf-gcc compiler you can use the '-maout-heap=0xffff' parameter to allocate the max heap size
including 4k of stack. You can set the stack size with the '-maout-stack=' parameter. In this case you have to calculate the heap size for the
'
maout-heap' parameter. The maximum size is 65520 bytes or 64Kbytes. If you deduct 4096 bytes for the stack you get 61424 for the heap or
'-maout-heap=0xeff0'.

A.OUT header

uint32_t

type

uint32_t

header size

uint32_t

code section size (.text)

uint32_t

initialized data section (.data)

uint32_t

uninitialized data section (.bss)

uint32_t

unused 1

uint32_t

total data segment size

uint32_t

unused 2

ELKS does not use the optional relocation fields as the IA16 code is natively relocatable inside a segment with relative offsets.

The third byte in the type field is a bitfield giving the properties of the a.out file. ELKS uses the following flags:

A_EXEC
0x10
executable
A_SEP
0x20
separate I/D

The only valid values for ELKS are 0x20 and 0x30 which is 0x10 and 0x20 combined. A program compiled with ia16-elf-gcc will have a 0x30
value in this field while a program compiled with bcc will have 0x20 in there to indicate an executable program. The value 0x10 would
indicate a program with combined I/D which uses the same segment for text and data. This model is not supported by ELKS.

A program with splitted I/D loaded into memory will e.g. have the following layout:



The area between 207k and 208k is the heap. The grey box shows the memory usage in case of a combined I/D exectuable for comparison.

The chmem utility

To view the heap and stack specified for e.g. the kilo program you can call the 'chmem' utility like this:

chmem /bin/kilo

If the default values for heap and stack were specified, chmem will report these as zero. You can modify the heap parameter of a compiled
executable
using the '-h' parameter and the stack with the '-s' parameter.

To view the memory usage of the currently running programs, you can call the 'ps' utility which will report information about this.

The medium executable model

There is an additional executable format defined called the medium or FAR text model. This allows for more than 64k code using relocation to support
a larger kernel size. The max data section size remains 64k. This model is compiled with the following command line:

ia16-elf-gcc -melks -mcmodel=medium

For this model the a.out header has been extended, there are supplementary and relocation structures defined in the '/elks/include/linuxmt/minix.h' header file.


18th of June 2020 Georg Potthast