Skip to content

syscall

pf4 edited this page Sep 10, 2025 · 14 revisions

System Calls

System calls are the interface between user space and kernel space, these are some kernel functions that are securely available to all programs.

Related files

Index

Use System Calls

Usage in Assembly

To trigger a system call, you need to use the int 0x80 interrupt. The system call number is passed in the eax register, and the arguments are passed in the ebx, ecx, edx, esi, and edi registers. The return value is stored in the eax register.

mov eax, 0x0 ; syscall number
mov ebx, 0x1 ; arg1

int 0x80     ; trigger syscall

; return value is in eax

C headers usage

A ready-to-use C header is available in the profan/syscall.h file to use the system calls as functions.

#include <profan/syscall.h>
#include <stdio.h>

int main(void) {
    // call the syscall
    int ret = syscall_process_pid();

    printf("Current PID: %d\n", ret);

    return 0;
}

By default the header only contains the function prototypes, the functions are in the libC which dynamically links to each program. It is possible to declare them locally with the following defines:

// static functions declaration
#define _SYSCALL_CREATE_STATIC
#include <profan/syscall.h>

/* OR */

// global functions declaration
#define _SYSCALL_CREATE_FUNCS
#include <profan/syscall.h>

The #define _SYSCALL_CREATE_STATIC will create static functions that can be used in the current file only. The #define _SYSCALL_CREATE_FUNCS will create global functions that can be used in the whole program.

Note

You can also use asm volatile to call the system calls directly in C.

Syscalls List

The list represents them in the form of a C function prototype but they are all callable in assembler with their ID...

File System

Note

File system syscalls are really low-level, you should probably use the libC instead.

0: fs_get_default

Returns a pointer to the default file system structure.

filesys_t *syscall_fs_get_default (void);
  • Returns: Pointer to the structure.

1: fs_read

Reads data from a container. Reading is static, you have to use the offset (not like read).

int syscall_fs_read (
    uint32_t   sid,
    void      *buf,
    uint32_t   offset,
    uint32_t   size
);
  • sid: Container sector ID
  • buf: Buffer to store the data
  • offset: Offset to start reading
  • size: Number of bytes to read
  • Returns: 0 on success, 1 on error.

2: fs_write

Writes data to a container. Writing is static, you have to use the offset (not like write).

int syscall_fs_write (
    uint32_t   sid,
    void      *buf,
    uint32_t   offset,
    uint32_t   size
);
  • sid: Container sector ID
  • buf: Buffer to write
  • offset: Offset to start writing
  • size: Number of bytes to write
  • Returns: 0 on success, 1 on error.

3: fs_set_size

Sets the size of a container. And cuts the data if the size is smaller.

int syscall_fs_set_size (
    uint32_t   sid,
    uint32_t   size
);
  • sid: Container sector ID
  • size: New size of the container
  • Returns: 0 on success, 1 on error.

4: fs_get_size

Returns the size of a container.

uint32_t syscall_fs_get_size (
    uint32_t   sid
);
  • sid: Container sector ID
  • Returns: Size of the container

5: fs_delete

Deletes a container and all its data.

int syscall_fs_delete (
    uint32_t   sid
);
  • sid: Container sector ID
  • Returns: 0 on success, 1 on error.

6: fs_init

Initializes a new container.

uint32_t syscall_fs_init (
    uint32_t   device_id,
    char      *meta
);
  • device_id: ID of the device to use
  • meta: Metadata of the container
  • Returns: Sector ID of the new container

7: fs_meta

Get or set the metadata of a container.

char *syscall_fs_meta (
    uint32_t   sid,
    char      *meta
);
  • sid: Container sector ID
  • meta: Metadata to set (NULL to get)
  • Returns: Metadata of the container (NULL on error)

Kernel Memory Allocation

Note

The libC functions provide a more user-friendly and efficient way to allocate memory.

8: mem_alloc

Use kernel memory allocation to allocate memory.

void *syscall_mem_alloc (
    uint32_t size,
    int      state,
    uint32_t align
);
  • size: Size of the memory to allocate
  • state: Type of allocation
  • align: Alignment of the memory
  • Returns: Address of the allocated memory

State as no impact on the allocation, it is just a way to categorize the memory allocation to track it and free it later. It is advisable to use only the 1 and 2 states for allocations in user programs.

State Description
0 free block
1 simple alloc
2 kernel alloc
3 scuba page
4 module loader
5 runtime args
6 memory manager
7 initial alloc

9: mem_free

Free a memory block allocated by mem_alloc.

int syscall_mem_free (
    void *addr
);
  • addr: Address of the memory block to free
  • Returns: 0 on success, 1 on error

