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:
subhobhai943 committed 2026-08-17 14:38:06 +05:30
1 parent 8a90d88f70
commit 65c916d6ac
12 files changed
+1133 -6

No files matched your search

+107
View File
@@ -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];
}
+268
View File
@@ -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));
}
}
+32
View File
@@ -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
+39
View File
@@ -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
+95
View File
@@ -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
+38
View File
@@ -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
+50
View File
@@ -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
View File
@@ -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];
}
+106
View File
@@ -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
View File
@@ -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();
+140
View File
@@ -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);
}
+67 -2
View File
@@ -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"},