mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 02:16:58 +00:00
src/kernel --> src/
This commit is contained in:
94
src/userland/libc/libui.c
Normal file
94
src/userland/libc/libui.c
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "libui.h"
|
||||
#include "syscall.h"
|
||||
#include "syscall_user.h"
|
||||
#include <stddef.h>
|
||||
|
||||
extern uint64_t syscall3(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3);
|
||||
extern uint64_t syscall4(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
|
||||
extern uint64_t syscall5(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5);
|
||||
|
||||
// sys_gui uses syscall #3
|
||||
#define SYS_GUI 3
|
||||
#define GUI_CMD_GET_SCREEN_SIZE 17
|
||||
|
||||
ui_window_t ui_window_create(const char *title, int x, int y, int w, int h) {
|
||||
uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h };
|
||||
return (ui_window_t)syscall3(SYS_GUI, GUI_CMD_WINDOW_CREATE, (uint64_t)title, (uint64_t)params);
|
||||
}
|
||||
|
||||
bool ui_get_event(ui_window_t win, gui_event_t *ev) {
|
||||
int res = (int)syscall3(SYS_GUI, GUI_CMD_GET_EVENT, (uint64_t)win, (uint64_t)ev);
|
||||
return res != 0;
|
||||
}
|
||||
|
||||
void ui_draw_rect(ui_window_t win, int x, int y, int w, int h, uint32_t color) {
|
||||
uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h };
|
||||
syscall4(SYS_GUI, GUI_CMD_DRAW_RECT, (uint64_t)win, (uint64_t)params, (uint64_t)color);
|
||||
}
|
||||
|
||||
void ui_draw_rounded_rect_filled(ui_window_t win, int x, int y, int w, int h, int radius, uint32_t color) {
|
||||
uint64_t params[5] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h, (uint64_t)radius };
|
||||
syscall4(SYS_GUI, GUI_CMD_DRAW_ROUNDED_RECT_FILLED, (uint64_t)win, (uint64_t)params, (uint64_t)color);
|
||||
}
|
||||
|
||||
void ui_draw_string(ui_window_t win, int x, int y, const char *str, uint32_t color) {
|
||||
uint64_t coords = ((uint64_t)x & 0xFFFFFFFF) | ((uint64_t)y << 32);
|
||||
syscall5(SYS_GUI, GUI_CMD_DRAW_STRING, (uint64_t)win, coords, (uint64_t)str, (uint64_t)color);
|
||||
}
|
||||
|
||||
void ui_draw_string_bitmap(ui_window_t win, int x, int y, const char *str, uint32_t color) {
|
||||
uint64_t coords = ((uint64_t)x & 0xFFFFFFFF) | ((uint64_t)y << 32);
|
||||
syscall5(SYS_GUI, GUI_CMD_DRAW_STRING_BITMAP, (uint64_t)win, coords, (uint64_t)str, (uint64_t)color);
|
||||
}
|
||||
|
||||
void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h) {
|
||||
uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h };
|
||||
syscall3(SYS_GUI, GUI_CMD_MARK_DIRTY, (uint64_t)win, (uint64_t)params);
|
||||
}
|
||||
|
||||
void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data) {
|
||||
uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h };
|
||||
syscall4(SYS_GUI, GUI_CMD_DRAW_IMAGE, (uint64_t)win, (uint64_t)params, (uint64_t)image_data);
|
||||
}
|
||||
|
||||
uint32_t ui_get_string_width(const char *str) {
|
||||
return (uint32_t)syscall3(SYS_GUI, GUI_CMD_GET_STRING_WIDTH, (uint64_t)str, 0);
|
||||
}
|
||||
|
||||
uint32_t ui_get_font_height(void) {
|
||||
return (uint32_t)syscall3(SYS_GUI, GUI_CMD_GET_FONT_HEIGHT, 0, 0);
|
||||
}
|
||||
|
||||
void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h) {
|
||||
syscall3(SYS_GUI, GUI_CMD_GET_SCREEN_SIZE, (uint64_t)out_w, (uint64_t)out_h);
|
||||
}
|
||||
|
||||
void ui_draw_string_scaled(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale) {
|
||||
uint64_t coords = ((uint64_t)x & 0xFFFFFFFF) | ((uint64_t)y << 32);
|
||||
// Pack color into lower 32, scale (as uint32_t representation) into upper 32
|
||||
uint32_t scale_bits = *(uint32_t*)&scale;
|
||||
uint64_t packed_arg5 = ((uint64_t)scale_bits << 32) | (color & 0xFFFFFFFF);
|
||||
syscall5(SYS_GUI, GUI_CMD_DRAW_STRING_SCALED, (uint64_t)win, coords, (uint64_t)str, packed_arg5);
|
||||
}
|
||||
|
||||
uint32_t ui_get_string_width_scaled(const char *str, float scale) {
|
||||
uint32_t scale_bits = *(uint32_t*)&scale;
|
||||
return (uint32_t)syscall4(SYS_GUI, GUI_CMD_GET_STRING_WIDTH_SCALED, (uint64_t)str, (uint64_t)scale_bits, 0);
|
||||
}
|
||||
|
||||
uint32_t ui_get_font_height_scaled(float scale) {
|
||||
uint32_t scale_bits = *(uint32_t*)&scale;
|
||||
return (uint32_t)syscall3(SYS_GUI, GUI_CMD_GET_FONT_HEIGHT_SCALED, (uint64_t)scale_bits, 0);
|
||||
}
|
||||
|
||||
void ui_window_set_title(ui_window_t win, const char *title) {
|
||||
syscall3(SYS_GUI, GUI_CMD_WINDOW_SET_TITLE, (uint64_t)win, (uint64_t)title);
|
||||
}
|
||||
|
||||
void ui_window_set_resizable(ui_window_t win, bool resizable) {
|
||||
syscall3(SYS_GUI, GUI_CMD_WINDOW_SET_RESIZABLE, (uint64_t)win, resizable ? 1 : 0);
|
||||
}
|
||||
|
||||
void ui_set_font(ui_window_t win, const char *path) {
|
||||
syscall3(SYS_GUI, GUI_CMD_SET_FONT, (uint64_t)win, (uint64_t)path);
|
||||
}
|
||||
71
src/userland/libc/libui.h
Normal file
71
src/userland/libc/libui.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef LIBUI_H
|
||||
#define LIBUI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// GUI Command IDs
|
||||
#define GUI_CMD_WINDOW_CREATE 1
|
||||
#define GUI_CMD_DRAW_RECT 2
|
||||
#define GUI_CMD_DRAW_STRING 3
|
||||
#define GUI_CMD_MARK_DIRTY 4
|
||||
#define GUI_CMD_GET_EVENT 5
|
||||
#define GUI_CMD_DRAW_ROUNDED_RECT_FILLED 6
|
||||
#define GUI_CMD_DRAW_IMAGE 7
|
||||
#define GUI_CMD_GET_STRING_WIDTH 8
|
||||
#define GUI_CMD_GET_FONT_HEIGHT 9
|
||||
#define GUI_CMD_WINDOW_SET_RESIZABLE 14
|
||||
#define GUI_CMD_DRAW_STRING_BITMAP 10
|
||||
#define GUI_CMD_DRAW_STRING_SCALED 11
|
||||
#define GUI_CMD_GET_STRING_WIDTH_SCALED 12
|
||||
#define GUI_CMD_GET_FONT_HEIGHT_SCALED 13
|
||||
#define GUI_CMD_WINDOW_SET_TITLE 15
|
||||
#define GUI_CMD_SET_FONT 16
|
||||
|
||||
// Event Types
|
||||
#define GUI_EVENT_NONE 0
|
||||
#define GUI_EVENT_PAINT 1
|
||||
#define GUI_EVENT_CLICK 2
|
||||
#define GUI_EVENT_RIGHT_CLICK 3
|
||||
#define GUI_EVENT_CLOSE 4
|
||||
#define GUI_EVENT_KEY 5
|
||||
#define GUI_EVENT_KEYUP 10
|
||||
|
||||
#define GUI_EVENT_MOUSE_DOWN 6
|
||||
#define GUI_EVENT_MOUSE_UP 7
|
||||
#define GUI_EVENT_MOUSE_MOVE 8
|
||||
#define GUI_EVENT_MOUSE_WHEEL 9
|
||||
#define GUI_EVENT_RESIZE 11
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
int arg1; // For click: x
|
||||
int arg2; // For click: y
|
||||
int arg3; // For click: button state
|
||||
} gui_event_t;
|
||||
|
||||
// Window Handle
|
||||
typedef uint64_t ui_window_t;
|
||||
|
||||
// libui API
|
||||
ui_window_t ui_window_create(const char *title, int x, int y, int w, int h);
|
||||
bool ui_get_event(ui_window_t win, gui_event_t *ev);
|
||||
|
||||
void ui_draw_rect(ui_window_t win, int x, int y, int w, int h, uint32_t color);
|
||||
void ui_draw_rounded_rect_filled(ui_window_t win, int x, int y, int w, int h, int radius, uint32_t color);
|
||||
void ui_draw_string(ui_window_t win, int x, int y, const char *str, uint32_t color);
|
||||
void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h);
|
||||
void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data);
|
||||
uint32_t ui_get_string_width(const char *str);
|
||||
uint32_t ui_get_font_height(void);
|
||||
void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h);
|
||||
void ui_draw_string_bitmap(ui_window_t win, int x, int y, const char *str, uint32_t color);
|
||||
|
||||
void ui_draw_string_scaled(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale);
|
||||
uint32_t ui_get_string_width_scaled(const char *str, float scale);
|
||||
uint32_t ui_get_font_height_scaled(float scale);
|
||||
void ui_window_set_title(ui_window_t win, const char *title);
|
||||
void ui_window_set_resizable(ui_window_t win, bool resizable);
|
||||
void ui_set_font(ui_window_t win, const char *path);
|
||||
|
||||
#endif
|
||||
324
src/userland/libc/stdlib.c
Normal file
324
src/userland/libc/stdlib.c
Normal file
@@ -0,0 +1,324 @@
|
||||
#include "stdlib.h"
|
||||
#include "syscall.h"
|
||||
|
||||
// Block allocator over sys_sbrk with coalescing and splitting
|
||||
typedef struct BlockMeta {
|
||||
size_t size;
|
||||
int free;
|
||||
struct BlockMeta *next;
|
||||
struct BlockMeta *prev;
|
||||
} BlockMeta;
|
||||
|
||||
#define META_SIZE sizeof(BlockMeta)
|
||||
#define MIN_SPLIT_SIZE 64
|
||||
#define ALIGN8(x) (((x) + 7) & ~(size_t)7)
|
||||
|
||||
static BlockMeta *heap_head = NULL;
|
||||
static BlockMeta *heap_tail = NULL;
|
||||
|
||||
static BlockMeta *request_space(size_t size) {
|
||||
BlockMeta *block = (BlockMeta *)sys_sbrk(0);
|
||||
void *request = sys_sbrk(size + META_SIZE);
|
||||
if (request == (void*)-1) return NULL;
|
||||
|
||||
block->size = size;
|
||||
block->free = 0;
|
||||
block->next = NULL;
|
||||
block->prev = heap_tail;
|
||||
|
||||
if (heap_tail) heap_tail->next = block;
|
||||
else heap_head = block;
|
||||
heap_tail = block;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
// Split a block if remainder is large enough
|
||||
static void split_block(BlockMeta *block, size_t size) {
|
||||
size_t remain = block->size - size - META_SIZE;
|
||||
if (block->size < size + META_SIZE + MIN_SPLIT_SIZE) return;
|
||||
|
||||
BlockMeta *new_block = (BlockMeta *)((char *)(block + 1) + size);
|
||||
new_block->size = remain;
|
||||
new_block->free = 1;
|
||||
new_block->next = block->next;
|
||||
new_block->prev = block;
|
||||
|
||||
if (block->next) block->next->prev = new_block;
|
||||
else heap_tail = new_block;
|
||||
block->next = new_block;
|
||||
block->size = size;
|
||||
}
|
||||
|
||||
void *malloc(size_t size) {
|
||||
if (size == 0) return NULL;
|
||||
|
||||
size = ALIGN8(size);
|
||||
|
||||
// First-fit search (faster than best-fit for large heaps)
|
||||
BlockMeta *current = heap_head;
|
||||
while (current) {
|
||||
if (current->free && current->size >= size) {
|
||||
split_block(current, size);
|
||||
current->free = 0;
|
||||
return (current + 1);
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// No suitable block found, request more space
|
||||
BlockMeta *block = request_space(size);
|
||||
if (!block) return NULL;
|
||||
return (block + 1);
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
if (!ptr) return;
|
||||
|
||||
BlockMeta *block = (BlockMeta *)ptr - 1;
|
||||
block->free = 1;
|
||||
|
||||
// Coalesce with next block
|
||||
if (block->next && block->next->free) {
|
||||
block->size += META_SIZE + block->next->size;
|
||||
block->next = block->next->next;
|
||||
if (block->next) block->next->prev = block;
|
||||
else heap_tail = block;
|
||||
}
|
||||
|
||||
// Coalesce with previous block
|
||||
if (block->prev && block->prev->free) {
|
||||
block->prev->size += META_SIZE + block->size;
|
||||
block->prev->next = block->next;
|
||||
if (block->next) block->next->prev = block->prev;
|
||||
else heap_tail = block->prev;
|
||||
}
|
||||
}
|
||||
|
||||
void *calloc(size_t nelem, size_t elsize) {
|
||||
size_t size = nelem * elsize;
|
||||
void *ptr = malloc(size);
|
||||
if (ptr) {
|
||||
char *p = ptr;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
p[i] = 0;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
if (!ptr) {
|
||||
return malloc(size);
|
||||
}
|
||||
if (size == 0) {
|
||||
free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BlockMeta *block = (BlockMeta*)ptr - 1;
|
||||
if (block->size >= size) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *new_ptr = malloc(size);
|
||||
if (!new_ptr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *src = ptr;
|
||||
char *dst = new_ptr;
|
||||
for (size_t i = 0; i < block->size; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
free(ptr);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
unsigned char *p = (unsigned char *)s;
|
||||
while (n--) *p++ = (unsigned char)c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n) {
|
||||
unsigned char *d = (unsigned char *)dest;
|
||||
const unsigned char *s = (const unsigned char *)src;
|
||||
while (n--) *d++ = *s++;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n) {
|
||||
unsigned char *d = (unsigned char *)dest;
|
||||
const unsigned char *s = (const unsigned char *)src;
|
||||
if (d < s) {
|
||||
while (n--) *d++ = *s++;
|
||||
} else {
|
||||
d += n;
|
||||
s += n;
|
||||
while (n--) *--d = *--s;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const unsigned char *p1 = (const unsigned char *)s1;
|
||||
const unsigned char *p2 = (const unsigned char *)s2;
|
||||
while (n--) {
|
||||
if (*p1 != *p2) return *p1 - *p2;
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// String functions
|
||||
size_t strlen(const char *s) {
|
||||
size_t len = 0;
|
||||
while (s[len]) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
char* strcpy(char *dest, const char *src) {
|
||||
char *ret = dest;
|
||||
while (*src) *dest++ = *src++;
|
||||
*dest = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* strcat(char *dest, const char *src) {
|
||||
char *ret = dest;
|
||||
while (*dest) dest++;
|
||||
while (*src) *dest++ = *src++;
|
||||
*dest = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int atoi(const char *nptr) {
|
||||
int res = 0;
|
||||
int sign = 1;
|
||||
if (*nptr == '-') {
|
||||
sign = -1;
|
||||
nptr++;
|
||||
}
|
||||
while (*nptr >= '0' && *nptr <= '9') {
|
||||
res = res * 10 + (*nptr - '0');
|
||||
nptr++;
|
||||
}
|
||||
return sign * res;
|
||||
}
|
||||
|
||||
void itoa(int n, char *buf) {
|
||||
if (n == 0) {
|
||||
buf[0] = '0'; buf[1] = 0; return;
|
||||
}
|
||||
int i = 0;
|
||||
int sign = n < 0;
|
||||
if (sign) n = -n;
|
||||
while (n > 0) {
|
||||
buf[i++] = (n % 10) + '0';
|
||||
n /= 10;
|
||||
}
|
||||
if (sign) buf[i++] = '-';
|
||||
buf[i] = 0;
|
||||
// Reverse
|
||||
for (int j = 0; j < i / 2; j++) {
|
||||
char t = buf[j];
|
||||
buf[j] = buf[i - 1 - j];
|
||||
buf[i - 1 - j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
// IO functions
|
||||
void puts(const char *s) {
|
||||
sys_write(1, s, strlen(s));
|
||||
sys_write(1, "\n", 1);
|
||||
}
|
||||
|
||||
void printf(const char *fmt, ...) {
|
||||
__builtin_va_list args;
|
||||
__builtin_va_start(args, fmt);
|
||||
char buf[1024];
|
||||
int buf_idx = 0;
|
||||
|
||||
while (*fmt) {
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
// Flush current buffer
|
||||
if (buf_idx > 0) {
|
||||
sys_write(1, buf, buf_idx);
|
||||
buf_idx = 0;
|
||||
}
|
||||
|
||||
if (*fmt == 's') {
|
||||
char *s = __builtin_va_arg(args, char *);
|
||||
if (s) sys_write(1, s, strlen(s));
|
||||
else sys_write(1, "(null)", 6);
|
||||
} else if (*fmt == 'd') {
|
||||
int d = __builtin_va_arg(args, int);
|
||||
char ibuf[32];
|
||||
itoa(d, ibuf);
|
||||
sys_write(1, ibuf, strlen(ibuf));
|
||||
} else if (*fmt == 'X' || *fmt == 'x') {
|
||||
uint32_t val = __builtin_va_arg(args, uint32_t);
|
||||
char xbuf[16];
|
||||
int xi = 0;
|
||||
if (val == 0) xbuf[xi++] = '0';
|
||||
else {
|
||||
while (val > 0) {
|
||||
uint32_t rem = val % 16;
|
||||
xbuf[xi++] = (rem < 10) ? (rem + '0') : (rem - 10 + 'A');
|
||||
val /= 16;
|
||||
}
|
||||
}
|
||||
while (xi > 0) {
|
||||
char c = xbuf[--xi];
|
||||
sys_write(1, &c, 1);
|
||||
}
|
||||
} else if (*fmt == 'c') {
|
||||
char c = (char)__builtin_va_arg(args, int);
|
||||
sys_write(1, &c, 1);
|
||||
} else if (*fmt == '%') {
|
||||
char c = '%';
|
||||
sys_write(1, &c, 1);
|
||||
}
|
||||
} else {
|
||||
buf[buf_idx++] = *fmt;
|
||||
if (buf_idx >= 1024) {
|
||||
sys_write(1, buf, buf_idx);
|
||||
buf_idx = 0;
|
||||
}
|
||||
}
|
||||
fmt++;
|
||||
}
|
||||
if (buf_idx > 0) {
|
||||
sys_write(1, buf, buf_idx);
|
||||
}
|
||||
__builtin_va_end(args);
|
||||
}
|
||||
|
||||
// System/Process functions
|
||||
int chdir(const char *path) {
|
||||
return sys_chdir(path);
|
||||
}
|
||||
|
||||
char* getcwd(char *buf, int size) {
|
||||
if (sys_getcwd(buf, size) == 0) return buf;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sleep(int ms) {
|
||||
sys_system(46, ms, 0, 0, 0);
|
||||
}
|
||||
|
||||
void exit(int status) {
|
||||
sys_exit(status);
|
||||
}
|
||||
32
src/userland/libc/stdlib.h
Normal file
32
src/userland/libc/stdlib.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef STDLIB_H
|
||||
#define STDLIB_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void* malloc(size_t size);
|
||||
void free(void* ptr);
|
||||
void* calloc(size_t nmemb, size_t size);
|
||||
void* realloc(void* ptr, size_t size);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
// String functions
|
||||
size_t strlen(const char *s);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
char* strcpy(char *dest, const char *src);
|
||||
char* strcat(char *dest, const char *src);
|
||||
int atoi(const char *nptr);
|
||||
void itoa(int n, char *buf);
|
||||
|
||||
// IO functions
|
||||
void puts(const char *s);
|
||||
void printf(const char *fmt, ...);
|
||||
|
||||
// System/Process functions
|
||||
int chdir(const char *path);
|
||||
char* getcwd(char *buf, int size);
|
||||
void sleep(int ms);
|
||||
void exit(int status);
|
||||
|
||||
#endif
|
||||
11
src/userland/libc/string.h
Normal file
11
src/userland/libc/string.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef BOREDOS_LIBC_STRING_H
|
||||
#define BOREDOS_LIBC_STRING_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
|
||||
#endif
|
||||
241
src/userland/libc/syscall.c
Normal file
241
src/userland/libc/syscall.c
Normal file
@@ -0,0 +1,241 @@
|
||||
#include "syscall.h"
|
||||
|
||||
|
||||
|
||||
uint64_t syscall0(uint64_t sys_num) {
|
||||
uint64_t ret;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(sys_num)
|
||||
: "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t syscall1(uint64_t sys_num, uint64_t arg1) {
|
||||
uint64_t ret;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(sys_num), "D"(arg1)
|
||||
: "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t syscall2(uint64_t sys_num, uint64_t arg1, uint64_t arg2) {
|
||||
uint64_t ret;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(sys_num), "D"(arg1), "S"(arg2)
|
||||
: "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t syscall3(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3) {
|
||||
uint64_t ret;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(sys_num), "D"(arg1), "S"(arg2), "d"(arg3)
|
||||
: "rcx", "r11", "memory", "r10", "r8", "r9");
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t syscall4(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) {
|
||||
uint64_t ret;
|
||||
register uint64_t r10 asm("r10") = arg4;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(sys_num), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
|
||||
: "rcx", "r11", "memory", "r8", "r9");
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t syscall5(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) {
|
||||
uint64_t ret;
|
||||
register uint64_t r10 asm("r10") = arg4;
|
||||
register uint64_t r8 asm("r8") = arg5;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(sys_num), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
|
||||
: "rcx", "r11", "memory", "r9");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void sys_exit(int status) {
|
||||
syscall1(SYS_EXIT, (uint64_t)status);
|
||||
while (1);
|
||||
}
|
||||
|
||||
int sys_write(int fd, const char *buf, int len) {
|
||||
return (int)syscall3(SYS_WRITE, (uint64_t)fd, (uint64_t)buf, (uint64_t)len);
|
||||
}
|
||||
|
||||
void *sys_sbrk(int incr) {
|
||||
return (void *)syscall1(SYS_SBRK, (uint64_t)incr);
|
||||
}
|
||||
|
||||
int sys_system(int cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) {
|
||||
return (int)syscall5(SYS_SYSTEM, (uint64_t)cmd, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
int sys_open(const char *path, const char *mode) {
|
||||
return (int)syscall3(SYS_FS, FS_CMD_OPEN, (uint64_t)path, (uint64_t)mode);
|
||||
}
|
||||
|
||||
int sys_read(int fd, void *buf, uint32_t len) {
|
||||
return (int)syscall4(SYS_FS, FS_CMD_READ, (uint64_t)fd, (uint64_t)buf, (uint64_t)len);
|
||||
}
|
||||
|
||||
int sys_write_fs(int fd, const void *buf, uint32_t len) {
|
||||
return (int)syscall4(SYS_FS, FS_CMD_WRITE, (uint64_t)fd, (uint64_t)buf, (uint64_t)len);
|
||||
}
|
||||
|
||||
void sys_close(int fd) {
|
||||
syscall2(SYS_FS, FS_CMD_CLOSE, (uint64_t)fd);
|
||||
}
|
||||
|
||||
int sys_seek(int fd, int offset, int whence) {
|
||||
return (int)syscall4(SYS_FS, FS_CMD_SEEK, (uint64_t)fd, (uint64_t)offset, (uint64_t)whence);
|
||||
}
|
||||
|
||||
uint32_t sys_tell(int fd) {
|
||||
return (uint32_t)syscall2(SYS_FS, FS_CMD_TELL, (uint64_t)fd);
|
||||
}
|
||||
|
||||
uint32_t sys_size(int fd) {
|
||||
return (uint32_t)syscall2(SYS_FS, FS_CMD_SIZE, (uint64_t)fd);
|
||||
}
|
||||
|
||||
int sys_list(const char *path, FAT32_FileInfo *entries, int max_entries) {
|
||||
return (int)syscall4(SYS_FS, FS_CMD_LIST, (uint64_t)path, (uint64_t)entries, (uint64_t)max_entries);
|
||||
}
|
||||
|
||||
int sys_get_file_info(const char *path, FAT32_FileInfo *info) {
|
||||
return (int)syscall3(SYS_FS, FS_CMD_GET_INFO, (uint64_t)path, (uint64_t)info);
|
||||
}
|
||||
|
||||
int sys_delete(const char *path) {
|
||||
return (int)syscall2(SYS_FS, FS_CMD_DELETE, (uint64_t)path);
|
||||
}
|
||||
|
||||
int sys_mkdir(const char *path) {
|
||||
return (int)syscall2(SYS_FS, FS_CMD_MKDIR, (uint64_t)path);
|
||||
}
|
||||
|
||||
int sys_exists(const char *path) {
|
||||
return (int)syscall2(SYS_FS, FS_CMD_EXISTS, (uint64_t)path);
|
||||
}
|
||||
|
||||
int sys_getcwd(char *buf, int size) {
|
||||
return (int)syscall3(SYS_FS, FS_CMD_GETCWD, (uint64_t)buf, (uint64_t)size);
|
||||
}
|
||||
|
||||
int sys_chdir(const char *path) {
|
||||
return (int)syscall2(SYS_FS, FS_CMD_CHDIR, (uint64_t)path);
|
||||
}
|
||||
|
||||
void sys_kill(int pid) {
|
||||
syscall1(SYS_KILL, (uint64_t)pid);
|
||||
}
|
||||
|
||||
// Network API implementations
|
||||
int sys_network_init(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_INIT, 0);
|
||||
}
|
||||
|
||||
int sys_network_dhcp_acquire(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_DHCP, 0);
|
||||
}
|
||||
|
||||
int sys_network_get_mac(net_mac_address_t *mac) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_MAC, (uint64_t)mac);
|
||||
}
|
||||
|
||||
int sys_network_get_nic_name(char *name_out) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_NIC_NAME, (uint64_t)name_out);
|
||||
}
|
||||
|
||||
int sys_network_get_ip(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_IP, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_set_ip(const net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_SET_IP, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_get_stat(int stat_type) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_STATS, (uint64_t)stat_type);
|
||||
}
|
||||
|
||||
int sys_get_dns_server(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_DNS, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_get_gateway(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_GATEWAY, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_network_get_dns(net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_GET_DNS, (uint64_t)ip);
|
||||
}
|
||||
|
||||
int sys_udp_send(const net_ipv4_address_t *dest_ip, uint16_t dest_port, uint16_t src_port, const void *data, size_t data_len) {
|
||||
uint32_t ports = (dest_port & 0xFFFF) | ((src_port & 0xFFFF) << 16);
|
||||
return (int)syscall5(SYS_SYSTEM, SYSTEM_CMD_UDP_SEND, (uint64_t)dest_ip, (uint64_t)ports, (uint64_t)data, (uint64_t)data_len);
|
||||
}
|
||||
|
||||
int sys_icmp_ping(const net_ipv4_address_t *dest_ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_ICMP_PING, (uint64_t)dest_ip);
|
||||
}
|
||||
|
||||
int sys_network_is_initialized(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_IS_INIT, 0);
|
||||
}
|
||||
|
||||
int sys_network_has_ip(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_NETWORK_HAS_IP, 0);
|
||||
}
|
||||
|
||||
uint64_t sys_get_shell_config(const char *key) {
|
||||
return (uint64_t)sys_system(SYSTEM_CMD_GET_SHELL_CONFIG, (uint64_t)key, 0, 0, 0);
|
||||
}
|
||||
|
||||
void sys_set_text_color(uint32_t color) {
|
||||
sys_system(SYSTEM_CMD_SET_TEXT_COLOR, (uint64_t)color, 0, 0, 0);
|
||||
}
|
||||
|
||||
int sys_tcp_connect(const net_ipv4_address_t *ip, uint16_t port) {
|
||||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_TCP_CONNECT, (uint64_t)ip, (uint64_t)port);
|
||||
}
|
||||
|
||||
int sys_tcp_send(const void *data, size_t len) {
|
||||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_TCP_SEND, (uint64_t)data, (uint64_t)len);
|
||||
}
|
||||
|
||||
int sys_tcp_recv(void *buf, size_t max_len) {
|
||||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_TCP_RECV, (uint64_t)buf, (uint64_t)max_len);
|
||||
}
|
||||
|
||||
int sys_tcp_recv_nb(void *buf, size_t max_len) {
|
||||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_TCP_RECV_NB, (uint64_t)buf, (uint64_t)max_len);
|
||||
}
|
||||
|
||||
int sys_tcp_close(void) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_TCP_CLOSE, 0);
|
||||
}
|
||||
|
||||
int sys_dns_lookup(const char *name, net_ipv4_address_t *out_ip) {
|
||||
return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_DNS_LOOKUP, (uint64_t)name, (uint64_t)out_ip);
|
||||
}
|
||||
|
||||
int sys_set_dns_server(const net_ipv4_address_t *ip) {
|
||||
return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_SET_DNS, (uint64_t)ip);
|
||||
}
|
||||
|
||||
void sys_network_force_unlock(void) {
|
||||
syscall2(SYS_SYSTEM, SYSTEM_CMD_NET_UNLOCK, 0);
|
||||
}
|
||||
|
||||
void sys_yield(void) {
|
||||
syscall1(SYS_SYSTEM, SYSTEM_CMD_YIELD);
|
||||
}
|
||||
|
||||
159
src/userland/libc/syscall.h
Normal file
159
src/userland/libc/syscall.h
Normal file
@@ -0,0 +1,159 @@
|
||||
#ifndef SYSCALL_H
|
||||
#define SYSCALL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Standard syscalls available from Kernel mode
|
||||
#define SYS_EXIT 0
|
||||
#define SYS_WRITE 1
|
||||
#define SYS_GUI 3
|
||||
#define SYS_FS 4
|
||||
#define SYS_SYSTEM 5
|
||||
#define SYS_KILL 10
|
||||
#define SYS_SBRK 9
|
||||
|
||||
// FS Commands
|
||||
#define FS_CMD_OPEN 1
|
||||
#define FS_CMD_READ 2
|
||||
#define FS_CMD_WRITE 3
|
||||
#define FS_CMD_CLOSE 4
|
||||
#define FS_CMD_SEEK 5
|
||||
#define FS_CMD_TELL 6
|
||||
#define FS_CMD_LIST 7
|
||||
#define FS_CMD_DELETE 8
|
||||
#define FS_CMD_SIZE 9
|
||||
#define FS_CMD_MKDIR 10
|
||||
#define FS_CMD_EXISTS 11
|
||||
#define FS_CMD_GETCWD 12
|
||||
#define FS_CMD_CHDIR 13
|
||||
#define FS_CMD_GET_INFO 14
|
||||
|
||||
// System Commands (via SYS_SYSTEM)
|
||||
#define SYSTEM_CMD_SET_BG_COLOR 1
|
||||
#define SYSTEM_CMD_SET_BG_PATTERN 2
|
||||
#define SYSTEM_CMD_SET_WALLPAPER 3
|
||||
#define SYSTEM_CMD_SET_DESKTOP_PROP 4
|
||||
#define SYSTEM_CMD_SET_MOUSE_SPEED 5
|
||||
#define SYSTEM_CMD_NETWORK_INIT 6
|
||||
#define SYSTEM_CMD_GET_DESKTOP_PROP 7
|
||||
#define SYSTEM_CMD_GET_MOUSE_SPEED 8
|
||||
#define SYSTEM_CMD_GET_WALLPAPER_THUMB 9
|
||||
#define SYSTEM_CMD_CLEAR_SCREEN 10
|
||||
#define SYSTEM_CMD_RTC_GET 11
|
||||
#define SYSTEM_CMD_REBOOT 12
|
||||
#define SYSTEM_CMD_SHUTDOWN 13
|
||||
#define SYSTEM_CMD_BEEP 14
|
||||
#define SYSTEM_CMD_MEMINFO 15
|
||||
#define SYSTEM_CMD_UPTIME 16
|
||||
#define SYSTEM_CMD_PCI_LIST 17
|
||||
#define SYSTEM_CMD_NETWORK_DHCP 18
|
||||
#define SYSTEM_CMD_NETWORK_GET_MAC 19
|
||||
#define SYSTEM_CMD_NETWORK_GET_IP 20
|
||||
#define SYSTEM_CMD_NETWORK_SET_IP 21
|
||||
#define SYSTEM_CMD_UDP_SEND 22
|
||||
#define SYSTEM_CMD_NETWORK_GET_STATS 23
|
||||
#define SYSTEM_CMD_NETWORK_GET_GATEWAY 24
|
||||
#define SYSTEM_CMD_NETWORK_GET_DNS 25
|
||||
#define SYSTEM_CMD_ICMP_PING 26
|
||||
#define SYSTEM_CMD_NETWORK_IS_INIT 27
|
||||
#define SYSTEM_CMD_NETWORK_HAS_IP 30
|
||||
#define SYSTEM_CMD_GET_SHELL_CONFIG 28
|
||||
#define SYSTEM_CMD_NETWORK_GET_NIC_NAME 48
|
||||
#define SYSTEM_CMD_SET_TEXT_COLOR 29
|
||||
#define SYSTEM_CMD_SET_WALLPAPER_PATH 31
|
||||
#define SYSTEM_CMD_TCP_CONNECT 33
|
||||
#define SYSTEM_CMD_TCP_SEND 34
|
||||
#define SYSTEM_CMD_TCP_RECV 35
|
||||
#define SYSTEM_CMD_TCP_CLOSE 36
|
||||
#define SYSTEM_CMD_DNS_LOOKUP 37
|
||||
#define SYSTEM_CMD_SET_DNS 38
|
||||
#define SYSTEM_CMD_NET_UNLOCK 39
|
||||
#define SYSTEM_CMD_PROCESS_LIST 44
|
||||
#define SYSTEM_CMD_GET_CPU_MODEL 45
|
||||
#define SYSTEM_CMD_SLEEP 46
|
||||
#define SYSTEM_CMD_SET_RAW_MODE 41
|
||||
#define SYSTEM_CMD_TCP_RECV_NB 42
|
||||
#define SYSTEM_CMD_YIELD 43
|
||||
|
||||
// Internal assembly entry into Ring 0
|
||||
extern uint64_t syscall0(uint64_t sys_num);
|
||||
extern uint64_t syscall1(uint64_t sys_num, uint64_t arg1);
|
||||
extern uint64_t syscall2(uint64_t sys_num, uint64_t arg1, uint64_t arg2);
|
||||
extern uint64_t syscall3(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3);
|
||||
extern uint64_t syscall4(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
|
||||
extern uint64_t syscall5(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5);
|
||||
|
||||
// Public API
|
||||
void sys_exit(int status);
|
||||
int sys_write(int fd, const char *buf, int len);
|
||||
void *sys_sbrk(int incr);
|
||||
void sys_kill(int pid);
|
||||
int sys_system(int cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
|
||||
|
||||
// FS API
|
||||
int sys_open(const char *path, const char *mode);
|
||||
int sys_read(int fd, void *buf, uint32_t len);
|
||||
int sys_write_fs(int fd, const void *buf, uint32_t len);
|
||||
void sys_close(int fd);
|
||||
int sys_seek(int fd, int offset, int whence);
|
||||
uint32_t sys_tell(int fd);
|
||||
uint32_t sys_size(int fd);
|
||||
int sys_delete(const char *path);
|
||||
int sys_mkdir(const char *path);
|
||||
int sys_exists(const char *path);
|
||||
int sys_getcwd(char *buf, int size);
|
||||
int sys_chdir(const char *path);
|
||||
|
||||
typedef struct {
|
||||
char name[256];
|
||||
uint32_t size;
|
||||
uint8_t is_directory;
|
||||
uint32_t start_cluster;
|
||||
uint16_t write_date;
|
||||
uint16_t write_time;
|
||||
} FAT32_FileInfo;
|
||||
|
||||
int sys_list(const char *path, FAT32_FileInfo *entries, int max_entries);
|
||||
int sys_get_file_info(const char *path, FAT32_FileInfo *info);
|
||||
|
||||
typedef struct {
|
||||
uint32_t pid;
|
||||
char name[64];
|
||||
uint64_t ticks;
|
||||
size_t used_memory;
|
||||
} ProcessInfo;
|
||||
|
||||
// Network API
|
||||
typedef struct { uint8_t bytes[6]; } net_mac_address_t;
|
||||
typedef struct { uint8_t bytes[4]; } net_ipv4_address_t;
|
||||
|
||||
int sys_network_init(void);
|
||||
int sys_network_dhcp_acquire(void);
|
||||
int sys_network_get_mac(net_mac_address_t *mac);
|
||||
int sys_network_get_nic_name(char *name_out);
|
||||
int sys_network_get_ip(net_ipv4_address_t *ip);
|
||||
int sys_network_set_ip(const net_ipv4_address_t *ip);
|
||||
int sys_network_get_stat(int stat_type);
|
||||
int sys_network_get_gateway(net_ipv4_address_t *ip);
|
||||
int sys_network_get_dns(net_ipv4_address_t *ip);
|
||||
int sys_get_dns_server(net_ipv4_address_t *ip);
|
||||
int sys_udp_send(const net_ipv4_address_t *dest_ip, uint16_t dest_port, uint16_t src_port, const void *data, size_t data_len);
|
||||
int sys_icmp_ping(const net_ipv4_address_t *dest_ip);
|
||||
int sys_network_is_initialized(void);
|
||||
int sys_network_has_ip(void);
|
||||
uint64_t sys_get_shell_config(const char *key);
|
||||
void sys_set_text_color(uint32_t color);
|
||||
|
||||
int sys_tcp_connect(const net_ipv4_address_t *ip, uint16_t port);
|
||||
int sys_tcp_send(const void *data, size_t len);
|
||||
int sys_tcp_recv(void *buf, size_t max_len);
|
||||
int sys_tcp_recv_nb(void *buf, size_t max_len);
|
||||
int sys_tcp_close(void);
|
||||
int sys_dns_lookup(const char *name, net_ipv4_address_t *out_ip);
|
||||
int sys_set_dns_server(const net_ipv4_address_t *ip);
|
||||
void sys_network_force_unlock(void);
|
||||
void sys_yield(void);
|
||||
|
||||
|
||||
#endif
|
||||
11
src/userland/libc/syscall_user.h
Normal file
11
src/userland/libc/syscall_user.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef SYSCALL_USER_H
|
||||
#define SYSCALL_USER_H
|
||||
|
||||
#include "syscall.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static inline void sys_serial_write(const char *str) {
|
||||
syscall2(8, 0, (uint64_t)str);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user