forked from PoliEcho-holding-org/kern
Compare commits
9
Commits
675ff8519a
...
318fe96319
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
318fe96319 | ||
|
|
b0ab02c634 | ||
|
|
a95839c7c6 | ||
|
|
3fe3d05b1b | ||
|
|
700b1ec4b4 | ||
|
|
07bd738566 | ||
|
|
16fde28a8b | ||
|
|
7c0ac01110 | ||
|
|
b917ebe973 |
+18
-17
@@ -13,23 +13,24 @@
|
|||||||
// TODO: Add correct errno.h numbers
|
// TODO: Add correct errno.h numbers
|
||||||
enum {
|
enum {
|
||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
ENOMEM, // Cannot allocate memory
|
ENOMEM, // Cannot allocate memory
|
||||||
EPERM, // Operation not permitted
|
EPERM, // Operation not permitted
|
||||||
ENOENT, // No entry (no such file or directory)
|
ENOENT, // No entry (no such file or directory)
|
||||||
EIO, // Input/Output error
|
EIO, // Input/Output error
|
||||||
ENXIO, // No such device or address
|
ENXIO, // No such device or address
|
||||||
EAGAIN, // Resource temporarly busy
|
EAGAIN, // Resource temporarly busy
|
||||||
EACCES, // Permission denied
|
EACCES, // Permission denied
|
||||||
EFAULT, // Bad address
|
EFAULT, // Bad address
|
||||||
ENODEV, // No such device
|
ENODEV, // No such device
|
||||||
EINVAL, // Invalid argument
|
EINVAL, // Invalid argument
|
||||||
EDOM, // Numerical argument out of domain
|
EDOM, // Numerical argument out of domain
|
||||||
ERANGE, // Numerical result out of range
|
ERANGE, // Numerical result out of range
|
||||||
ENOSYS, // Function not implemented
|
ENOSYS, // Function not implemented
|
||||||
ENOTSUP, // Not supported
|
ENOTSUP, // Not supported
|
||||||
EILLSEQ, // Illegal byte sequence
|
EILLSEQ, // Illegal byte sequence
|
||||||
EOVERFLOW, //
|
EOVERFLOW, //
|
||||||
EALIGN, // Not aligned
|
EALIGN, // Not aligned
|
||||||
|
EEXIST, // already exists
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+43
-34
@@ -19,45 +19,54 @@ void* kcalloc(size_t count, size_t size);
|
|||||||
#define KMALLOC_MAX_SIZE 17
|
#define KMALLOC_MAX_SIZE 17
|
||||||
#define LOWEST_POWER 3
|
#define LOWEST_POWER 3
|
||||||
|
|
||||||
union per_cpu_freelist_cache {
|
struct freelist {
|
||||||
void** freelists[KMALLOC_MAX_SIZE];
|
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 {
|
struct {
|
||||||
void** kmalloc_8;
|
struct freelist* kmalloc_8;
|
||||||
void** kmalloc_16;
|
struct freelist* kmalloc_16;
|
||||||
void** kmalloc_32;
|
struct freelist* kmalloc_32;
|
||||||
void** kmalloc_64;
|
struct freelist* kmalloc_64;
|
||||||
void** kmalloc_128;
|
struct freelist* kmalloc_128;
|
||||||
void** kmalloc_256;
|
struct freelist* kmalloc_256;
|
||||||
void** kmalloc_512;
|
struct freelist* kmalloc_512;
|
||||||
void** kmalloc_1024;
|
struct freelist* kmalloc_1024;
|
||||||
void** kmalloc_2048;
|
struct freelist* kmalloc_2048;
|
||||||
void** kmalloc_4096;
|
struct freelist* kmalloc_4096;
|
||||||
void** kmalloc_8192;
|
struct freelist* kmalloc_8192;
|
||||||
void** kmalloc_16384;
|
struct freelist* kmalloc_16384;
|
||||||
void** kmalloc_32768;
|
struct freelist* kmalloc_32768;
|
||||||
void** kmalloc_65536;
|
struct freelist* kmalloc_65536;
|
||||||
void** kmalloc_131072;
|
struct freelist* kmalloc_131072;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
union partial_list {
|
union partialy_freelists_list {
|
||||||
void** freelists[KMALLOC_MAX_SIZE];
|
struct partialy_freelist* partialy_freelists[KMALLOC_MAX_SIZE];
|
||||||
struct {
|
struct {
|
||||||
void** kmalloc_8;
|
struct partialy_freelist* kmalloc_8;
|
||||||
void** kmalloc_16;
|
struct partialy_freelist* kmalloc_16;
|
||||||
void** kmalloc_32;
|
struct partialy_freelist* kmalloc_32;
|
||||||
void** kmalloc_64;
|
struct partialy_freelist* kmalloc_64;
|
||||||
void** kmalloc_128;
|
struct partialy_freelist* kmalloc_128;
|
||||||
void** kmalloc_256;
|
struct partialy_freelist* kmalloc_256;
|
||||||
void** kmalloc_512;
|
struct partialy_freelist* kmalloc_512;
|
||||||
void** kmalloc_1024;
|
struct partialy_freelist* kmalloc_1024;
|
||||||
void** kmalloc_2048;
|
struct partialy_freelist* kmalloc_2048;
|
||||||
void** kmalloc_4096;
|
struct partialy_freelist* kmalloc_4096;
|
||||||
void** kmalloc_8192;
|
struct partialy_freelist* kmalloc_8192;
|
||||||
void** kmalloc_16384;
|
struct partialy_freelist* kmalloc_16384;
|
||||||
void** kmalloc_32768;
|
struct partialy_freelist* kmalloc_32768;
|
||||||
void** kmalloc_65536;
|
struct partialy_freelist* kmalloc_65536;
|
||||||
void** kmalloc_131072;
|
struct partialy_freelist* kmalloc_131072;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
#ifndef _LIMIT_H
|
#ifndef _LIMIT_H
|
||||||
#define _LIMIT_H
|
#define _LIMIT_H
|
||||||
|
|
||||||
#define CHAR_BIT 8
|
#define CHAR_BIT 8
|
||||||
|
|
||||||
|
#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
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _RANDOM_H
|
||||||
|
#define _RANDOM_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
void rand_init();
|
||||||
|
|
||||||
|
extern uint64_t (*get_random_number)();
|
||||||
|
#endif
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <paging.h>
|
#include <paging.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
#include <random.h>
|
||||||
#include <splash.h>
|
#include <splash.h>
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include <gdt.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 = 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);
|
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.
|
// The most important function in the world.
|
||||||
splash();
|
splash();
|
||||||
|
|
||||||
|
|||||||
+57
-6
@@ -6,7 +6,8 @@
|
|||||||
// this file contains SLUB inspired HEAP allocator
|
// this file contains SLUB inspired HEAP allocator
|
||||||
|
|
||||||
// TODO this will be an allocated array later when we have APIC MADT
|
// 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) {
|
void* kcalloc(size_t count, size_t size) {
|
||||||
size_t size_to_alloc;
|
size_t size_to_alloc;
|
||||||
@@ -54,26 +55,76 @@ void* kmalloc(size_t size) {
|
|||||||
size_t alloc_index;
|
size_t alloc_index;
|
||||||
{
|
{
|
||||||
uint8_t leading_zeros = __builtin_clzll(size);
|
uint8_t leading_zeros = __builtin_clzll(size);
|
||||||
if (__builtin_popcountll(size) == 1) {
|
if (/*__builtin_popcountll(size) == */1) {
|
||||||
alloc_index = leading_zeros;
|
alloc_index = leading_zeros;
|
||||||
} else {
|
} else {
|
||||||
alloc_index = sizeof(size) * CHAR_BIT - leading_zeros;
|
alloc_index = sizeof(size) * CHAR_BIT - leading_zeros;
|
||||||
}
|
}
|
||||||
if (alloc_index > KMALLOC_MAX_SIZE) {
|
if (alloc_index > KMALLOC_MAX_SIZE) {
|
||||||
// NOT IMPLEMENTED
|
// NOT IMPLEMENTED
|
||||||
printk("Cannot allocate [%lu] bytes: \e[1MNOT "
|
printk("Cannot allocate [%lu] bytes: \e[1mNOT "
|
||||||
"IMPLEMENTED!\e[8M\n",
|
"IMPLEMENTED!\e[0m\n",
|
||||||
size);
|
size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
alloc_index -= LOWEST_POWER;
|
alloc_index -= LOWEST_POWER;
|
||||||
}
|
}
|
||||||
void** selected_freelist =
|
struct freelist* selected_freelist =
|
||||||
freelists_all_cpus[core_id].freelists[alloc_index];
|
freelists_all_cpus[core_id].freelists[alloc_index];
|
||||||
if (selected_freelist != NULL) {
|
if (selected_freelist != NULL) {
|
||||||
// fast path
|
// 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 {
|
} else {
|
||||||
// slower path
|
// 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user