mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-04 10:33:12 +00:00
Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffa23b1dba | ||
|
|
6c609e9840 | ||
|
|
318fe96319 | ||
|
|
b0ab02c634 | ||
|
|
a95839c7c6 | ||
|
|
3fe3d05b1b | ||
|
|
700b1ec4b4 | ||
|
|
07bd738566 | ||
|
|
16fde28a8b | ||
|
|
7c0ac01110 | ||
|
|
b917ebe973 | ||
|
|
675ff8519a | ||
|
|
8ab7e5a33d | ||
|
|
eba8b5ad4f | ||
|
|
ce75e8c195 | ||
|
|
9bdc3c8fc9 | ||
|
|
8909e3c4ca | ||
|
|
70114f6326 |
+4
-4
@@ -79,7 +79,7 @@ AllowShortCaseLabelsOnASingleLine: false
|
|||||||
AllowShortCompoundRequirementOnASingleLine: true
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
AllowShortEnumsOnASingleLine: true
|
AllowShortEnumsOnASingleLine: true
|
||||||
AllowShortFunctionsOnASingleLine: All
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||||
AllowShortLambdasOnASingleLine: All
|
AllowShortLambdasOnASingleLine: All
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AllowShortNamespacesOnASingleLine: false
|
AllowShortNamespacesOnASingleLine: false
|
||||||
@@ -171,7 +171,7 @@ IndentExternBlock: AfterExternBlock
|
|||||||
IndentGotoLabels: true
|
IndentGotoLabels: true
|
||||||
IndentPPDirectives: None
|
IndentPPDirectives: None
|
||||||
IndentRequiresClause: true
|
IndentRequiresClause: true
|
||||||
IndentWidth: 2
|
IndentWidth: 8
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
InsertBraces: false
|
InsertBraces: false
|
||||||
InsertNewlineAtEOF: false
|
InsertNewlineAtEOF: false
|
||||||
@@ -216,7 +216,7 @@ PenaltyBreakTemplateDeclaration: 10
|
|||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyIndentedWhitespace: 0
|
PenaltyIndentedWhitespace: 0
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Right
|
PointerAlignment: Left
|
||||||
PPIndentWidth: -1
|
PPIndentWidth: -1
|
||||||
QualifierAlignment: Leave
|
QualifierAlignment: Leave
|
||||||
ReferenceAlignment: Pointer
|
ReferenceAlignment: Pointer
|
||||||
@@ -284,7 +284,7 @@ StatementMacros:
|
|||||||
- QT_REQUIRE_VERSION
|
- QT_REQUIRE_VERSION
|
||||||
TableGenBreakInsideDAGArg: DontBreak
|
TableGenBreakInsideDAGArg: DontBreak
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
UseTab: Never
|
UseTab: Always
|
||||||
VerilogBreakBetweenInstancePorts: true
|
VerilogBreakBetweenInstancePorts: true
|
||||||
WhitespaceSensitiveMacros:
|
WhitespaceSensitiveMacros:
|
||||||
- BOOST_PP_STRINGIZE
|
- BOOST_PP_STRINGIZE
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Low-Level Hardware & Interrupts
|
|||||||
Memory Management
|
Memory Management
|
||||||
[x] Physical memory manager (Bitmap or Buddy)
|
[x] Physical memory manager (Bitmap or Buddy)
|
||||||
[x] Paging (Recursive or Offset mapping)
|
[x] Paging (Recursive or Offset mapping)
|
||||||
[ ] Kernel heap (kmalloc/kfree - Linked list or Slab)
|
[-] Kernel heap (kmalloc/kfree - Linked list or Slab)
|
||||||
[ ] Memory mapped I/O (MMIO) API for drivers
|
[ ] Memory mapped I/O (MMIO) API for drivers
|
||||||
[ ] VMM: Shared memory regions (For IPC/Framebuffers)
|
[ ] VMM: Shared memory regions (For IPC/Framebuffers)
|
||||||
[ ] VMM: Copy-on-Write (COW) support (Optional but good)
|
[ ] VMM: Copy-on-Write (COW) support (Optional but good)
|
||||||
|
|||||||
@@ -48,3 +48,19 @@ A pointer to allocated memory or NULL.
|
|||||||
**Parameters**
|
**Parameters**
|
||||||
* `size_t count` -
|
* `size_t count` -
|
||||||
|
|
||||||
|
**Description**
|
||||||
|
This function allocates memory for `count` elements each of `size` bytes, zeroed-out memory.
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
A pointer to allocated memory or NULL.
|
||||||
|
|
||||||
|
`void* kfree(void* p)`
|
||||||
|
******************************************
|
||||||
|
**Parameters**
|
||||||
|
* `void* p` -
|
||||||
|
|
||||||
|
**Description**
|
||||||
|
This function frees memory previously allocated using `k[m,z,c]alloc()`
|
||||||
|
|
||||||
|
**Returns**
|
||||||
|
Nothing
|
||||||
@@ -30,6 +30,7 @@ enum {
|
|||||||
EILLSEQ, // Illegal byte sequence
|
EILLSEQ, // Illegal byte sequence
|
||||||
EOVERFLOW, //
|
EOVERFLOW, //
|
||||||
EALIGN, // Not aligned
|
EALIGN, // Not aligned
|
||||||
|
EEXIST, // already exists
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#ifndef _KMALLOC_H
|
||||||
|
#define _KMALLOC_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
// This function allocates size bytes of contiguous memory.
|
||||||
|
// Returns a pointer to allocated memory or NULL.
|
||||||
|
void* kmalloc(size_t size);
|
||||||
|
|
||||||
|
// This function allocates size bytes of contiguous, zeroed-out memory.
|
||||||
|
// Returns a pointer to allocated memory or NULL.
|
||||||
|
void* kzalloc(size_t size);
|
||||||
|
|
||||||
|
// This function allocates memory for count elements each of size bytes,
|
||||||
|
// zeroed-out memory. Returns a pointer to allocated memory or NULL.
|
||||||
|
void* kcalloc(size_t count, size_t size);
|
||||||
|
|
||||||
|
// powers of 2
|
||||||
|
#define KMALLOC_MAX_SIZE 17
|
||||||
|
#define LOWEST_POWER 3
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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 partialy_freelists_list {
|
||||||
|
struct partialy_freelist* partialy_freelists[KMALLOC_MAX_SIZE];
|
||||||
|
struct {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef _LIMIT_H
|
||||||
|
#define _LIMIT_H
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _RANDOM_H
|
||||||
|
#define _RANDOM_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
void rand_init();
|
||||||
|
|
||||||
|
extern uint64_t (*get_random_number)();
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef _VMM_H
|
||||||
|
#define _VMM_H
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define CANONICAL_MASK_KERNEL 0xFFFF800000000000
|
||||||
|
#define CANONICAL_MASK_USER 0x00007FFFFFFFFFF000
|
||||||
|
|
||||||
|
int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags);
|
||||||
|
#endif
|
||||||
+34
-15
@@ -1,22 +1,28 @@
|
|||||||
|
#include "errno.h"
|
||||||
|
#include "types.h"
|
||||||
#include <bootloader.h>
|
#include <bootloader.h>
|
||||||
#include <kernel.h>
|
|
||||||
#include <paging.h>
|
|
||||||
#include <serial.h>
|
|
||||||
#include <splash.h>
|
|
||||||
#include <system.h>
|
|
||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
#include <isr.h>
|
#include <isr.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <paging.h>
|
||||||
#include <pmm.h>
|
#include <pmm.h>
|
||||||
|
#include <random.h>
|
||||||
|
#include <serial.h>
|
||||||
|
#include <splash.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <system.h>
|
||||||
|
#include <vmm.h>
|
||||||
|
|
||||||
__noreturn
|
__noreturn void _start(void) {
|
||||||
void _start(void) {
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
// Serial console for debugging
|
// Serial console for debugging
|
||||||
if ((err = serial_init(COM1)) < 0) panic(NULL, "Failed to initialize Serial driver. (%d)", err);
|
if ((err = serial_init(COM1)) < 0)
|
||||||
|
panic(NULL, "Failed to initialize Serial driver. (%d)", err);
|
||||||
|
|
||||||
// Load structures from bootloader
|
// Load structures from bootloader
|
||||||
if ((err = boot_init()) < 0) panic(NULL, "Failed to parse bootloader structures. (%d)", err);
|
if ((err = boot_init()) < 0)
|
||||||
|
panic(NULL, "Failed to parse bootloader structures. (%d)", err);
|
||||||
|
|
||||||
// CPUID thingy :p
|
// CPUID thingy :p
|
||||||
uint32_t eax = 0;
|
uint32_t eax = 0;
|
||||||
@@ -25,17 +31,30 @@ void _start(void) {
|
|||||||
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
pr_info("[kernel] CPUID_GETVENDORID: %s\n", s);
|
||||||
|
|
||||||
// System init
|
// System init
|
||||||
if ((err = gdt_init()) < 0) panic(NULL, "Failed to initalize GDT. (%d)", err);
|
if ((err = gdt_init()) < 0)
|
||||||
if ((err = isr_init()) < 0) panic(NULL, "Failed to initalize ISRs. (%d)", err);
|
panic(NULL, "Failed to initalize GDT. (%d)", err);
|
||||||
|
if ((err = isr_init()) < 0)
|
||||||
|
panic(NULL, "Failed to initalize ISRs. (%d)", err);
|
||||||
|
|
||||||
// Memory management
|
// Memory management
|
||||||
if ((err = pmm_init()) < 0) panic(NULL, "Failed to initalize Physical Memory Manager. (%d)", err);
|
if ((err = pmm_init()) < 0)
|
||||||
if ((err = pag_init()) < 0) panic(NULL, "Failed to initalize Paging. (%d)", err);
|
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.
|
// The most important function in the world.
|
||||||
splash();
|
splash();
|
||||||
|
|
||||||
// Patiently wait for things to do :)
|
// Patiently wait for things to do :)
|
||||||
while (1);
|
while (1)
|
||||||
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
#include "kernel.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include <kmalloc.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
// this file contains SLUB inspired HEAP allocator
|
||||||
|
|
||||||
|
// TODO this will be an allocated array later when we have APIC MADT
|
||||||
|
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;
|
||||||
|
__asm__ volatile goto(".intel_syntax noprefix\n\t"
|
||||||
|
"mov rax, %1\n\t"
|
||||||
|
"mov rdx, %2\n\t"
|
||||||
|
"mul rdx\n\t"
|
||||||
|
"jo %l[overflow]\n\t"
|
||||||
|
"mov %0, rax\n\t"
|
||||||
|
".att_syntax prefix\n\t"
|
||||||
|
: "=r"(size_to_alloc)
|
||||||
|
: "r"(count), "r"(size)
|
||||||
|
: "rax", "rdx", "cc"
|
||||||
|
: overflow);
|
||||||
|
return kzalloc(size_to_alloc);
|
||||||
|
|
||||||
|
overflow:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* kzalloc(size_t size) {
|
||||||
|
void* allocated = kmalloc(size);
|
||||||
|
if (!allocated) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(allocated, 0, size);
|
||||||
|
return allocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* kmalloc(size_t size) {
|
||||||
|
if (!size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uint32_t core_id;
|
||||||
|
__asm__ volatile(
|
||||||
|
"rdtscp"
|
||||||
|
: "=c"(core_id) // Core ID from IA32_TSC_AUX is placed in ECX
|
||||||
|
:
|
||||||
|
: "eax", "edx");
|
||||||
|
|
||||||
|
// freelists_all_cpus[core_id];
|
||||||
|
// TODO disable when we actualy know how many CPUs we have
|
||||||
|
core_id = 0;
|
||||||
|
|
||||||
|
size_t alloc_index;
|
||||||
|
{
|
||||||
|
uint8_t leading_zeros = __builtin_clzll(size);
|
||||||
|
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[0m\n",
|
||||||
|
size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
alloc_index -= LOWEST_POWER;
|
||||||
|
}
|
||||||
|
struct freelist* selected_freelist =
|
||||||
|
freelists_all_cpus[core_id].freelists[alloc_index];
|
||||||
|
if (selected_freelist != NULL) {
|
||||||
|
// fast path
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,89 @@
|
|||||||
|
#include "vmm.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <isr.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <paging.h>
|
||||||
|
#include <pmm.h>
|
||||||
|
#include <random.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;
|
||||||
|
}
|
||||||
|
bool random_vaddr = *vaddr ? false : true;
|
||||||
|
|
||||||
|
uint64_t* pml4 = pag_get_pml4();
|
||||||
|
{
|
||||||
|
uint8_t limit_counter = 0;
|
||||||
|
while (true) {
|
||||||
|
if (random_vaddr) {
|
||||||
|
retry_selection:
|
||||||
|
*vaddr = (void*)ALIGN_DOWN(get_random_number(),
|
||||||
|
PAGE_SIZE);
|
||||||
|
|
||||||
|
*vaddr = (void*)((uint64_t)(*vaddr) &
|
||||||
|
CANONICAL_MASK_USER);
|
||||||
|
if (!(flags & PTE_FLAG_USER)) {
|
||||||
|
*vaddr = (void*)((uint64_t)(*vaddr) |
|
||||||
|
CANONICAL_MASK_KERNEL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (flags & PTE_FLAG_USER) {
|
||||||
|
if ((void*)((uint64_t)(*vaddr) &
|
||||||
|
CANONICAL_MASK_KERNEL)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!((void*)((uint64_t)(*vaddr) &
|
||||||
|
CANONICAL_MASK_KERNEL))) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
uint64_t* pte =
|
||||||
|
pag_get_pte(pml4, *vaddr + (i * PAGE_SIZE));
|
||||||
|
if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) {
|
||||||
|
if (!random_vaddr) {
|
||||||
|
return -EEXIST;
|
||||||
|
} else {
|
||||||
|
if (limit_counter < UINT8_MAX) {
|
||||||
|
goto retry_selection;
|
||||||
|
} else {
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < count; i++) {
|
||||||
|
void* paddr = pmm_alloc();
|
||||||
|
int pag_map_ret =
|
||||||
|
pag_map(pml4, *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,
|
||||||
|
*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