Compare commits

...
9 Commits
Author SHA1 Message Date
PoliEcho 318fe96319 maybe fix colors in kmalloc 2026-09-25 17:20:56 +02:00
PoliEcho b0ab02c634 basic vmm_alloc structure 2026-09-25 17:20:24 +02:00
PoliEcho a95839c7c6 add RNG test to main 2026-09-25 17:20:01 +02:00
PoliEcho 3fe3d05b1b random numer generation 2026-09-25 17:18:40 +02:00
PoliEcho 700b1ec4b4 add EEXIST to errno.h 2026-09-25 16:08:22 +02:00
PoliEcho 07bd738566 fix limits 2026-09-25 13:07:33 +02:00
PoliEcho 16fde28a8b more limits 2026-09-25 13:02:22 +02:00
PoliEcho 7c0ac01110 partialy freelist madness 2026-09-24 20:58:16 +02:00
PoliEcho b917ebe973 used brain (kmalloc.h)
improve type clarity
2026-09-24 20:46:08 +02:00
8 changed files with 264 additions and 58 deletions
+18 -17
View File
@@ -13,23 +13,24 @@
// TODO: Add correct errno.h numbers
enum {
SUCCESS = 0,
ENOMEM, // Cannot allocate memory
EPERM, // Operation not permitted
ENOENT, // No entry (no such file or directory)
EIO, // Input/Output error
ENXIO, // No such device or address
EAGAIN, // Resource temporarly busy
EACCES, // Permission denied
EFAULT, // Bad address
ENODEV, // No such device
EINVAL, // Invalid argument
EDOM, // Numerical argument out of domain
ERANGE, // Numerical result out of range
ENOSYS, // Function not implemented
ENOTSUP, // Not supported
EILLSEQ, // Illegal byte sequence
EOVERFLOW, //
EALIGN, // Not aligned
ENOMEM, // Cannot allocate memory
EPERM, // Operation not permitted
ENOENT, // No entry (no such file or directory)
EIO, // Input/Output error
ENXIO, // No such device or address
EAGAIN, // Resource temporarly busy
EACCES, // Permission denied
EFAULT, // Bad address
ENODEV, // No such device
EINVAL, // Invalid argument
EDOM, // Numerical argument out of domain
ERANGE, // Numerical result out of range
ENOSYS, // Function not implemented
ENOTSUP, // Not supported
EILLSEQ, // Illegal byte sequence
EOVERFLOW, //
EALIGN, // Not aligned
EEXIST, // already exists
};
#endif
+43 -34
View File
@@ -19,45 +19,54 @@ void* kcalloc(size_t count, size_t size);
#define KMALLOC_MAX_SIZE 17
#define LOWEST_POWER 3
union per_cpu_freelist_cache {
void** freelists[KMALLOC_MAX_SIZE];
struct freelist {
struct freelist* nextnode;
};
struct partialy_freelist {
struct freelist* freelist_nextnode;
struct partialy_freelist* partialy_freelist_nextnode;
};
union freelists_list {
struct freelist* freelists[KMALLOC_MAX_SIZE];
struct {
void** kmalloc_8;
void** kmalloc_16;
void** kmalloc_32;
void** kmalloc_64;
void** kmalloc_128;
void** kmalloc_256;
void** kmalloc_512;
void** kmalloc_1024;
void** kmalloc_2048;
void** kmalloc_4096;
void** kmalloc_8192;
void** kmalloc_16384;
void** kmalloc_32768;
void** kmalloc_65536;
void** kmalloc_131072;
struct freelist* kmalloc_8;
struct freelist* kmalloc_16;
struct freelist* kmalloc_32;
struct freelist* kmalloc_64;
struct freelist* kmalloc_128;
struct freelist* kmalloc_256;
struct freelist* kmalloc_512;
struct freelist* kmalloc_1024;
struct freelist* kmalloc_2048;
struct freelist* kmalloc_4096;
struct freelist* kmalloc_8192;
struct freelist* kmalloc_16384;
struct freelist* kmalloc_32768;
struct freelist* kmalloc_65536;
struct freelist* kmalloc_131072;
};
};
union partial_list {
void** freelists[KMALLOC_MAX_SIZE];
union partialy_freelists_list {
struct partialy_freelist* partialy_freelists[KMALLOC_MAX_SIZE];
struct {
void** kmalloc_8;
void** kmalloc_16;
void** kmalloc_32;
void** kmalloc_64;
void** kmalloc_128;
void** kmalloc_256;
void** kmalloc_512;
void** kmalloc_1024;
void** kmalloc_2048;
void** kmalloc_4096;
void** kmalloc_8192;
void** kmalloc_16384;
void** kmalloc_32768;
void** kmalloc_65536;
void** kmalloc_131072;
struct partialy_freelist* kmalloc_8;
struct partialy_freelist* kmalloc_16;
struct partialy_freelist* kmalloc_32;
struct partialy_freelist* kmalloc_64;
struct partialy_freelist* kmalloc_128;
struct partialy_freelist* kmalloc_256;
struct partialy_freelist* kmalloc_512;
struct partialy_freelist* kmalloc_1024;
struct partialy_freelist* kmalloc_2048;
struct partialy_freelist* kmalloc_4096;
struct partialy_freelist* kmalloc_8192;
struct partialy_freelist* kmalloc_16384;
struct partialy_freelist* kmalloc_32768;
struct partialy_freelist* kmalloc_65536;
struct partialy_freelist* kmalloc_131072;
};
};
+27 -1
View File
@@ -1,5 +1,31 @@
#ifndef _LIMIT_H
#define _LIMIT_H
#define CHAR_BIT 8
#endif
#define INT8_WIDTH 8
#define INT16_WIDTH 16
#define INT32_WIDTH 32
#define INT64_WIDTH 64
#define UINT8_WIDTH 8
#define UINT16_WIDTH 16
#define UINT32_WIDTH 32
#define UINT64_WIDTH 64
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1LL)
#define UINT8_MAX 255U
#define UINT16_MAX 65535U
#define UINT32_MAX 4294967295U
#define UINT64_MAX 18446744073709551615ULL
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef _RANDOM_H
#define _RANDOM_H
#include <types.h>
void rand_init();
extern uint64_t (*get_random_number)();
#endif
+10
View File
@@ -2,6 +2,7 @@
#include <kernel.h>
#include <paging.h>
#include <serial.h>
#include <random.h>
#include <splash.h>
#include <system.h>
#include <gdt.h>
@@ -32,6 +33,15 @@ void _start(void) {
if ((err = pmm_init()) < 0) panic(NULL, "Failed to initalize Physical Memory Manager. (%d)", err);
if ((err = pag_init()) < 0) panic(NULL, "Failed to initalize Paging. (%d)", err);
// random number generation
rand_init();
// test random number generation
printk("Random number generation test:\n");
for (uint8_t i = 0; i <= 16; i++) {
printk("%d: %lu\n",i,get_random_number());
}
// The most important function in the world.
splash();
+57 -6
View File
@@ -6,7 +6,8 @@
// this file contains SLUB inspired HEAP allocator
// TODO this will be an allocated array later when we have APIC MADT
union per_cpu_freelist_cache freelists_all_cpus[1];
union freelists_list freelists_all_cpus[1];
union partialy_freelists_list partial_free_lists[1];
void* kcalloc(size_t count, size_t size) {
size_t size_to_alloc;
@@ -54,26 +55,76 @@ void* kmalloc(size_t size) {
size_t alloc_index;
{
uint8_t leading_zeros = __builtin_clzll(size);
if (__builtin_popcountll(size) == 1) {
if (/*__builtin_popcountll(size) == */1) {
alloc_index = leading_zeros;
} else {
alloc_index = sizeof(size) * CHAR_BIT - leading_zeros;
}
if (alloc_index > KMALLOC_MAX_SIZE) {
// NOT IMPLEMENTED
printk("Cannot allocate [%lu] bytes: \e[1MNOT "
"IMPLEMENTED!\e[8M\n",
printk("Cannot allocate [%lu] bytes: \e[1mNOT "
"IMPLEMENTED!\e[0m\n",
size);
return NULL;
}
alloc_index -= LOWEST_POWER;
}
void** selected_freelist =
struct freelist* selected_freelist =
freelists_all_cpus[core_id].freelists[alloc_index];
if (selected_freelist != NULL) {
// fast path
void** second_item_in_list = *selected_freelist;
if (selected_freelist->nextnode == NULL) {
freelists_all_cpus[core_id].freelists[alloc_index] =
NULL;
} else {
freelists_all_cpus[core_id].freelists[alloc_index] =
selected_freelist->nextnode;
}
return selected_freelist;
} else {
// slower path
if (partial_free_lists[core_id]
.partialy_freelists[alloc_index] != NULL) {
// partialy freelist available
struct partialy_freelist* selected_partialy_freelist =
partial_free_lists[core_id]
.partialy_freelists[alloc_index];
if (selected_partialy_freelist->freelist_nextnode ==
NULL) {
// only one free object available
if (selected_partialy_freelist
->partialy_freelist_nextnode != NULL) {
// next partialy free list available
partial_free_lists[core_id]
.partialy_freelists[alloc_index] =
selected_partialy_freelist
->partialy_freelist_nextnode;
} else {
// no other partialy free list available
partial_free_lists[core_id]
.partialy_freelists[alloc_index] =
NULL;
}
} else {
// multiple free objects available
partial_free_lists[core_id]
.partialy_freelists[alloc_index] =
selected_partialy_freelist
->partialy_freelist_nextnode;
freelists_all_cpus[core_id]
.freelists[alloc_index] =
selected_partialy_freelist
->freelist_nextnode;
}
return selected_partialy_freelist;
} else {
// slowest path
}
}
}
+52
View File
@@ -0,0 +1,52 @@
#include "kernel.h"
#include <system.h>
#include <types.h>
uint64_t (*get_random_number)();
// this starting value it truly random i have thrown a dice few times
uint64_t LFSR = 61113534451;
// RDSEED may be backdoored by NSA
extern uint64_t rand_rdrand();
asm(".intel_syntax noprefix\n"
".global rand_rdrand\n"
"rand_rdrand:"
" rdrand rax\n"
" ret\n"
".att_syntax prefix\n");
uint64_t rand_software() {
uint64_t lsb = LFSR & 1;
LFSR >>= 1;
if (lsb) {
LFSR ^= 0x800000000000000DULL;
}
return LFSR;
}
void rand_init() {
uint32_t eax = 1, ebx = 0, ecx = 0, edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
// check for RDRAND
if ((ecx >> 30) & 1) {
get_random_number = rand_rdrand;
} else {
printk("[\e[33mWARNING\e[0m] RDRAND not available falling back "
"to software\n");
// check for RDSEED
if ((ebx >> 18) & 1) {
asm(".intel_syntax noprefix\n"
"rdseed %0\n"
".att_syntax prefix\n"
: "=r"(LFSR));
} else {
printk("[\e[\e[33mWARNING\e[0m] RDSEED not available "
"falling back "
"to developers dice trows\n");
}
get_random_number = rand_software;
}
printk("[\e[32mINFO\e[0m] RNG initialized!\n");
}
+49
View File
@@ -0,0 +1,49 @@
#include "kernel.h"
#include <errno.h>
#include <isr.h>
#include <limits.h>
#include <paging.h>
#include <pmm.h>
#include <types.h>
// allocates set number of pages at address provided
// if address is NULL address is chosen internaly
int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags) {
if (flags == 0) {
flags = PTE_FLAG_PRESENT | PTE_FLAG_WRITE | PTE_FLAG_NOEXEC;
}
uint64_t* pml4 = pag_get_pml4();
for (uint64_t i = 0; i < count; i++) {
uint64_t* pte = pag_get_pte(pml4, vaddr);
if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) {
// TODO actualy handle conflict
return EEXIST;
}
}
for (uint64_t i = 0; i < count; i++) {
void* paddr = pmm_alloc();
int pag_map_ret =
pag_map(pml4, (void*)(((size_t)vaddr) * i * PAGE_SIZE),
paddr, flags);
if (pag_map_ret != SUCCESS) {
if (i != 0) {
for (i -= 1; i != UINT64_MAX; i--) {
if (pag_unmap(pml4,
(void*)(((size_t)vaddr) *
i * PAGE_SIZE)) !=
SUCCESS) {
panic(NULL,
"failed to unmap "
"previously mapped "
"page. %s:%d",
__FILE_NAME__, __LINE__);
}
}
}
return pag_map_ret;
}
}
return SUCCESS;
}