-
Notifications
You must be signed in to change notification settings - Fork 7
syscall
System calls are the interface between user space and kernel space, these are some kernel functions that are securely available to all programs.
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 eaxA 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.
The list represents them in the form of a C function prototype but they are all callable in assembler with their ID...
Note
File system syscalls are really low-level, you should probably use the libC instead.
Returns a pointer to the default file system structure.
filesys_t *syscall_fs_get_default (void);- Returns: Pointer to the structure.
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:
0on success,1on error.
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:
0on success,1on error.
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:
0on success,1on error.
Returns the size of a container.
uint32_t syscall_fs_get_size (
uint32_t sid
);-
sid: Container sector ID - Returns: Size of the container
Deletes a container and all its data.
int syscall_fs_delete (
uint32_t sid
);-
sid: Container sector ID -
Returns:
0on success,1on error.
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
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 (NULLto get) -
Returns: Metadata of the container (
NULLon error)
Note
The libC functions provide a more user-friendly and efficient way to allocate memory.
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 |
Free a memory block allocated by mem_alloc.
int syscall_mem_free (
void *addr
);-
addr: Address of the memory block to free -
Returns:
0on success,1on error
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 or0to free all states - Returns: number of freed blocks
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 or0to get the size -
Returns: Size or
-1on error
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
|
Returns the number of milliseconds since the system started.
uint32_t syscall_ms_get (void);- Returns: Number of milliseconds
Returns the current time in a tm structure.
int syscall_time_get (
struct tm *ptr
);-
ptr: Pointer to thetm_tstructure -
Returns:
0on success,1on error
Returns a pointer to the raw kernel font data.
uint8_t *syscall_font_get (void);- Returns: Pointer to the font data
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
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)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:
0on success,1on error
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:
0on success,1on error
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:
0on success,1on error
Get the oldest scancode from the keyboard buffer.
int syscall_sc_get (void);- Returns: Scancode
Reboot or shutdown the system.
int syscall_sys_power (
int mode
);-
mode: Action to do -
Returns:
0on success,1on error
| Mode | Description |
|---|---|
0 |
reboot |
1 |
shutdown |
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:
0on success,1on error
profanOS processes management functions are a bit different from the standard POSIX functions, some of the POSIX functions are available in the libC too.
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.
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
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.
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:
0on success,1on error
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 toWNOHANG) - Returns: Process ID of the finished process
Note
The sys/wait.h header is available to use wait functions
in a more POSIX way.
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:
1on error (no return on success)
Get the PID of the current process.
uint32_t syscall_process_pid (void);- Returns: Process ID
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) |
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
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 |
Unload a kernel module
int syscall_mod_unload (
uint32_t id
);-
id: ID of the module -
Returns:
0on success,1on error
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
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:
0on success,1on error
Unmap a virtual page.
int syscall_scuba_unmap(void *virt);-
virt: Virtual address -
Returns:
0on success,1on error
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
