Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
90dc26ee11
|
|||
|
c8a72244b1
|
|||
|
b9f55d89f6
|
|||
|
a7d9e70a61
|
@@ -10,3 +10,4 @@ iso_root
|
||||
.gdb_history
|
||||
symbols.map
|
||||
symbols.S
|
||||
*.log
|
||||
@@ -1,13 +1,11 @@
|
||||
SOURCES = src/io/term/flanterm_backends/fb.c src/io/term/flanterm.c src/debug/panic.c src/debug/stacktrace.c src/boot/boot.c src/sched/scheduler.c src/sched/process.c src/mem/heap/kheap.c src/mem/paging/vmm.c src/mem/paging/paging.c src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
||||
SOURCES = src/debug/misc.c src/io/term/flanterm_backends/fb.c src/io/term/flanterm.c src/debug/panic.c src/debug/stacktrace.c src/boot/boot.c src/sched/scheduler.c src/sched/process.c src/mem/heap/kheap.c src/mem/paging/vmm.c src/mem/paging/paging.c src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
||||
|
||||
PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
|
||||
|
||||
build:
|
||||
rm -f *.o
|
||||
x86_64-elf-gcc -g -c -Isrc $(SOURCES) $(PROBLEMATIC_FLAGS) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
|
||||
objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o
|
||||
nasm -f elf64 src/idt/idt.S -o idt_stub.o
|
||||
nasm -f elf64 src/entry.S -o entry.o
|
||||
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
||||
nm -n pepperk | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
|
||||
python3 symbols.py
|
||||
@@ -37,7 +35,7 @@ build-iso: limine/limine build
|
||||
./limine/limine bios-install pepper.iso
|
||||
|
||||
debug:
|
||||
/usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -no-reboot -no-shutdown &
|
||||
/usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -D qemu.log -no-reboot -no-shutdown &
|
||||
gdb pepperk --command=debug.gdb
|
||||
|
||||
debug2:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
target remote localhost:1234
|
||||
set disassembly-flavor intel
|
||||
display/4i $rip
|
||||
|
||||
# Trying to debug that flanterm page fault
|
||||
|
||||
# b plot_char_unscaled_uncanvas if $rdi == 0 || $rsi == 0 || $rdx == 0 || $r10 == 0
|
||||
@@ -1,6 +1,6 @@
|
||||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
|
||||
ENTRY(_start)
|
||||
ENTRY(kmain)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@
|
||||
#define PEPPEROS_VERSION_MAJOR "0"
|
||||
#define PEPPEROS_VERSION_MINOR "0"
|
||||
#define PEPPEROS_VERSION_PATCH "58"
|
||||
#define PEPPEROS_SPLASH "pepperOS version "PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\n"
|
||||
#define PEPPEROS_SPLASH "\x1b[38;5;196mPepperOS\x1b[0m version "PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\n"
|
||||
|
||||
/* process */
|
||||
#define PROCESS_NAME_MAX 64
|
||||
@@ -30,7 +30,7 @@
|
||||
#define KERNEL_STACK_SIZE 65536
|
||||
|
||||
/* heap */
|
||||
#define KHEAP_SIZE (16*1024*1024)
|
||||
#define KHEAP_SIZE (32*1024*1024)
|
||||
|
||||
/* term */
|
||||
#define TERM_HISTORY_MAX_LINES 256
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <kernel.h>
|
||||
#include "limine.h"
|
||||
#include "string/string.h"
|
||||
|
||||
extern struct boot_context boot_ctx;
|
||||
|
||||
// Display the memmap so we see how the memory is laid out at handoff
|
||||
void memmap_display(struct limine_memmap_response* response)
|
||||
{
|
||||
DEBUG("Got memory map from Limine: revision %u, %u entries", response->revision, response->entry_count);
|
||||
|
||||
for (size_t i=0; i<response->entry_count; i++)
|
||||
{
|
||||
struct limine_memmap_entry* entry = response->entries[i];
|
||||
char type[32] = {0};
|
||||
switch(entry->type)
|
||||
{
|
||||
case LIMINE_MEMMAP_USABLE:
|
||||
strcpy(type, "USABLE");
|
||||
break;
|
||||
case LIMINE_MEMMAP_RESERVED:
|
||||
strcpy(type, "RESERVED");
|
||||
break;
|
||||
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
|
||||
strcpy(type, "ACPI_RECLAIMABLE");
|
||||
break;
|
||||
case LIMINE_MEMMAP_ACPI_NVS:
|
||||
strcpy(type, "ACPI_NVS");
|
||||
break;
|
||||
case LIMINE_MEMMAP_BAD_MEMORY:
|
||||
strcpy(type, "BAD_MEMORY");
|
||||
break;
|
||||
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
|
||||
strcpy(type, "BOOTLOADER_RECLAIMABLE");
|
||||
break;
|
||||
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
|
||||
strcpy(type, "KERNEL_AND_MODULES");
|
||||
break;
|
||||
case LIMINE_MEMMAP_FRAMEBUFFER:
|
||||
strcpy(type, "FRAMEBUFFER");
|
||||
break;
|
||||
default:
|
||||
strcpy(type, "UNKNOWN");
|
||||
break;
|
||||
}
|
||||
DEBUG("entry %02u: [0x%016x | %016u bytes] - %s", i, entry->base, entry->length, type);
|
||||
}
|
||||
}
|
||||
|
||||
// Display the HHDM
|
||||
void hhdm_display(struct limine_hhdm_response* hhdm)
|
||||
{
|
||||
DEBUG("Got HHDM revision=%u offset=0x%p", hhdm->revision, hhdm->offset);
|
||||
}
|
||||
|
||||
void boot_mem_display()
|
||||
{
|
||||
memmap_display(boot_ctx.mmap);
|
||||
hhdm_display(boot_ctx.hhdm);
|
||||
DEBUG("kernel: phys_base=0x%p virt_base=0x%p", boot_ctx.kaddr->physical_base, boot_ctx.kaddr->virtual_base);
|
||||
}
|
||||
@@ -9,7 +9,9 @@ void panic(struct cpu_status_t* ctx, const char* str)
|
||||
if (ctx == NULL)
|
||||
{
|
||||
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m Something went horribly wrong! (no cpu ctx)");
|
||||
fctprintf((void*)&skputc, 0, "\x1b[38;5;231m\x1b[48;5;27m");
|
||||
DIE_DEBUG(str);
|
||||
fctprintf((void*)&skputc, 0, "\x1b[0m");
|
||||
skputc('\r');
|
||||
skputc('\n');
|
||||
DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m");
|
||||
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
bits 64
|
||||
global _start
|
||||
|
||||
extern kmain
|
||||
extern kernel_stack
|
||||
|
||||
KERNEL_STACK_SIZE equ 65536
|
||||
|
||||
section .text
|
||||
|
||||
_start:
|
||||
cli
|
||||
|
||||
; load kernel stack
|
||||
lea rsp, [kernel_stack+KERNEL_STACK_SIZE]
|
||||
|
||||
; rbp=0 so last frame in stack trace
|
||||
xor rbp, rbp
|
||||
|
||||
; 16 byte align
|
||||
and rsp, -16
|
||||
|
||||
call kmain
|
||||
@@ -203,9 +203,6 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||
if (ticks % SCHEDULER_QUANTUM == 0)
|
||||
{
|
||||
return scheduler_schedule(context);
|
||||
//struct cpu_status_t* current_ctx = scheduler_schedule(context);
|
||||
//process_switch(current_ctx->iret_rsp, current_ctx->iret_rip);
|
||||
//SET_INTERRUPTS;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -42,7 +42,7 @@ int serial_init()
|
||||
// Set normal operation mode
|
||||
outb(PORT + 4, 0x0F);
|
||||
|
||||
DEBUG("serial initialized");
|
||||
DEBUG("*** Welcome to PepperOS! ***");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer."
|
||||
#endif
|
||||
@@ -662,6 +664,17 @@ static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, struct flan
|
||||
}
|
||||
|
||||
static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) {
|
||||
|
||||
if (_ctx == NULL)
|
||||
{
|
||||
panic(NULL, "plot_char_unscaled_uncanvas: _ctx is NULL");
|
||||
}
|
||||
|
||||
if (c == NULL)
|
||||
{
|
||||
panic(NULL, "plot_char_unscaled_uncanvas: c is NULL");
|
||||
}
|
||||
|
||||
struct flanterm_fb_context *ctx = (void *)_ctx;
|
||||
|
||||
if (x >= _ctx->cols || y >= _ctx->rows) {
|
||||
@@ -953,6 +966,12 @@ static void draw_cursor(struct flanterm_context *_ctx) {
|
||||
}
|
||||
|
||||
static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) {
|
||||
|
||||
if (_ctx == NULL)
|
||||
{
|
||||
panic(NULL, "flanterm_fb_double_buffer_flush: _ctx is NULL");
|
||||
}
|
||||
|
||||
struct flanterm_fb_context *ctx = (void *)_ctx;
|
||||
|
||||
if (_ctx->cursor_enabled) {
|
||||
|
||||
+1
-90
@@ -11,104 +11,14 @@ because this shitty implementation will be replaced one day by Flanterm
|
||||
(once memory management is okay: paging & kernel malloc)
|
||||
*/
|
||||
|
||||
#include <limine.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel.h>
|
||||
#include "term.h"
|
||||
#include "mem/misc/utils.h"
|
||||
#include "config.h"
|
||||
#include "flanterm.h"
|
||||
|
||||
extern struct boot_context boot_ctx;
|
||||
|
||||
// Importing the PSF object file
|
||||
extern unsigned char _binary_zap_light16_psf_start[];
|
||||
extern unsigned char _binary_zap_light16_psf_end[];
|
||||
|
||||
PSF1_Header* font = (PSF1_Header*)_binary_zap_light16_psf_start;
|
||||
uint8_t* glyphs = _binary_zap_light16_psf_start + sizeof(PSF1_Header);
|
||||
|
||||
#define FONT_WIDTH 8
|
||||
#define FONT_HEIGHT font->characterSize
|
||||
|
||||
extern struct flanterm_context* ft_ctx;
|
||||
|
||||
// Character cursor
|
||||
typedef struct
|
||||
{
|
||||
size_t x;
|
||||
size_t y;
|
||||
} Cursor;
|
||||
|
||||
static Cursor cursor = {0, 0};
|
||||
|
||||
static uint8_t* fb;
|
||||
static struct limine_framebuffer* framebuffer;
|
||||
|
||||
uint8_t lines_length[TERM_HISTORY_MAX_LINES];
|
||||
|
||||
static inline size_t term_max_cols(void)
|
||||
{
|
||||
return framebuffer->width / FONT_WIDTH;
|
||||
}
|
||||
|
||||
static inline size_t term_max_lines(void)
|
||||
{
|
||||
return framebuffer->height / FONT_HEIGHT;
|
||||
}
|
||||
|
||||
int term_init()
|
||||
{
|
||||
// Get framebuffer address from Limine struct
|
||||
|
||||
if (!boot_ctx.fb)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
framebuffer = boot_ctx.fb;
|
||||
fb = (uint8_t*)framebuffer->address;
|
||||
|
||||
memset(lines_length, 0, sizeof(lines_length));
|
||||
|
||||
DEBUG("terminal initialized, fb=0x%p (width=%u height=%u pitch=%u bpp=%u)", fb, framebuffer->width, framebuffer->height, framebuffer->pitch, framebuffer->bpp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// These are marked "static" because we don't wanna expose them all around
|
||||
// AKA they should just be seen here (kind of like private functions in cpp)
|
||||
static inline void putpixel(size_t x, size_t y, uint32_t color)
|
||||
{
|
||||
// Guard so we don't write past fb boundaries
|
||||
if (x >= framebuffer->width || y >= framebuffer->height) return;
|
||||
// Depth isn't part of limine_framebuffer attributes so it will be 4
|
||||
size_t pos = x*4 + y*framebuffer->pitch;
|
||||
fb[pos] = color & 255; // blue channel
|
||||
fb[pos+1] = (color >> 8) & 255; // green
|
||||
fb[pos+2] = (color >> 16) & 255; // blue
|
||||
}
|
||||
|
||||
void term_scroll()
|
||||
{
|
||||
// Erase first text line
|
||||
memset(fb, 255, FONT_HEIGHT*framebuffer->pitch);
|
||||
|
||||
// Move whole framebuffer up by one text line
|
||||
memmove(fb, fb+(FONT_HEIGHT*framebuffer->pitch), (framebuffer->height-FONT_HEIGHT)*framebuffer->pitch);
|
||||
|
||||
// Clear last text line
|
||||
size_t clear_start = (framebuffer->height - FONT_HEIGHT) * framebuffer->pitch;
|
||||
memset(fb + clear_start, 255, FONT_HEIGHT * framebuffer->pitch);
|
||||
|
||||
// Shift line lengths by 1 (for backspace handling)
|
||||
size_t max_lines = term_max_lines();
|
||||
for (size_t i = 1; i < max_lines; i++)
|
||||
{
|
||||
lines_length[i - 1] = lines_length[i];
|
||||
}
|
||||
lines_length[max_lines - 1] = 0;
|
||||
}
|
||||
|
||||
// Overhead that could be avoided, right? (for printf)
|
||||
void _putchar(char character)
|
||||
{
|
||||
@@ -124,4 +34,5 @@ void kputs(const char* str)
|
||||
_putchar(str[i]);
|
||||
i++;
|
||||
}
|
||||
_putchar('\r');
|
||||
}
|
||||
@@ -7,26 +7,7 @@
|
||||
#ifndef TERM_H
|
||||
#define TERM_H
|
||||
|
||||
int term_init();
|
||||
void kputs(const char* str);
|
||||
void _putchar(char character);
|
||||
|
||||
enum TermColors
|
||||
{
|
||||
BLACK = 0x000000,
|
||||
WHITE = 0xffffff
|
||||
};
|
||||
|
||||
#define PSF1_FONT_MAGIC 0x0436
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t magic;
|
||||
uint8_t fontMode;
|
||||
uint8_t characterSize; // height
|
||||
} PSF1_Header;
|
||||
|
||||
// debug
|
||||
void term_scroll();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,7 @@ void idle();
|
||||
|
||||
void debug_stack_trace(unsigned int max_frames);
|
||||
const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset);
|
||||
void boot_mem_display();
|
||||
|
||||
#define assert(check) do { if(!(check)) hcf(); } while(0)
|
||||
|
||||
|
||||
+23
-31
@@ -41,7 +41,7 @@ void hcf()
|
||||
// Doing nothing (can be interrupted)
|
||||
void idle() {SET_INTERRUPTS; for(;;)asm("hlt");}
|
||||
|
||||
uint8_t kernel_stack[KERNEL_STACK_SIZE] __attribute__((aligned(16)));
|
||||
// uint8_t kernel_stack[KERNEL_STACK_SIZE] __attribute__((aligned(16)));
|
||||
|
||||
struct boot_context boot_ctx;
|
||||
|
||||
@@ -55,12 +55,8 @@ extern struct process_t* current_process;
|
||||
|
||||
void pedicel_main(void* arg)
|
||||
{
|
||||
//printf("Hello, world from a KERNEL PROCESS!");
|
||||
}
|
||||
|
||||
void two_main(void* arg)
|
||||
{
|
||||
//printf("...process 2 speaking!!!");
|
||||
// FROM THE NEXT LINE ONWARDS, CANNOT WRITE TO FRAMEBUFFER WITHOUT PAGE FAULT!
|
||||
//printf("\n\nWelcome to PepperOS! Pedicel speaking.\nNothing left to do, halting the system!");
|
||||
}
|
||||
|
||||
void idle_main(void* arg)
|
||||
@@ -68,26 +64,41 @@ void idle_main(void* arg)
|
||||
for(;;)asm("hlt");
|
||||
}
|
||||
|
||||
void flanterm_free_wrapper(void* ptr, size_t size)
|
||||
{
|
||||
(void)size;
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
extern uintptr_t kheap_start;
|
||||
|
||||
// This is our entry point
|
||||
void kmain()
|
||||
{
|
||||
CLEAR_INTERRUPTS;
|
||||
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
|
||||
|
||||
serial_init();
|
||||
|
||||
// Populate boot context
|
||||
boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL;
|
||||
boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL;
|
||||
boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL;
|
||||
boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
|
||||
|
||||
boot_mem_display();
|
||||
pmm_init(boot_ctx.mmap, boot_ctx.hhdm);
|
||||
|
||||
// Remap kernel , HHDM and framebuffer
|
||||
paging_init(boot_ctx.kaddr, boot_ctx.fb);
|
||||
kheap_init();
|
||||
|
||||
keyboard_init(FR);
|
||||
|
||||
uint32_t bgColor = 0x252525;
|
||||
ft_ctx = flanterm_fb_init(
|
||||
NULL,
|
||||
NULL,
|
||||
kmalloc,
|
||||
flanterm_free_wrapper,
|
||||
boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch,
|
||||
boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift,
|
||||
boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift,
|
||||
@@ -102,24 +113,15 @@ void kmain()
|
||||
0
|
||||
);
|
||||
|
||||
serial_init();
|
||||
|
||||
memmap_display(boot_ctx.mmap);
|
||||
hhdm_display(boot_ctx.hhdm);
|
||||
DEBUG("kernel: phys_base=0x%p virt_base=0x%p", boot_ctx.kaddr->physical_base, boot_ctx.kaddr->virtual_base);
|
||||
|
||||
CLEAR_INTERRUPTS;
|
||||
gdt_init();
|
||||
idt_init();
|
||||
|
||||
timer_init();
|
||||
|
||||
kheap_init();
|
||||
|
||||
vmm_init();
|
||||
|
||||
process_init();
|
||||
struct process_t* idle_proc = process_create("idle", (void*)idle_main, 0);
|
||||
struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0);
|
||||
struct process_t* two = process_create("two", (void*)two_main, 0);
|
||||
|
||||
process_display_list(processes_list);
|
||||
|
||||
@@ -128,16 +130,6 @@ void kmain()
|
||||
current_process = idle_proc;
|
||||
current_process->status = RUNNING;
|
||||
|
||||
SET_INTERRUPTS;
|
||||
|
||||
keyboard_init(FR);
|
||||
//term_init();
|
||||
|
||||
//printf(PEPPEROS_SPLASH);
|
||||
|
||||
//printf("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu diam id sem tincidunt vestibulum. Etiam sed congue nisl, vitae aliquet orci. Donec magna turpis, semper sed ipsum eget, semper blandit dolor. Morbi faucibus posuere sapien. Vestibulum aliquet mi vel orci finibus, vestibulum rhoncus tellus sagittis. Vivamus a arcu suscipit sem iaculis volutpat vel nec est. Nulla malesuada, urna vel pretium pretium, enim tortor pulvinar velit, porttitor dictum lectus turpis id tortor. Quisque egestas ultricies lorem, egestas ultrices tellus elementum porta. Fusce consequat nisi in diam placerat fermentum. Suspendisse tempus turpis nec turpis condimentum fringilla. Maecenas nec orci pharetra, feugiat enim vel, viverra neque. Vivamus placerat purus in tincidunt ultricies. Pellentesque vel mi molestie, congue nibh nec, cursus nisl. Cras dapibus lectus mauris, sed interdum risus tristique non. ");
|
||||
|
||||
flanterm_write(ft_ctx, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu diam id sem tincidunt vestibulum. Etiam sed congue nisl, vitae aliquet orci. Donec magna turpis, semper sed ipsum eget, semper blandit dolor. Morbi faucibus posuere sapien. Vestibulum aliquet mi vel orci finibus, vestibulum rhoncus tellus sagittis. Vivamus a arcu suscipit sem iaculis volutpat vel nec est. Nulla malesuada, urna vel pretium pretium, enim tortor pulvinar velit, porttitor dictum lectus turpis id tortor. Quisque egestas ultricies lorem, egestas ultrices tellus elementum porta. Fusce consequat nisi in diam placerat fermentum. Suspendisse tempus turpis nec turpis condimentum fringilla. Maecenas nec orci pharetra, feugiat enim vel, viverra neque. Vivamus placerat purus in tincidunt ultricies. Pellentesque vel mi molestie, congue nibh nec, cursus nisl. Cras dapibus lectus mauris, sed interdum risus tristique non.", sizeof("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu diam id sem tincidunt vestibulum. Etiam sed congue nisl, vitae aliquet orci. Donec magna turpis, semper sed ipsum eget, semper blandit dolor. Morbi faucibus posuere sapien. Vestibulum aliquet mi vel orci finibus, vestibulum rhoncus tellus sagittis. Vivamus a arcu suscipit sem iaculis volutpat vel nec est. Nulla malesuada, urna vel pretium pretium, enim tortor pulvinar velit, porttitor dictum lectus turpis id tortor. Quisque egestas ultricies lorem, egestas ultrices tellus elementum porta. Fusce consequat nisi in diam placerat fermentum. Suspendisse tempus turpis nec turpis condimentum fringilla. Maecenas nec orci pharetra, feugiat enim vel, viverra neque. Vivamus placerat purus in tincidunt ultricies. Pellentesque vel mi molestie, congue nibh nec, cursus nisl. Cras dapibus lectus mauris, sed interdum risus tristique non. "));
|
||||
|
||||
kputs(PEPPEROS_SPLASH);
|
||||
idle();
|
||||
}
|
||||
|
||||
+30
-47
@@ -23,40 +23,36 @@ static uintptr_t end;
|
||||
// Kernel root table (level 4)
|
||||
extern uint64_t *kernel_pml4;
|
||||
|
||||
static void kheap_grow(size_t size)
|
||||
{
|
||||
size_t pages = ALIGN_UP(size + sizeof(struct heap_block_t), PAGE_SIZE) / PAGE_SIZE;
|
||||
|
||||
if (pages == 0) pages = 1;
|
||||
|
||||
for (size_t i = 0; i < pages; i++)
|
||||
{
|
||||
kheap_map_page();
|
||||
}
|
||||
}
|
||||
|
||||
void kheap_map_page()
|
||||
{
|
||||
uintptr_t phys = pmm_alloc();
|
||||
paging_map_page(kernel_pml4, end, phys, PTE_PRESENT | PTE_WRITABLE | PTE_NOEXEC);
|
||||
end += PAGE_SIZE;
|
||||
//DEBUG("Mapped first kheap page");
|
||||
}
|
||||
|
||||
void kheap_init()
|
||||
{
|
||||
kheap_start = ALIGN_UP(kernel_virt_base + KERNEL_SIZE, PAGE_SIZE);
|
||||
end = kheap_start;
|
||||
|
||||
// At least 1 page must be mapped for it to work
|
||||
kheap_map_page();
|
||||
size_t heap_pages = ALIGN_UP(KHEAP_SIZE, PAGE_SIZE) / PAGE_SIZE;
|
||||
DEBUG("Mapping %d kernel heap pages at 0x%p", heap_pages, kheap_start);
|
||||
|
||||
uintptr_t current_addr = kheap_start;
|
||||
|
||||
// Map/alloc enough pages for heap (KHEAP_SIZE)
|
||||
for (size_t i=0; i<heap_pages; i++)
|
||||
{
|
||||
uintptr_t phys = pmm_alloc();
|
||||
if (phys == 0)
|
||||
{
|
||||
panic(NULL, "Not enough memory available to initialize kernel heap.");
|
||||
}
|
||||
|
||||
paging_map_page(kernel_pml4, current_addr, phys, PTE_PRESENT | PTE_WRITABLE);
|
||||
current_addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
end = current_addr;
|
||||
|
||||
// Give linked list head its properties
|
||||
head = (struct heap_block_t*)kheap_start;
|
||||
head->size = PAGE_SIZE - sizeof(struct heap_block_t);
|
||||
head->size = (end-kheap_start) - sizeof(struct heap_block_t);
|
||||
head->free = true;
|
||||
head->next = NULL;
|
||||
DEBUG("kheap initialized, head=0x%p, size=%u", head, head->size);
|
||||
DEBUG("Kernel heap initialized, head=0x%p, size=%u bytes", head, head->size);
|
||||
}
|
||||
|
||||
void* kmalloc(size_t size)
|
||||
@@ -73,12 +69,12 @@ void* kmalloc(size_t size)
|
||||
if (curr->free && curr->size >= size)
|
||||
{
|
||||
// We split the block if it is big enough
|
||||
if (curr->size >= size + BLOCK_MIN_SIZE)
|
||||
if (curr->size >= size + sizeof(struct heap_block_t) + 16)
|
||||
{
|
||||
//struct heap_block_t* new_block = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
|
||||
struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(*curr) + size);
|
||||
struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
|
||||
|
||||
split->size = curr->size - size - sizeof(*curr);
|
||||
split->size = curr->size - size - sizeof(struct heap_block_t);
|
||||
split->free = true;
|
||||
split->next = curr->next;
|
||||
|
||||
@@ -94,25 +90,12 @@ void* kmalloc(size_t size)
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
// If we're here it means we didn't have enough memory
|
||||
// for the block allocation. So we will allocate more..
|
||||
uintptr_t old_end = end;
|
||||
kheap_grow(size + sizeof(struct heap_block_t));
|
||||
|
||||
struct heap_block_t* block = (struct heap_block_t*)old_end;
|
||||
block->size = ALIGN_UP(end - old_end - sizeof(struct heap_block_t), 16);
|
||||
block->free = true;
|
||||
block->next = NULL;
|
||||
|
||||
// Put the block at the end of the list
|
||||
curr = head;
|
||||
while (curr->next)
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
curr->next = block;
|
||||
|
||||
return kmalloc(size);
|
||||
// No growing. If we're here it means the initial pool
|
||||
// wasn't sufficient. Too bad.
|
||||
DEBUG("Kernel heap is OUT OF MEMORY!");
|
||||
// if we were terrorists maybe we should panic
|
||||
// or just wait for others to free stuff?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void kfree(void* ptr)
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct heap_block_t
|
||||
{
|
||||
size_t size;
|
||||
bool free;
|
||||
bool free; // 1byte
|
||||
uint8_t reserved[7]; // (7+1 = 8 bytes)
|
||||
struct heap_block_t* next;
|
||||
};
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
void kheap_init();
|
||||
void* kmalloc(size_t size);
|
||||
|
||||
@@ -77,52 +77,3 @@ int memcmp(const void* s1, const void* s2, size_t n)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Display the memmap so we see how the memory is laid out at handoff
|
||||
void memmap_display(struct limine_memmap_response* response)
|
||||
{
|
||||
DEBUG("Got memory map from Limine: revision %u, %u entries", response->revision, response->entry_count);
|
||||
|
||||
for (size_t i=0; i<response->entry_count; i++)
|
||||
{
|
||||
struct limine_memmap_entry* entry = response->entries[i];
|
||||
char type[32] = {0};
|
||||
switch(entry->type)
|
||||
{
|
||||
case LIMINE_MEMMAP_USABLE:
|
||||
strcpy(type, "USABLE");
|
||||
break;
|
||||
case LIMINE_MEMMAP_RESERVED:
|
||||
strcpy(type, "RESERVED");
|
||||
break;
|
||||
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
|
||||
strcpy(type, "ACPI_RECLAIMABLE");
|
||||
break;
|
||||
case LIMINE_MEMMAP_ACPI_NVS:
|
||||
strcpy(type, "ACPI_NVS");
|
||||
break;
|
||||
case LIMINE_MEMMAP_BAD_MEMORY:
|
||||
strcpy(type, "BAD_MEMORY");
|
||||
break;
|
||||
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
|
||||
strcpy(type, "BOOTLOADER_RECLAIMABLE");
|
||||
break;
|
||||
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
|
||||
strcpy(type, "KERNEL_AND_MODULES");
|
||||
break;
|
||||
case LIMINE_MEMMAP_FRAMEBUFFER:
|
||||
strcpy(type, "FRAMEBUFFER");
|
||||
break;
|
||||
default:
|
||||
strcpy(type, "UNKNOWN");
|
||||
break;
|
||||
}
|
||||
DEBUG("entry %02u: [0x%016x | %016u bytes] - %s", i, entry->base, entry->length, type);
|
||||
}
|
||||
}
|
||||
|
||||
// Display the HHDM
|
||||
void hhdm_display(struct limine_hhdm_response* hhdm)
|
||||
{
|
||||
DEBUG("Got HHDM revision=%u offset=0x%p", hhdm->revision, hhdm->offset);
|
||||
}
|
||||
@@ -68,5 +68,6 @@ void vmm_setup_pt_root()
|
||||
|
||||
void vmm_init()
|
||||
{
|
||||
vmm_setup_pt_root();
|
||||
// NO U
|
||||
//vmm_setup_pt_root();
|
||||
}
|
||||
+6
-20
@@ -13,6 +13,9 @@
|
||||
#include "config.h"
|
||||
#include "io/serial/serial.h"
|
||||
|
||||
#include "io/term/flanterm.h"
|
||||
extern struct flanterm_context* ft_ctx;
|
||||
|
||||
struct process_t* processes_list;
|
||||
struct process_t* current_process;
|
||||
|
||||
@@ -42,7 +45,7 @@ void process_display_list(struct process_t* processes_list)
|
||||
|
||||
struct process_t* process_create(char* name, void(*function)(void*), void* arg)
|
||||
{
|
||||
CLEAR_INTERRUPTS;
|
||||
/* CLEAR_INTERRUPTS; */
|
||||
struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t));
|
||||
|
||||
struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t));
|
||||
@@ -76,7 +79,7 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg)
|
||||
|
||||
process_add(&processes_list, proc);
|
||||
|
||||
SET_INTERRUPTS;
|
||||
/* SET_INTERRUPTS; */
|
||||
return proc;
|
||||
}
|
||||
|
||||
@@ -139,23 +142,6 @@ struct process_t* process_get_next(struct process_t* process)
|
||||
return process->next;
|
||||
}
|
||||
|
||||
// (from gdt) This will switch tasks ONLY in ring 0
|
||||
// KERNEL CS = 0x08
|
||||
// KERNEL SS = 0x10
|
||||
__attribute__((naked, noreturn))
|
||||
void process_switch(uint64_t stack_addr, uint64_t code_addr)
|
||||
{
|
||||
asm volatile(" \
|
||||
push $0x10 \n\
|
||||
push %0 \n\
|
||||
push $0x202 \n\
|
||||
push $0x08 \n\
|
||||
push %1 \n\
|
||||
iretq \n\
|
||||
" :: "r"(stack_addr), "r"(code_addr));
|
||||
}
|
||||
|
||||
|
||||
// Will be used to clean up resources (if any, when we implement it)
|
||||
// Just mark as DEAD then idle. Scheduler will delete process at next timer interrupt % quantum.
|
||||
void process_exit()
|
||||
@@ -168,7 +154,7 @@ void process_exit()
|
||||
}
|
||||
SET_INTERRUPTS;
|
||||
|
||||
outb(0x20, 0x20);
|
||||
//outb(0x20, 0x20);
|
||||
for (;;)
|
||||
{
|
||||
asm("hlt");
|
||||
|
||||
@@ -34,7 +34,6 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg);
|
||||
void process_add(struct process_t** processes_list, struct process_t* process);
|
||||
void process_delete(struct process_t** processes_list, struct process_t* process);
|
||||
struct process_t* process_get_next(struct process_t* process);
|
||||
void process_switch(uint64_t stack_addr, uint64_t code_addr);
|
||||
void process_exit();
|
||||
|
||||
void process_display_list(struct process_t* processes_list);
|
||||
|
||||
@@ -21,6 +21,18 @@ void scheduler_init()
|
||||
|
||||
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
||||
{
|
||||
if (context == NULL)
|
||||
{
|
||||
panic(NULL, "Scheduler called with NULL context");
|
||||
}
|
||||
|
||||
if (current_process == NULL)
|
||||
{
|
||||
// Wtf happened
|
||||
current_process = processes_list;
|
||||
//panic(NULL, "Scheduler called without current process");
|
||||
}
|
||||
|
||||
current_process->context = context;
|
||||
//current_process->status = READY;
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
; Task (process) switching
|
||||
|
||||
bits 64
|
||||
|
||||
global switch_to_task
|
||||
switch_to_task:
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user