10: mem_free_all

Free all memory blocks allocated by a process.

Warning

This function is dangerous, it will free all memory blocks allocated by the process, including the dynamic linker! Use profan_cleanup of the profan.h header instead.

int syscall_mem_free_all (
    int pid,
    int state
);
  • pid: Process ID
  • state: State of the memory blocks to free or 0 to free all states
  • Returns: number of freed blocks

11: mem_fetch

Get the size of an allocated memory block or change its pid.

uint32_t syscall_mem_fetch (
    void *addr,
    int   arg
);
  • addr: Address of the memory block
  • arg: New pid or 0 to get the size
  • Returns: Size or -1 on error

12: mem_info

Get information about memory and memory allocation.

int syscall_mem_info (
    int mode,
    int arg
);
  • mode: Information to get
  • arg: Argument for the information
  • Returns: Information
Mode Description
0 physical memory size
1 base address
2 MEM_PARTS size
3 MEM_PARTS addr
4 total alloc count
5 total free count
6 used memory size
07 simple alloc count of pid arg
08 simple alloc size of pid arg
09 alloc count of type arg
10 alloc size of type arg
11 all alloc count of pid arg
12 all alloc size of pid arg

Clock and Timer

13: ms_get

Returns the number of milliseconds since the system started.

uint32_t syscall_ms_get (void);
  • Returns: Number of milliseconds

14: time_get

Returns the current time in a tm structure.

int syscall_time_get (
    struct tm *ptr
);
  • ptr: Pointer to the tm_t structure
  • Returns: 0 on success, 1 on error

Console and Display

15: font_get

Returns a pointer to the raw kernel font data.

uint8_t *syscall_font_get (void);
  • Returns: Pointer to the font data

16: kcnprint

Prints a string to the kernel console, ANSI codes are supported.

int syscall_kcnprint (
    char *str,
    int   len,
    char  color
);
  • str: String to print
  • len: Length of the string
  • color: Color of the beginning of the string
  • Returns: Number of printed characters

17: vesa_info

Get information about the VESA mode.

int syscall_vesa_info (
    int mode
);
  • mode: Information to get
Mode Description
0 width
1 height
2 pitch
3 framebuffer address
4 state (active or not)

The following defines are available to get the information:

#define syscall_vesa_width()   syscall_vesa_info(0)
#define syscall_vesa_height()  syscall_vesa_info(1)
#define syscall_vesa_pitch()   syscall_vesa_info(2)
#define syscall_vesa_fb() ((void *) syscall_vesa_info(3))
#define syscall_vesa_state()   syscall_vesa_info(4)

AFFT I/O

18: afft_read

Read data from an AFFT.

int syscall_afft_read (
    int      id,
    void    *buf,
    uint32_t offset,
    uint32_t size
);
  • id: AFFT ID
  • buf: Buffer to store the data
  • offset: Offset to start reading
  • size: Number of bytes to read
  • Returns: 0 on success, 1 on error

19: afft_write

Write data to an AFFT.

int syscall_afft_write (
    int      id,
    void    *buf,
    uint32_t offset,
    uint32_t size
);
  • id: AFFT ID
  • buf: Buffer to write
  • offset: Offset to start writing
  • size: Number of bytes to write
  • Returns: 0 on success, 1 on error

20: afft_cmd

Send a command to an AFFT.

int syscall_afft_cmd (
    int id,
    int cmd,
    int arg
);
  • id: AFFT ID
  • cmd: Command to send
  • arg: Argument for the command
  • Returns: 0 on success, 1 on error

Keyboard

21: sc_get

Get the oldest scancode from the keyboard buffer.

int syscall_sc_get (void);
  • Returns: Scancode

System Management

22: sys_power

Reboot or shutdown the system.

int syscall_sys_power (
    int mode
);
  • mode: Action to do
  • Returns: 0 on success, 1 on error
Mode Description
0 reboot
1 shutdown

23: elf_exec

Execute a binary file with arguments and environment variables. The function will replace the current page directory with a new one and jump to the binary file (similar to the execve function).

Warning

The libC or run_ifexist function is probably a better way to run a program safely.

int syscall_elf_exec(
    uint32_t sid,
    int      argc,
    char   **argv,
    char   **envp
);
  • sid: Sector ID of the binary file
  • argc: Number of arguments
  • argv: Arguments
  • envp: Environment variables
  • Returns: 0 on success, 1 on error

Process Management

profanOS processes management functions are a bit different from the standard POSIX functions, some of the POSIX functions are available in the libC too.

24: process_create

Create a new process with a function pointer.

