feat: Add SLAB allocator, Ramdisk, Kernel Namespaces, Event Tracing, NetFilter Firewall, 8-Bit Melodies, and Shell Scripting (sh)

This commit is contained in:
subhobhai943 committed 2026-08-17 12:40:59 +05:30
1 parent 9f9a19bab0
commit 2f1f785cee
17 files changed
+1021 -115

No files matched your search

+177 -4
View File
@@ -822,12 +822,178 @@ static int applet_poweroff(int argc, char** argv) {
static int applet_lazybox(int argc, char** argv);
// -------------------------------------------------------------
// Applet Dispatch Table (Over 50 Linux Tools)
// Advanced Linux Subsystem Applets
// -------------------------------------------------------------
#include <mm/slab.h>
#include <kernel/trace.h>
#include <kernel/namespace.h>
#include <net/filter.h>
#include <sound/melody.h>
#include <userland/sh.h>
static int applet_sh(int argc, char** argv) {
return sh_main(argc, argv);
}
static int applet_slabinfo(int argc, char** argv) {
(void)argc; (void)argv;
printk(ANSI_BRIGHT_CYAN "slabinfo - version: 2.1\n" ANSI_RESET);
printk(ANSI_YELLOW "# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>\n" ANSI_RESET);
size_t count = slab_get_cache_count();
for (size_t i = 0; i < count; i++) {
const kmem_cache_t* c = slab_get_cache(i);
if (c && c->in_use) {
printk("%-18s %11u %10u %9llu %12llu %14d\n",
c->name, c->active_objects, c->active_objects + 16,
(uint64_t)c->object_size, (uint64_t)c->objects_per_slab, 1);
}
}
return 0;
}
static int applet_trace(int argc, char** argv) {
if (argc >= 2) {
if (strcmp(argv[1], "on") == 0) {
trace_enable(true);
printk(KERN_INFO "Tracing enabled\n");
return 0;
} else if (strcmp(argv[1], "off") == 0) {
trace_enable(false);
printk(KERN_INFO "Tracing disabled\n");
return 0;
} else if (strcmp(argv[1], "clear") == 0) {
trace_clear();
printk(KERN_INFO "Trace buffer cleared\n");
return 0;
}
}
size_t total = trace_get_count();
printk(ANSI_BRIGHT_CYAN "=== SUB-OS Kernel Event Trace Ringbuffer (%llu events) ===\n" ANSI_RESET, (uint64_t)total);
printk(ANSI_YELLOW "# CPU PID TIMESTAMP CATEGORY EVENT\n" ANSI_RESET);
const char* cat_names[] = {"SYS ", "IRQ ", "SCHED", "MM ", "NET ", "FS "};
for (size_t i = 0; i < total; i++) {
const trace_entry_t* e = trace_get_entry(i);
if (e) {
const char* cat_str = (e->category < TRACE_CAT_MAX) ? cat_names[e->category] : "MISC ";
printk("[%3u] %4u %10llu ms [%s] %s\n",
e->cpu_id, e->pid, e->timestamp * 10, cat_str, e->message);
}
}
return 0;
}
static int applet_unshare(int argc, char** argv) {
const char* name = (argc >= 2) ? argv[1] : "isolated_container";
nsproxy_t* ns = namespace_create(name, CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNS);
if (ns) {
printk(KERN_INFO "Created and entered isolated namespace ID %u ('%s')\n", ns->id, ns->name);
printk(" Hostname: %s\n", ns->uts.hostname);
printk(" PID Offset: %u\n", ns->pid_offset);
namespace_switch(ns->id);
} else {
printk(KERN_ERR "unshare: failed to create namespace\n");
}
return 0;
}
static int applet_iptables(int argc, char** argv) {
(void)argc; (void)argv;
printk(ANSI_BRIGHT_CYAN "Chain INPUT (policy ACCEPT)\n" ANSI_RESET);
printk(ANSI_YELLOW "target prot opt source destination\n" ANSI_RESET);
size_t count = filter_get_rule_count();
for (size_t i = 0; i < count; i++) {
const filter_rule_t* r = filter_get_rule(i);
if (r && r->in_use) {
const char* act = (r->action == FILTER_ACTION_ACCEPT) ? "ACCEPT " : "DROP ";
const char* proto = (r->protocol == 1) ? "icmp" : (r->protocol == 6) ? "tcp " : (r->protocol == 17) ? "udp " : "all ";
printk("%s %-4s -- 0.0.0.0/0 0.0.0.0/0 dport:%-5u /* %s */ (pkts: %llu, bytes: %llu)\n",
act, proto, r->dst_port, r->comment, r->packet_count, r->byte_count);
}
}
return 0;
}
static int applet_tune(int argc, char** argv) {
const char* which = (argc >= 2) ? argv[1] : "startup";
if (strcmp(which, "tetris") == 0) {
melody_play_tetris();
} else if (strcmp(which, "mario") == 0) {
melody_play_mario();
} else {
melody_play_startup();
}
return 0;
}
static int applet_env(int argc, char** argv) {
(void)argc; (void)argv;
const char* keys[] = {"PATH", "USER", "HOME", "SHELL", "TERM", "OS", NULL};
for (int i = 0; keys[i] != NULL; i++) {
const char* val = sh_get_env(keys[i]);
if (val) {
printk("%s=%s\n", keys[i], val);
}
}
return 0;
}
static int applet_export(int argc, char** argv) {
if (argc < 2) {
return applet_env(argc, argv);
}
for (int i = 1; i < argc; i++) {
char* eq = strchr(argv[i], '=');
if (eq) {
*eq = '\0';
sh_set_env(argv[i], eq + 1);
}
}
return 0;
}
static int applet_basename(int argc, char** argv) {
if (argc < 2) {
printk("\n");
return 0;
}
const char* p = argv[1];
const char* last = strrchr(p, '/');
printk("%s\n", last ? last + 1 : p);
return 0;
}
static int applet_dirname(int argc, char** argv) {
if (argc < 2) {
printk(".\n");
return 0;
}
char buf[256];
strncpy(buf, argv[1], sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
char* last = strrchr(buf, '/');
if (!last) {
printk(".\n");
} else if (last == buf) {
printk("/\n");
} else {
*last = '\0';
printk("%s\n", buf);
}
return 0;
}
// -------------------------------------------------------------
// Applet Dispatch Table (Over 55 Linux Tools)
// -------------------------------------------------------------
static const lazybox_applet_t applets[] = {
// Core
// Core & Scripting
{"lazybox", applet_lazybox, "lazybox [applet]", "Multi-call utility manager", "Core"},
{"sh", applet_sh, "sh <script> | -c <cmd>", "Shell script interpreter", "Core"},
{"echo", applet_echo, "echo [text...]", "Display text to stdout", "Core"},
{"env", applet_env, "env", "Print environment variables","Core"},
{"export", applet_export, "export VAR=VAL", "Set environment variable", "Core"},
{"whoami", applet_whoami, "whoami", "Print current user", "Core"},
{"id", applet_id, "id", "Print user and group IDs", "Core"},
{"date", applet_date, "date", "Display CMOS RTC date", "Core"},
@@ -847,16 +1013,22 @@ static const lazybox_applet_t applets[] = {
{"cp", applet_cp, "cp <src> <dst>", "Copy files", "Filesystem"},
{"grep", applet_grep, "grep <pattern> <file>", "Search pattern in file", "Filesystem"},
{"hexdump", applet_hexdump, "hexdump <file>", "Display hex dump of file", "Filesystem"},
{"basename", applet_basename, "basename <path>", "Strip directory path", "Filesystem"},
{"dirname", applet_dirname, "dirname <path>", "Strip non-directory suffix", "Filesystem"},
{"nano", applet_nano_wrapper, "nano [file]", "Visual full-screen editor", "Filesystem"},
// Sound & Voice Synthesis
{"tts", applet_tts, "tts <text>", "Phonetic formant voice synth","Sound"},
{"tune", applet_tune, "tune [tetris|mario|startup]","8-bit retro chip melody player","Sound"},
{"alsamixer", applet_alsamixer, "alsamixer", "Audio control & mixer", "Sound"},
// Kernel Modules & Dynamic Loading
// Kernel, Diagnostics & Namespaces
{"lsmod", applet_lsmod, "lsmod", "Show kernel module status", "Kernel"},
{"insmod", applet_insmod, "insmod <mod>", "Insert kernel module", "Kernel"},
{"rmmod", applet_rmmod, "rmmod <mod>", "Remove kernel module", "Kernel"},
{"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"},
// Cryptography & Security
{"md5sum", applet_md5sum, "md5sum <file|text>", "Compute MD5 hash", "Crypto"},
@@ -867,12 +1039,13 @@ static const lazybox_applet_t applets[] = {
{"capsh", applet_capsh, "capsh", "View process capabilities", "Security"},
{"ipcs", applet_ipcs, "ipcs", "Show IPC facilities status", "Security"},
// Network
// Network & Firewall
{"ifconfig", applet_ifconfig, "ifconfig", "Display network interface", "Network"},
{"ping", applet_ping, "ping <ip> [count]", "ICMP Echo ping utility", "Network"},
{"arp", applet_arp, "arp", "View ARP cache table", "Network"},
{"dhclient", applet_dhclient, "dhclient", "Request DHCP lease", "Network"},
{"nslookup", applet_nslookup, "nslookup <host>", "Query DNS name servers", "Network"},
{"iptables", applet_iptables, "iptables", "Firewall packet filter rules","Network"},
// Storage & Devices
{"hdparm", applet_hdparm, "hdparm", "Inspect ATA hard disk", "Storage"},
+169
View File
@@ -0,0 +1,169 @@
#include <userland/sh.h>
#include <userland/lazybox.h>
#include <fs/vfs.h>
#include <lib/string.h>
#include <kernel/printk.h>
#define MAX_ENV_VARS 32
#define MAX_LINE_LEN 256
typedef struct {
char key[32];
char value[128];
bool in_use;
} env_var_t;
static env_var_t env_table[MAX_ENV_VARS];
static void init_default_env(void) {
static bool env_inited = false;
if (env_inited) return;
memset(env_table, 0, sizeof(env_table));
sh_set_env("PATH", "/bin:/usr/bin");
sh_set_env("USER", "root");
sh_set_env("HOME", "/root");
sh_set_env("SHELL", "/bin/sh");
sh_set_env("TERM", "xterm-256color");
sh_set_env("OS", "SUB-OS");
env_inited = true;
}
const char* sh_get_env(const char* key) {
init_default_env();
if (!key) return NULL;
for (size_t i = 0; i < MAX_ENV_VARS; i++) {
if (env_table[i].in_use && strcmp(env_table[i].key, key) == 0) {
return env_table[i].value;
}
}
return NULL;
}
int sh_set_env(const char* key, const char* value) {
if (!key || !value) return -1;
for (size_t i = 0; i < MAX_ENV_VARS; i++) {
if (env_table[i].in_use && strcmp(env_table[i].key, key) == 0) {
strncpy(env_table[i].value, value, sizeof(env_table[i].value) - 1);
return 0;
}
}
for (size_t i = 0; i < MAX_ENV_VARS; i++) {
if (!env_table[i].in_use) {
env_table[i].in_use = true;
strncpy(env_table[i].key, key, sizeof(env_table[i].key) - 1);
strncpy(env_table[i].value, value, sizeof(env_table[i].value) - 1);
return 0;
}
}
return -1;
}
static void expand_variables(const char* in, char* out, size_t max_len) {
size_t out_idx = 0;
while (*in && out_idx < max_len - 1) {
if (*in == '$') {
in++;
char var_name[32];
size_t vi = 0;
while ((*in >= 'A' && *in <= 'Z') || (*in >= 'a' && *in <= 'z') || (*in >= '0' && *in <= '9') || *in == '_') {
if (vi < sizeof(var_name) - 1) var_name[vi++] = *in;
in++;
}
var_name[vi] = '\0';
const char* val = sh_get_env(var_name);
if (val) {
while (*val && out_idx < max_len - 1) {
out[out_idx++] = *val++;
}
}
} else {
out[out_idx++] = *in++;
}
}
out[out_idx] = '\0';
}
static int execute_single_line(char* line) {
while (*line == ' ' || *line == '\t') line++;
if (*line == '\0' || *line == '#') return 0; // Skip empty or comment lines
char expanded[MAX_LINE_LEN];
expand_variables(line, expanded, sizeof(expanded));
char* argv[16];
int argc = 0;
char* token = expanded;
while (*token) {
while (*token == ' ' || *token == '\t') *token++ = '\0';
if (*token == '\0') break;
if (argc < 16) argv[argc++] = token;
while (*token && *token != ' ' && *token != '\t') token++;
}
if (argc == 0) return 0;
// Check variable assignment: VAR=VALUE
char* eq = strchr(argv[0], '=');
if (eq && argc == 1) {
*eq = '\0';
return sh_set_env(argv[0], eq + 1);
}
if (lazybox_has_applet(argv[0])) {
return lazybox_run_applet(argv[0], argc, argv);
}
printk(KERN_ERR "sh: %s: command not found\n", argv[0]);
return 127;
}
int sh_execute_script(const char* filepath) {
init_default_env();
int fd = vfs_open(filepath, O_RDONLY);
if (fd < 0) {
printk(KERN_ERR "sh: %s: No such file or directory\n", filepath);
return 1;
}
char line[MAX_LINE_LEN];
size_t line_pos = 0;
char c;
while (vfs_read(fd, &c, 1) == 1) {
if (c == '\r') continue;
if (c == '\n') {
line[line_pos] = '\0';
execute_single_line(line);
line_pos = 0;
} else {
if (line_pos < sizeof(line) - 1) {
line[line_pos++] = c;
}
}
}
if (line_pos > 0) {
line[line_pos] = '\0';
execute_single_line(line);
}
vfs_close(fd);
return 0;
}
int sh_main(int argc, char** argv) {
init_default_env();
if (argc < 2) {
printk(KERN_INFO "Usage: sh <script_file.sub> | sh -c \"<command>\"\n");
return 1;
}
if (strcmp(argv[1], "-c") == 0 && argc >= 3) {
char cmd_buf[MAX_LINE_LEN];
strncpy(cmd_buf, argv[2], sizeof(cmd_buf) - 1);
cmd_buf[sizeof(cmd_buf) - 1] = '\0';
return execute_single_line(cmd_buf);
}
return sh_execute_script(argv[1]);
}