feat: basic scheduler; basic composer
This commit is contained in:
@@ -1,4 +1,16 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
// Copyright (c) 2025 0xKarinyash
|
// Copyright (c) 2025 0xKarinyash
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <types.h>
|
||||||
|
typedef struct task {
|
||||||
|
u64 rsp;
|
||||||
|
struct task* next;
|
||||||
|
u32 id;
|
||||||
|
u32 sleep_ticks;
|
||||||
|
} task_t;
|
||||||
|
|
||||||
|
void sched_init();
|
||||||
|
task_t* sched_spawn(void(*entry)());
|
||||||
|
u64 sched_next(u64 curr_rsp);
|
||||||
|
void yield(u64 ticks);
|
||||||
@@ -26,6 +26,15 @@ typedef struct {
|
|||||||
const unsigned char* base;
|
const unsigned char* base;
|
||||||
} SG_Font;
|
} SG_Font;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SG_Context *ctx;
|
||||||
|
SG_Point pos;
|
||||||
|
const char *title;
|
||||||
|
} SG_Window;
|
||||||
|
|
||||||
|
void sg_init(SG_Context *ctx);
|
||||||
void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img);
|
void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img);
|
||||||
void sg_draw_rect(SG_Context *ctx, SG_Point *p, u32 w, u32 h, u32 color);
|
void sg_draw_rect(SG_Context *ctx, SG_Point *p, u32 w, u32 h, u32 color);
|
||||||
void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Font *font);
|
void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Font *font);
|
||||||
|
SG_Window* create_window(const char *title, SG_Point* size, SG_Point* position);
|
||||||
|
void composer_task();
|
||||||
@@ -5,6 +5,6 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
void timer_init(u32 freq);
|
void timer_init(u32 freq);
|
||||||
void timer_handler();
|
u64 timer_handler(Registers *regs);
|
||||||
void sleep(u64 ms);
|
void sleep(u64 ms);
|
||||||
u64 get_uptime();
|
u64 get_uptime();
|
||||||
|
|||||||
@@ -70,9 +70,10 @@ global %2
|
|||||||
mov rdi, rsp
|
mov rdi, rsp
|
||||||
cld
|
cld
|
||||||
call irq_handler_c
|
call irq_handler_c
|
||||||
|
|
||||||
|
mov rsp, rax
|
||||||
|
|
||||||
POPALL
|
POPALL
|
||||||
|
|
||||||
add rsp, 16
|
add rsp, 16
|
||||||
iretq
|
iretq
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ void isr_handler_c(Registers *regs) {
|
|||||||
panic_exception(regs);
|
panic_exception(regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_handler_c(Registers *regs) {
|
u64 irq_handler_c(Registers *regs) {
|
||||||
|
u64 curr_rsp = (u64)regs;
|
||||||
switch (regs->int_no) {
|
switch (regs->int_no) {
|
||||||
case 32: return timer_handler();
|
case 32: curr_rsp = timer_handler(regs); break;
|
||||||
case 33: return kb_handler();
|
case 33: kb_handler(); break;
|
||||||
default: outb(SLAVE_COMMAND, 0x20); break;
|
default: outb(SLAVE_COMMAND, 0x20); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
outb(MASTER_COMMAND, 0x20);
|
outb(MASTER_COMMAND, 0x20);
|
||||||
|
return curr_rsp;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright (c) 2025 0xKarinyash
|
||||||
|
|
||||||
|
#include <core/panic.h>
|
||||||
|
#include <core/scheduler.h>
|
||||||
|
#include <mm/heap.h>
|
||||||
|
|
||||||
|
task_t* curr_task = nullptr;
|
||||||
|
u32 next_pid = 1;
|
||||||
|
|
||||||
|
extern void irq0_handler();
|
||||||
|
|
||||||
|
void sched_init() {
|
||||||
|
task_t* kt = (task_t*)malloc(sizeof(task_t));
|
||||||
|
|
||||||
|
kt->id = 0;
|
||||||
|
kt->sleep_ticks = 0;
|
||||||
|
kt->next = kt;
|
||||||
|
|
||||||
|
curr_task = kt;
|
||||||
|
}
|
||||||
|
|
||||||
|
task_t* sched_spawn(void(*entry)()) {
|
||||||
|
task_t* t = (task_t*)malloc(sizeof(task_t));
|
||||||
|
if (!t) return nullptr;
|
||||||
|
|
||||||
|
u64 stack_size = 16384;
|
||||||
|
u8* stack_base = (u8*)malloc(stack_size);
|
||||||
|
if (!stack_base) panic("OOM for task stack");
|
||||||
|
u64* rsp = (u64*)(stack_base + stack_size);
|
||||||
|
|
||||||
|
*--rsp = 0x10; // SS -- Kernel data
|
||||||
|
*--rsp = (u64)stack_base + stack_size; // rsp
|
||||||
|
*--rsp = 0x202; // RFLAGS -- Interrupts Enabled | Reserved bit;
|
||||||
|
*--rsp = 0x08; // CS -- Kernel Code;
|
||||||
|
*--rsp = (u64)entry; // RIP
|
||||||
|
|
||||||
|
*--rsp = 0; // int no
|
||||||
|
*--rsp = 0; // err code
|
||||||
|
|
||||||
|
for (u8 i = 0; i < 15; i++) *--rsp = 0; // R15 .. RAX
|
||||||
|
|
||||||
|
t->rsp = (u64)rsp;
|
||||||
|
t->id = next_pid++;
|
||||||
|
t->sleep_ticks = 0;
|
||||||
|
t->next = curr_task->next;
|
||||||
|
curr_task->next = t;
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 sched_next(u64 curr_rsp) {
|
||||||
|
if (!curr_task) return curr_rsp;
|
||||||
|
|
||||||
|
curr_task->rsp = curr_rsp;
|
||||||
|
task_t* it = curr_task->next;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (it->sleep_ticks > 0) it->sleep_ticks--;
|
||||||
|
it = it->next;
|
||||||
|
} while (it != curr_task->next);
|
||||||
|
|
||||||
|
if (curr_task->sleep_ticks > 0) curr_task->sleep_ticks--;
|
||||||
|
|
||||||
|
task_t* next = curr_task->next;
|
||||||
|
while (next != curr_task && next->sleep_ticks > 0) next = next->next; // what the fuck i just wrote
|
||||||
|
|
||||||
|
curr_task = next;
|
||||||
|
return curr_task->rsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void yield(u64 ticks) {
|
||||||
|
curr_task->sleep_ticks = ticks;
|
||||||
|
__asm__ volatile("hlt");
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <core/string.h>
|
#include <core/string.h>
|
||||||
|
|
||||||
i32 strcmp(const char* s1, const char* s2) {
|
i32 strcmp(const char *s1, const char *s2) {
|
||||||
while (*s1 && (*s1 == *s2)) {
|
while (*s1 && (*s1 == *s2)) {
|
||||||
s1++;
|
s1++;
|
||||||
s2++;
|
s2++;
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
// Copyright (c) 2025 0xKarinyash
|
// Copyright (c) 2025 0xKarinyash
|
||||||
|
|
||||||
|
#include <core/scheduler.h>
|
||||||
|
#include <core/panic.h>
|
||||||
#include <drivers/shitgui.h>
|
#include <drivers/shitgui.h>
|
||||||
|
#include <mm/heap.h>
|
||||||
|
#include <mm/memory.h>
|
||||||
|
|
||||||
#define SHITGUI_TRANSPARENCY_KEY 0xFF00FF
|
#define SHITGUI_TRANSPARENCY_KEY 0xFF00FF
|
||||||
|
#define SHITGUI_MAX_WINDOWS_AMOUNT 64
|
||||||
|
|
||||||
|
SG_Context* main_context;
|
||||||
|
SG_Window* windows[SHITGUI_MAX_WINDOWS_AMOUNT]; // нет блять линукс
|
||||||
|
u64 windows_amount = 0;
|
||||||
|
|
||||||
|
void sg_init(SG_Context *ctx) {
|
||||||
|
main_context = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img) {
|
void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img) {
|
||||||
if (!ctx->fb || !img) return;
|
if (!ctx->fb || !img) return;
|
||||||
@@ -67,4 +80,64 @@ void sg_draw_char_bitmap(SG_Context *ctx, SG_Point *p, char c, u32 color, SG_Fon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_Window* create_window(const char *title, SG_Point* size, SG_Point* position) {
|
||||||
|
if (windows_amount >= SHITGUI_MAX_WINDOWS_AMOUNT) return nullptr;
|
||||||
|
SG_Context* ctx = nullptr;
|
||||||
|
u32* fb = nullptr;
|
||||||
|
SG_Window* window = nullptr;
|
||||||
|
|
||||||
|
ctx = (SG_Context*)malloc(sizeof(SG_Context));
|
||||||
|
if (!ctx) goto fail; // goto is GOOD for cleaning up in C stfu.
|
||||||
|
// Mainline linux kernel contains 100k gotos
|
||||||
|
|
||||||
|
fb = malloc(size->x * size->y * sizeof(u32));
|
||||||
|
if (!fb) goto fail;
|
||||||
|
memset(fb, 0, size->x * size->y * sizeof(u32));
|
||||||
|
|
||||||
|
window = (SG_Window*)malloc(sizeof(SG_Window));
|
||||||
|
if (!window) goto fail;
|
||||||
|
|
||||||
|
ctx->fb = fb;
|
||||||
|
ctx->height = size->y;
|
||||||
|
ctx->width = size->x;
|
||||||
|
ctx->pitch = size->x;
|
||||||
|
|
||||||
|
|
||||||
|
window->ctx = ctx;
|
||||||
|
window->title = title;
|
||||||
|
window->pos.x = position->x;
|
||||||
|
window->pos.y = position->y;
|
||||||
|
|
||||||
|
windows[windows_amount] = window;
|
||||||
|
windows_amount++;
|
||||||
|
|
||||||
|
return window;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (ctx) free(ctx);
|
||||||
|
if (fb) free(fb);
|
||||||
|
if (window) free(window);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_window(SG_Context *ctx, SG_Window *window) {
|
||||||
|
SG_Image img = {0};
|
||||||
|
img.buffer = window->ctx->fb;
|
||||||
|
if (!img.buffer) panic("No img buffer found");
|
||||||
|
img.height = window->ctx->height;
|
||||||
|
img.width = window->ctx->width;
|
||||||
|
|
||||||
|
sg_put_img(ctx, &window->pos, &img);
|
||||||
|
}
|
||||||
|
|
||||||
|
void composer_task() {
|
||||||
|
while (true) {
|
||||||
|
for (u64 i = 0; i < windows_amount; i++) {
|
||||||
|
render_window(main_context, windows[i]);
|
||||||
|
}
|
||||||
|
yield(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <drivers/timer.h>
|
#include <drivers/timer.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <core/scheduler.h>
|
||||||
|
|
||||||
#define PIT_BASE_CLOCK 1193180
|
#define PIT_BASE_CLOCK 1193180
|
||||||
#define PIT_CMD 0x43
|
#define PIT_CMD 0x43
|
||||||
@@ -23,9 +24,10 @@ void timer_init(u32 freq) {
|
|||||||
outb(0x21, mask);
|
outb(0x21, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_handler() {
|
u64 timer_handler(Registers *regs) {
|
||||||
ticks++;
|
ticks++;
|
||||||
outb(MASTER_COMMAND, 0x20);
|
outb(MASTER_COMMAND, 0x20);
|
||||||
|
return sched_next((u64)regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep(u64 ms) {
|
void sleep(u64 ms) {
|
||||||
|
|||||||
+10
-3
@@ -2,6 +2,7 @@
|
|||||||
// Copyright (c) 2025 0xKarinyash
|
// Copyright (c) 2025 0xKarinyash
|
||||||
|
|
||||||
#include "bootinfo.h"
|
#include "bootinfo.h"
|
||||||
|
#include "core/scheduler.h"
|
||||||
#include <shell/ksh.h>
|
#include <shell/ksh.h>
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
@@ -48,6 +49,10 @@ void kmain(Bootinfo* info) {
|
|||||||
kprintf("Timer initialized\n");
|
kprintf("Timer initialized\n");
|
||||||
heap_init();
|
heap_init();
|
||||||
kprintf("Heap initialized\n");
|
kprintf("Heap initialized\n");
|
||||||
|
sched_init();
|
||||||
|
kprintf("Scheduler initialized\n");
|
||||||
|
sg_init(&sg_ctx);
|
||||||
|
kprintf("Shitgui initialized");
|
||||||
|
|
||||||
info = (Bootinfo*)PHYS_TO_HHDM((u64)info);
|
info = (Bootinfo*)PHYS_TO_HHDM((u64)info);
|
||||||
|
|
||||||
@@ -65,8 +70,10 @@ void kmain(Bootinfo* info) {
|
|||||||
|
|
||||||
show_splash(&sg_ctx);
|
show_splash(&sg_ctx);
|
||||||
|
|
||||||
ksh();
|
sched_spawn(composer_task);
|
||||||
|
sched_spawn(ksh);
|
||||||
panic("Kernel main loop exited");
|
__asm__ volatile("sti");
|
||||||
|
|
||||||
|
while (true) __asm__ volatile("hlt");
|
||||||
|
panic("How in the name of God you got here?");
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <core/panic.h>
|
#include <core/panic.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#define HEAP_SIZE_PAGES 32
|
#define HEAP_SIZE_PAGES 1024
|
||||||
|
|
||||||
extern u64* pml4_kernel;
|
extern u64* pml4_kernel;
|
||||||
static block_header* heap_list_head = nullptr;
|
static block_header* heap_list_head = nullptr;
|
||||||
|
|||||||
@@ -3,18 +3,65 @@
|
|||||||
// contents of this file will be changed CONSTANTLY
|
// contents of this file will be changed CONSTANTLY
|
||||||
// im just testing new stuff here
|
// im just testing new stuff here
|
||||||
|
|
||||||
|
#include "core/panic.h"
|
||||||
|
#include "drivers/shitgui.h"
|
||||||
#include <drivers/timer.h>
|
#include <drivers/timer.h>
|
||||||
#include <drivers/console.h>
|
#include <drivers/console.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <shell/dbgcmd.h>
|
#include <shell/dbgcmd.h>
|
||||||
|
|
||||||
|
#include <core/scheduler.h>
|
||||||
|
|
||||||
|
SG_Window* win_a = nullptr;
|
||||||
|
SG_Window* win_b = nullptr;
|
||||||
|
|
||||||
|
void a() {
|
||||||
|
SG_Point sizes = {0};
|
||||||
|
sizes.x = win_a->ctx->width;
|
||||||
|
sizes.y = win_a->ctx->height;
|
||||||
|
|
||||||
|
u64 t = 0;
|
||||||
|
while (true) {
|
||||||
|
for (u32 y = 0; y < sizes.y; y++) {
|
||||||
|
for (u32 x = 0; x < sizes.x; x++) {
|
||||||
|
win_a->ctx->fb[y * sizes.x + x] = (x * y) ^ t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void b() {
|
||||||
|
SG_Point sizes = {0};
|
||||||
|
sizes.x = win_b->ctx->width;
|
||||||
|
sizes.y = win_b->ctx->height;
|
||||||
|
|
||||||
|
u64 t = 0;
|
||||||
|
while (true) {
|
||||||
|
for (u32 y = 0; y < sizes.y; y++) {
|
||||||
|
for (u32 x = 0; x < sizes.x; x++) {
|
||||||
|
win_b->ctx->fb[y * sizes.x + x] = (x ^ y) ^ t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u64 debug() {
|
u64 debug() {
|
||||||
kprintf("Float test\n");
|
kprintf("scheduler test\n");
|
||||||
kprintf("Trying 3.14 + 1.44 in 3 seconds..\n");
|
SG_Point sizes = {0};
|
||||||
sleep(3000);
|
sizes.x = 256;
|
||||||
volatile float a = 3.14;
|
sizes.y = 256;
|
||||||
volatile float b = 1.44;
|
SG_Point pos_a = {0};
|
||||||
volatile float c = a + b;
|
pos_a.x = 100;
|
||||||
kprintf("%d", (i32)c);
|
pos_a.y = 40;
|
||||||
|
SG_Point pos_b = {0};
|
||||||
|
pos_b.x = 512;
|
||||||
|
pos_b.y = 40;
|
||||||
|
win_a = create_window("A", &sizes, &pos_a);
|
||||||
|
if (!win_a) panic("No win a");
|
||||||
|
win_b = create_window("B", &sizes, &pos_b);
|
||||||
|
if (!win_b) panic("No win b");
|
||||||
|
sched_spawn(a);
|
||||||
|
sched_spawn(b);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user