int syscall_process_create (
    void     *func,
    int       copy_page,
    int       argc,
    uint32_t *argv
);
  • func: Function pointer
  • copy_page: Copy the parent page directory
  • argc: Number of arguments
  • argv: Arguments (32bit numbers pushed on the stack)
  • Returns: Process ID

Note

To push a struct on the stack, you should cut it into 32bit numbers and increment the argument count.

25: process_fork

Fork the current process (exactly like the fork function) but don't wake up the child process.

int syscall_process_fork (void);
  • Returns: Process ID of the child process

26: process_sleep

Put a process to sleep for a number of milliseconds. The process will not be scheduled until the time is over.

int syscall_process_sleep (
    uint32_t pid,
    uint32_t ms
);
  • pid: Process ID
  • ms: Number of milliseconds

Note

ms can be 0 to switch to the next process immediately (like yield), UINT32_MAX to sleep forever or any other value to sleep for a number of milliseconds.

27: process_wakeup

Wakeup a sleeping process. The process will be scheduled again. The handover parameter is used to automatically wait for pid to finish before waking up the current process.

int syscall_process_wakeup (
    uint32_t pid
    int      handover
);
  • pid: Process ID
  • handover: Handover the process
  • Returns: 0 on success, 1 on error

28: process_wait

Wait for a process to finish. The function will put the current process to sleep until the process with the given PID finishes.

int syscall_process_wait (
    int      pid,
    uint8_t *retcode
    int      block
);
  • pid: Process ID (-1 to wait for any child)
  • retcode: pointer to an u8 to store the return code
  • block: Block the current process (similar to WNOHANG)
  • Returns: Process ID of the finished process

Note

The sys/wait.h header is available to use wait functions in a more POSIX way.

29: process_kill

Kill a process and free its memory.

int syscall_process_kill (
    uint32_t pid,
    int      retcode,
);
  • pid: Process ID
  • retcode: Return code of the process
  • Returns: 1 on error (no return on success)

30: process_pid

Get the PID of the current process.

uint32_t syscall_process_pid (void);
  • Returns: Process ID

31: process_info

Get information about a process.

uint32_t syscall_process_info (
    uint32_t pid,
    int      mode
    void    *ptr
);
  • pid: Process ID
  • mode: Information to get
  • ptr: Pointer to store the information

The following defines are available to get the information:

#define PROC_INFO_PPID     0    // get parent PID
#define PROC_INFO_STATE    1    // get state
#define PROC_INFO_SLEEP_TO 2    // get sleep timeout
#define PROC_INFO_RUN_TIME 3    // get run time
#define PROC_INFO_NAME     4    // get name
#define PROC_INFO_STACK    5    // get stack pointer
#define PROC_INFO_SET_NAME 6    // set name (in ptr)
State Description
0 free
1 zombie
2 sleeping
3 in queue
4 running
5 idle (pid 1 only)

32: process_list_all

List all the alive processes.

int syscall_process_list_all (
    uint32_t *buf,
    int       max
);
  • buf: Buffer to store the PIDs
  • max: Size of the buffer
  • Returns: Number of PIDs

Kernel Modules

33: mod_load

Load a kernel module from a path

int syscall_mod_load (
    char    *path,
    uint32_t id
);
  • path: Path to the module
  • id: ID of the module
  • Returns: function count or error code
Error code Description
-1 file not found
-2 invalid module id range
-3 file is not a dynamic ELF
-4 ELF relocation failed
-5 failed to read functions
-6 init function exited with error

34: mod_unload

Unload a kernel module

int syscall_mod_unload (
    uint32_t id
);
  • id: ID of the module
  • Returns: 0 on success, 1 on error

Virtual Memory

35: scuba_generate

Allocate and map virtual page(s) to physical memory.

void *syscall_scuba_generate(void *virt, uint32_t count);
  • virt: Virtual address
  • count: Number of following pages
  • Returns: physical address

36: scuba_map

Map a virtual page to physical memory.

int syscall_scuba_map(void *virt, void *phys, int child_copy);
  • virt: Virtual address
  • phys: Physical address
  • child_copy: Copy the page in future children
  • Returns: 0 on success, 1 on error

37: scuba_unmap

Unmap a virtual page.

int syscall_scuba_unmap(void *virt);
  • virt: Virtual address
  • Returns: 0 on success, 1 on error

38: scuba_phys

Get the physical address of a virtual address.

void *syscall_scuba_phys(void *virt);
  • virt: Virtual address
  • Returns: Physical address

Updated for generic kernel 1.3.1b


Halloween Happy Halloween profanOS! by @louisraverdy.

User Guide

Development Guide

Library Documentation

Clone this wiki locally