I386_VM86(2)

okay bestie, welcome to the System Calls Manual section of the Unix lore πŸ’… this one's a deep cut, like a b-side from 1998 that only the real ones know about. It's giving vintage. It's giving x86 real mode. Let's get into it πŸŽ€


🌸 LIBRARY 🌸

Standard C Library (libc, -lc) β€” yeah she lives in libc, no extra credit needed, you already have her 🫢


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <sys/types.h>
#include <machine/sysarch.h>
#include <machine/vm86.h>

int
i386_vm86(int function, void *data);

like three whole includes, she's high maintenance but honestly? worth it ✨


πŸ’– DESCRIPTION πŸ’–

So i386_vm86() is the syscall you call when you want to do various vm86 related functions. That's the whole vibe. It's a multiplexer, she contains multitudes πŸ’€

The function argument is the main character here, and she can be one of these three values:

  • VM86_INIT β€” this initializes the kernel's vm86 parameter area for the process, and permits the process to make vm86 calls πŸŽ€ The data argument points to this structure:
struct vm86_init_args {
        int     debug;
        int     cpu_type;
        u_char  int_map[32];
};
  • the debug argument is used to turn on debugging code (not me turning on debug mode and immediately forgetting what I was doing πŸ™ˆ)
  • the cpu_type argument controls the type of CPU being emulated, and is currently unimplemented β€” so like, she's there, she's just not doing anything yet, queen of showing up 😭
  • the int_map argument is a bitmap that decides whether vm86 interrupts should be handled in vm86 mode, or reflected back to the process. If the Nth bit is set, the interrupt will be reflected to the process, otherwise it will be dispatched by the vm86 interrupt table. periodt ✨
  • VM86_INTCALL β€” this lets the process make calls to vm86 interrupt handlers. It effectively simulates an INT instruction, no cap. data should point to this structure:
struct vm86_intcall_args {
        int     intnum;
        struct  vm86frame vmf;
};
  • intnum specifies the operand of INT for the simulated call. A value of 0x10, for example, would often be used to call into the VGA BIOS. iconic behavior fr fr
  • vmf is used to initialize CPU registers according to the calling convention for the interrupt handler 🧚
  • VM86_GET_VME β€” this one's a little getter, she retrieves the current state of the Pentium(r) processor's VME (Virtual-8086 Mode Extensions) flag, which is bit 0 of CR4. data should be initialized to point to this:
struct vm86_vme_args {
        int     state;                  /* status */
};
  • state will contain the state of the VME flag on return πŸ‘‘

okay and now the part that's giving actual lore 🫢

vm86 mode is entered by calling sigreturn(2) with the correct machine context for vm86, and with the PSL_VM bit set. Control returns to the process upon delivery of a signal. that's the whole ritual bestie, that's the vibe check 🌈


πŸ’… RETURN VALUES πŸ’…

The i386_vm86() function returns the value 0 if successful β€” slay ✨ otherwise the value -1 is returned and the global variable errno is set to indicate the error. we hate to see it but at least she tells you why πŸ’€


πŸ”₯ ERRORS πŸ”₯

The i386_vm86() system call will fail if:

  • [EINVAL] β€” the kernel does not have vm86 support, or an invalid function was specified. (either your kernel said "not today" or you asked for something that doesn't exist πŸ™ˆ)
  • [ENOMEM] β€” there is not enough memory to initialize the kernel data structures. she's broke, it happens 😭

🌟 AUTHORS 🌟

This man page was written by Jonathan Lemon, and updated by Bruce M Simpson. absolute legends, we stan πŸ«ΆπŸ’œ


ngl bestie, this page is old old. like, July 27, 1998 old. Debian shipped it, the manual section is I386_VM86(2), and she has aged like fine wine β€” still out here controlling vm86-related functions after all these years πŸ‘‘πŸŒΈ bye bestie, go make some vm86 calls responsibly πŸ’–
πŸ“¦ where this page comes from