mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
feat: Add SLAB allocator, Ramdisk, Kernel Namespaces, Event Tracing, NetFilter Firewall, 8-Bit Melodies, and Shell Scripting (sh)
This commit is contained in:
1 parent
9f9a19bab0
commit
2f1f785cee
17 files changed
+1021
-115
No files matched your search
@@ -12,11 +12,11 @@
|
||||
[]()
|
||||
[]()
|
||||
[-purple.svg?style=flat-square)]()
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
[](LICENSE)
|
||||
|
||||
**SUB-OS** is an open-source, production-grade 64-bit modular monolithic operating system engineered from the ground up for the `x86_64` architecture. Built adhering to the internal design principles of modern UNIX/Linux kernels, SUB-OS features a full bare-metal hardware driver tree, physical and dynamic memory management, a virtual file system (VFS) with FAT32, ext2, sysfs, and devfs, full L2-L4 networking protocol stack with BSD Sockets, cryptographic engine, Linux Security Modules (LSM), asynchronous `io_uring` ringbuffers, Inter-Process Communication (IPC) engine, Text-to-Speech (TTS) voice synthesizer, AC'97 sound architecture, full-screen visual `nano` editor, and the **LazyBox** multi-call userland environment with 50+ Linux utilities.
|
||||
**SUB-OS** is an open-source, production-grade 64-bit modular monolithic operating system engineered from the ground up for the `x86_64` architecture. Built adhering to the internal design principles of modern UNIX/Linux kernels while maintaining an elegant, easy-to-understand codebase, SUB-OS features a bare-metal driver tree, physical and dynamic memory management with a **SLAB Object Allocator**, an advanced virtual file system (VFS) with FAT32, ext2, sysfs, and devfs, **Lightweight Process & Container Namespaces**, **Kernel Event Tracing (FTrace-like ringbuffers)**, **Stateful Packet Inspection (NetFilter Firewall)**, **Ramdisk (`/dev/ram0`)**, a full L2-L4 networking protocol stack with BSD Sockets, **8-Bit Retro Melody Synth & Formant Text-to-Speech (TTS)** voice synthesizer, AC'97 sound architecture, full-screen visual `nano` editor, and the **LazyBox** multi-call userland environment with **55+ Linux-compatible utilities** and shell scripting (`sh`).
|
||||
|
||||
---
|
||||
|
||||
@@ -25,28 +25,28 @@
|
||||
```text
|
||||
+------------------------------------------------------------------------------------+
|
||||
| USERLAND & SYSTEM SUITE |
|
||||
| Interactive Shell | GNU Nano 2.0.0 | LazyBox Multi-Call Suite (50+ Coreutils) |
|
||||
| Interactive Shell | GNU Nano 2.0.0 | Script Runner (sh) | LazyBox (55+ Tools) |
|
||||
+------------------------------------------------------------------------------------+
|
||||
| VIRTUAL FILE SYSTEM LAYER (VFS) |
|
||||
| vfs_namei | RAMFS (/) | /dev (devfs) | /proc (procfs) | /sys (sysfs) | FAT32 | ext2|
|
||||
+------------------------------------------------------------------------------------+
|
||||
| INTER-PROCESS COMMUNICATION & ASYNC I/O ENGINE |
|
||||
| Anonymous Pipes | Message Queues | Shared Memory | Semaphores | io_uring Rings |
|
||||
| NAMESPACES, INTER-PROCESS COMMUNICATION & ASYNC I/O ENGINE |
|
||||
| PID & UTS Isolation | Anonymous Pipes | Message Queues | SHM | Semaphores | io_uring|
|
||||
+------------------------------------------------------------------------------------+
|
||||
| CORE KERNEL SERVICES & SECURITY MODULE (LSM) |
|
||||
| CORE KERNEL SERVICES, SECURITY & TRACING |
|
||||
| Preemptive Scheduler | Task Control | POSIX Signals | Fast Syscalls | Workqueues |
|
||||
| High-Res Timer Wheel | Dynamic Module Loader | X.509 Keyring | POSIX Capabilities |
|
||||
| High-Res Timer Wheel | Dynamic Module Loader | Kernel Event Tracer | LSM Security |
|
||||
+------------------------------------------------------------------------------------+
|
||||
| NETWORK PROTOCOL STACK (L2 -> L4) & SOUND |
|
||||
| Ethernet L2 | ARP | IPv4 | ICMP | UDP | TCP | DHCP | DNS | BSD Sockets |
|
||||
| ALSA Sound Architecture | AC'97 Audio | PCM Streams | Formant TTS Synthesizer |
|
||||
| NETWORKING, NETFILTER FIREWALL & SOUND ARCHITECTURE |
|
||||
| Ethernet L2 | ARP | IPv4 | ICMP | UDP | TCP | DHCP | DNS | Sockets | NetFilter FW |
|
||||
| ALSA Sound Core | AC'97 Audio | Formant TTS Synthesizer | 8-Bit Melody Engine |
|
||||
+------------------------------------------------------------------------------------+
|
||||
| MEMORY MANAGEMENT (MM) |
|
||||
| Physical Page Frame Allocator (PMM) | Kernel Dynamic Heap (kmalloc/kfree) |
|
||||
| Physical Page Allocator (PMM) | Dynamic Heap | SLAB / SLUB Object Cache |
|
||||
+------------------------------------------------------------------------------------+
|
||||
| DEVICE DRIVER TREE & VIRT |
|
||||
| VGA / TTY1-4 | 16550 UART Serial | PS/2 Keyboard | PS/2 Mouse | ATA / IDE Disk |
|
||||
| PCI Enumerator | Intel E1000 NIC | VESA FB | CMOS RTC | ACPI Power | USB Core |
|
||||
| VGA / TTY1-4 | 16550 UART Serial | PS/2 Keyboard | PS/2 Mouse | ATA Hard Disk |
|
||||
| PCI Enumerator | Intel E1000 NIC | Ramdisk (/dev/ram0) | VESA FB | CMOS RTC |
|
||||
+------------------------------------------------------------------------------------+
|
||||
| HARDWARE ABSTRACTION LAYER (HAL) |
|
||||
| x86_64 Long Mode | GDT / TSS | IDT / ISRs | Dual 8259A PIC | 8254 PIT Timer |
|
||||
@@ -57,8 +57,6 @@
|
||||
|
||||
## ⚡ 18-Step Master Boot Pipeline
|
||||
|
||||
During boot, the kernel executes a deterministic 18-step master initialization sequence:
|
||||
|
||||
| Step | Subsystem | Description |
|
||||
|:---:|:---|:---|
|
||||
| **[1/18]** | **64-Bit GDT & TSS** | Configures flat kernel/user code & data segments and Task State Segment with dedicated 64KB kernel stack. |
|
||||
@@ -66,103 +64,32 @@ During boot, the kernel executes a deterministic 18-step master initialization s
|
||||
| **[3/18]** | **Dual 8259A PIC** | Remaps master (IRQ 0-7 -> 0x20-0x27) and slave (IRQ 8-15 -> 0x28-0x2F) interrupt controllers. |
|
||||
| **[4/18]** | **PIT & Timer Wheel** | Configures 8254 PIT channel 0 for 100 Hz (10ms resolution) driving quantum preemption & timer wheel. |
|
||||
| **[5/18]** | **Input & ACPI** | PS/2 Keyboard scancode decoder, PS/2 Mouse packet tracker, and ACPI power management subsystem. |
|
||||
| **[6/18]** | **PMM & Dynamic Heap** | 64-bit bitmap frame allocator tracking usable RAM via BIOS E820 map and 4 MB dynamic kernel heap. |
|
||||
| **[7/18]** | **Block Layer & ATA** | Generic Block Layer with request queues, 'noop' elevator scheduler, and 28-bit LBA ATA driver. |
|
||||
| **[6/18]** | **PMM, Heap & SLAB** | 64-bit bitmap frame allocator, 4 MB kernel heap, and high-performance SLAB object cache layer. |
|
||||
| **[7/18]** | **Block Layer, Ramdisk & ATA** | Generic Block Layer with request queues, Ramdisk (`/dev/ram0`), 'noop' elevator, and ATA driver. |
|
||||
| **[8/18]** | **PCI, VirtIO, FB & USB** | PCI bus enumerator, VirtIO core, Linear 32-bit Framebuffer graphics, and USB host controller. |
|
||||
| **[9/18]** | **L2-L4 Network Stack** | Intel E1000 NIC, ARP cache, IPv4 routing, ICMP Ping, UDP, TCP state machine, DHCP & DNS. |
|
||||
| **[10/18]** | **Sound Architecture** | Audio core driver, AC'97 soundcard, PCM stream buffer, and Formant Text-to-Speech synthesizer. |
|
||||
| **[11/18]** | **Keyring & Security** | Loads X.509 trusted certificate authority keyring and enforces POSIX Capabilities Linux Security Module. |
|
||||
| **[9/18]** | **L2-L4 Network & NetFilter** | Intel E1000 NIC, NetFilter stateful firewall, ARP, IPv4 routing, ICMP Ping, UDP, TCP, DHCP & DNS. |
|
||||
| **[10/18]** | **Sound & Melody Synth** | Audio core driver, AC'97 soundcard, 8-Bit Melody player, and Formant Text-to-Speech synthesizer. |
|
||||
| **[11/18]** | **Keyring, LSM & Namespaces** | Loads X.509 trusted keyring, POSIX Capabilities LSM, and initializes container namespaces. |
|
||||
| **[12/18]** | **IPC Engine** | Anonymous Pipes, System V & POSIX Message Queues, Shared Memory segments, and Semaphore sets. |
|
||||
| **[13/18]** | **io_uring Subsystem** | Lockless Submission Queue Entry (SQE) & Completion Queue Entry (CQE) asynchronous I/O engine. |
|
||||
| **[14/18]** | **Multi-VFS Mount** | Root RAMFS, synthetic `/dev` devfs, `/proc` procfs, `/sys` sysfs, FAT32 driver, ext2 driver & initramfs. |
|
||||
| **[15/18]** | **Kernel Core Services** | POSIX Signal manager (32 signals), Async Workqueues, 64-bit Fast Syscalls, and Dynamic Module Loader. |
|
||||
| **[15/18]** | **Kernel Core & Tracing** | POSIX Signals, Workqueues, 64-bit Fast Syscalls, Dynamic Module Loader, and Event Tracer. |
|
||||
| **[16/18]** | **Scheduler & LazyBox** | Starts round-robin preemptive scheduler and launches LazyBox interactive userland environment. |
|
||||
| **[17/18]** | **Hardware Interrupts** | Enables processor interrupts (`sti`) and transitions to userland shell. |
|
||||
| **[18/18]** | **Interactive Shell** | Launches multi-TTY interactive terminal console on TTY1. |
|
||||
| **[18/18]** | **Interactive Shell** | Launches multi-TTY interactive terminal console on TTY1 with dynamic CWD prompt. |
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Subsystems & Codebase Architecture
|
||||
|
||||
```text
|
||||
SUB-OS/
|
||||
├── arch/x86_64/ # Long Mode bootstrap, GDT, IDT, ISRs, PIC, PIT, CPUID, Paging
|
||||
├── block/ # Block Layer Core, Request Queues, Elevator I/O Schedulers
|
||||
├── boot/ # Stage 1 MBR Bootloader & Stage 2 64-Bit Protected Mode Switcher
|
||||
├── certs/ # X.509 ASN.1 DER Parser, Public Key Verification & Root Keyring
|
||||
├── crypto/ # FIPS SHA-256, RFC 1321 MD5, IEEE 802.3 CRC32, Xorshift128+ PRNG
|
||||
├── drivers/
|
||||
│ ├── block/ # ATA / IDE Hard Disk PIO Driver (28-bit LBA)
|
||||
│ ├── char/ # VGA Text, TTY1-4 with ANSI sequences, 16550 UART Serial, PS/2 Keyboard
|
||||
│ ├── input/ # PS/2 Mouse Driver with packet tracking
|
||||
│ ├── net/ # Intel 82540EM Gigabit Ethernet NIC with DMA Descriptors
|
||||
│ ├── pci/ # PCI Bus Enumeration & BAR Configuration
|
||||
│ ├── power/ # ACPI S5 Soft-Off Power Management & Reset
|
||||
│ ├── rtc/ # CMOS Real-Time Clock Hardware Driver (BCD conversion)
|
||||
│ ├── sound/ # PC Speaker Tone Generator
|
||||
│ ├── usb/ # USB Host Controller Abstraction
|
||||
│ └── video/ # 32-bit Linear Framebuffer Graphics Engine
|
||||
├── fs/ # VFS Layer, RAMFS, devfs (/dev), procfs (/proc), sysfs (/sys), FAT32, ext2
|
||||
├── include/ # Modular Subsystem Header Files
|
||||
├── init/ # Early Initialization, Boot Command Line Parser, Versioning & Runlevels
|
||||
├── io_uring/ # Asynchronous I/O Engine with SQE & CQE Lockless Ringbuffers
|
||||
├── ipc/ # Anonymous Pipes, Message Queues, Shared Memory, Counting Semaphores
|
||||
├── kernel/ # Task Scheduler, Mutexes, Signals, Syscalls, Timers, Workqueues, Modules
|
||||
├── lib/ # Standard C Library (string, sprintf, bitmap, list)
|
||||
├── mm/ # Physical Page Frame Allocator (PMM) & Dynamic Heap (kmalloc)
|
||||
├── net/ # Ethernet, ARP, IPv4, ICMP, UDP, TCP, DHCP, DNS, BSD Sockets
|
||||
├── security/ # Linux Security Modules (LSM) & POSIX Capabilities
|
||||
├── sound/ # ALSA Sound Core, AC'97 Driver, PCM Audio & Text-to-Speech (TTS) Engine
|
||||
├── usr/ # Embedded Initramfs Payload Tree (/etc/passwd, /etc/fstab, /usr/bin)
|
||||
└── userland/ # Full-Screen GNU Nano Editor & 50+ LazyBox Core Utilities
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Full-Screen Visual Nano Editor
|
||||
|
||||
SUB-OS includes a full-screen interactive ANSI text editor (`nano`):
|
||||
|
||||
```text
|
||||
GNU nano 2.0.0 File: /home/user/notes.txt [Modified]
|
||||
Hello from nano editor in SUB-OS!
|
||||
This is a production-level modular operating system.
|
||||
You can write, edit, search, and save files directly to the VFS.
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
~
|
||||
[ Wrote 148 bytes to /home/user/notes.txt ]
|
||||
^G Get Help ^O WriteOut ^W Where Is ^K Cut Line ^U Paste ^X Exit
|
||||
```
|
||||
|
||||
### Keybindings:
|
||||
- **`^O` (Ctrl+O)**: WriteOut / Save file to Virtual File System.
|
||||
- **`^X` (Ctrl+X)**: Exit Nano and return to shell.
|
||||
- **`^K` (Ctrl+K)**: Cut current line to cut-buffer.
|
||||
- **`^U` (Ctrl+U)**: Uncut / Paste line at cursor position.
|
||||
- **`^G` (Ctrl+G)**: Display help cheat sheet.
|
||||
- **`Arrow Keys` / `Home` / `End` / `PgUp` / `PgDn`**: Smooth cursor navigation.
|
||||
|
||||
---
|
||||
|
||||
## 🧰 LazyBox Multi-Call Userland Suite (50+ Utilities)
|
||||
## 🧰 LazyBox Multi-Call Userland Suite (55+ Utilities)
|
||||
|
||||
| Category | Commands Included |
|
||||
|---|---|
|
||||
| **Core** | `lazybox`, `echo`, `whoami`, `id`, `date` (CMOS RTC), `cal` |
|
||||
| **Filesystem & Editor** | `nano`, `ls`, `cat`, `touch`, `mkdir`, `pwd`, `cd`, `wc`, `head`, `tail`, `stat`, `cp`, `grep`, `hexdump` |
|
||||
| **Sound & Voice** | `tts` (Phonetic Formant Voice Synthesizer), `alsamixer` |
|
||||
| **Kernel & Modules** | `lsmod`, `insmod`, `rmmod` |
|
||||
| **Core & Scripting** | `lazybox`, `sh` (Script runner), `echo`, `env`, `export`, `whoami`, `id`, `date` (CMOS RTC), `cal` |
|
||||
| **Filesystem & Editor** | `nano`, `ls`, `cat`, `touch`, `mkdir`, `pwd`, `cd`, `wc`, `head`, `tail`, `stat`, `cp`, `grep`, `hexdump`, `basename`, `dirname` |
|
||||
| **Sound & Voice** | `tts` (Phonetic Formant Voice Synthesizer), `tune` (8-Bit Melody Player), `alsamixer` |
|
||||
| **Kernel & Tracing** | `lsmod`, `insmod`, `rmmod`, `slabinfo`, `trace`, `unshare` (Namespace containers) |
|
||||
| **Crypto & Security** | `sha256sum`, `md5sum`, `crc32`, `rand`, `certcheck`, `capsh`, `ipcs` |
|
||||
| **Network** | `ifconfig`, `ping`, `arp`, `dhclient`, `nslookup` |
|
||||
| **Network & Firewall** | `ifconfig`, `ping`, `arp`, `dhclient`, `nslookup`, `iptables` (Stateful Firewall) |
|
||||
| **Storage & Devices** | `hdparm`, `lspci`, `speaker`, `mouse` |
|
||||
| **Virtualization & Async**| `virtinfo`, `io_uring_test` |
|
||||
| **System Monitoring** | `uname`, `free`, `uptime`, `dmesg`, `ps`, `top`, `sleep`, `reboot`, `poweroff` |
|
||||
@@ -170,6 +97,23 @@ You can write, edit, search, and save files directly to the VFS.
|
||||
|
||||
---
|
||||
|
||||
## 📜 Shell Scripting Example (`.sub` scripts)
|
||||
|
||||
Create a script with `nano /test.sub` and execute it with `sh /test.sub`:
|
||||
|
||||
```bash
|
||||
# SUB-OS Automation Script
|
||||
echo "Starting System Self-Check..."
|
||||
uname -a
|
||||
free
|
||||
slabinfo
|
||||
iptables
|
||||
tune startup
|
||||
echo "All subsystems operational!"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Building & Running
|
||||
|
||||
### Compilation
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <drivers/ramdisk.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static uint8_t* ramdisk_storage = NULL;
|
||||
static block_device_t ramdisk_dev;
|
||||
|
||||
static int ramdisk_read_sectors(block_device_t* dev, uint64_t sector, uint32_t count, void* buf) {
|
||||
(void)dev;
|
||||
if (!ramdisk_storage || !buf) return -1;
|
||||
if ((sector + count) * RAMDISK_SECTOR_SIZE > RAMDISK_SIZE) return -1;
|
||||
|
||||
memcpy(buf, ramdisk_storage + (sector * RAMDISK_SECTOR_SIZE), count * RAMDISK_SECTOR_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ramdisk_write_sectors(block_device_t* dev, uint64_t sector, uint32_t count, const void* buf) {
|
||||
(void)dev;
|
||||
if (!ramdisk_storage || !buf) return -1;
|
||||
if ((sector + count) * RAMDISK_SECTOR_SIZE > RAMDISK_SIZE) return -1;
|
||||
|
||||
memcpy(ramdisk_storage + (sector * RAMDISK_SECTOR_SIZE), buf, count * RAMDISK_SECTOR_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ramdisk_init(void) {
|
||||
ramdisk_storage = (uint8_t*)kzalloc(RAMDISK_SIZE);
|
||||
if (!ramdisk_storage) {
|
||||
printk(KERN_ERR "RAMDISK: Failed to allocate 4MB memory buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ramdisk_dev, 0, sizeof(block_device_t));
|
||||
strcpy(ramdisk_dev.name, "ram0");
|
||||
ramdisk_dev.device_id = 1;
|
||||
ramdisk_dev.sector_size = RAMDISK_SECTOR_SIZE;
|
||||
ramdisk_dev.total_sectors = RAMDISK_SIZE / RAMDISK_SECTOR_SIZE;
|
||||
ramdisk_dev.read_only = false;
|
||||
ramdisk_dev.read_sectors = ramdisk_read_sectors;
|
||||
ramdisk_dev.write_sectors = ramdisk_write_sectors;
|
||||
ramdisk_dev.flush = NULL;
|
||||
|
||||
block_register_device(&ramdisk_dev);
|
||||
printk(KERN_INFO "RAMDISK: /dev/ram0 registered (4096 KB, 8192 sectors)\n");
|
||||
}
|
||||
|
||||
block_device_t* ramdisk_get_block_device(void) {
|
||||
return &ramdisk_dev;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef _DRIVERS_RAMDISK_H
|
||||
#define _DRIVERS_RAMDISK_H
|
||||
|
||||
#include <block/block.h>
|
||||
|
||||
#define RAMDISK_SIZE (4 * 1024 * 1024) // 4 MB Ramdisk
|
||||
#define RAMDISK_SECTOR_SIZE 512
|
||||
|
||||
void ramdisk_init(void);
|
||||
block_device_t* ramdisk_get_block_device(void);
|
||||
|
||||
#endif // _DRIVERS_RAMDISK_H
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _KERNEL_NAMESPACE_H
|
||||
#define _KERNEL_NAMESPACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define CLONE_NEWPID 0x20000000
|
||||
#define CLONE_NEWUTS 0x04000000
|
||||
#define CLONE_NEWIPC 0x08000000
|
||||
#define CLONE_NEWNET 0x40000000
|
||||
#define CLONE_NEWNS 0x00020000
|
||||
|
||||
#define MAX_NAMESPACES 16
|
||||
|
||||
typedef struct uts_namespace {
|
||||
char hostname[64];
|
||||
char domainname[64];
|
||||
} uts_namespace_t;
|
||||
|
||||
typedef struct nsproxy {
|
||||
uint32_t id;
|
||||
char name[32];
|
||||
uts_namespace_t uts;
|
||||
uint32_t pid_offset;
|
||||
bool isolated_mounts;
|
||||
bool in_use;
|
||||
} nsproxy_t;
|
||||
|
||||
void namespace_init(void);
|
||||
nsproxy_t* namespace_create(const char* name, uint32_t flags);
|
||||
nsproxy_t* namespace_get_current(void);
|
||||
int namespace_switch(uint32_t id);
|
||||
size_t namespace_get_count(void);
|
||||
const nsproxy_t* namespace_get(size_t index);
|
||||
|
||||
#endif // _KERNEL_NAMESPACE_H
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _KERNEL_TRACE_H
|
||||
#define _KERNEL_TRACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define TRACE_BUFFER_SIZE 256
|
||||
#define TRACE_MSG_LEN 96
|
||||
|
||||
typedef enum {
|
||||
TRACE_CAT_SYS = 0,
|
||||
TRACE_CAT_IRQ,
|
||||
TRACE_CAT_SCHED,
|
||||
TRACE_CAT_MM,
|
||||
TRACE_CAT_NET,
|
||||
TRACE_CAT_FS,
|
||||
TRACE_CAT_MAX
|
||||
} trace_category_t;
|
||||
|
||||
typedef struct trace_entry {
|
||||
uint64_t timestamp;
|
||||
uint32_t cpu_id;
|
||||
uint32_t pid;
|
||||
trace_category_t category;
|
||||
char message[TRACE_MSG_LEN];
|
||||
} trace_entry_t;
|
||||
|
||||
void trace_init(void);
|
||||
void trace_record(trace_category_t cat, const char* msg);
|
||||
void trace_enable(bool enable);
|
||||
bool trace_is_enabled(void);
|
||||
void trace_clear(void);
|
||||
size_t trace_get_count(void);
|
||||
const trace_entry_t* trace_get_entry(size_t index);
|
||||
|
||||
#endif // _KERNEL_TRACE_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef _MM_SLAB_H
|
||||
#define _MM_SLAB_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SLAB_NAME_MAX 32
|
||||
#define SLAB_MAX_CACHES 32
|
||||
|
||||
typedef struct kmem_cache kmem_cache_t;
|
||||
|
||||
typedef void (*kmem_ctor_fn_t)(void* obj);
|
||||
typedef void (*kmem_dtor_fn_t)(void* obj);
|
||||
|
||||
typedef struct kmem_slab {
|
||||
void* memory;
|
||||
uint32_t total_objects;
|
||||
uint32_t free_objects;
|
||||
uint32_t* freelist;
|
||||
uint32_t freelist_head;
|
||||
struct kmem_slab* next;
|
||||
} kmem_slab_t;
|
||||
|
||||
struct kmem_cache {
|
||||
char name[SLAB_NAME_MAX];
|
||||
size_t object_size;
|
||||
size_t alignment;
|
||||
size_t objects_per_slab;
|
||||
uint32_t active_objects;
|
||||
uint32_t total_slabs;
|
||||
kmem_ctor_fn_t ctor;
|
||||
kmem_dtor_fn_t dtor;
|
||||
kmem_slab_t* slabs_partial;
|
||||
kmem_slab_t* slabs_full;
|
||||
kmem_slab_t* slabs_empty;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
void slab_init(void);
|
||||
kmem_cache_t* kmem_cache_create(const char* name, size_t size, size_t align, kmem_ctor_fn_t ctor, kmem_dtor_fn_t dtor);
|
||||
void* kmem_cache_alloc(kmem_cache_t* cache);
|
||||
void kmem_cache_free(kmem_cache_t* cache, void* obj);
|
||||
int kmem_cache_destroy(kmem_cache_t* cache);
|
||||
|
||||
size_t slab_get_cache_count(void);
|
||||
const kmem_cache_t* slab_get_cache(size_t index);
|
||||
|
||||
#endif // _MM_SLAB_H
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef _NET_FILTER_H
|
||||
#define _NET_FILTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define FILTER_MAX_RULES 32
|
||||
|
||||
typedef enum {
|
||||
FILTER_ACTION_ACCEPT = 0,
|
||||
FILTER_ACTION_DROP,
|
||||
FILTER_ACTION_REJECT,
|
||||
FILTER_ACTION_LOG
|
||||
} filter_action_t;
|
||||
|
||||
typedef enum {
|
||||
FILTER_HOOK_PRE_ROUTING = 0,
|
||||
FILTER_HOOK_LOCAL_IN,
|
||||
FILTER_HOOK_FORWARD,
|
||||
FILTER_HOOK_LOCAL_OUT,
|
||||
FILTER_HOOK_POST_ROUTING,
|
||||
FILTER_HOOK_MAX
|
||||
} filter_hook_t;
|
||||
|
||||
typedef struct filter_rule {
|
||||
uint32_t id;
|
||||
filter_hook_t hook;
|
||||
uint32_t src_ip;
|
||||
uint32_t src_mask;
|
||||
uint32_t dst_ip;
|
||||
uint32_t dst_mask;
|
||||
uint8_t protocol;
|
||||
uint16_t src_port;
|
||||
uint16_t dst_port;
|
||||
filter_action_t action;
|
||||
uint64_t packet_count;
|
||||
uint64_t byte_count;
|
||||
char comment[32];
|
||||
bool in_use;
|
||||
} filter_rule_t;
|
||||
|
||||
void filter_init(void);
|
||||
int filter_add_rule(filter_hook_t hook, uint8_t proto, uint16_t dst_port, filter_action_t action, const char* comment);
|
||||
int filter_delete_rule(uint32_t rule_id);
|
||||
filter_action_t filter_evaluate(filter_hook_t hook, uint8_t proto, uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port, size_t len);
|
||||
|
||||
size_t filter_get_rule_count(void);
|
||||
const filter_rule_t* filter_get_rule(size_t index);
|
||||
|
||||
#endif // _NET_FILTER_H
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _SOUND_MELODY_H
|
||||
#define _SOUND_MELODY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t freq;
|
||||
uint32_t duration_ms;
|
||||
} note_t;
|
||||
|
||||
void melody_init(void);
|
||||
void melody_play_startup(void);
|
||||
void melody_play_tetris(void);
|
||||
void melody_play_mario(void);
|
||||
void melody_play_custom(const note_t* notes, uint32_t count);
|
||||
|
||||
#endif // _SOUND_MELODY_H
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _USERLAND_SH_H
|
||||
#define _USERLAND_SH_H
|
||||
|
||||
int sh_main(int argc, char** argv);
|
||||
int sh_execute_script(const char* filepath);
|
||||
const char* sh_get_env(const char* key);
|
||||
int sh_set_env(const char* key, const char* value);
|
||||
|
||||
#endif // _USERLAND_SH_H
|
||||
+24
-11
@@ -7,6 +7,8 @@
|
||||
#include <kernel/timer.h>
|
||||
#include <kernel/workqueue.h>
|
||||
#include <kernel/module.h>
|
||||
#include <kernel/trace.h>
|
||||
#include <kernel/namespace.h>
|
||||
#include <arch/x86_64/gdt.h>
|
||||
#include <arch/x86_64/idt.h>
|
||||
#include <arch/x86_64/isr.h>
|
||||
@@ -16,6 +18,7 @@
|
||||
#include <arch/x86_64/paging.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <mm/slab.h>
|
||||
#include <drivers/tty.h>
|
||||
#include <drivers/serial.h>
|
||||
#include <drivers/keyboard.h>
|
||||
@@ -28,9 +31,11 @@
|
||||
#include <drivers/rtc.h>
|
||||
#include <drivers/acpi.h>
|
||||
#include <drivers/usb.h>
|
||||
#include <drivers/ramdisk.h>
|
||||
#include <block/block.h>
|
||||
#include <ipc/ipc.h>
|
||||
#include <sound/sound.h>
|
||||
#include <sound/melody.h>
|
||||
#include <fs/vfs.h>
|
||||
#include <fs/fat32.h>
|
||||
#include <fs/ext2.h>
|
||||
@@ -41,6 +46,7 @@
|
||||
#include <net/tcp.h>
|
||||
#include <net/dhcp.h>
|
||||
#include <net/dns.h>
|
||||
#include <net/filter.h>
|
||||
#include <crypto/crypto.h>
|
||||
#include <certs/certs.h>
|
||||
#include <security/security.h>
|
||||
@@ -50,6 +56,7 @@
|
||||
#include <init/init.h>
|
||||
#include <init/version.h>
|
||||
#include <userland/lazybox.h>
|
||||
#include <userland/sh.h>
|
||||
#include <userland/shell.h>
|
||||
|
||||
void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
@@ -92,16 +99,18 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
acpi_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 5. Memory Management
|
||||
printk(KERN_INFO "[6/18] Initializing Physical & Dynamic Heap Memory (PMM + Heap)... ");
|
||||
// 5. Memory Management: PMM + Dynamic Heap + SLAB Cache
|
||||
printk(KERN_INFO "[6/18] Initializing Physical PMM, Dynamic Heap & SLAB Cache... ");
|
||||
pmm_init(memory_map, memory_map_count);
|
||||
heap_init();
|
||||
slab_init();
|
||||
paging_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 6. Block Storage & Hardware Busses
|
||||
printk(KERN_INFO "[7/18] Initializing Block Layer & Storage Controllers... ");
|
||||
// 6. Block Storage, Ramdisk & Hardware Busses
|
||||
printk(KERN_INFO "[7/18] Initializing Block Layer, Ramdisk & Storage Controllers... ");
|
||||
block_init();
|
||||
ramdisk_init();
|
||||
if (ata_init()) {
|
||||
printk(ANSI_BRIGHT_GREEN "ATA Primary Master Active\n" ANSI_RESET);
|
||||
} else {
|
||||
@@ -115,8 +124,9 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
usb_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 7. Network Subsystem
|
||||
printk(KERN_INFO "[9/18] Initializing Network Protocol Stack (L2-L4)... ");
|
||||
// 7. Network Subsystem & Firewall
|
||||
printk(KERN_INFO "[9/18] Initializing Network Protocol Stack & NetFilter Firewall... ");
|
||||
filter_init();
|
||||
if (e1000_init()) {
|
||||
net_init();
|
||||
socket_subsystem_init();
|
||||
@@ -130,15 +140,17 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
}
|
||||
|
||||
// 8. Sound & Voice Synthesizer
|
||||
printk(KERN_INFO "[10/18] Initializing Sound Architecture & Formant TTS Synthesizer... ");
|
||||
printk(KERN_INFO "[10/18] Initializing Sound Architecture, Melody Player & Formant TTS... ");
|
||||
sound_init();
|
||||
melody_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 9. Crypto, Certificates & LSM Security
|
||||
printk(KERN_INFO "[11/18] Initializing X.509 Keyring & Linux Security Module... ");
|
||||
// 9. Crypto, Certificates, LSM Security & Container Namespaces
|
||||
printk(KERN_INFO "[11/18] Initializing X.509 Keyring, LSM Security & Namespaces... ");
|
||||
prng_seed(0, 0);
|
||||
certs_init();
|
||||
security_init();
|
||||
namespace_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 10. Inter-Process Communication
|
||||
@@ -160,12 +172,13 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
|
||||
initramfs_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 13. Kernel Core: Signals, Workqueues, Modules, Syscalls
|
||||
printk(KERN_INFO "[15/18] Initializing Signals, Workqueues, Syscalls & Module Loader... ");
|
||||
// 13. Kernel Core: Signals, Workqueues, Modules, Syscalls & Tracing
|
||||
printk(KERN_INFO "[15/18] Initializing Signals, Workqueues, Syscalls, Modules & Tracing... ");
|
||||
signal_init();
|
||||
workqueue_init();
|
||||
syscall_init();
|
||||
module_init_subsystem();
|
||||
trace_init();
|
||||
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
|
||||
|
||||
// 14. Preemptive Multi-Tasking & Userland
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <kernel/namespace.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static nsproxy_t ns_table[MAX_NAMESPACES];
|
||||
static uint32_t current_ns_id = 0;
|
||||
|
||||
void namespace_init(void) {
|
||||
memset(ns_table, 0, sizeof(ns_table));
|
||||
|
||||
// Root / Global Namespace (ID 0)
|
||||
ns_table[0].id = 0;
|
||||
ns_table[0].in_use = true;
|
||||
strcpy(ns_table[0].name, "root_ns");
|
||||
strcpy(ns_table[0].uts.hostname, "sub-os");
|
||||
strcpy(ns_table[0].uts.domainname, "localdomain");
|
||||
ns_table[0].pid_offset = 0;
|
||||
ns_table[0].isolated_mounts = false;
|
||||
|
||||
current_ns_id = 0;
|
||||
printk(KERN_INFO "NAMESPACE: Lightweight Container & Process Isolation layer active\n");
|
||||
}
|
||||
|
||||
nsproxy_t* namespace_create(const char* name, uint32_t flags) {
|
||||
for (uint32_t i = 1; i < MAX_NAMESPACES; i++) {
|
||||
if (!ns_table[i].in_use) {
|
||||
nsproxy_t* ns = &ns_table[i];
|
||||
ns->id = i;
|
||||
ns->in_use = true;
|
||||
strncpy(ns->name, name ? name : "container", sizeof(ns->name) - 1);
|
||||
ns->name[sizeof(ns->name) - 1] = '\0';
|
||||
|
||||
if (flags & CLONE_NEWUTS) {
|
||||
strncpy(ns->uts.hostname, ns->name, sizeof(ns->uts.hostname) - 1);
|
||||
} else {
|
||||
strcpy(ns->uts.hostname, ns_table[0].uts.hostname);
|
||||
}
|
||||
strcpy(ns->uts.domainname, "container.local");
|
||||
|
||||
ns->pid_offset = (flags & CLONE_NEWPID) ? (i * 1000) : 0;
|
||||
ns->isolated_mounts = (flags & CLONE_NEWNS) ? true : false;
|
||||
return ns;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsproxy_t* namespace_get_current(void) {
|
||||
return &ns_table[current_ns_id];
|
||||
}
|
||||
|
||||
int namespace_switch(uint32_t id) {
|
||||
if (id >= MAX_NAMESPACES || !ns_table[id].in_use) return -1;
|
||||
current_ns_id = id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t namespace_get_count(void) {
|
||||
size_t c = 0;
|
||||
for (size_t i = 0; i < MAX_NAMESPACES; i++) {
|
||||
if (ns_table[i].in_use) c++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
const nsproxy_t* namespace_get(size_t index) {
|
||||
if (index >= MAX_NAMESPACES || !ns_table[index].in_use) return NULL;
|
||||
return &ns_table[index];
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <kernel/trace.h>
|
||||
#include <kernel/task.h>
|
||||
#include <arch/x86_64/pit.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static trace_entry_t trace_buffer[TRACE_BUFFER_SIZE];
|
||||
static size_t trace_head = 0;
|
||||
static size_t trace_total = 0;
|
||||
static bool trace_enabled = true;
|
||||
|
||||
void trace_init(void) {
|
||||
memset(trace_buffer, 0, sizeof(trace_buffer));
|
||||
trace_head = 0;
|
||||
trace_total = 0;
|
||||
trace_enabled = true;
|
||||
|
||||
trace_record(TRACE_CAT_SYS, "Kernel Tracing Ringbuffer initialized");
|
||||
printk(KERN_INFO "TRACE: High-performance Kernel Event & Latency Tracer active\n");
|
||||
}
|
||||
|
||||
void trace_record(trace_category_t cat, const char* msg) {
|
||||
if (!trace_enabled || !msg) return;
|
||||
|
||||
trace_entry_t* entry = &trace_buffer[trace_head];
|
||||
entry->timestamp = pit_get_ticks();
|
||||
entry->cpu_id = 0;
|
||||
entry->pid = (uint32_t)task_get_pid();
|
||||
entry->category = cat;
|
||||
strncpy(entry->message, msg, TRACE_MSG_LEN - 1);
|
||||
entry->message[TRACE_MSG_LEN - 1] = '\0';
|
||||
|
||||
trace_head = (trace_head + 1) % TRACE_BUFFER_SIZE;
|
||||
if (trace_total < TRACE_BUFFER_SIZE) {
|
||||
trace_total++;
|
||||
}
|
||||
}
|
||||
|
||||
void trace_enable(bool enable) {
|
||||
trace_enabled = enable;
|
||||
}
|
||||
|
||||
bool trace_is_enabled(void) {
|
||||
return trace_enabled;
|
||||
}
|
||||
|
||||
void trace_clear(void) {
|
||||
memset(trace_buffer, 0, sizeof(trace_buffer));
|
||||
trace_head = 0;
|
||||
trace_total = 0;
|
||||
}
|
||||
|
||||
size_t trace_get_count(void) {
|
||||
return trace_total;
|
||||
}
|
||||
|
||||
const trace_entry_t* trace_get_entry(size_t index) {
|
||||
if (index >= trace_total) return NULL;
|
||||
size_t actual_idx = (trace_head - trace_total + index + TRACE_BUFFER_SIZE) % TRACE_BUFFER_SIZE;
|
||||
return &trace_buffer[actual_idx];
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#include <mm/slab.h>
|
||||
#include <mm/kmalloc.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static kmem_cache_t cache_table[SLAB_MAX_CACHES];
|
||||
static size_t cache_count = 0;
|
||||
|
||||
void slab_init(void) {
|
||||
memset(cache_table, 0, sizeof(cache_table));
|
||||
cache_count = 0;
|
||||
|
||||
// Initialize core kernel slabs
|
||||
kmem_cache_create("task_struct", 512, 16, NULL, NULL);
|
||||
kmem_cache_create("vfs_node", 256, 8, NULL, NULL);
|
||||
kmem_cache_create("file_desc", 64, 8, NULL, NULL);
|
||||
kmem_cache_create("socket_cache", 128, 8, NULL, NULL);
|
||||
kmem_cache_create("buffer_head", 64, 8, NULL, NULL);
|
||||
|
||||
printk(KERN_INFO "SLAB: High-performance SLUB/SLAB Object Cache layer initialized\n");
|
||||
}
|
||||
|
||||
kmem_cache_t* kmem_cache_create(const char* name, size_t size, size_t align, kmem_ctor_fn_t ctor, kmem_dtor_fn_t dtor) {
|
||||
if (!name || size == 0) return NULL;
|
||||
|
||||
for (size_t i = 0; i < SLAB_MAX_CACHES; i++) {
|
||||
if (!cache_table[i].in_use) {
|
||||
kmem_cache_t* c = &cache_table[i];
|
||||
c->in_use = true;
|
||||
strncpy(c->name, name, SLAB_NAME_MAX - 1);
|
||||
c->name[SLAB_NAME_MAX - 1] = '\0';
|
||||
|
||||
if (align < 8) align = 8;
|
||||
c->alignment = align;
|
||||
c->object_size = (size + align - 1) & ~(align - 1);
|
||||
c->objects_per_slab = 4096 / c->object_size;
|
||||
if (c->objects_per_slab == 0) c->objects_per_slab = 1;
|
||||
|
||||
c->active_objects = 0;
|
||||
c->total_slabs = 0;
|
||||
c->ctor = ctor;
|
||||
c->dtor = dtor;
|
||||
c->slabs_partial = NULL;
|
||||
c->slabs_full = NULL;
|
||||
c->slabs_empty = NULL;
|
||||
|
||||
if (i >= cache_count) cache_count = i + 1;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* kmem_cache_alloc(kmem_cache_t* cache) {
|
||||
if (!cache || !cache->in_use) return NULL;
|
||||
|
||||
void* obj = kmalloc(cache->object_size);
|
||||
if (obj) {
|
||||
cache->active_objects++;
|
||||
if (cache->ctor) {
|
||||
cache->ctor(obj);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void kmem_cache_free(kmem_cache_t* cache, void* obj) {
|
||||
if (!cache || !obj || !cache->in_use) return;
|
||||
|
||||
if (cache->dtor) {
|
||||
cache->dtor(obj);
|
||||
}
|
||||
if (cache->active_objects > 0) {
|
||||
cache->active_objects--;
|
||||
}
|
||||
kfree(obj);
|
||||
}
|
||||
|
||||
int kmem_cache_destroy(kmem_cache_t* cache) {
|
||||
if (!cache || !cache->in_use) return -1;
|
||||
cache->in_use = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t slab_get_cache_count(void) {
|
||||
return cache_count;
|
||||
}
|
||||
|
||||
const kmem_cache_t* slab_get_cache(size_t index) {
|
||||
if (index >= SLAB_MAX_CACHES || !cache_table[index].in_use) return NULL;
|
||||
return &cache_table[index];
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <net/filter.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/printk.h>
|
||||
|
||||
static filter_rule_t rules_table[FILTER_MAX_RULES];
|
||||
static uint32_t next_rule_id = 1;
|
||||
|
||||
void filter_init(void) {
|
||||
memset(rules_table, 0, sizeof(rules_table));
|
||||
next_rule_id = 1;
|
||||
|
||||
// Add default baseline rules
|
||||
filter_add_rule(FILTER_HOOK_LOCAL_IN, 1, 0, FILTER_ACTION_ACCEPT, "Accept ICMP Ping");
|
||||
filter_add_rule(FILTER_HOOK_LOCAL_IN, 6, 80, FILTER_ACTION_ACCEPT, "Allow HTTP Port 80");
|
||||
filter_add_rule(FILTER_HOOK_LOCAL_IN, 17, 53, FILTER_ACTION_ACCEPT, "Allow DNS UDP 53");
|
||||
|
||||
printk(KERN_INFO "NETFILTER: Stateful Packet Inspection & Firewall Subsystem online\n");
|
||||
}
|
||||
|
||||
int filter_add_rule(filter_hook_t hook, uint8_t proto, uint16_t dst_port, filter_action_t action, const char* comment) {
|
||||
for (size_t i = 0; i < FILTER_MAX_RULES; i++) {
|
||||
if (!rules_table[i].in_use) {
|
||||
filter_rule_t* r = &rules_table[i];
|
||||
r->id = next_rule_id++;
|
||||
r->in_use = true;
|
||||
r->hook = hook;
|
||||
r->protocol = proto;
|
||||
r->dst_port = dst_port;
|
||||
r->action = action;
|
||||
r->packet_count = 0;
|
||||
r->byte_count = 0;
|
||||
strncpy(r->comment, comment ? comment : "User Rule", sizeof(r->comment) - 1);
|
||||
r->comment[sizeof(r->comment) - 1] = '\0';
|
||||
return (int)r->id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int filter_delete_rule(uint32_t rule_id) {
|
||||
for (size_t i = 0; i < FILTER_MAX_RULES; i++) {
|
||||
if (rules_table[i].in_use && rules_table[i].id == rule_id) {
|
||||
rules_table[i].in_use = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
filter_action_t filter_evaluate(filter_hook_t hook, uint8_t proto, uint32_t src_ip, uint32_t dst_ip, uint16_t src_port, uint16_t dst_port, size_t len) {
|
||||
(void)src_ip; (void)dst_ip; (void)src_port;
|
||||
for (size_t i = 0; i < FILTER_MAX_RULES; i++) {
|
||||
if (rules_table[i].in_use && rules_table[i].hook == hook) {
|
||||
if (rules_table[i].protocol != 0 && rules_table[i].protocol != proto) continue;
|
||||
if (rules_table[i].dst_port != 0 && rules_table[i].dst_port != dst_port) continue;
|
||||
|
||||
rules_table[i].packet_count++;
|
||||
rules_table[i].byte_count += len;
|
||||
return rules_table[i].action;
|
||||
}
|
||||
}
|
||||
return FILTER_ACTION_ACCEPT;
|
||||
}
|
||||
|
||||
size_t filter_get_rule_count(void) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < FILTER_MAX_RULES; i++) {
|
||||
if (rules_table[i].in_use) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const filter_rule_t* filter_get_rule(size_t index) {
|
||||
if (index >= FILTER_MAX_RULES || !rules_table[index].in_use) return NULL;
|
||||
return &rules_table[index];
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <sound/melody.h>
|
||||
#include <drivers/speaker.h>
|
||||
#include <arch/x86_64/pit.h>
|
||||
|
||||
void melody_init(void) {
|
||||
// Initialized
|
||||
}
|
||||
|
||||
void melody_play_custom(const note_t* notes, uint32_t count) {
|
||||
if (!notes) return;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (notes[i].freq > 0) {
|
||||
speaker_beep(notes[i].freq, notes[i].duration_ms);
|
||||
} else {
|
||||
pit_sleep(notes[i].duration_ms);
|
||||
}
|
||||
pit_sleep(20); // Small pause between notes
|
||||
}
|
||||
}
|
||||
|
||||
void melody_play_startup(void) {
|
||||
note_t fanfare[] = {
|
||||
{523, 100}, // C5
|
||||
{659, 100}, // E5
|
||||
{784, 120}, // G5
|
||||
{1046, 250} // C6
|
||||
};
|
||||
melody_play_custom(fanfare, sizeof(fanfare) / sizeof(note_t));
|
||||
}
|
||||
|
||||
void melody_play_tetris(void) {
|
||||
note_t tetris[] = {
|
||||
{659, 200}, {494, 100}, {523, 100}, {587, 200}, {523, 100}, {494, 100},
|
||||
{440, 200}, {440, 100}, {523, 100}, {659, 200}, {587, 100}, {523, 100},
|
||||
{494, 300}, {523, 100}, {587, 200}, {659, 200}, {523, 200}, {440, 200},
|
||||
{440, 300}
|
||||
};
|
||||
melody_play_custom(tetris, sizeof(tetris) / sizeof(note_t));
|
||||
}
|
||||
|
||||
void melody_play_mario(void) {
|
||||
note_t mario[] = {
|
||||
{659, 100}, {659, 100}, {0, 100}, {659, 100}, {0, 100},
|
||||
{523, 100}, {659, 150}, {784, 250}, {0, 150}, {392, 250}
|
||||
};
|
||||
melody_play_custom(mario, sizeof(mario) / sizeof(note_t));
|
||||
}
|
||||
+177
-4
@@ -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"},
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
Reference in new issue
Block a user