Files
vystem/docs/vyx.md
2026-05-27 19:34:54 +02:00

5.1 KiB

The VYX executable format

Introduction

The VYX format, standing for Vystem Executable, is a very simple binary format made for simple binary loading from any environnement. As long as you can access the .vyx file, you can load a VYX binary.

Header

Because VYX format has been designed to provide a simple way to load any kind of binary, we wanted to make it as easily updatable as possible. For the moment, it's just a very simple format built for loading the Shelter kernel, but in a few updates, it will be use for loading all kind of binaries. No spoiler on that. The header is designed like that:

  • Signature: three bytes spelling VyX in ASCII
  • VYX format version: the version of the VYX format used in the binary, represented as an uint16_t. Depending on the version number, the following structure will probably changed a lot. The current version is 0x0002.
  • .text base address: the virtual address (VA) at which the .text should be loaded. It should be aligned on the boundary of a 4 kilobytes page. Represented as an uint64_t
  • stack base: the VA at which the stack base should be setup. Be careful, it indicates the base, not the top. It should be aligned on the boundary of a 4 kilobytes page. Represented as an uint64_t
  • the size of the .text section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t
  • the size of the .data section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t
  • the size of the .rodata section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t
  • the size of the .bss section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t
  • the number of payloads integrated into the VYX file. Represented as an uint64_t

All the multibytes integers should be written in little endian. The VYX executable format has been made for x86-64 only binary.

Sections organizations

The VYX format only support three sections inside the binary that should be in the following order: .text, .data, .rodata. The .bss should be initialized and zeroed by the loader just after the .rodata section. The space occupied by the three sections inside the binary should occupy a multiple of 4096 bytes, according to the size indicated in the header, padded with zeroes if necessary. For example, if each sections take 2 pages, after being padded to the nearest multiple of 4096 bytes superior to their real size, and that the .text base is 0x1000, .text should be located at 0x1000, .data at 0x3000, .rodata at 0x5000 and .bss at 0x7000

Payloads

The VYX format now support, as of 0x0002 version, the integration of payloads. There are additionnal ressources that the VYX loader need to discover.

This discovery process is started from the end of the .rodata section. The loader need to look for the signature VPAYLOAD in ASCII. Once localised, the loader know it has found a payload header, which is structured like this:

  • Signature: 8 bytes
  • Payload size in bytes: represented as an uint32_t
  • Payload size in amount of 4 kilobytes pages: represented as an uint32_t
  • Payload mapping flags: 1 byte specifying how the VYX loader should map the payload in the virtual address space of the program being loaded:
    • Bit 0: if 1, the payload should be mapped as executable data
    • Bit 1: if 1, the payload should be mapped as writable data
  • Payload virtual address! the address at which the payload should be mapped by the VYX loader. Should be aligned on 4 kilobytes pages frontier and shouldn't be in reserved virtual address space for program image and stack

Then, for the indicated payload size in bytes, the VYX loader should extract the payload (that come immediately after the payload header) and map it accordingly. Restriction can be applied on mapping flags depending on the VYX loader context.

If the payload size in bytes is bigger that the remaining size in bytes into the VYX file, it indicates VYX file corruption. The discovery process continue as long as the amount of payloads discovered isn't the same as indicated into the header.

Specifications

The VYX binaries use the SystemV ABI. They doesn't support rellocations nor dynamic linking. While relative addressing into the binary code is theoretically working, all the Vystem binaries will be compiled 64 bits static addressing with position-dependent code (non-PIC), especially the kernel. That why respecting the indicated .text section base and order of sections loading is extremely important. Obviously, the right privileges should be applied in term of pagging: no execution unless .text pages, read only .text and .rodata sections, read-write .data and .bss sections. For the moment, the entry point is located at the base of the .text section. The stack size can be decided at the convenience of the loader, but the stack size used for the Shelter kernel is, for the moment, 256 kilobytes. The stack growing downward, the initial stack pointer should be set to stack base + stack size. A reference implementation of a VYX loader, exploiting all currently documented features, can be found into the Blastproof bootloader source code.