Espresso 0.0.2c

This commit is contained in:
2026-03-20 16:57:08 -05:00
parent 021fdbbcef
commit 5971218b56
77 changed files with 4538 additions and 518 deletions

58
lib/espresso/kstring.c Normal file
View File

@ -0,0 +1,58 @@
#include <stdlib.h>
#include <types.h>
#include <string.h>
/*
A custom standard for strings for use in the Espresso kernel.
*/
struct kstring {
size_t s_len;
char* data; /* NOT null-terminated */
};
/*
if the length of initial_data is more than initial_len, only initial_len bytes will be copied.
if the length of initial_data is less then initial_len, the rest of the bytes are zeroed.
if initial_data is null, no data is copied and the string in set to zero.
*/
struct kstring* make_kstring(size_t initial_len, const char* initial_data)
{
struct kstring* str = malloc(sizeof(struct kstring));
if (!str)
{
return NULL;
}
str->s_len = initial_len;
str->data = malloc(initial_len);
if (!str->data)
{
return NULL;
}
memset(str->data, 0, initial_len);
if (initial_data)
{
size_t slen = strlen(initial_data);
if (slen < initial_len)
{
strncpy(str->data, initial_data, slen);
}
else if (slen > initial_len)
{
strncpy(str->data, initial_data, initial_len);
}
else
{
strcpy(str->data, initial_data);
}
}
return str;
}

79
lib/math/random.c Normal file
View File

@ -0,0 +1,79 @@
#include <types.h>
#include <math/random.h>
/*
This code uses Xorshift (high speed, small) and PCG (Permuted Congruential Generator).
PCG may or may not be slightly slower than Xorshift.
*/
static uint32_t xorshift_state = 2463534242;
static void srand_xorshift(uint32_t seed)
{
xorshift_state = seed;
}
static inline uint32_t rand_xorshift(void)
{
uint32_t x = xorshift_state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return xorshift_state = x;
}
static uint64_t state = 0x853c49e6748fea9bULL;
static uint64_t inc = 0xda3e39cb94b95bdbULL;
static inline uint32_t rand_pcg32(void)
{
uint64_t oldstate = state;
state = oldstate * 6364136223846793005ULL + (inc | 1);
uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}
void seed_rand(uint32_t seed)
{
srand_xorshift(seed);
state = seed * 6364136223846793005ULL + (seed | 1);
}
uint32_t uirand(void)
{
return rand_pcg32() ^ rand_xorshift();
}
/* get a number between 0 and max-1 */
uint32_t uirand_range(uint32_t max)
{
if (max == 0)
{
return 0;
}
return uirand() % max;
}
uint64_t ulrand(void)
{
uint64_t hi = uirand();
uint64_t lo = uirand();
return (hi << 32) | lo;
}
/* get a number between 0 and max-1 */
uint64_t ulrand_range(uint64_t max)
{
if (max == 0)
{
return 0;
}
return ulrand() % max;
}

View File

