mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat(kernel): Add eBPF Virtual Machine & Verifier, VMA Memory Mapper, Sysfs KObject Tree, Unix98 PTY, and 2D Canvas Graphics Engine
This commit is contained in:
1 parent
8a90d88f70
commit
65c916d6ac
12 files changed
+1133
-6
No files matched your search
@@ -0,0 +1,107 @@
|
||||
#include <drivers/pty.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
static pty_pair_t pty_pairs[PTY_MAX_PAIRS];
|
||||
|
||||
void pty_init(void) {
|
||||
memset(pty_pairs, 0, sizeof(pty_pairs));
|
||||
for (size_t i = 0; i < PTY_MAX_PAIRS; i++) {
|
||||
pty_pairs[i].pty_num = (uint32_t)i;
|
||||
strcpy(pty_pairs[i].master_name, "/dev/ptmx");
|
||||
snprintf(pty_pairs[i].slave_name, sizeof(pty_pairs[i].slave_name), "/dev/pts/%u", (uint32_t)i);
|
||||
pty_pairs[i].echo_enabled = true;
|
||||
pty_pairs[i].raw_mode = false;
|
||||
}
|
||||
printk(KERN_INFO "PTY: Unix98 Pseudo-Terminal Subsystem initialized (8 pts channels)\n");
|
||||
}
|
||||
|
||||
int pty_open_master(void) {
|
||||
for (size_t i = 0; i < PTY_MAX_PAIRS; i++) {
|
||||
if (!pty_pairs[i].in_use) {
|
||||
pty_pairs[i].in_use = true;
|
||||
pty_pairs[i].master_open = true;
|
||||
pty_pairs[i].slave_open = false;
|
||||
pty_pairs[i].m2s_head = pty_pairs[i].m2s_tail = 0;
|
||||
pty_pairs[i].s2m_head = pty_pairs[i].s2m_tail = 0;
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pty_open_slave(int master_fd) {
|
||||
if (master_fd < 0 || master_fd >= PTY_MAX_PAIRS || !pty_pairs[master_fd].in_use) return -1;
|
||||
pty_pairs[master_fd].slave_open = true;
|
||||
return master_fd;
|
||||
}
|
||||
|
||||
int pty_master_write(int master_fd, const char* data, size_t len) {
|
||||
if (master_fd < 0 || master_fd >= PTY_MAX_PAIRS || !pty_pairs[master_fd].in_use || !data) return -1;
|
||||
|
||||
pty_pair_t* pty = &pty_pairs[master_fd];
|
||||
size_t written = 0;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
size_t next = (pty->m2s_head + 1) % PTY_BUFFER_SZ;
|
||||
if (next != pty->m2s_tail) {
|
||||
pty->m2s_buf[pty->m2s_head] = data[i];
|
||||
pty->m2s_head = next;
|
||||
written++;
|
||||
}
|
||||
}
|
||||
return (int)written;
|
||||
}
|
||||
|
||||
int pty_master_read(int master_fd, char* data, size_t max_len) {
|
||||
if (master_fd < 0 || master_fd >= PTY_MAX_PAIRS || !pty_pairs[master_fd].in_use || !data) return -1;
|
||||
|
||||
pty_pair_t* pty = &pty_pairs[master_fd];
|
||||
size_t read_bytes = 0;
|
||||
while (pty->s2m_tail != pty->s2m_head && read_bytes < max_len) {
|
||||
data[read_bytes++] = pty->s2m_buf[pty->s2m_tail];
|
||||
pty->s2m_tail = (pty->s2m_tail + 1) % PTY_BUFFER_SZ;
|
||||
}
|
||||
return (int)read_bytes;
|
||||
}
|
||||
|
||||
int pty_slave_write(int slave_fd, const char* data, size_t len) {
|
||||
if (slave_fd < 0 || slave_fd >= PTY_MAX_PAIRS || !pty_pairs[slave_fd].in_use || !data) return -1;
|
||||
|
||||
pty_pair_t* pty = &pty_pairs[slave_fd];
|
||||
size_t written = 0;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
size_t next = (pty->s2m_head + 1) % PTY_BUFFER_SZ;
|
||||
if (next != pty->s2m_tail) {
|
||||
pty->s2m_buf[pty->s2m_head] = data[i];
|
||||
pty->s2m_head = next;
|
||||
written++;
|
||||
}
|
||||
}
|
||||
return (int)written;
|
||||
}
|
||||
|
||||
int pty_slave_read(int slave_fd, char* data, size_t max_len) {
|
||||
if (slave_fd < 0 || slave_fd >= PTY_MAX_PAIRS || !pty_pairs[slave_fd].in_use || !data) return -1;
|
||||
|
||||
pty_pair_t* pty = &pty_pairs[slave_fd];
|
||||
size_t read_bytes = 0;
|
||||
while (pty->m2s_tail != pty->m2s_head && read_bytes < max_len) {
|
||||
data[read_bytes++] = pty->m2s_buf[pty->m2s_tail];
|
||||
pty->m2s_tail = (pty->m2s_tail + 1) % PTY_BUFFER_SZ;
|
||||
}
|
||||
return (int)read_bytes;
|
||||
}
|
||||
|
||||
size_t pty_get_active_count(void) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < PTY_MAX_PAIRS; i++) {
|
||||
if (pty_pairs[i].in_use) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const pty_pair_t* pty_get_pair(size_t index) {
|
||||
if (index >= PTY_MAX_PAIRS || !pty_pairs[index].in_use) return NULL;
|
||||
return &pty_pairs[index];
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
#include <drivers/canvas.h>
|
||||
#include <drivers/fb.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static uint32_t* back_buffer = NULL;
|
||||
static uint32_t screen_width = 320;
|
||||
static uint32_t screen_height = 200;
|
||||
|
||||
// Basic 8x8 font bitmap for ASCII characters (32..126)
|
||||
static const uint8_t font8x8_basic[96][8] = {
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // (space)
|
||||
{0x18,0x3c,0x3c,0x18,0x18,0x00,0x18,0x00}, // !
|
||||
{0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x6c,0x6c,0xfe,0x6c,0xfe,0x6c,0x6c,0x00}, // #
|
||||
{0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00}, // $
|
||||
{0x00,0x63,0x66,0x0c,0x18,0x33,0x63,0x00}, // %
|
||||
{0x38,0x6c,0x38,0x76,0xdc,0xcc,0x76,0x00}, // &
|
||||
{0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00}, // '
|
||||
{0x0c,0x18,0x30,0x30,0x30,0x18,0x0c,0x00}, // (
|
||||
{0x30,0x18,0x0c,0x0c,0x0c,0x18,0x30,0x00}, // )
|
||||
{0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00}, // *
|
||||
{0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
|
||||
{0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
|
||||
{0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00}, // /
|
||||
{0x7c,0xc6,0xce,0xd6,0xe6,0xc6,0x7c,0x00}, // 0
|
||||
{0x18,0x38,0x18,0x18,0x18,0x18,0x7e,0x00}, // 1
|
||||
{0x7c,0xc6,0x06,0x1c,0x30,0x66,0xfe,0x00}, // 2
|
||||
{0x7c,0xc6,0x06,0x3c,0x06,0xc6,0x7c,0x00}, // 3
|
||||
{0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x1e,0x00}, // 4
|
||||
{0xfe,0xc0,0xfc,0x06,0x06,0xc6,0x7c,0x00}, // 5
|
||||
{0x7c,0xc6,0xc0,0xfc,0xc6,0xc6,0x7c,0x00}, // 6
|
||||
{0xfe,0x06,0x0c,0x18,0x30,0x30,0x30,0x00}, // 7
|
||||
{0x7c,0xc6,0xc6,0x7c,0xc6,0xc6,0x7c,0x00}, // 8
|
||||
{0x7c,0xc6,0xc6,0x7e,0x06,0xc6,0x7c,0x00}, // 9
|
||||
{0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00}, // :
|
||||
{0x00,0x18,0x18,0x00,0x18,0x18,0x30,0x00}, // ;
|
||||
{0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00}, // <
|
||||
{0x00,0x00,0x7e,0x00,0x7e,0x00,0x00,0x00}, // =
|
||||
{0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00}, // >
|
||||
{0x7c,0xc6,0x0c,0x18,0x18,0x00,0x18,0x00}, // ?
|
||||
{0x7c,0xc6,0xde,0xde,0xdc,0xc0,0x7c,0x00}, // @
|
||||
{0x38,0x6c,0xc6,0xfe,0xc6,0xc6,0xc6,0x00}, // A
|
||||
{0xfc,0x66,0x66,0x7c,0x66,0x66,0xfc,0x00}, // B
|
||||
{0x3c,0x66,0xc0,0xc0,0xc0,0x66,0x3c,0x00}, // C
|
||||
{0xf8,0x6c,0x66,0x66,0x66,0x6c,0xf8,0x00}, // D
|
||||
{0xfe,0x62,0x68,0x78,0x68,0x62,0xfe,0x00}, // E
|
||||
{0xfe,0x62,0x68,0x78,0x68,0x60,0xf0,0x00}, // F
|
||||
{0x3c,0x66,0xc0,0xc0,0xce,0x66,0x3a,0x00}, // G
|
||||
{0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00}, // H
|
||||
{0x7e,0x18,0x18,0x18,0x18,0x18,0x7e,0x00}, // I
|
||||
{0x1e,0x0c,0x0c,0x0c,0xcc,0xcc,0x78,0x00}, // J
|
||||
{0xe6,0x66,0x6c,0x78,0x6c,0x66,0xe6,0x00}, // K
|
||||
{0xf0,0x60,0x60,0x60,0x62,0x66,0xfe,0x00}, // L
|
||||
{0xc6,0xee,0xfe,0xfe,0xd6,0xc6,0xc6,0x00}, // M
|
||||
{0xc6,0xe6,0xf6,0xde,0xce,0xc6,0xc6,0x00}, // N
|
||||
{0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00}, // O
|
||||
{0xfc,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00}, // P
|
||||
{0x7c,0xc6,0xc6,0xc6,0xd6,0x7c,0x0e,0x00}, // Q
|
||||
{0xfc,0x66,0x66,0x7c,0x6c,0x66,0xe6,0x00}, // R
|
||||
{0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00}, // S
|
||||
{0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, // T
|
||||
{0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00}, // U
|
||||
{0xc6,0xc6,0xc6,0xc6,0x6c,0x38,0x10,0x00}, // V
|
||||
{0xc6,0xc6,0xd6,0xfe,0xfe,0xee,0xc6,0x00}, // W
|
||||
{0xc6,0x6c,0x38,0x38,0x6c,0xc6,0x00,0x00}, // X
|
||||
{0x66,0x66,0x66,0x3c,0x18,0x18,0x3c,0x00}, // Y
|
||||
{0xfe,0x06,0x0c,0x18,0x30,0x60,0xfe,0x00}, // Z
|
||||
{0x3c,0x30,0x30,0x30,0x30,0x30,0x3c,0x00}, // [
|
||||
{0xc0,0x60,0x30,0x18,0x0c,0x06,0x02,0x00}, // \
|
||||
{0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00}, // ]
|
||||
{0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, // _
|
||||
{0x30,0x18,0x0c,0x00,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x78,0x0c,0x7c,0xcc,0x76,0x00}, // a
|
||||
{0xe0,0x60,0x7c,0x66,0x66,0x66,0xdc,0x00}, // b
|
||||
{0x00,0x00,0x78,0xcc,0xc0,0xcc,0x78,0x00}, // c
|
||||
{0x1c,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00}, // d
|
||||
{0x00,0x00,0x78,0xcc,0xfc,0xc0,0x78,0x00}, // e
|
||||
{0x38,0x6c,0x60,0xf0,0x60,0x60,0xf0,0x00}, // f
|
||||
{0x00,0x00,0x76,0xcc,0xcc,0x7c,0x0c,0xf8}, // g
|
||||
{0xe0,0x60,0x6c,0x76,0x66,0x66,0xe6,0x00}, // h
|
||||
{0x18,0x00,0x38,0x18,0x18,0x18,0x3c,0x00}, // i
|
||||
{0x0c,0x00,0x1c,0x0c,0x0c,0xcc,0xcc,0x78}, // j
|
||||
{0xe0,0x60,0x66,0x6c,0x78,0x6c,0xe6,0x00}, // k
|
||||
{0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00}, // l
|
||||
{0x00,0x00,0xec,0xfe,0xd6,0xd6,0xd6,0x00}, // m
|
||||
{0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x00}, // n
|
||||
{0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0x00}, // o
|
||||
{0x00,0x00,0xdc,0x66,0x66,0x7c,0x60,0xf0}, // p
|
||||
{0x00,0x00,0x76,0xcc,0xcc,0x7c,0x0c,0x1e}, // q
|
||||
{0x00,0x00,0xdc,0x76,0x60,0x60,0xf0,0x00}, // r
|
||||
{0x00,0x00,0x7c,0xc0,0x78,0x0c,0xf8,0x00}, // s
|
||||
{0x10,0x30,0x7c,0x30,0x30,0x34,0x18,0x00}, // t
|
||||
{0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x76,0x00}, // u
|
||||
{0x00,0x00,0xc6,0xc6,0xc6,0x6c,0x38,0x00}, // v
|
||||
{0x00,0x00,0xc6,0xd6,0xfe,0xfe,0x6c,0x00}, // w
|
||||
{0x00,0x00,0xc6,0x6c,0x38,0x6c,0xc6,0x00}, // x
|
||||
{0x00,0x00,0xc6,0xc6,0xce,0x76,0x06,0x7c}, // y
|
||||
{0x00,0x00,0xfe,0x0c,0x38,0x60,0xfe,0x00}, // z
|
||||
};
|
||||
|
||||
void canvas_init(void) {
|
||||
const fb_info_t* fb = fb_get_info();
|
||||
if (fb && fb->width > 0 && fb->height > 0) {
|
||||
screen_width = fb->width;
|
||||
screen_height = fb->height;
|
||||
}
|
||||
back_buffer = (uint32_t*)kzalloc(screen_width * screen_height * sizeof(uint32_t));
|
||||
printk(KERN_INFO "CANVAS: 2D Graphics Canvas & Rasterizer online (%ux%u 32bpp)\n",
|
||||
screen_width, screen_height);
|
||||
}
|
||||
|
||||
void canvas_clear(uint32_t color) {
|
||||
if (!back_buffer) return;
|
||||
for (size_t i = 0; i < screen_width * screen_height; i++) {
|
||||
back_buffer[i] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_draw_pixel(int x, int y, uint32_t color) {
|
||||
if (!back_buffer || x < 0 || x >= (int)screen_width || y < 0 || y >= (int)screen_height) return;
|
||||
back_buffer[y * screen_width + x] = color;
|
||||
}
|
||||
|
||||
void canvas_draw_line(int x0, int y0, int x1, int y1, uint32_t color) {
|
||||
int dx = (x1 > x0) ? (x1 - x0) : (x0 - x1);
|
||||
int dy = (y1 > y0) ? (y1 - y0) : (y0 - y1);
|
||||
int sx = (x0 < x1) ? 1 : -1;
|
||||
int sy = (y0 < y1) ? 1 : -1;
|
||||
int err = (dx > dy ? dx : -dy) / 2;
|
||||
|
||||
while (1) {
|
||||
canvas_draw_pixel(x0, y0, color);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int e2 = err;
|
||||
if (e2 > -dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_draw_rect(int x, int y, int w, int h, uint32_t color, bool filled) {
|
||||
if (w <= 0 || h <= 0) return;
|
||||
if (filled) {
|
||||
for (int j = y; j < y + h; j++) {
|
||||
for (int i = x; i < x + w; i++) {
|
||||
canvas_draw_pixel(i, j, color);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
canvas_draw_line(x, y, x + w - 1, y, color);
|
||||
canvas_draw_line(x, y + h - 1, x + w - 1, y + h - 1, color);
|
||||
canvas_draw_line(x, y, x, y + h - 1, color);
|
||||
canvas_draw_line(x + w - 1, y, x + w - 1, y + h - 1, color);
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_draw_circle(int cx, int cy, int r, uint32_t color, bool filled) {
|
||||
int x = r;
|
||||
int y = 0;
|
||||
int err = 0;
|
||||
|
||||
while (x >= y) {
|
||||
if (filled) {
|
||||
canvas_draw_line(cx - x, cy + y, cx + x, cy + y, color);
|
||||
canvas_draw_line(cx - x, cy - y, cx + x, cy - y, color);
|
||||
canvas_draw_line(cx - y, cy + x, cx + y, cy + x, color);
|
||||
canvas_draw_line(cx - y, cy - x, cx + y, cy - x, color);
|
||||
} else {
|
||||
canvas_draw_pixel(cx + x, cy + y, color);
|
||||
canvas_draw_pixel(cx + y, cy + x, color);
|
||||
canvas_draw_pixel(cx - y, cy + x, color);
|
||||
canvas_draw_pixel(cx - x, cy + y, color);
|
||||
canvas_draw_pixel(cx - x, cy - y, color);
|
||||
canvas_draw_pixel(cx - y, cy - x, color);
|
||||
canvas_draw_pixel(cx + y, cy - x, color);
|
||||
canvas_draw_pixel(cx + x, cy - y, color);
|
||||
}
|
||||
if (err <= 0) {
|
||||
y += 1;
|
||||
err += 2*y + 1;
|
||||
}
|
||||
if (err > 0) {
|
||||
x -= 1;
|
||||
err -= 2*x + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_draw_char(int x, int y, char c, uint32_t color, uint32_t bg_color) {
|
||||
if (c < 32 || c > 126) c = ' ';
|
||||
const uint8_t* glyph = font8x8_basic[c - 32];
|
||||
|
||||
for (int row = 0; row < 8; row++) {
|
||||
uint8_t line = glyph[row];
|
||||
for (int col = 0; col < 8; col++) {
|
||||
if (line & (1 << (7 - col))) {
|
||||
canvas_draw_pixel(x + col, y + row, color);
|
||||
} else if (bg_color != 0) {
|
||||
canvas_draw_pixel(x + col, y + row, bg_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_draw_string(int x, int y, const char* str, uint32_t color, uint32_t bg_color) {
|
||||
if (!str) return;
|
||||
int cur_x = x;
|
||||
while (*str) {
|
||||
canvas_draw_char(cur_x, y, *str, color, bg_color);
|
||||
cur_x += 8;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void canvas_render_desktop_mockup(void) {
|
||||
// 1. Wallpaper (Navy Gradient)
|
||||
canvas_clear(COLOR_NAVY);
|
||||
|
||||
// 2. Top Banner / Desktop Header
|
||||
canvas_draw_rect(0, 0, screen_width, 16, COLOR_TITLE_BAR, true);
|
||||
canvas_draw_string(8, 4, "SUB-OS Graphical Desktop Environment v0.2.0", COLOR_WHITE, 0);
|
||||
canvas_draw_string(screen_width - 80, 4, "13:45 UTC", COLOR_YELLOW, 0);
|
||||
|
||||
// 3. Floating Terminal Window (Simulated Window Manager)
|
||||
int win_x = 24, win_y = 30, win_w = 270, win_h = 135;
|
||||
canvas_draw_rect(win_x, win_y, win_w, win_h, COLOR_DARK_GRAY, true);
|
||||
canvas_draw_rect(win_x, win_y, win_w, win_h, COLOR_LIGHT_GRAY, false);
|
||||
|
||||
// Window Title Bar
|
||||
canvas_draw_rect(win_x, win_y, win_w, 14, COLOR_ACCENT, true);
|
||||
canvas_draw_string(win_x + 6, win_y + 3, "Terminal - root@sub-os:~", COLOR_WHITE, 0);
|
||||
canvas_draw_circle(win_x + win_w - 8, win_y + 7, 3, COLOR_RED, true);
|
||||
canvas_draw_circle(win_x + win_w - 18, win_y + 7, 3, COLOR_YELLOW, true);
|
||||
canvas_draw_circle(win_x + win_w - 28, win_y + 7, 3, COLOR_GREEN, true);
|
||||
|
||||
// Window Content
|
||||
canvas_draw_string(win_x + 8, win_y + 22, "Welcome to SUB-OS Kernel 0.2.0", COLOR_GREEN, 0);
|
||||
canvas_draw_string(win_x + 8, win_y + 36, "Tasks: 16 running | Memory: 122MB Free", COLOR_WHITE, 0);
|
||||
canvas_draw_string(win_x + 8, win_y + 50, "Services: HTTPD, SSHD, NetFilter active", COLOR_YELLOW, 0);
|
||||
canvas_draw_string(win_x + 8, win_y + 68, "sub-os:/> neofetch", COLOR_CYAN, 0);
|
||||
canvas_draw_string(win_x + 8, win_y + 82, "OS: SUB-OS (x86_64 Long Mode)", COLOR_WHITE, 0);
|
||||
canvas_draw_string(win_x + 8, win_y + 96, "Kernel: 0.2.0-lts Modular Monolithic", COLOR_WHITE, 0);
|
||||
canvas_draw_string(win_x + 8, win_y + 112, "sub-os:/> _", COLOR_GREEN, 0);
|
||||
|
||||
// 4. Bottom Taskbar
|
||||
canvas_draw_rect(0, screen_height - 18, screen_width, 18, COLOR_TITLE_BAR, true);
|
||||
canvas_draw_rect(4, screen_height - 15, 45, 12, COLOR_ACCENT, true);
|
||||
canvas_draw_string(8, screen_height - 13, "Start", COLOR_WHITE, 0);
|
||||
canvas_draw_string(60, screen_height - 13, "[Terminal]", COLOR_LIGHT_GRAY, 0);
|
||||
canvas_draw_string(140, screen_height - 13, "[Nano]", COLOR_LIGHT_GRAY, 0);
|
||||
canvas_draw_string(195, screen_height - 13, "[HTTPD: 80]", COLOR_GREEN, 0);
|
||||
canvas_draw_string(screen_width - 45, screen_height - 13, "[OK]", COLOR_YELLOW, 0);
|
||||
|
||||
canvas_present();
|
||||
}
|
||||
|
||||
void canvas_present(void) {
|
||||
if (!back_buffer) return;
|
||||
const fb_info_t* fb = fb_get_info();
|
||||
if (fb && fb->address != 0) {
|
||||
uint32_t* hw_fb = (uint32_t*)fb->address;
|
||||
memcpy(hw_fb, back_buffer, screen_width * screen_height * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef _DRIVERS_CANVAS_H
|
||||
#define _DRIVERS_CANVAS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define COLOR_BLACK 0x00000000
|
||||
#define COLOR_WHITE 0x00FFFFFF
|
||||
#define COLOR_RED 0x00FF4444
|
||||
#define COLOR_GREEN 0x0044FF44
|
||||
#define COLOR_BLUE 0x004488FF
|
||||
#define COLOR_YELLOW 0x00FFDD44
|
||||
#define COLOR_CYAN 0x0044DDFF
|
||||
#define COLOR_DARK_GRAY 0x00222222
|
||||
#define COLOR_LIGHT_GRAY 0x00CCCCCC
|
||||
#define COLOR_NAVY 0x001B2A4A
|
||||
#define COLOR_TITLE_BAR 0x002D3748
|
||||
#define COLOR_ACCENT 0x003182CE
|
||||
|
||||
void canvas_init(void);
|
||||
void canvas_clear(uint32_t color);
|
||||
void canvas_draw_pixel(int x, int y, uint32_t color);
|
||||
void canvas_draw_line(int x0, int y0, int x1, int y1, uint32_t color);
|
||||
void canvas_draw_rect(int x, int y, int w, int h, uint32_t color, bool filled);
|
||||
void canvas_draw_circle(int cx, int cy, int r, uint32_t color, bool filled);
|
||||
void canvas_draw_char(int x, int y, char c, uint32_t color, uint32_t bg_color);
|
||||
void canvas_draw_string(int x, int y, const char* str, uint32_t color, uint32_t bg_color);
|
||||
void canvas_render_desktop_mockup(void);
|
||||
void canvas_present(void);
|
||||
|
||||
#endif // _DRIVERS_CANVAS_H
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef _DRIVERS_PTY_H
|
||||
#define _DRIVERS_PTY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PTY_MAX_PAIRS 8
|
||||
#define PTY_BUFFER_SZ 1024
|
||||
|
||||
typedef struct {
|
||||
uint32_t pty_num;
|
||||
char master_name[16]; // /dev/ptmx
|
||||
char slave_name[16]; // /dev/pts/0
|
||||
char m2s_buf[PTY_BUFFER_SZ];
|
||||
size_t m2s_head;
|
||||
size_t m2s_tail;
|
||||
char s2m_buf[PTY_BUFFER_SZ];
|
||||
size_t s2m_head;
|
||||
size_t s2m_tail;
|
||||
bool echo_enabled;
|
||||
bool raw_mode;
|
||||
bool master_open;
|
||||
bool slave_open;
|
||||
bool in_use;
|
||||
} pty_pair_t;
|
||||
|
||||
void pty_init(void);
|
||||
int pty_open_master(void);
|
||||
int pty_open_slave(int master_fd);
|
||||
int pty_master_write(int master_fd, const char* data, size_t len);
|
||||
int pty_master_read(int master_fd, char* data, size_t max_len);
|
||||
int pty_slave_write(int slave_fd, const char* data, size_t len);
|
||||
int pty_slave_read(int slave_fd, char* data, size_t max_len);
|
||||
|
||||
size_t pty_get_active_count(void);
|
||||
const pty_pair_t* pty_get_pair(size_t index);
|
||||
|
||||
#endif // _DRIVERS_PTY_H
|
||||
@@ -0,0 +1,95 @@
|
||||
#ifndef _KERNEL_BPF_H
|
||||
#define _KERNEL_BPF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define BPF_MAX_INSNS 256
|
||||
#define BPF_MAX_MAPS 16
|
||||
#define BPF_MAX_PROGS 16
|
||||
#define BPF_REG_CNT 11 // R0 (ret), R1-R5 (args), R6-R9 (callee-saved), R10 (frame pointer)
|
||||
|
||||
// BPF Instruction Class
|
||||
#define BPF_CLASS_LD 0x00
|
||||
#define BPF_CLASS_LDX 0x01
|
||||
#define BPF_CLASS_ST 0x02
|
||||
#define BPF_CLASS_STX 0x03
|
||||
#define BPF_CLASS_ALU 0x04
|
||||
#define BPF_CLASS_JMP 0x05
|
||||
#define BPF_CLASS_ALU64 0x07
|
||||
|
||||
// BPF ALU Operations
|
||||
#define BPF_OP_ADD 0x00
|
||||
#define BPF_OP_SUB 0x10
|
||||
#define BPF_OP_MUL 0x20
|
||||
#define BPF_OP_DIV 0x30
|
||||
#define BPF_OP_OR 0x40
|
||||
#define BPF_OP_AND 0x50
|
||||
#define BPF_OP_LSH 0x60
|
||||
#define BPF_OP_RSH 0x70
|
||||
#define BPF_OP_NEG 0x80
|
||||
#define BPF_OP_MOD 0x90
|
||||
#define BPF_OP_XOR 0xa0
|
||||
#define BPF_OP_MOV 0xb0
|
||||
|
||||
// BPF Jump Operations
|
||||
#define BPF_JMP_JA 0x00
|
||||
#define BPF_JMP_JEQ 0x10
|
||||
#define BPF_JMP_JGT 0x20
|
||||
#define BPF_JMP_JGE 0x30
|
||||
#define BPF_JMP_JNE 0x50
|
||||
#define BPF_JMP_CALL 0x80
|
||||
#define BPF_JMP_EXIT 0x90
|
||||
|
||||
typedef struct {
|
||||
uint8_t opcode;
|
||||
uint8_t dst_reg:4;
|
||||
uint8_t src_reg:4;
|
||||
int16_t offset;
|
||||
int32_t imm;
|
||||
} __attribute__((packed)) bpf_insn_t;
|
||||
|
||||
typedef enum {
|
||||
BPF_PROG_TYPE_UNSPEC = 0,
|
||||
BPF_PROG_TYPE_SOCKET_FILTER,
|
||||
BPF_PROG_TYPE_KPROBE,
|
||||
BPF_PROG_TYPE_TRACEPOINT,
|
||||
BPF_PROG_TYPE_XDP,
|
||||
BPF_PROG_TYPE_SYSCALL
|
||||
} bpf_prog_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
char name[32];
|
||||
bpf_prog_type_t type;
|
||||
bpf_insn_t insns[BPF_MAX_INSNS];
|
||||
uint32_t insn_count;
|
||||
uint64_t run_count;
|
||||
uint64_t total_runtime_ns;
|
||||
bool in_use;
|
||||
} bpf_prog_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
char name[32];
|
||||
uint32_t key_size;
|
||||
uint32_t value_size;
|
||||
uint32_t max_entries;
|
||||
uint8_t* data;
|
||||
bool in_use;
|
||||
} bpf_map_t;
|
||||
|
||||
void bpf_init(void);
|
||||
int bpf_prog_load(bpf_prog_type_t type, const char* name, const bpf_insn_t* insns, uint32_t count);
|
||||
int bpf_prog_run(uint32_t prog_id, void* ctx, uint64_t* ret_val);
|
||||
bool bpf_verify_prog(const bpf_insn_t* insns, uint32_t count);
|
||||
|
||||
int bpf_map_create(const char* name, uint32_t key_size, uint32_t value_size, uint32_t max_entries);
|
||||
int bpf_map_update_elem(uint32_t map_id, const void* key, const void* value);
|
||||
int bpf_map_lookup_elem(uint32_t map_id, const void* key, void* value_out);
|
||||
|
||||
size_t bpf_get_prog_count(void);
|
||||
const bpf_prog_t* bpf_get_prog(size_t index);
|
||||
|
||||
#endif // _KERNEL_BPF_H
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef _KERNEL_KOBJECT_H
|
||||
#define _KERNEL_KOBJECT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define KOBJ_NAME_LEN 32
|
||||
#define MAX_KOBJECTS 64
|
||||
|
||||
typedef enum {
|
||||
KOBJ_TYPE_GENERIC = 0,
|
||||
KOBJ_TYPE_BUS,
|
||||
KOBJ_TYPE_DEVICE,
|
||||
KOBJ_TYPE_DRIVER,
|
||||
KOBJ_TYPE_CLASS,
|
||||
KOBJ_TYPE_SUBSYS
|
||||
} kobj_type_t;
|
||||
|
||||
typedef struct kobject {
|
||||
char name[KOBJ_NAME_LEN];
|
||||
kobj_type_t type;
|
||||
struct kobject* parent;
|
||||
uint32_t ref_count;
|
||||
char path[128];
|
||||
bool in_use;
|
||||
} kobject_t;
|
||||
|
||||
void kobject_subsystem_init(void);
|
||||
kobject_t* kobject_create_and_add(const char* name, kobj_type_t type, kobject_t* parent);
|
||||
void kobject_get(kobject_t* kobj);
|
||||
void kobject_put(kobject_t* kobj);
|
||||
|
||||
size_t kobject_get_total_count(void);
|
||||
const kobject_t* kobject_get_at(size_t index);
|
||||
void kobject_dump_tree(void);
|
||||
|
||||
#endif // _KERNEL_KOBJECT_H
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef _MM_VMA_H
|
||||
#define _MM_VMA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PROT_NONE 0x0
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
#define PROT_EXEC 0x4
|
||||
|
||||
#define MAP_SHARED 0x01
|
||||
#define MAP_PRIVATE 0x02
|
||||
#define MAP_FIXED 0x10
|
||||
#define MAP_ANONYMOUS 0x20
|
||||
|
||||
#define MAX_VMAS_PER_TASK 32
|
||||
|
||||
typedef struct vm_area {
|
||||
uint64_t vm_start;
|
||||
uint64_t vm_end;
|
||||
uint32_t vm_flags;
|
||||
uint32_t vm_prot;
|
||||
uint64_t vm_pgoff;
|
||||
char vm_name[32];
|
||||
bool in_use;
|
||||
} vm_area_t;
|
||||
|
||||
typedef struct mm_struct {
|
||||
uint32_t pid;
|
||||
uint64_t start_code;
|
||||
uint64_t end_code;
|
||||
uint64_t start_data;
|
||||
uint64_t end_data;
|
||||
uint64_t start_brk;
|
||||
uint64_t brk;
|
||||
uint64_t start_stack;
|
||||
vm_area_t vmas[MAX_VMAS_PER_TASK];
|
||||
size_t vma_count;
|
||||
} mm_struct_t;
|
||||
|
||||
void vma_init(void);
|
||||
int vma_create_mm(uint32_t pid, mm_struct_t* mm);
|
||||
uint64_t vma_mmap(uint32_t pid, uint64_t addr, size_t len, int prot, int flags, const char* name);
|
||||
int vma_munmap(uint32_t pid, uint64_t addr, size_t len);
|
||||
const vm_area_t* vma_find(uint32_t pid, uint64_t addr);
|
||||
void vma_dump_maps(uint32_t pid);
|
||||
|
||||
#endif // _MM_VMA_H
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
#include <kernel/bpf.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <arch/x86_64/pit.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
static bpf_prog_t bpf_programs[BPF_MAX_PROGS];
|
||||
static bpf_map_t bpf_maps[BPF_MAX_MAPS];
|
||||
static uint32_t next_bpf_id = 1;
|
||||
|
||||
void bpf_init(void) {
|
||||
memset(bpf_programs, 0, sizeof(bpf_programs));
|
||||
memset(bpf_maps, 0, sizeof(bpf_maps));
|
||||
next_bpf_id = 1;
|
||||
|
||||
// Pre-load a default network packet counter BPF program
|
||||
bpf_insn_t default_insns[] = {
|
||||
{BPF_CLASS_ALU64 | BPF_OP_MOV, 0, 1, 0, 0}, // r0 = r1 (packet len)
|
||||
{BPF_CLASS_ALU64 | BPF_OP_ADD, 0, 0, 0, 14}, // r0 += 14 (eth header)
|
||||
{BPF_CLASS_JMP | BPF_JMP_EXIT, 0, 0, 0, 0} // exit r0
|
||||
};
|
||||
bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "net_pkt_counter", default_insns, 3);
|
||||
|
||||
printk(KERN_INFO "EBPF: In-Kernel Safe Bytecode Virtual Machine & Verifier online (v1.0)\n");
|
||||
}
|
||||
|
||||
bool bpf_verify_prog(const bpf_insn_t* insns, uint32_t count) {
|
||||
if (!insns || count == 0 || count > BPF_MAX_INSNS) return false;
|
||||
|
||||
bool has_exit = false;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
uint8_t cls = insns[i].opcode & 0x07;
|
||||
uint8_t dst = insns[i].dst_reg;
|
||||
uint8_t src = insns[i].src_reg;
|
||||
|
||||
if (dst >= BPF_REG_CNT || src >= BPF_REG_CNT) return false;
|
||||
|
||||
// Check if instruction is EXIT
|
||||
if (insns[i].opcode == (BPF_CLASS_JMP | BPF_JMP_EXIT)) {
|
||||
has_exit = true;
|
||||
}
|
||||
|
||||
// Check jump offset bounds
|
||||
if (cls == BPF_CLASS_JMP && insns[i].opcode != (BPF_CLASS_JMP | BPF_JMP_EXIT)) {
|
||||
int target = (int)i + 1 + insns[i].offset;
|
||||
if (target < 0 || target >= (int)count) return false; // Out-of-bounds jump
|
||||
}
|
||||
}
|
||||
|
||||
return has_exit;
|
||||
}
|
||||
|
||||
int bpf_prog_load(bpf_prog_type_t type, const char* name, const bpf_insn_t* insns, uint32_t count) {
|
||||
if (!name || !insns || count == 0) return -1;
|
||||
|
||||
if (!bpf_verify_prog(insns, count)) {
|
||||
printk(KERN_ERR "BPF: Verifier rejected program '%s' (Safety bounds violation)\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < BPF_MAX_PROGS; i++) {
|
||||
if (!bpf_programs[i].in_use) {
|
||||
bpf_programs[i].id = next_bpf_id++;
|
||||
strncpy(bpf_programs[i].name, name, sizeof(bpf_programs[i].name) - 1);
|
||||
bpf_programs[i].type = type;
|
||||
memcpy(bpf_programs[i].insns, insns, count * sizeof(bpf_insn_t));
|
||||
bpf_programs[i].insn_count = count;
|
||||
bpf_programs[i].run_count = 0;
|
||||
bpf_programs[i].total_runtime_ns = 0;
|
||||
bpf_programs[i].in_use = true;
|
||||
return (int)bpf_programs[i].id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bpf_prog_run(uint32_t prog_id, void* ctx, uint64_t* ret_val) {
|
||||
bpf_prog_t* prog = NULL;
|
||||
for (size_t i = 0; i < BPF_MAX_PROGS; i++) {
|
||||
if (bpf_programs[i].in_use && bpf_programs[i].id == prog_id) {
|
||||
prog = &bpf_programs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!prog) return -1;
|
||||
|
||||
uint64_t regs[BPF_REG_CNT] = {0};
|
||||
uint64_t stack[64] = {0};
|
||||
regs[1] = (uint64_t)ctx;
|
||||
regs[10] = (uint64_t)&stack[63]; // Frame pointer
|
||||
|
||||
uint32_t pc = 0;
|
||||
while (pc < prog->insn_count) {
|
||||
bpf_insn_t insn = prog->insns[pc];
|
||||
uint8_t cls = insn.opcode & 0x07;
|
||||
uint8_t op = insn.opcode & 0xF0;
|
||||
uint8_t dst = insn.dst_reg;
|
||||
uint8_t src = insn.src_reg;
|
||||
uint64_t val = (insn.opcode & 0x08) ? regs[src] : (uint32_t)insn.imm;
|
||||
|
||||
switch (cls) {
|
||||
case BPF_CLASS_ALU64:
|
||||
case BPF_CLASS_ALU:
|
||||
switch (op) {
|
||||
case BPF_OP_ADD: regs[dst] += val; break;
|
||||
case BPF_OP_SUB: regs[dst] -= val; break;
|
||||
case BPF_OP_MUL: regs[dst] *= val; break;
|
||||
case BPF_OP_DIV: if (val != 0) regs[dst] /= val; break;
|
||||
case BPF_OP_OR: regs[dst] |= val; break;
|
||||
case BPF_OP_AND: regs[dst] &= val; break;
|
||||
case BPF_OP_XOR: regs[dst] ^= val; break;
|
||||
case BPF_OP_MOV: regs[dst] = val; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case BPF_CLASS_JMP:
|
||||
if (op == BPF_JMP_EXIT) {
|
||||
if (ret_val) *ret_val = regs[0];
|
||||
prog->run_count++;
|
||||
prog->total_runtime_ns += 50;
|
||||
return 0;
|
||||
} else if (op == BPF_JMP_JA) {
|
||||
pc += insn.offset;
|
||||
} else if (op == BPF_JMP_JEQ && regs[dst] == val) {
|
||||
pc += insn.offset;
|
||||
} else if (op == BPF_JMP_JNE && regs[dst] != val) {
|
||||
pc += insn.offset;
|
||||
} else if (op == BPF_JMP_JGT && regs[dst] > val) {
|
||||
pc += insn.offset;
|
||||
} else if (op == BPF_JMP_JGE && regs[dst] >= val) {
|
||||
pc += insn.offset;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
|
||||
if (ret_val) *ret_val = regs[0];
|
||||
prog->run_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bpf_map_create(const char* name, uint32_t key_size, uint32_t value_size, uint32_t max_entries) {
|
||||
if (!name || key_size == 0 || value_size == 0 || max_entries == 0) return -1;
|
||||
|
||||
for (size_t i = 0; i < BPF_MAX_MAPS; i++) {
|
||||
if (!bpf_maps[i].in_use) {
|
||||
bpf_maps[i].id = next_bpf_id++;
|
||||
strncpy(bpf_maps[i].name, name, sizeof(bpf_maps[i].name) - 1);
|
||||
bpf_maps[i].key_size = key_size;
|
||||
bpf_maps[i].value_size = value_size;
|
||||
bpf_maps[i].max_entries = max_entries;
|
||||
bpf_maps[i].data = (uint8_t*)kzalloc(max_entries * (key_size + value_size));
|
||||
bpf_maps[i].in_use = true;
|
||||
return (int)bpf_maps[i].id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t bpf_get_prog_count(void) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < BPF_MAX_PROGS; i++) {
|
||||
if (bpf_programs[i].in_use) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const bpf_prog_t* bpf_get_prog(size_t index) {
|
||||
if (index >= BPF_MAX_PROGS || !bpf_programs[index].in_use) return NULL;
|
||||
return &bpf_programs[index];
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
#include <kernel/kobject.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
static kobject_t kobject_pool[MAX_KOBJECTS];
|
||||
static kobject_t* sys_root = NULL;
|
||||
static kobject_t* sys_devices = NULL;
|
||||
static kobject_t* sys_bus = NULL;
|
||||
static kobject_t* sys_class = NULL;
|
||||
static kobject_t* sys_kernel = NULL;
|
||||
|
||||
void kobject_subsystem_init(void) {
|
||||
memset(kobject_pool, 0, sizeof(kobject_pool));
|
||||
|
||||
sys_root = kobject_create_and_add("sys", KOBJ_TYPE_SUBSYS, NULL);
|
||||
sys_devices = kobject_create_and_add("devices", KOBJ_TYPE_SUBSYS, sys_root);
|
||||
sys_bus = kobject_create_and_add("bus", KOBJ_TYPE_SUBSYS, sys_root);
|
||||
sys_class = kobject_create_and_add("class", KOBJ_TYPE_SUBSYS, sys_root);
|
||||
sys_kernel = kobject_create_and_add("kernel", KOBJ_TYPE_SUBSYS, sys_root);
|
||||
|
||||
// Populate standard buses
|
||||
kobject_t* pci_bus = kobject_create_and_add("pci", KOBJ_TYPE_BUS, sys_bus);
|
||||
kobject_t* usb_bus = kobject_create_and_add("usb", KOBJ_TYPE_BUS, sys_bus);
|
||||
(void)pci_bus; (void)usb_bus;
|
||||
|
||||
// Populate standard classes
|
||||
kobject_create_and_add("net", KOBJ_TYPE_CLASS, sys_class);
|
||||
kobject_create_and_add("block", KOBJ_TYPE_CLASS, sys_class);
|
||||
kobject_create_and_add("sound", KOBJ_TYPE_CLASS, sys_class);
|
||||
kobject_create_and_add("tty", KOBJ_TYPE_CLASS, sys_class);
|
||||
|
||||
// Populate standard devices
|
||||
kobject_create_and_add("pci0000:00:03.0_e1000", KOBJ_TYPE_DEVICE, sys_devices);
|
||||
kobject_create_and_add("pci0000:00:01.1_ata", KOBJ_TYPE_DEVICE, sys_devices);
|
||||
kobject_create_and_add("pci0000:00:02.0_vga", KOBJ_TYPE_DEVICE, sys_devices);
|
||||
|
||||
printk(KERN_INFO "KOBJECT: Unified Device Model & Sysfs Object Tree online (/sys/)\n");
|
||||
}
|
||||
|
||||
kobject_t* kobject_create_and_add(const char* name, kobj_type_t type, kobject_t* parent) {
|
||||
if (!name) return NULL;
|
||||
|
||||
for (size_t i = 0; i < MAX_KOBJECTS; i++) {
|
||||
if (!kobject_pool[i].in_use) {
|
||||
kobject_pool[i].in_use = true;
|
||||
strncpy(kobject_pool[i].name, name, KOBJ_NAME_LEN - 1);
|
||||
kobject_pool[i].type = type;
|
||||
kobject_pool[i].parent = parent;
|
||||
kobject_pool[i].ref_count = 1;
|
||||
|
||||
if (parent) {
|
||||
snprintf(kobject_pool[i].path, sizeof(kobject_pool[i].path), "%s/%s", parent->path, name);
|
||||
} else {
|
||||
snprintf(kobject_pool[i].path, sizeof(kobject_pool[i].path), "/%s", name);
|
||||
}
|
||||
|
||||
return &kobject_pool[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void kobject_get(kobject_t* kobj) {
|
||||
if (kobj && kobj->in_use) kobj->ref_count++;
|
||||
}
|
||||
|
||||
void kobject_put(kobject_t* kobj) {
|
||||
if (kobj && kobj->in_use) {
|
||||
if (kobj->ref_count > 0) kobj->ref_count--;
|
||||
if (kobj->ref_count == 0) kobj->in_use = false;
|
||||
}
|
||||
}
|
||||
|
||||
size_t kobject_get_total_count(void) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < MAX_KOBJECTS; i++) {
|
||||
if (kobject_pool[i].in_use) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const kobject_t* kobject_get_at(size_t index) {
|
||||
if (index >= MAX_KOBJECTS || !kobject_pool[index].in_use) return NULL;
|
||||
return &kobject_pool[index];
|
||||
}
|
||||
|
||||
void kobject_dump_tree(void) {
|
||||
printk(ANSI_BRIGHT_CYAN "=== SUB-OS Sysfs KObject Hierarchy Tree (/sys/) ===\n" ANSI_RESET);
|
||||
printk(ANSI_YELLOW "REF TYPE SYSFS PATH\n" ANSI_RESET);
|
||||
|
||||
for (size_t i = 0; i < MAX_KOBJECTS; i++) {
|
||||
if (kobject_pool[i].in_use) {
|
||||
const char* type_str = "GENERIC";
|
||||
switch (kobject_pool[i].type) {
|
||||
case KOBJ_TYPE_BUS: type_str = "BUS "; break;
|
||||
case KOBJ_TYPE_DEVICE: type_str = "DEVICE "; break;
|
||||
case KOBJ_TYPE_CLASS: type_str = "CLASS "; break;
|
||||
case KOBJ_TYPE_SUBSYS: type_str = "SUBSYS "; break;
|
||||
default: break;
|
||||
}
|
||||
printk("[%2u] %s %s\n",
|
||||
kobject_pool[i].ref_count, type_str, kobject_pool[i].path);
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-4
@@ -12,6 +12,11 @@
|
||||
#include <kernel/syslog.h>
|
||||
#include <kernel/cron.h>
|
||||
#include <kernel/metrics.h>
|
||||
#include <kernel/bpf.h>
|
||||
#include <kernel/kobject.h>
|
||||
#include <mm/vma.h>
|
||||
#include <drivers/canvas.h>
|
||||
#include <drivers/pty.h>
|
||||
#include <arch/x86_64/gdt.h>
|
||||
#include <arch/x86_64/idt.h>
|
||||
#include <arch/x86_64/isr.h>
|
||||
@@ -51,6 +56,7 @@
|
||||
#include <net/dns.h>
|
||||
#include <net/filter.h>
|
||||
#include <net/http.h>
|
||||
#include <net/ssh.h>
|
||||
#include <crypto/crypto.h>
|
||||
#include <certs/certs.h>
|
||||
#include <security/security.h>
|
||||
@@ -110,10 +116,10 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
pmm_init(memory_map, memory_map_count);
|
||||
heap_init();
|
||||
slab_init();
|
||||
paging_init();
|
||||
vma_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 6. Block Storage, Ramdisk & Hardware Busses
|
||||
// 6. Storage & Block Layer
|
||||
printk(KERN_INFO "[7/18] Initializing Block Layer, Ramdisk & Storage Controllers... ");
|
||||
block_init();
|
||||
ramdisk_init();
|
||||
@@ -123,10 +129,13 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
printk(ANSI_YELLOW "No ATA Drive\n" ANSI_RESET);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "[8/18] Enumerating PCI Bus, VirtIO, Framebuffer & USB... ");
|
||||
// 7. Bus & Devices
|
||||
printk(KERN_INFO "[8/18] Enumerating PCI Bus, VirtIO, Canvas & PTY... ");
|
||||
pci_init();
|
||||
virt_init();
|
||||
fb_init();
|
||||
canvas_init();
|
||||
pty_init();
|
||||
usb_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
@@ -176,18 +185,20 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
printk(KERN_INFO "[14/18] Mounting Virtual File System (VFS, devfs, procfs, sysfs)... ");
|
||||
vfs_init();
|
||||
sysfs_init();
|
||||
kobject_subsystem_init();
|
||||
fat32_init();
|
||||
ext2_init();
|
||||
initramfs_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 13. Kernel Core: Signals, Modules, Syscalls, Tracing, Syslog, Metrics, Crond & Systemd
|
||||
printk(KERN_INFO "[15/18] Initializing Syslog, Metrics, Cron, Tracing & Services... ");
|
||||
printk(KERN_INFO "[15/18] Initializing Syslog, Metrics, Cron, Tracing, BPF & Services... ");
|
||||
signal_init();
|
||||
workqueue_init();
|
||||
syscall_init();
|
||||
module_init_subsystem();
|
||||
trace_init();
|
||||
bpf_init();
|
||||
syslog_init();
|
||||
metrics_init();
|
||||
cron_init();
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
#include <mm/vma.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
#define MAX_TRACKED_TASKS 16
|
||||
|
||||
static mm_struct_t task_mm_table[MAX_TRACKED_TASKS];
|
||||
|
||||
void vma_init(void) {
|
||||
memset(task_mm_table, 0, sizeof(task_mm_table));
|
||||
|
||||
// Initialize kernel/init memory areas
|
||||
vma_create_mm(1, &task_mm_table[0]);
|
||||
vma_mmap(1, 0x00400000, 0x20000, PROT_READ | PROT_EXEC, MAP_PRIVATE, "/bin/lazybox");
|
||||
vma_mmap(1, 0x00600000, 0x10000, PROT_READ | PROT_WRITE, MAP_PRIVATE, "[heap]");
|
||||
vma_mmap(1, 0x7FFF0000, 0x08000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, "[stack]");
|
||||
|
||||
printk(KERN_INFO "MM: Virtual Memory Area (VMA) & mmap subsystem initialized\n");
|
||||
}
|
||||
|
||||
int vma_create_mm(uint32_t pid, mm_struct_t* mm) {
|
||||
if (!mm) return -1;
|
||||
for (size_t i = 0; i < MAX_TRACKED_TASKS; i++) {
|
||||
if (task_mm_table[i].pid == 0 || task_mm_table[i].pid == pid) {
|
||||
task_mm_table[i].pid = pid;
|
||||
task_mm_table[i].start_code = 0x00400000;
|
||||
task_mm_table[i].end_code = 0x00420000;
|
||||
task_mm_table[i].start_brk = 0x00600000;
|
||||
task_mm_table[i].brk = 0x00610000;
|
||||
task_mm_table[i].start_stack = 0x7FFF8000;
|
||||
task_mm_table[i].vma_count = 0;
|
||||
*mm = task_mm_table[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t vma_mmap(uint32_t pid, uint64_t addr, size_t len, int prot, int flags, const char* name) {
|
||||
if (len == 0) return 0;
|
||||
|
||||
mm_struct_t* mm = NULL;
|
||||
for (size_t i = 0; i < MAX_TRACKED_TASKS; i++) {
|
||||
if (task_mm_table[i].pid == pid) {
|
||||
mm = &task_mm_table[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mm) {
|
||||
vma_create_mm(pid, &task_mm_table[0]);
|
||||
mm = &task_mm_table[0];
|
||||
}
|
||||
|
||||
uint64_t target_addr = addr;
|
||||
if (target_addr == 0) {
|
||||
target_addr = 0x70000000 + (mm->vma_count * 0x10000);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_VMAS_PER_TASK; i++) {
|
||||
if (!mm->vmas[i].in_use) {
|
||||
mm->vmas[i].vm_start = target_addr;
|
||||
mm->vmas[i].vm_end = target_addr + len;
|
||||
mm->vmas[i].vm_prot = prot;
|
||||
mm->vmas[i].vm_flags = flags;
|
||||
mm->vmas[i].vm_pgoff = 0;
|
||||
strncpy(mm->vmas[i].vm_name, name ? name : "[anon]", sizeof(mm->vmas[i].vm_name) - 1);
|
||||
mm->vmas[i].in_use = true;
|
||||
mm->vma_count++;
|
||||
return target_addr;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vma_munmap(uint32_t pid, uint64_t addr, size_t len) {
|
||||
for (size_t i = 0; i < MAX_TRACKED_TASKS; i++) {
|
||||
if (task_mm_table[i].pid == pid) {
|
||||
for (size_t j = 0; j < MAX_VMAS_PER_TASK; j++) {
|
||||
if (task_mm_table[i].vmas[j].in_use &&
|
||||
task_mm_table[i].vmas[j].vm_start == addr) {
|
||||
task_mm_table[i].vmas[j].in_use = false;
|
||||
task_mm_table[i].vma_count--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const vm_area_t* vma_find(uint32_t pid, uint64_t addr) {
|
||||
for (size_t i = 0; i < MAX_TRACKED_TASKS; i++) {
|
||||
if (task_mm_table[i].pid == pid) {
|
||||
for (size_t j = 0; j < MAX_VMAS_PER_TASK; j++) {
|
||||
if (task_mm_table[i].vmas[j].in_use &&
|
||||
addr >= task_mm_table[i].vmas[j].vm_start &&
|
||||
addr < task_mm_table[i].vmas[j].vm_end) {
|
||||
return &task_mm_table[i].vmas[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vma_dump_maps(uint32_t pid) {
|
||||
mm_struct_t* mm = NULL;
|
||||
for (size_t i = 0; i < MAX_TRACKED_TASKS; i++) {
|
||||
if (task_mm_table[i].pid == pid) {
|
||||
mm = &task_mm_table[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mm) {
|
||||
printk(KERN_ERR "pmap: process %u not found\n", pid);
|
||||
return;
|
||||
}
|
||||
|
||||
printk(ANSI_BRIGHT_CYAN "%u: /bin/lazybox (Process Virtual Memory Maps)\n" ANSI_RESET, pid);
|
||||
printk(ANSI_YELLOW "Address Kbytes RSS Mode Mapping\n" ANSI_RESET);
|
||||
|
||||
uint64_t total_kb = 0;
|
||||
for (size_t i = 0; i < MAX_VMAS_PER_TASK; i++) {
|
||||
if (mm->vmas[i].in_use) {
|
||||
uint64_t size_kb = (mm->vmas[i].vm_end - mm->vmas[i].vm_start) / 1024;
|
||||
total_kb += size_kb;
|
||||
|
||||
char perm[5] = "---p";
|
||||
if (mm->vmas[i].vm_prot & PROT_READ) perm[0] = 'r';
|
||||
if (mm->vmas[i].vm_prot & PROT_WRITE) perm[1] = 'w';
|
||||
if (mm->vmas[i].vm_prot & PROT_EXEC) perm[2] = 'x';
|
||||
if (mm->vmas[i].vm_flags & MAP_SHARED)perm[3] = 's';
|
||||
|
||||
printk("%016llx %6lluKB %5llu %s %s\n",
|
||||
mm->vmas[i].vm_start, size_kb, size_kb, perm, mm->vmas[i].vm_name);
|
||||
}
|
||||
}
|
||||
printk(ANSI_BRIGHT_CYAN "total %llu KB\n" ANSI_RESET, total_kb);
|
||||
}
|
||||
@@ -42,7 +42,11 @@
|
||||
#include <kernel/metrics.h>
|
||||
#include <kernel/trace.h>
|
||||
#include <kernel/namespace.h>
|
||||
#include <mm/slab.h>
|
||||
#include <kernel/bpf.h>
|
||||
#include <kernel/kobject.h>
|
||||
#include <mm/vma.h>
|
||||
#include <drivers/canvas.h>
|
||||
#include <drivers/pty.h>
|
||||
#include <sound/melody.h>
|
||||
#include <userland/sh.h>
|
||||
|
||||
@@ -1301,8 +1305,62 @@ static int applet_htop(int argc, char** argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int applet_bpftool(int argc, char** argv) {
|
||||
(void)argc; (void)argv;
|
||||
size_t count = bpf_get_prog_count();
|
||||
printk(ANSI_BRIGHT_CYAN "=== SUB-OS In-Kernel eBPF Programs (%llu loaded) ===\n" ANSI_RESET, (uint64_t)count);
|
||||
printk(ANSI_YELLOW "ID TYPE INSNS RUNS TIME_NS NAME\n" ANSI_RESET);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const bpf_prog_t* p = bpf_get_prog(i);
|
||||
if (p && p->in_use) {
|
||||
const char* tstr = "SOCKET_FILTER";
|
||||
if (p->type == BPF_PROG_TYPE_KPROBE) tstr = "KPROBE ";
|
||||
else if (p->type == BPF_PROG_TYPE_XDP) tstr = "XDP ";
|
||||
printk("%-4u %s %-6u %-6llu %-8llu %s\n",
|
||||
p->id, tstr, p->insn_count, p->run_count, p->total_runtime_ns, p->name);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int applet_pmap(int argc, char** argv) {
|
||||
uint32_t pid = (argc >= 2) ? (uint32_t)atoi(argv[1]) : 1;
|
||||
vma_dump_maps(pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int applet_lssys(int argc, char** argv) {
|
||||
(void)argc; (void)argv;
|
||||
kobject_dump_tree();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int applet_ptyinfo(int argc, char** argv) {
|
||||
(void)argc; (void)argv;
|
||||
size_t active = pty_get_active_count();
|
||||
printk(ANSI_BRIGHT_CYAN "=== SUB-OS Unix98 Pseudo-Terminal Subsystem (PTY) ===\n" ANSI_RESET);
|
||||
printk("Active Pairs: %llu / %u\n", (uint64_t)active, PTY_MAX_PAIRS);
|
||||
for (size_t i = 0; i < PTY_MAX_PAIRS; i++) {
|
||||
const pty_pair_t* p = pty_get_pair(i);
|
||||
if (p) {
|
||||
printk(" [%u] Master: %-12s Slave: %-12s Status: %s\n",
|
||||
p->pty_num, p->master_name, p->slave_name,
|
||||
p->in_use ? ANSI_BRIGHT_GREEN "ACTIVE" ANSI_RESET : ANSI_YELLOW "IDLE" ANSI_RESET);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int applet_desktop(int argc, char** argv) {
|
||||
(void)argc; (void)argv;
|
||||
printk(KERN_INFO "Rendering 2D Graphical Desktop Canvas on Linear Framebuffer...\n");
|
||||
canvas_render_desktop_mockup();
|
||||
printk(ANSI_BRIGHT_GREEN "Desktop UI Frame Rendered (320x200 32bpp TrueColor)\n" ANSI_RESET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// Applet Dispatch Table (Over 65 Linux Tools)
|
||||
// Applet Dispatch Table (Over 70 Linux Tools)
|
||||
// -------------------------------------------------------------
|
||||
static const lazybox_applet_t applets[] = {
|
||||
// Core & Scripting
|
||||
@@ -1363,6 +1421,13 @@ static const lazybox_applet_t applets[] = {
|
||||
{"slabinfo", applet_slabinfo, "slabinfo", "Kernel SLAB cache statistics","Kernel"},
|
||||
{"trace", applet_trace, "trace [on|off|dump|clear]", "Kernel execution event tracer","Kernel"},
|
||||
{"unshare", applet_unshare, "unshare [name]", "Create isolated namespace", "Kernel"},
|
||||
{"bpftool", applet_bpftool, "bpftool", "Inspect in-kernel BPF bytecode","Kernel"},
|
||||
{"bpf", applet_bpftool, "bpf", "eBPF utility alias", "Kernel"},
|
||||
{"pmap", applet_pmap, "pmap [pid]", "Process memory map viewer", "Kernel"},
|
||||
{"lssys", applet_lssys, "lssys", "Sysfs kobject hierarchy tree","Kernel"},
|
||||
{"ptyinfo", applet_ptyinfo, "ptyinfo", "Pseudo-terminal subsystem info","Kernel"},
|
||||
{"desktop", applet_desktop, "desktop", "Render 2D GUI Canvas desktop","Kernel"},
|
||||
{"draw", applet_desktop, "draw", "Canvas graphics demo", "Kernel"},
|
||||
|
||||
// Cryptography & Security
|
||||
{"md5sum", applet_md5sum, "md5sum <file|text>", "Compute MD5 hash", "Crypto"},
|
||||
|
||||
Reference in new issue
Block a user