fix(linker): _start is now always first in binary

feat(rand): real random using rdrand/xorshift

chore(panic): added 2 more fun_messages

feat(ksh): removed rectest and added rand command

wip(ksh/kfetch): now it shows vendor string instead of stub
This commit is contained in:
Karina
2026-01-29 04:41:44 +04:00
parent d01a91c993
commit 3525c81d9e
10 changed files with 160 additions and 24 deletions
+36
View File
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include <types.h>
#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);
+2 -1
View File
@@ -4,4 +4,5 @@
#pragma once
#include <types.h>
u64 shitrand();
void rng_init();
u64 krand();
+1 -1
View File
@@ -10,4 +10,4 @@ void cmd_regs();
void print_regs();
void cmd_sleep();
void cmd_debug();
int rectest(int a);
void cmd_rand();
+58
View File
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2026 0xKarinyash
#include "types.h"
#include <cpuinfo.h>
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;
}
+1 -1
View File
@@ -29,7 +29,7 @@ stack_bottom:
resb 16384
stack_top:
section .text
section .text.entry
global _start
global gdt_flush
extern kmain
+5 -2
View File
@@ -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");
+34 -4
View File
@@ -1,15 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include "bootinfo.h"
#include <core/rand.h>
#include <cpuinfo.h>
#include <types.h>
// 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();
}
+6
View File
@@ -2,6 +2,7 @@
// Copyright (c) 2025 0xKarinyash
#include "bootinfo.h"
#include "core/rand.h"
#include <shell/ksh.h>
#include <types.h>
@@ -18,6 +19,7 @@
#include <gdt.h>
#include <idt.h>
#include <pic.h>
#include <cpuinfo.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
@@ -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();
+14 -13
View File
@@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <drivers/console.h>
#include <core/rand.h>
#include <drivers/timer.h>
#include <types.h>
#include <cpuinfo.h>
#include <drivers/console.h>
#include <drivers/timer.h>
#include <core/rand.h>
#include <shell/dbgcmd.h>
#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);
+3 -2
View File
@@ -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;