diff options
| author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2022-10-06 16:45:17 +0200 |
|---|---|---|
| committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2022-10-06 16:45:17 +0200 |
| commit | f8397815545adb7d0da36614e0065aa68453a2e4 (patch) | |
| tree | a771f526970c6724b2511577dceece8783450a49 /stage3/fut | |
| download | cuddles-f8397815545adb7d0da36614e0065aa68453a2e4.tar.xz | |
Initial commit
Diffstat (limited to 'stage3/fut')
| -rwxr-xr-x | stage3/fut/linkgen.lua | 101 | ||||
| -rw-r--r-- | stage3/fut/os | 161 | ||||
| -rw-r--r-- | stage3/fut/process.c | 77 | ||||
| -rw-r--r-- | stage3/fut/sys_kern.c | 21 | ||||
| -rw-r--r-- | stage3/fut/sys_kern.h | 91 | ||||
| -rw-r--r-- | stage3/fut/sys_user.c | 36 | ||||
| -rw-r--r-- | stage3/fut/sys_user.h | 91 | ||||
| -rw-r--r-- | stage3/fut/yield.asm | 49 |
8 files changed, 627 insertions, 0 deletions
diff --git a/stage3/fut/linkgen.lua b/stage3/fut/linkgen.lua new file mode 100755 index 0000000..f7a6d21 --- /dev/null +++ b/stage3/fut/linkgen.lua @@ -0,0 +1,101 @@ +#!/usr/bin/env lua +--[[ + +--- trigger warning: brain damage --- + +BOGUS DYNAMIC LINKING v69.420 by LIZZY FLECKENSTEIN + +How this works: +⠀⠀⠀⠀⠀⢰⡿⠋⠁⠀⠀⠈⠉⠙⠻⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢀⣿⠇⠀⢀⣴⣶⡾⠿⠿⠿⢿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⣀⣀⣸⡿⠀⠀⢸⣿⣇⠀⠀⠀⠀⠀⠀⠙⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⣾⡟⠛⣿⡇⠀⠀⢸⣿⣿⣷⣤⣤⣤⣤⣶⣶⣿⠇⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀ +⢀⣿⠀⢀⣿⡇⠀⠀⠀⠻⢿⣿⣿⣿⣿⣿⠿⣿⡏⠀⠀⠀⠀⢴⣶⣶⣿⣿⣿⣆ +⢸⣿⠀⢸⣿⡇⠀⠀⠀⠀⠀⠈⠉⠁⠀⠀⠀⣿⡇⣀⣠⣴⣾⣮⣝⠿⠿⠿⣻⡟ +⢸⣿⠀⠘⣿⡇⠀⠀⠀⠀⠀⠀⠀⣠⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠉⠀ +⠸⣿⠀⠀⣿⡇⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠉⠀⠀⠀⠀ +⠀⠻⣷⣶⣿⣇⠀⠀⠀⢠⣼⣿⣿⣿⣿⣿⣿⣿⣛⣛⣻⠉⠁⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢸⣿⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢸⣿⣀⣀⣀⣼⡿⢿⣿⣿⣿⣿⣿⡿⣿⣿⡿ + +Amogus sus 😳 ((impassta)) + +I FUCKING HATE TEH ANTICRIST!!!! +WE GOT YOU SURROUNDEND, USE DYNAMIC LINKING + +:trollface: + +]] + +-- in +local hdr_kern = io.open("sys_kern.h", "r") +-- out +local hdr_user = io.open("sys_user.h", "w") +local src_kern = io.open("sys_kern.c", "w") +local src_user = io.open("sys_user.c", "w") + +local count = 0 +local calltable = "0x500" + +local body_kern = "" +local body_user = "" + +src_kern:write("#include <sys_kern.h>\n") +src_user:write("#include <sys_user.h>\n\n") + +local function process_line(line) + if line == "" or line:sub(1, 1) == "\t" then + return + end + + local f, t = line:find("[%w_]+%(") + + if not f then + return + end + + local start, mid, fin = line:sub(1, f-1), line:sub(f, t-1), line:sub(t) + + if mid == "__attribute__" or mid == "link" then + return + end + + local decl = start .. "(*" .. mid .. ")" .. fin .. "\n" + + hdr_user:write("extern " .. decl) + src_user:write(decl) + + body_kern = body_kern .. "\tcalltable[" .. count .. "] = &" .. mid .. ";\n" + body_user = body_user .. "\t" .. mid .. " = calltable[" .. count .. "];\n" + + count = count + 1 + + return true +end + +while true do + local line = hdr_kern:read() + + if not line then + break + end + + if not process_line(line) then + hdr_user:write(line .. "\n") + end +end + +local function write_link(f, content) + f:write("\nvoid link()\n{\n") + f:write("\tvoid **calltable = " .. calltable .. ";\n\n") + f:write(content) + f:write("}\n") +end + +write_link(src_kern, body_kern) +write_link(src_user, body_user) + +hdr_kern:close() +hdr_user:close() +src_kern:close() +src_user:close() diff --git a/stage3/fut/os b/stage3/fut/os new file mode 100644 index 0000000..64d627f --- /dev/null +++ b/stage3/fut/os @@ -0,0 +1,161 @@ +gfx + - modes text, pixel + - different buffers + - switch between them manually or thingily + +- similar to tmux +- hierarchy + +- text input channel +- keyboard input channel +- mouse input channel + +- text output channel + - +- graphics output channel + +- add text? +- scrollback? + +init + +copy +remove +move +list +edit +directory + +shell +terminal + +mouse +keyboard +text + +tiler +desktop + +-- + +process, display, channel + +-- + +display.x +display.y +display.width +display.height +display.index +display.parent + +display = current_display() +display = create_display(x, y, width, height) + +add_display(parent, child, -1) +remove_display(parent, child) + +display.set_char(pos, color, text) +display.set_pixel(pos, color) +display.flush() + +channel = create_channel() +add_channel(display, channel, name) +channel = get_channel(display, name) + +-- + +process = create_process(path, display) + +add_channel(process, channel) +get_channel(process, "signal") +get_channel(process, "status") + +-- + +current_process() + .get_channel("status") + .send(finish) + +-- +void main() +{ + current_display() + .get_channel("text") + .send("hello, world\n"); +} + +-- + +append(string self, string other) +{ + self.grow(other.len()) + memcpy(self.ptr + self.len() - other.len(), other.ptr, other.len()) +} + +-- +string get_line(channel input) +{ + string s = ""; + + loop { + string c = input.recv(); + + if (c[0] == '\n') + break; + + s.append(c); + } + + return s; +} + +-- +void main() +{ + channel input = current_display() + .get_channel("keyboard"); + + loop { + string command = get_line(input); + + process proc = create_process(path, current_display()); + + receiver status = proc + .get_channel("status") + .subscribe(); + + proc.start(); + + while (!status.recv().equal("finish")) + yield(); + } +} + +-- +void main() +{ + +} + +-- channels +void send(channel c, value v) +{ + listener l = c.listeners.pop(); + + if (l) { + listener.resume(v) + } else { + for (s in c.subscribers) { + if (s.active) + s.active.resume(v) + else + s.buffer.append(v) + } + } +} + +-- queue + +- runqueue pointer at fixed address +- processes must free all heap allocated memory before exit diff --git a/stage3/fut/process.c b/stage3/fut/process.c new file mode 100644 index 0000000..ea99ccf --- /dev/null +++ b/stage3/fut/process.c @@ -0,0 +1,77 @@ +#define STACK_SIZE 65536 +#define CURRENT *((process *) 0x500) + +process process_current() +{ + return CURRENT; +} + +static void process_delete(process p) +{ + free(p->stack); + free(p->code); + map_clear(&p->channels); +} + +static void process_push(process p, u64 value) +{ + p->stack_ptr -= sizeof value; + *p->stack_ptr = value; +} + +void process_exit() +{ + if (CURRENT->next == CURRENT) + panic("init exited"); + + CURRENT->prev->next = CURRENT->next; + CURRENT->next->prev = CURRENT->prev; + rc_drop(*current); + + process_yield(); +} + +process process_create(char *path, display d) +{ + process p = rc_create(sizeof *p, &process_delete); + + p->state = PROCESS_CREATED; + + p->stack = malloc(STACK_SIZE); + p->stack_ptr = p->stack + STACK_SIZE; + p->code = p->code_ptr = file_read(path); + + process_push(p, (u64) &process_exit); + // push 6 callee resaved registers - contents dont actually matter. + for (int i = 0; i < 6; i++) + process_push(p, 0); + + p->displ = d; + p->next = p->prev = nil; + map_init(&p->channels); + + channel sig = channel_create(); + process_channel_add(p, "signal", sig); + rc_drop(sig); + + channel stat = channel_create(); + process_channel_add(p, "status", stat); + rc_drop(stat); + + return p; +} + +void process_start(process p) +{ + if (p->code_ptr == nil) + panic("attempt to start invalid process"); + + if (p->state != PROCESS_CREATED) + panic("attempt to start running or dead process"); + + rc_grab(p); + + p->next = CURRENT->next; + CURRENT->next = p; + p->prev = CURRENT; +} diff --git a/stage3/fut/sys_kern.c b/stage3/fut/sys_kern.c new file mode 100644 index 0000000..c7c5fcc --- /dev/null +++ b/stage3/fut/sys_kern.c @@ -0,0 +1,21 @@ +#include <sys_kern.h> + +void link() +{ + void **calltable = 0x500; + + calltable[0] = &display_current; + calltable[1] = &display_create; + calltable[2] = &display_add; + calltable[3] = &display_remove; + calltable[4] = &display_pixel; + calltable[5] = &display_channel_add; + calltable[6] = &display_channel_get; + calltable[7] = &rc_grab; + calltable[8] = &rc_drop; + calltable[9] = &rc_create; + calltable[10] = &weak_downgrade; + calltable[11] = &weak_upgrade; + calltable[12] = &weak_drop; + calltable[13] = &channel_create; +} diff --git a/stage3/fut/sys_kern.h b/stage3/fut/sys_kern.h new file mode 100644 index 0000000..083fce3 --- /dev/null +++ b/stage3/fut/sys_kern.h @@ -0,0 +1,91 @@ +#ifndef _SYS_H_ +#define _SYS_H_ + +// misc + +typedef struct { + i32 x, y; +} pos; + +typedef struct { + u32 width, height; +} bounds; + +typedef struct { + u8 r, g, b +} color; + +// display + +typedef struct display { + pos p; + bounds b; + struct display *parent; + u64 index; +} *display; + +display display_current(); +display display_create(); +void display_add(display parent, display child, i32 index); +void display_remove(display child); + +void display_pixel(display d, pos p, color c); + +void display_channel_add(char *name, channel ch); +channel display_channel_get(char *name); + +// rc + +typedef struct __attribute__((packed)) { + u32 ref; + u32 own; + void *data; + void (*delete)(void *data); +} rc_header; + +void rc_grab(void *rc); +void rc_drop(void *rc); + +void *rc_create(u64 siz, void *delete); +void *weak_downgrade(void *rc); +void *weak_upgrade(void *weak) +void weak_drop(void *weak); + +// channel + +typedef struct { + array listeners; + array subscribers; +} *channel; + +channel channel_create(); + +// buffered + +typedef struct { + void *active; + array buffer; +} buffered; + +// process + +typedef struct process __attribute__((packed)) { + void *code; + void *stack; + u64 *stack_ptr; + struct process *next; + struct process *prev; + map channels; + display displ; + enum { + PROCESS_CREATED, + PROCESS_RUNNING, + PROCESS_DEAD, + } state; +} *process; + +// setup pointers + +void link(); + +#endif diff --git a/stage3/fut/sys_user.c b/stage3/fut/sys_user.c new file mode 100644 index 0000000..4490513 --- /dev/null +++ b/stage3/fut/sys_user.c @@ -0,0 +1,36 @@ +#include <sys_user.h> + +display (*display_current)(); +display (*display_create)(); +void (*display_add)(display parent, display child, i32 index); +void (*display_remove)(display child); +void (*display_pixel)(display d, pos p, color c); +void (*display_channel_add)(char *name, channel ch); +channel (*display_channel_get)(char *name); +void (*rc_grab)(void *rc); +void (*rc_drop)(void *rc); +void *(*rc_create)(u64 siz, void *delete); +void *(*weak_downgrade)(void *rc); +void *(*weak_upgrade)(void *weak) +void (*weak_drop)(void *weak); +channel (*channel_create)(); + +void link() +{ + void **calltable = 0x500; + + display_current = calltable[0]; + display_create = calltable[1]; + display_add = calltable[2]; + display_remove = calltable[3]; + display_pixel = calltable[4]; + display_channel_add = calltable[5]; + display_channel_get = calltable[6]; + rc_grab = calltable[7]; + rc_drop = calltable[8]; + rc_create = calltable[9]; + weak_downgrade = calltable[10]; + weak_upgrade = calltable[11]; + weak_drop = calltable[12]; + channel_create = calltable[13]; +} diff --git a/stage3/fut/sys_user.h b/stage3/fut/sys_user.h new file mode 100644 index 0000000..3be3d58 --- /dev/null +++ b/stage3/fut/sys_user.h @@ -0,0 +1,91 @@ +#ifndef _SYS_H_ +#define _SYS_H_ + +// misc + +typedef struct { + i32 x, y; +} pos; + +typedef struct { + u32 width, height; +} bounds; + +typedef struct { + u8 r, g, b +} color; + +// display + +typedef struct display { + pos p; + bounds b; + struct display *parent; + u64 index; +} *display; + +extern display (*display_current)(); +extern display (*display_create)(); +extern void (*display_add)(display parent, display child, i32 index); +extern void (*display_remove)(display child); + +extern void (*display_pixel)(display d, pos p, color c); + +extern void (*display_channel_add)(char *name, channel ch); +extern channel (*display_channel_get)(char *name); + +// rc + +typedef struct __attribute__((packed)) { + u32 ref; + u32 own; + void *data; + void (*delete)(void *data); +} rc_header; + +extern void (*rc_grab)(void *rc); +extern void (*rc_drop)(void *rc); + +extern void *(*rc_create)(u64 siz, void *delete); +extern void *(*weak_downgrade)(void *rc); +extern void *(*weak_upgrade)(void *weak) +extern void (*weak_drop)(void *weak); + +// channel + +typedef struct { + array listeners; + array subscribers; +} *channel; + +extern channel (*channel_create)(); + +// buffered + +typedef struct { + void *active; + array buffer; +} buffered; + +// process + +typedef struct process __attribute__((packed)) { + void *code; + void *stack; + u64 *stack_ptr; + struct process *next; + struct process *prev; + map channels; + display displ; + enum { + PROCESS_CREATED, + PROCESS_RUNNING, + PROCESS_DEAD, + } state; +} *process; + +// setup pointers + +void link(); + +#endif diff --git a/stage3/fut/yield.asm b/stage3/fut/yield.asm new file mode 100644 index 0000000..0c4a134 --- /dev/null +++ b/stage3/fut/yield.asm @@ -0,0 +1,49 @@ +global process_yield +extern rc_drop + +%define CURRENT [0x500] + +section .text +process_yield: + ; save callee reserved regs to old stack + push rbx + push rbp + push r12 + push r13 + push r14 + push r15 + + ; get CURRENT + mov rdi, CURRENT + + ; set CURRENT->stack_ptr + mov rax, rdi + add rax, 16 + mov [rax], rsp + + ; switch to new process + add rax, 8 + mov rbx, [rax] + mov CURRENT, rbx + + ; activate new stack + add rbx, 16 + mov rsp, [rbx] + + ; drop old process (=rdi) + call rc_drop + + ; grab new process + mov rdi, CURRENT + call rc_grab + + ; restore callee reserved registers + pop r15 + pop r14 + pop r13 + pop r12 + pop rbp + pop rbx + + ; jump into new process, with style + ret |