@ -111,7 +111,12 @@ void free(void* ptr)
block_t* curr = free_list;
while (curr && curr->next)
{
if (curr->free && curr->next->free)
/*if (curr->free && curr->next->free)
{
curr->size += BLOCK_SIZE + curr->next->size;
curr->next = curr->next->next;
}*/
if (curr->free && curr->next->free && (uint8_t*)curr + BLOCK_SIZE + curr->size == (uint8_t*)curr->next)
{
curr->size += BLOCK_SIZE + curr->next->size;
curr->next = curr->next->next;

View File

@ -12,6 +12,10 @@ static size_t total_pages;
#define BITMAP_CLEAR(i) (bitmap[(i) / 8] &= ~(1 << ((i) % 8)))
#define BITMAP_TEST(i) (bitmap[(i) / 8] & (1 << ((i) % 8)))
extern uint32_t __kernel_start;
extern uint32_t __kernel_end;
void pmm_init(multiboot_info_t* mb)
{
#ifdef _DEBUG
@ -45,6 +49,18 @@ void pmm_init(multiboot_info_t* mb)
}
}
total_pages = MAX_PAGES;
uintptr_t start = (uintptr_t)&__kernel_start;
uintptr_t end = (uintptr_t)&__kernel_end;
start &= ~0xFFF;
end = (end + 0xFFF) & ~0xFFF;
for (uintptr_t addr = start; addr < end; addr += 0x1000)
{
size_t idx = addr / 0x1000;
BITMAP_SET(idx); // Mark kernel pages as USED
}
#ifdef _DEBUG
printf("[ PMM ] Physical memory manager initialized\n");
@ -55,6 +71,14 @@ void* pmm_alloc_page(void)
{
for (uint32_t i = 0; i < total_pages; ++i)
{
void* page = (void*)(i * 4096);
if ((uintptr_t)page >= (uintptr_t)&__kernel_start &&
(uintptr_t)page < (uintptr_t)&__kernel_end)
{
printf("PMM allocating inside kernel at %x\n", page);
}
if (!BITMAP_TEST(i))
{
BITMAP_SET(i);

View File

@ -4,6 +4,8 @@
#include <stdint.h>
#include <drivers/serio.h>
#include <tty.h>
#include <printf.h>
static uint8_t color = 0xFF;

View File

@ -3,13 +3,18 @@
#include <processes.h>
int32_t next_id = 9; /* 0 through 8 are reserved for kernel operations */
pid_t next_id = 1; /* start at 1 */
int32_t make_process(char* name, char* group, elf_executable_t* exe)
pid_t make_process(char* name, char* group, elf_executable_t* exe)
{
pid_t ret = (pid_t) 0;
if (!name || !group || !exe)
{
return -1;
return ret; /* ret is already zero */
}
return 0;
next_id++;
return ret;
}

76
lib/scheduler.c Normal file
View File

@ -0,0 +1,76 @@
#include <stdlib.h>
#include <string.h>
#include <drivers/irq.h>
#include <scheduler.h>
#define STACK_SIZE (8192)
task_t* current_task = NULL;
task_t* task_list = NULL;
uint32_t next_pid = 1;
void init_scheduler(void)
{
set_irq_handler(0, (irq_func_t) schedule);
}
void scheduler(registers_t* boot_regs)
{
task_t* task = malloc(sizeof(task_t));
task->id = next_pid++;
task->regs = boot_regs;
task->next = task;
task_list = task;
current_task = task;
}
registers_t* schedule(registers_t* regs)
{
if (!current_task)
{
return regs;
}
current_task->regs = regs;
current_task = current_task->next;
return current_task->regs;
}
task_t* create_task(void (*entry)())
{
task_t* task = malloc(sizeof(task_t));
uint32_t* stack = malloc(STACK_SIZE);
uint32_t stack_top = (uint32_t)stack + 4096;
stack_top -= sizeof(registers_t);
registers_t* regs = (registers_t*)stack_top;
memset(regs, 0, sizeof(registers_t));
regs->eip = (uint32_t) entry;
regs->cs = 0x08; /* kernel code */
regs->ds = 0x10;
regs->es = 0x10;
regs->fs = 0x10;
regs->gs = 0x10;
regs->eflags = 0x202; /* IF = 1 */
task->id = next_pid++;
task->regs = regs;
/* insert into circular list */
task->next = task_list->next;
task_list->next = task;
return task;
}

View File

@ -2,8 +2,45 @@
#include <stdlib.h>
#include <string.h>
#include <kernel/syscall.h>
#include <tty.h>
#include <new_tty.h>
#include <stdio.h>
int write(uint32_t fd, void* data, size_t len)
{
if (fd == STDOUT)
{
print_uint((uint32_t) len);
terminal_write((char*) data, len);
}
else
{
return -1;
}
return 0;
}
int read(uint32_t fd, void* data, size_t max_len)
{
int rv = 0;
if (fd == STDIN)
{
char* sptr = (char*) data; /* this really shouldn't be needed... */
sptr = gets_new(&rv);
}
else
{
return -1;
}
return rv;
}
extern bool ps2keyboard_initialized;
char getchar(void)
@ -31,40 +68,33 @@ char* gets(void)
return kbd_gets();
}
/*char* fgets(char* buf, int n, FILE file)
char* gets_new(int* num)
{
if (!buf || n <= 1 || file < 1)
char* __s = malloc(256);
memset(__s, 0, 256);
ssize_t n = tty_read_active(__s, 255);
*num = (int) n;
return __s;
}
int getstr(char* dest)
{
int i = 0;
char* p = gets_new(&i);
if (i != 0)
{
return NULL;
return -1;
}
int total_read = 0;
char c;
strcpy(dest, p);
}
while (total_read < n - 1)
{
int bytes = 0*//*read_file(file, &c, 1)*/;
/*if (bytes <= 0)
{
break; *//* EOF or error */
/*}
buf[total_read++] = c;
if (c == '\n')
{
break; *//* Stop at newline */
/*}
}
if (total_read == 0)
{
return NULL; *//* Nothing read (e.g. EOF) */
/*}
buf[total_read] = '\0';
return buf;
}*/
void putc(char c)
{
syscall1(SYS_TERMINAL_PUTCHAR, c);
}

View File

@ -1,10 +1,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <vector_extensions/sse.h>
#include <string.h>
#ifdef DEBUG_USE_SSE2
#include <vector_extensions/sse.h>
extern int32_t sse_initialized;
#endif
size_t strlen(const char* str)
{
@ -76,10 +78,12 @@ char* strcpy(char *dst, const char *src)
char* strncpy(char *dest, const char *src, uint32_t n)
{
#ifdef DEBUG_USE_SSE2
if (sse_initialized > 0)
{
return sse2_strncpy(dest, src, n);
}
#endif
uint32_t i = 0;
for (; i < n && src[i]; ++i)
@ -217,10 +221,12 @@ void* memset(void* dst, int c, size_t n)
void* memcpy(void *dst, const void *src, uint32_t n)
{
#ifdef DEBUG_USE_SSE2
if (sse_initialized > 1)
{
return sse2_memcpy(dst, src, n);
}
#endif
char *d = dst;
const char *s = src;
@ -234,8 +240,8 @@ void* memcpy(void *dst, const void *src, uint32_t n)
int32_t memcmp(const void *s1, const void *s2, size_t n)
{
const uint8_t *p1 = (const uint8_t *)s1;
const uint8_t *p2 = (const uint8_t *)s2;
const uint8_t *p1 = (const uint8_t*) s1;
const uint8_t *p2 = (const uint8_t*) s2;
/*printf("p1: %i, p2: %i\n", (int32_t)*p1, (int32_t)*p2);*/
@ -252,10 +258,12 @@ int32_t memcmp(const void *s1, const void *s2, size_t n)
void* memclr(void* m_start, size_t m_count)
{
#ifdef DEBUG_USE_SSE2
if (sse_initialized > 1)
{
return memclr_sse2(m_start, m_count);
}
#endif
return memset(m_start, '\0', (uint32_t)m_count);
}
@ -451,3 +459,36 @@ double atof(const char *str)
return sign * (res + frac / frac_div);
}
char* strnlstrip(const char* s)
{
if (!s)
{
return NULL;
}
char* new = strdup(s);
if (!new)
{
return NULL;
}
size_t len = strlen(new);
while (len > 0 && (new[len-1] == '\n' || new[len-1] == '\r'))
{
new[len-1] = '\0';
len--;
}
return new;
}
void strlnstripip(char* s)
{
size_t len = strlen(s);
if (len > 0 && s[len-1] == '\n')
{
s[len-1] = '\0';
}
}

40
lib/sync.c Normal file
View File

@ -0,0 +1,40 @@
#include <sync.h>
void spinlock_init(spinlock_t* lock)
{
lock->locked = 0;
}
static inline int atomic_xchg(volatile int* addr, int newval)
{
int result;
asm volatile (
"xchg %0, %1"
: "=r"(result), "+m"(*addr)
: "0"(newval)
: "memory"
);
return result;
}
void spin_lock(spinlock_t* lock)
{
while (atomic_xchg(&lock->locked, 1))
{
while (lock->locked)
{
asm volatile("pause");
}
}
}
void spin_unlock(spinlock_t* lock)
{
__atomic_clear(&lock->locked, __ATOMIC_RELEASE);
}

View File

@ -1,3 +1,5 @@
#ifdef DEBUG_USE_SSE2
#include <types.h>
#include <stdio.h>
@ -248,3 +250,5 @@ void* memclr_sse2(void *m_start, size_t m_count)
return m_start;
}
#endif