diff --git a/kernel/inc/arch/x86_64/cpuinfo.h b/kernel/inc/arch/x86_64/cpuinfo.h new file mode 100644 index 0000000..01e3b6b --- /dev/null +++ b/kernel/inc/arch/x86_64/cpuinfo.h @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include + +#define CPU_FEAT_FPU (1ULL << 0) +#define CPU_FEAT_TSC (1ULL << 1) +#define CPU_FEAT_MSR (1ULL << 2) +#define CPU_FEAT_APIC (1ULL << 3) +#define CPU_FEAT_MTRR (1ULL << 4) +#define CPU_FEAT_PAE (1ULL << 5) + +#define CPU_FEAT_SSE (1ULL << 10) +#define CPU_FEAT_SSE2 (1ULL << 11) +#define CPU_FEAT_SSE3 (1ULL << 12) +#define CPU_FEAT_SSSE3 (1ULL << 13) +#define CPU_FEAT_SSE4_1 (1ULL << 14) +#define CPU_FEAT_SSE4_2 (1ULL << 15) + +#define CPU_FEAT_AVX (1ULL << 20) +#define CPU_FEAT_F16C (1ULL << 21) +#define CPU_FEAT_RDRAND (1ULL << 22) + +#define CPU_FEAT_HYPERVISOR (1ULL << 30) + +typedef struct { + i32 features; + char vendor[13]; + u32 family; + u32 model; +} cpu_info; + +extern cpu_info g_cpu; + +void cpuinfo_init(); +bool cpu_has(u64 feature); \ No newline at end of file diff --git a/kernel/inc/core/rand.h b/kernel/inc/core/rand.h index 95844fa..c7d83cc 100644 --- a/kernel/inc/core/rand.h +++ b/kernel/inc/core/rand.h @@ -4,4 +4,5 @@ #pragma once #include -u64 shitrand(); +void rng_init(); +u64 krand(); \ No newline at end of file diff --git a/kernel/inc/shell/builtins.h b/kernel/inc/shell/builtins.h index 7a6975d..14402cb 100644 --- a/kernel/inc/shell/builtins.h +++ b/kernel/inc/shell/builtins.h @@ -10,4 +10,4 @@ void cmd_regs(); void print_regs(); void cmd_sleep(); void cmd_debug(); -int rectest(int a); +void cmd_rand(); diff --git a/kernel/src/arch/x86_64/cpuinfo.c b/kernel/src/arch/x86_64/cpuinfo.c new file mode 100644 index 0000000..6552402 --- /dev/null +++ b/kernel/src/arch/x86_64/cpuinfo.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 0xKarinyash + +#include "types.h" +#include + +cpu_info g_cpu = {0}; + +static inline void cpuid(u32 leaf, u32 subleaf, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) { + __asm__ volatile("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(leaf), "c"(subleaf) + ); +} + +void cpuinfo_init() { + u32 eax, ebx, ecx, edx; + + cpuid(0, 0, &eax, &ebx, &ecx, &edx); + + u32* vendor_ptr = (u32*)g_cpu.vendor; + vendor_ptr[0] = ebx; + vendor_ptr[1] = edx; + vendor_ptr[2] = ecx; + g_cpu.vendor[12] = '\0'; + + cpuid(1, 0, &eax, &ebx, &ecx, &edx); + + g_cpu.family = (eax >> 8) & 0xF; + g_cpu.model = (eax >> 4) & 0xF; + if (g_cpu.family == 6 || g_cpu.family == 15) { + g_cpu.model += ((eax >> 16) & 0xF) << 4; + } + + if (edx & (1 << 0)) g_cpu.features |= CPU_FEAT_FPU; + if (edx & (1 << 4)) g_cpu.features |= CPU_FEAT_TSC; + if (edx & (1 << 5)) g_cpu.features |= CPU_FEAT_MSR; + if (edx & (1 << 6)) g_cpu.features |= CPU_FEAT_PAE; + if (edx & (1 << 9)) g_cpu.features |= CPU_FEAT_APIC; + if (edx & (1 << 12)) g_cpu.features |= CPU_FEAT_MTRR; + if (edx & (1 << 25)) g_cpu.features |= CPU_FEAT_SSE; + if (edx & (1 << 26)) g_cpu.features |= CPU_FEAT_SSE2; + + if (ecx & (1 << 0)) g_cpu.features |= CPU_FEAT_SSE3; + if (ecx & (1 << 9)) g_cpu.features |= CPU_FEAT_SSSE3; + if (ecx & (1 << 19)) g_cpu.features |= CPU_FEAT_SSE4_1; + if (ecx & (1 << 20)) g_cpu.features |= CPU_FEAT_SSE4_2; + if (ecx & (1 << 28)) g_cpu.features |= CPU_FEAT_AVX; + if (ecx & (1 << 29)) g_cpu.features |= CPU_FEAT_F16C; + + if (ecx & (1 << 30)) g_cpu.features |= CPU_FEAT_RDRAND; + + if (ecx & (1 << 31)) g_cpu.features |= CPU_FEAT_HYPERVISOR; +} + +bool cpu_has(u64 feature) { + return (g_cpu.features & feature) != 0; +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/entry.asm b/kernel/src/arch/x86_64/entry.asm index 2328b5a..e7ea1eb 100644 --- a/kernel/src/arch/x86_64/entry.asm +++ b/kernel/src/arch/x86_64/entry.asm @@ -29,7 +29,7 @@ stack_bottom: resb 16384 stack_top: -section .text +section .text.entry global _start global gdt_flush extern kmain diff --git a/kernel/src/core/panic.c b/kernel/src/core/panic.c index cf6bc8d..a790b76 100644 --- a/kernel/src/core/panic.c +++ b/kernel/src/core/panic.c @@ -51,7 +51,10 @@ const char* fun_messages[] = { "Attaboy, Jack. He's good. Really good.", "Zhenih priehal", "YOUR PC WAS BLOCKED BY FBI FOR WATCHING PORNOGRAPHY SEND 20 US DOLLARS", - "fuck off" + "fuck off", + "Your GPU is now mining Ethereum for me. Thanks.", + "Your PC is locked!\n\t\t\t\tPay a fee of 0.019082006 bitcoins to a wallet 1KtoProchitalTotSosal to get decryption key!", + }; @@ -102,7 +105,7 @@ void draw_panic_bg() { console_set_default_color(0xFFFFFF); u64 msg_count = sizeof(fun_messages) / sizeof(fun_messages[0]); - u8 rand_num = shitrand() % msg_count; + u8 rand_num = krand() % msg_count; kprintf("\n\n"); kprintf("\t\t\t\t^bKERNEL PANIC^! :( \n"); diff --git a/kernel/src/core/rand.c b/kernel/src/core/rand.c index 213f264..319b04c 100644 --- a/kernel/src/core/rand.c +++ b/kernel/src/core/rand.c @@ -1,15 +1,45 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 0xKarinyash +#include "bootinfo.h" #include +#include #include -// really shiity rand lol. -// not shitty.. basic. +static u64 prng_state = 0; -u64 shitrand() { - int lo, hi; +static inline u64 rdtsc() { + u32 lo, hi; __asm__ volatile ("rdtsc" : "=a" (lo), "=d" (hi)); return ((u64)hi << 32) | lo; +} + +void rng_init() { + prng_state = rdtsc(); + if (prng_state == 0) prng_state = BOOTINFO_MAGIC; // why not reuse "termOS"? +} + +static u64 xorshift_rand() { + u64 x = prng_state; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + return prng_state = x; +} + +static bool hw_rand(u64 *val) { + u8 ok; + __asm__ volatile ("rdrand %0; setc %1" + : "=r" (*val), "=qm" (ok)); + return ok != 0; +} + +u64 krand() { + u64 res; + if (cpu_has(CPU_FEAT_RDRAND)) { + if (hw_rand(&res)) return res; + } + + return xorshift_rand(); } \ No newline at end of file diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index 7c40f36..431215c 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -2,6 +2,7 @@ // Copyright (c) 2025 0xKarinyash #include "bootinfo.h" +#include "core/rand.h" #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include @@ -40,6 +42,10 @@ void kmain(Bootinfo* info) { if (info->magic != BOOTINFO_MAGIC) panic("Corrupt bootinfo!"); + cpuinfo_init(); + kprintf("Got CPUINFO\n"); + rng_init(); + kprintf("RNG initialized\n"); gdt_init(); kprintf("GDT initialized\n"); idt_init(); diff --git a/kernel/src/shell/builtins.c b/kernel/src/shell/builtins.c index 1bfa955..197d4fa 100644 --- a/kernel/src/shell/builtins.c +++ b/kernel/src/shell/builtins.c @@ -1,14 +1,17 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (c) 2025 0xKarinyash -#include -#include -#include #include +#include + +#include +#include + +#include +#include #include "../data/cats.h" -#include "shell/dbgcmd.h" const char* ascii_logo[] = { " /\\___/\\ ", @@ -21,12 +24,6 @@ const char* ascii_logo[] = { " |_______| " }; -int rectest(int a) { - volatile int b = a + 1; - kprintf("%d", b); - return rectest(b * 2); -} - void cmd_kfetch() { u64 uptime_s = get_uptime() / 1000; @@ -38,13 +35,13 @@ void cmd_kfetch() { kprintf("^p %s ^!\t\t^gUptime^!: %d seconds\n^!", ascii_logo[4], uptime_s); kprintf("^p %s ^!\t\t^gShell^!: ksh\n^!", ascii_logo[5]); kprintf("^p %s ^p\t\t^gDE^!: shitgui\n^!", ascii_logo[6]); - kprintf("^p %s ^p\t\t^gCPU^!: %s\n^!", ascii_logo[7], "cool one"); + kprintf("^p %s ^p\t\t^gCPU^!: %s\n^!", ascii_logo[7], g_cpu.vendor); kprintf("\n\n"); } void cmd_meow() { u64 cats_count = sizeof(cats) / sizeof(cats[0]); - u8 rand_num = shitrand() % cats_count; + u8 rand_num = krand() % cats_count; kprintf("Nyaaa!!\n\n%s\n\n", cats[rand_num]); } @@ -58,7 +55,6 @@ void cmd_help() { kprintf("\t\t^ysleep^! \t\tSleep for 3seconds\n"); kprintf("\t\t^ydbg^! \t\tTest new stuff\n"); kprintf("\t\t^yregs^! \t\tPrint current regs\n"); - kprintf("\t\t^yrectest^! \t\tTSS test\n"); kprintf("\t\t^ypanic^! \t\tPanics (lol)\n"); kprintf("\t\t^yud2^! \t\tPanics with #UD\n"); kprintf("\t\t^ypf^! \t\tPanics with #PF\n"); @@ -74,6 +70,7 @@ void cmd_help() { kprintf("\t^bMisc^!:\n"); kprintf("\t\t^yclear^! \t\tClear console\n"); kprintf("\t\t^yhelp^! \t\tShow this menu\n"); + kprintf("\t\t^yrand^! \t\tGet a random number\n"); } void cmd_regs() { @@ -100,6 +97,10 @@ void cmd_sleep() { sleep(3000); } +void cmd_rand() { + kprintf("Your rand number (0..100) is ... ^y%d^!!\n", krand() % 100); +} + void cmd_debug() { u64 status = debug(); kprintf("\nDebug ended with code %d\n", status); diff --git a/kernel/src/shell/ksh.c b/kernel/src/shell/ksh.c index f15c51e..a1764f6 100644 --- a/kernel/src/shell/ksh.c +++ b/kernel/src/shell/ksh.c @@ -36,6 +36,7 @@ typedef enum { TOKEN_CLEAR, TOKEN_BLINKING, + TOKEN_RAND, TOKEN_BACK, TOKEN_FORWARD, @@ -56,7 +57,6 @@ static const ksh_command_map token_map[] = { {"sleep", TOKEN_SLEEP}, {"dbg", TOKEN_DEBUG}, {"regs", TOKEN_REGS}, - {"rectest", TOKEN_RECTEST}, {"panic", TOKEN_PANIC}, {"ud2", TOKEN_PANIC_UD2}, {"pf", TOKEN_PANIC_PF}, @@ -69,6 +69,7 @@ static const ksh_command_map token_map[] = { // misc {"help", TOKEN_HELP}, {"clear", TOKEN_CLEAR}, + {"rand", TOKEN_RAND}, {nullptr, TOKEN_NULL} }; @@ -90,11 +91,11 @@ void ksh() { case TOKEN_CLEAR: console_clear((u32) console_get_colors() & 0xFFFFFFFF); break; case TOKEN_BLINKING: console_toggle_cursor_blink(); break; + case TOKEN_RAND: cmd_rand(); break; case TOKEN_SLEEP: cmd_sleep(); break; case TOKEN_DEBUG: cmd_debug(); break; case TOKEN_REGS: cmd_regs(); break; - case TOKEN_RECTEST: rectest(0); break; case TOKEN_PANIC: panic("Manually initiated panic"); case TOKEN_PANIC_UD2: __asm__ volatile ("ud2"); case TOKEN_PANIC_PF: u64* bad_ptr = (u64*)0xDEADBEEF; *bad_ptr = 666;