diff --git a/release_notes.md b/release_notes.md new file mode 100644 index 0000000..8ed4b4e --- /dev/null +++ b/release_notes.md @@ -0,0 +1,88 @@ +# BoredOS 26.4 "Voyager" + +**Welcome to BoredOS Voyager**, the next generation of the BoredOS kernel featuring significant architectural improvements and system-level refinements. + +--- + +## Kernel Upgrade + +The headline of this release is the **Kernel 4.0.0** upgrade, a major step forward from Kernel 3.2.3, bringing enhanced stability and performance improvements. + +- **Kernel Version**: Boredkernel 4.0.0-stable +- **Major Focus**: Multi-processor reliability and VFS infrastructure + +--- + +## Virtual File System (VFS) + +A new VFS layer implementation, providing robust path normalization and mount management. + +- **Path Normalization**: Proper handling of relative and absolute paths +- **Mount System**: Support for multiple filesystem mounts +- **Stability**: Comprehensive error handling and resource management + +--- + +## System Introspection + +New kernel introspection frameworks enabling real-time system monitoring: + +- **SysFS**: Virtual filesystem exposing system information and device states + - Graphics information (resolution, framebuffer details) + - Memory tracking and allocation statistics + - Module information + +- **ProcFS**: Process filesystem with enhanced process information exposure + +--- + +## Storage & Filesystem + +Significant improvements to disk and filesystem handling: + +- **FAT32 Enhancements**: Major refactor with improved file operations +- **AHCI Driver**: Better disk controller support and reliability +- **Disk Manager**: Refined disk operation handling + +--- + +## Performance & Stability + +- **SMP Improvements**: Enhanced multi-processor support and synchronization +- **Kernel Subsystem Architecture**: Reorganized for better modularity +- **Syscall System**: Refined syscall interface for better reliability + +--- + +## User Interface & Tools + +- **Task Manager**: Improved process viewing and management +- **File Explorer**: Removed legacy drive selector for streamlined operation +- **Standard Library**: Added `strstr()` and `strchr()` string functions + +--- + + + +--- + +## Installation & Updates + +To update to the latest version, pull the latest changes from the repository and rebuild your environment: + +```bash +git pull +make clean +make +``` + +Or download the provided `.iso` from this release. + +## 🔐 Security & Verification +If downloading from a third-party source, please verify your image. +SHA-256 Hash: ```55cca8f07b9570276afbdc8eb71b1a9c9a34ebd003ae9754a8371e00ece8e986``` + + +--- + + diff --git a/src/core/platform.c b/src/core/platform.c index 2f741b8..d1bcedb 100644 --- a/src/core/platform.c +++ b/src/core/platform.c @@ -5,6 +5,7 @@ #include "limine.h" #include #include "platform.h" +#include "kutils.h" static volatile struct limine_hhdm_request hhdm_request __attribute__((used, section(".requests"))) = { .id = LIMINE_HHDM_REQUEST, .revision = 0, @@ -80,3 +81,73 @@ void platform_get_cpu_vendor(char *vendor) { *((uint32_t *)&p[8]) = ecx; p[12] = '\0'; } + +void platform_get_cpu_info(cpu_info_t *info) { + uint32_t eax, ebx, ecx, edx; + + // CPUID leaf 1: basic feature information + asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1)); + + info->stepping = eax & 0xF; + info->model = (eax >> 4) & 0xF; + info->family = (eax >> 8) & 0xF; + info->microcode = (ebx >> 8) & 0xFF; + info->flags = ((uint64_t)ecx << 32) | edx; // ECX and EDX contain feature flags + info->cache_size = (ebx >> 16) & 0xFF; // Cache line size in bytes +} + +void platform_get_cpu_flags(char *flags_str) { + uint32_t eax, ebx, ecx, edx; + + flags_str[0] = '\0'; + + // CPUID leaf 1 + asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1)); + + // ECX flags + if (ecx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "sse3 "); + if (ecx & (1 << 1)) k_strcpy(flags_str + k_strlen(flags_str), "pclmulqdq "); + if (ecx & (1 << 3)) k_strcpy(flags_str + k_strlen(flags_str), "monitor "); + if (ecx & (1 << 6)) k_strcpy(flags_str + k_strlen(flags_str), "ssse3 "); + if (ecx & (1 << 9)) k_strcpy(flags_str + k_strlen(flags_str), "sdbg "); + if (ecx & (1 << 12)) k_strcpy(flags_str + k_strlen(flags_str), "fma "); + if (ecx & (1 << 13)) k_strcpy(flags_str + k_strlen(flags_str), "cx16 "); + if (ecx & (1 << 19)) k_strcpy(flags_str + k_strlen(flags_str), "sse4_1 "); + if (ecx & (1 << 20)) k_strcpy(flags_str + k_strlen(flags_str), "sse4_2 "); + if (ecx & (1 << 23)) k_strcpy(flags_str + k_strlen(flags_str), "popcnt "); + if (ecx & (1 << 25)) k_strcpy(flags_str + k_strlen(flags_str), "aes "); + if (ecx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "xsave "); + if (ecx & (1 << 28)) k_strcpy(flags_str + k_strlen(flags_str), "avx "); + + // EDX flags + if (edx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "fpu "); + if (edx & (1 << 3)) k_strcpy(flags_str + k_strlen(flags_str), "pse "); + if (edx & (1 << 4)) k_strcpy(flags_str + k_strlen(flags_str), "tsc "); + if (edx & (1 << 6)) k_strcpy(flags_str + k_strlen(flags_str), "pae "); + if (edx & (1 << 8)) k_strcpy(flags_str + k_strlen(flags_str), "cx8 "); + if (edx & (1 << 9)) k_strcpy(flags_str + k_strlen(flags_str), "apic "); + if (edx & (1 << 11)) k_strcpy(flags_str + k_strlen(flags_str), "sep "); + if (edx & (1 << 15)) k_strcpy(flags_str + k_strlen(flags_str), "cmov "); + if (edx & (1 << 23)) k_strcpy(flags_str + k_strlen(flags_str), "mmx "); + if (edx & (1 << 24)) k_strcpy(flags_str + k_strlen(flags_str), "fxsr "); + if (edx & (1 << 25)) k_strcpy(flags_str + k_strlen(flags_str), "sse "); + if (edx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "sse2 "); + + // Extended leaf 0x80000001 for advanced flags + asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0x80000001)); + + if (edx & (1 << 11)) k_strcpy(flags_str + k_strlen(flags_str), "syscall "); + if (edx & (1 << 20)) k_strcpy(flags_str + k_strlen(flags_str), "nx "); + if (edx & (1 << 26)) k_strcpy(flags_str + k_strlen(flags_str), "pdpe1gb "); + if (edx & (1 << 27)) k_strcpy(flags_str + k_strlen(flags_str), "rdtscp "); + if (edx & (1 << 29)) k_strcpy(flags_str + k_strlen(flags_str), "lm "); + + if (ecx & (1 << 0)) k_strcpy(flags_str + k_strlen(flags_str), "lahf_lm "); + if (ecx & (1 << 5)) k_strcpy(flags_str + k_strlen(flags_str), "abm "); + + // Remove trailing space + int len = k_strlen(flags_str); + if (len > 0 && flags_str[len-1] == ' ') { + flags_str[len-1] = '\0'; + } +} diff --git a/src/core/platform.h b/src/core/platform.h index fc20ae2..612dc15 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -6,10 +6,21 @@ #include +typedef struct { + uint32_t family; + uint32_t model; + uint32_t stepping; + uint32_t microcode; + uint64_t flags; + uint32_t cache_size; +} cpu_info_t; + void platform_init(void); uint64_t p2v(uint64_t phys); uint64_t v2p(uint64_t virt); void platform_get_cpu_model(char *model); void platform_get_cpu_vendor(char *vendor); +void platform_get_cpu_info(cpu_info_t *info); +void platform_get_cpu_flags(char *flags_str); #endif diff --git a/src/fs/procfs.c b/src/fs/procfs.c index 8b4bf9e..f472c32 100644 --- a/src/fs/procfs.c +++ b/src/fs/procfs.c @@ -4,6 +4,7 @@ #include "../dev/disk.h" #include "memory_manager.h" #include "core/kutils.h" +#include "core/platform.h" typedef struct { uint32_t pid; @@ -88,34 +89,173 @@ int procfs_read(void *fs_private, void *handle, void *buf, int size) { } else if (k_strcmp(h->type, "cpuinfo") == 0) { extern uint32_t smp_cpu_count(void); extern void platform_get_cpu_model(char *model); + extern void platform_get_cpu_vendor(char *vendor); + extern void platform_get_cpu_info(cpu_info_t *info); + extern void platform_get_cpu_flags(char *flags_str); + char model[64]; + char vendor[16]; + char flags[1024]; + cpu_info_t info; + platform_get_cpu_model(model); - - k_strcpy(out, "Processor: "); - k_strcpy(out + k_strlen(out), model); - k_strcpy(out + k_strlen(out), "\nCores: "); - char c_s[16]; k_itoa(smp_cpu_count(), c_s); - k_strcpy(out + k_strlen(out), c_s); - k_strcpy(out + k_strlen(out), "\nArchitecture: x86_64\n"); + platform_get_cpu_vendor(vendor); + platform_get_cpu_info(&info); + platform_get_cpu_flags(flags); + + uint32_t cpu_count = smp_cpu_count(); + out[0] = '\0'; + + // Output info for each processor + for (uint32_t i = 0; i < cpu_count; i++) { + char buf[32]; + + k_strcpy(out + k_strlen(out), "processor\t: "); + k_itoa(i, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "vendor_id\t: "); + k_strcpy(out + k_strlen(out), vendor); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "cpu family\t: "); + k_itoa(info.family, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "model\t\t: "); + k_itoa(info.model, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "model name\t: "); + k_strcpy(out + k_strlen(out), model); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "stepping\t: "); + k_itoa(info.stepping, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "microcode\t: 0x"); + char hex[16]; + int temp = info.microcode; + int hex_pos = 0; + for (int j = 7; j >= 0; j--) { + int digit = (temp >> (j * 4)) & 0xF; + hex[hex_pos++] = digit < 10 ? '0' + digit : 'a' + (digit - 10); + } + hex[hex_pos] = '\0'; + k_strcpy(out + k_strlen(out), hex); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "cache size\t: "); + k_itoa(info.cache_size, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), " KB\n"); + + k_strcpy(out + k_strlen(out), "physical id\t: 0\n"); + k_strcpy(out + k_strlen(out), "siblings\t: "); + k_itoa(cpu_count, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "core id\t\t: "); + k_itoa(i, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "cpu cores\t: "); + k_itoa(cpu_count, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "apicid\t\t: "); + k_itoa(i, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "initial apicid\t: "); + k_itoa(i, buf); + k_strcpy(out + k_strlen(out), buf); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "fpu\t\t: yes\n"); + k_strcpy(out + k_strlen(out), "fpu_exception\t: yes\n"); + + k_strcpy(out + k_strlen(out), "cpuid level\t: 13\n"); + + k_strcpy(out + k_strlen(out), "wp\t\t: yes\n"); + + k_strcpy(out + k_strlen(out), "flags\t\t: "); + k_strcpy(out + k_strlen(out), flags); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "bugs\t\t: \n"); + k_strcpy(out + k_strlen(out), "bogomips\t: 4800.00\n"); + + if (i < cpu_count - 1) { + k_strcpy(out + k_strlen(out), "\n"); + } + } } else if (k_strcmp(h->type, "meminfo") == 0) { extern MemStats memory_get_stats(void); MemStats stats = memory_get_stats(); - k_strcpy(out, "MemTotal: "); - char m_s[32]; k_itoa(stats.total_memory / 1024, m_s); + char m_s[32]; + + k_strcpy(out, "MemTotal:\t"); + k_itoa(stats.total_memory / 1024, m_s); k_strcpy(out + k_strlen(out), m_s); - k_strcpy(out + k_strlen(out), " kB\nMemFree: "); + k_strcpy(out + k_strlen(out), " kB\n"); + + k_strcpy(out + k_strlen(out), "MemFree:\t"); k_itoa(stats.available_memory / 1024, m_s); k_strcpy(out + k_strlen(out), m_s); - k_strcpy(out + k_strlen(out), " kB\nMemUsed: "); + k_strcpy(out + k_strlen(out), " kB\n"); + + k_strcpy(out + k_strlen(out), "MemAvailable:\t"); + k_itoa(stats.available_memory / 1024, m_s); + k_strcpy(out + k_strlen(out), m_s); + k_strcpy(out + k_strlen(out), " kB\n"); + + k_strcpy(out + k_strlen(out), "Buffers:\t0 kB\n"); + k_strcpy(out + k_strlen(out), "Cached:\t\t0 kB\n"); + + k_strcpy(out + k_strlen(out), "MemUsed:\t"); k_itoa(stats.used_memory / 1024, m_s); k_strcpy(out + k_strlen(out), m_s); - k_strcpy(out + k_strlen(out), " kB\nPeak: "); + k_strcpy(out + k_strlen(out), " kB\n"); + + k_strcpy(out + k_strlen(out), "MemPeak:\t"); k_itoa(stats.peak_memory_used / 1024, m_s); k_strcpy(out + k_strlen(out), m_s); - k_strcpy(out + k_strlen(out), " kB\nBlocks: "); + k_strcpy(out + k_strlen(out), " kB\n"); + + k_strcpy(out + k_strlen(out), "SwapTotal:\t0 kB\n"); + k_strcpy(out + k_strlen(out), "SwapFree:\t0 kB\n"); + + k_strcpy(out + k_strlen(out), "Dirty:\t\t0 kB\n"); + k_strcpy(out + k_strlen(out), "Writeback:\t0 kB\n"); + k_strcpy(out + k_strlen(out), "AnonPages:\t"); + k_itoa(stats.used_memory / 1024, m_s); + k_strcpy(out + k_strlen(out), m_s); + k_strcpy(out + k_strlen(out), " kB\n"); + + k_strcpy(out + k_strlen(out), "Mapped:\t\t0 kB\n"); + k_strcpy(out + k_strlen(out), "Shmem:\t\t0 kB\n"); + + k_strcpy(out + k_strlen(out), "Blocks:\t\t"); k_itoa(stats.allocated_blocks, m_s); k_strcpy(out + k_strlen(out), m_s); - k_strcpy(out + k_strlen(out), "\nFragmentation: "); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "FreeBlocks:\t"); + k_itoa(stats.free_blocks, m_s); + k_strcpy(out + k_strlen(out), m_s); + k_strcpy(out + k_strlen(out), "\n"); + + k_strcpy(out + k_strlen(out), "Fragmentation:\t"); k_itoa(stats.fragmentation_percent, m_s); k_strcpy(out + k_strlen(out), m_s); k_strcpy(out + k_strlen(out), "%\n"); @@ -123,15 +263,30 @@ int procfs_read(void *fs_private, void *handle, void *buf, int size) { extern int disk_get_count(void); extern Disk* disk_get_by_index(int index); int dcount = disk_get_count(); - k_strcpy(out, "Block Devices:\n"); + out[0] = '\0'; + + k_strcpy(out, "Character devices:\n"); + k_strcpy(out + k_strlen(out), " 1 mem\n"); + k_strcpy(out + k_strlen(out), " 4 tty\n"); + k_strcpy(out + k_strlen(out), " 5 cua\n"); + k_strcpy(out + k_strlen(out), " 7 vcs\n"); + k_strcpy(out + k_strlen(out), " 8 stdin\n"); + k_strcpy(out + k_strlen(out), " 13 input\n"); + k_strcpy(out + k_strlen(out), " 14 sound\n"); + k_strcpy(out + k_strlen(out), " 29 fb\n"); + k_strcpy(out + k_strlen(out), "189 usb\n\n"); + + k_strcpy(out + k_strlen(out), "Block devices:\n"); for (int i = 0; i < dcount; i++) { Disk *d = disk_get_by_index(i); - if (d) { - k_strcpy(out + k_strlen(out), " - "); + if (d && !d->is_partition) { + k_strcpy(out + k_strlen(out), " 8 "); k_strcpy(out + k_strlen(out), d->devname); k_strcpy(out + k_strlen(out), "\n"); } } + k_strcpy(out + k_strlen(out), " 11 sr\n"); + k_strcpy(out + k_strlen(out), "253 virtblk\n"); } } else { diff --git a/src/sys/sysfs_init.c b/src/sys/sysfs_init.c index 38b5489..886df13 100644 --- a/src/sys/sysfs_init.c +++ b/src/sys/sysfs_init.c @@ -7,6 +7,7 @@ #include "core/kutils.h" #include "wm/graphics.h" #include "core/platform.h" +#include "dev/disk.h" // --- Helper: itoa --- static void sys_itoa(int n, char *s) { @@ -131,15 +132,100 @@ static int read_pci_bus(char *buf, int size, int offset) { // --- CPU System Implementation --- static int read_cpu_info(char *buf, int size, int offset) { + char out[2048]; + k_memset(out, 0, 2048); + + char vendor[16]; + char model[64]; + char flags[1024]; + cpu_info_t info; + + platform_get_cpu_vendor(vendor); + platform_get_cpu_model(model); + platform_get_cpu_info(&info); + platform_get_cpu_flags(flags); + + uint32_t cpu_count = smp_cpu_count(); + + k_strcpy(out, "Vendor: "); + k_strcpy(out + k_strlen(out), vendor); + k_strcpy(out + k_strlen(out), "\nModel: "); + k_strcpy(out + k_strlen(out), model); + k_strcpy(out + k_strlen(out), "\nCores: "); + char c_s[16]; k_itoa(cpu_count, c_s); + k_strcpy(out + k_strlen(out), c_s); + k_strcpy(out + k_strlen(out), "\nCPU Family: "); + k_itoa(info.family, c_s); + k_strcpy(out + k_strlen(out), c_s); + k_strcpy(out + k_strlen(out), "\nModel Number: "); + k_itoa(info.model, c_s); + k_strcpy(out + k_strlen(out), c_s); + k_strcpy(out + k_strlen(out), "\nStepping: "); + k_itoa(info.stepping, c_s); + k_strcpy(out + k_strlen(out), c_s); + k_strcpy(out + k_strlen(out), "\nCache Size: "); + k_itoa(info.cache_size, c_s); + k_strcpy(out + k_strlen(out), c_s); + k_strcpy(out + k_strlen(out), " KB\nSpeed: ~3.00 GHz\nFlags: "); + k_strcpy(out + k_strlen(out), flags); + k_strcpy(out + k_strlen(out), "\n"); + + int len = (int)k_strlen(out); + if (offset >= len) return 0; + int to_copy = len - offset; + if (to_copy > size) to_copy = size; + k_memcpy(buf, out + offset, to_copy); + return to_copy; +} + +// --- Devices Implementation --- +static int read_sys_devices(char *buf, int size, int offset) { + char out[2048]; + k_memset(out, 0, 2048); + + extern int disk_get_count(void); + extern Disk* disk_get_by_index(int index); + + int dcount = disk_get_count(); + k_strcpy(out, "Block Devices:\n"); + for (int i = 0; i < dcount; i++) { + Disk *d = disk_get_by_index(i); + if (d && !d->is_partition) { + k_strcpy(out + k_strlen(out), " "); + k_strcpy(out + k_strlen(out), d->devname); + k_strcpy(out + k_strlen(out), " - "); + k_strcpy(out + k_strlen(out), d->label); + k_strcpy(out + k_strlen(out), "\n"); + } + } + + k_strcpy(out + k_strlen(out), "\nCharacter Devices:\n"); + k_strcpy(out + k_strlen(out), " console - System console\n"); + k_strcpy(out + k_strlen(out), " tty - Terminal devices\n"); + k_strcpy(out + k_strlen(out), " psmouse - Mouse input\n"); + k_strcpy(out + k_strlen(out), " keyboard - Keyboard input\n"); + k_strcpy(out + k_strlen(out), " framebuffer - Framebuffer device\n"); + + int len = (int)k_strlen(out); + if (offset >= len) return 0; + int to_copy = len - offset; + if (to_copy > size) to_copy = size; + k_memcpy(buf, out + offset, to_copy); + return to_copy; +} + +// --- Class Implementation --- +static int read_sys_class(char *buf, int size, int offset) { char out[1024]; k_memset(out, 0, 1024); - char vendor[16]; - platform_get_cpu_vendor(vendor); - k_strcpy(out + k_strlen(out), vendor); - k_strcpy(out + k_strlen(out), "\nCores: "); - char c_s[16]; k_itoa(smp_cpu_count(), c_s); - k_strcpy(out + k_strlen(out), c_s); - k_strcpy(out + k_strlen(out), "\nSpeed: ~3.00 GHz\nFeatures: sse sse2 sse3 apic smp\n"); + + k_strcpy(out, "Classes:\n"); + k_strcpy(out + k_strlen(out), " block - Block device class\n"); + k_strcpy(out + k_strlen(out), " input - Input device class\n"); + k_strcpy(out + k_strlen(out), " tty - TTY device class\n"); + k_strcpy(out + k_strlen(out), " sound - Sound device class\n"); + k_strcpy(out + k_strlen(out), " video - Video device class\n"); + k_strcpy(out + k_strlen(out), " net - Network device class\n"); int len = (int)k_strlen(out); if (offset >= len) return 0; @@ -172,7 +258,13 @@ void sysfs_init_subsystems(void) { subsystem_register("devices", &devices); subsystem_register("bus", &bus); subsystem_register("class", &class); - subsystem_register("kernel/debug", &debug); + subsystem_register("kernel/debug", &debug); + + // Devices info + subsystem_add_file(devices, "list", read_sys_devices, NULL); + + // Class info + subsystem_add_file(class, "list", read_sys_class, NULL); // CPU info subsystem_add_file(kernel, "cpuinfo", read_cpu_info, NULL);