4 Commits

25 changed files with 175 additions and 304 deletions
+2 -1
View File
@@ -9,4 +9,5 @@ iso_root
*/*/*.gch */*/*.gch
.gdb_history .gdb_history
symbols.map symbols.map
symbols.S symbols.S
*.log
+2 -4
View File
@@ -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 PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
build: build:
rm -f *.o 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 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/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 x86_64-elf-ld -o pepperk -T linker.ld *.o
nm -n pepperk | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map nm -n pepperk | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
python3 symbols.py python3 symbols.py
@@ -37,7 +35,7 @@ build-iso: limine/limine build
./limine/limine bios-install pepper.iso ./limine/limine bios-install pepper.iso
debug: 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 gdb pepperk --command=debug.gdb
debug2: debug2:
+4
View File
@@ -1,3 +1,7 @@
target remote localhost:1234 target remote localhost:1234
set disassembly-flavor intel set disassembly-flavor intel
display/4i $rip 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 -1
View File
@@ -1,6 +1,6 @@
OUTPUT_FORMAT(elf64-x86-64) OUTPUT_FORMAT(elf64-x86-64)
ENTRY(_start) ENTRY(kmain)
PHDRS PHDRS
{ {
+2 -2
View File
@@ -11,7 +11,7 @@
#define PEPPEROS_VERSION_MAJOR "0" #define PEPPEROS_VERSION_MAJOR "0"
#define PEPPEROS_VERSION_MINOR "0" #define PEPPEROS_VERSION_MINOR "0"
#define PEPPEROS_VERSION_PATCH "58" #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 */ /* process */
#define PROCESS_NAME_MAX 64 #define PROCESS_NAME_MAX 64
@@ -30,7 +30,7 @@
#define KERNEL_STACK_SIZE 65536 #define KERNEL_STACK_SIZE 65536
/* heap */ /* heap */
#define KHEAP_SIZE (16*1024*1024) #define KHEAP_SIZE (32*1024*1024)
/* term */ /* term */
#define TERM_HISTORY_MAX_LINES 256 #define TERM_HISTORY_MAX_LINES 256
+61
View File
@@ -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);
}
+2
View File
@@ -9,7 +9,9 @@ void panic(struct cpu_status_t* ctx, const char* str)
if (ctx == NULL) if (ctx == NULL)
{ {
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m Something went horribly wrong! (no cpu ctx)"); 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); DIE_DEBUG(str);
fctprintf((void*)&skputc, 0, "\x1b[0m");
skputc('\r'); skputc('\r');
skputc('\n'); skputc('\n');
DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m"); DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m");
-23
View File
@@ -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
-3
View File
@@ -203,9 +203,6 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
if (ticks % SCHEDULER_QUANTUM == 0) if (ticks % SCHEDULER_QUANTUM == 0)
{ {
return scheduler_schedule(context); 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; break;
+1 -1
View File
@@ -42,7 +42,7 @@ int serial_init()
// Set normal operation mode // Set normal operation mode
outb(PORT + 4, 0x0F); outb(PORT + 4, 0x0F);
DEBUG("serial initialized"); DEBUG("*** Welcome to PepperOS! ***");
return 0; return 0;
} }
+19
View File
@@ -25,6 +25,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <kernel.h>
#ifdef __cplusplus #ifdef __cplusplus
#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." #error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer."
#endif #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) { 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; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) { 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) { 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; struct flanterm_fb_context *ctx = (void *)_ctx;
if (_ctx->cursor_enabled) { if (_ctx->cursor_enabled) {
+1 -90
View File
@@ -11,104 +11,14 @@ because this shitty implementation will be replaced one day by Flanterm
(once memory management is okay: paging & kernel malloc) (once memory management is okay: paging & kernel malloc)
*/ */
#include <limine.h>
#include <stddef.h> #include <stddef.h>
#include <kernel.h> #include <kernel.h>
#include "term.h" #include "term.h"
#include "mem/misc/utils.h"
#include "config.h" #include "config.h"
#include "flanterm.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; 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) // Overhead that could be avoided, right? (for printf)
void _putchar(char character) void _putchar(char character)
{ {
@@ -124,4 +34,5 @@ void kputs(const char* str)
_putchar(str[i]); _putchar(str[i]);
i++; i++;
} }
_putchar('\r');
} }
-19
View File
@@ -7,26 +7,7 @@
#ifndef TERM_H #ifndef TERM_H
#define TERM_H #define TERM_H
int term_init();
void kputs(const char* str); void kputs(const char* str);
void _putchar(char character); 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 #endif
+1
View File
@@ -40,6 +40,7 @@ void idle();
void debug_stack_trace(unsigned int max_frames); void debug_stack_trace(unsigned int max_frames);
const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset); const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset);
void boot_mem_display();
#define assert(check) do { if(!(check)) hcf(); } while(0) #define assert(check) do { if(!(check)) hcf(); } while(0)
+24 -32
View File
@@ -41,7 +41,7 @@ void hcf()
// Doing nothing (can be interrupted) // Doing nothing (can be interrupted)
void idle() {SET_INTERRUPTS; for(;;)asm("hlt");} 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; struct boot_context boot_ctx;
@@ -55,12 +55,8 @@ extern struct process_t* current_process;
void pedicel_main(void* arg) void pedicel_main(void* arg)
{ {
//printf("Hello, world from a KERNEL PROCESS!"); // 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 two_main(void* arg)
{
//printf("...process 2 speaking!!!");
} }
void idle_main(void* arg) void idle_main(void* arg)
@@ -68,26 +64,41 @@ void idle_main(void* arg)
for(;;)asm("hlt"); 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 // This is our entry point
void kmain() void kmain()
{ {
CLEAR_INTERRUPTS;
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf(); if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
serial_init();
// Populate boot context // Populate boot context
boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL; boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL;
boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL; boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL;
boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL; boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL;
boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL; boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
boot_mem_display();
pmm_init(boot_ctx.mmap, boot_ctx.hhdm); pmm_init(boot_ctx.mmap, boot_ctx.hhdm);
// Remap kernel , HHDM and framebuffer // Remap kernel , HHDM and framebuffer
paging_init(boot_ctx.kaddr, boot_ctx.fb); paging_init(boot_ctx.kaddr, boot_ctx.fb);
kheap_init();
keyboard_init(FR);
uint32_t bgColor = 0x252525; uint32_t bgColor = 0x252525;
ft_ctx = flanterm_fb_init( ft_ctx = flanterm_fb_init(
NULL, kmalloc,
NULL, flanterm_free_wrapper,
boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch, 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->red_mask_size, boot_ctx.fb->red_mask_shift,
boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift, boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift,
@@ -102,25 +113,16 @@ void kmain()
0 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(); gdt_init();
idt_init(); idt_init();
timer_init();
kheap_init();
timer_init();
vmm_init(); vmm_init();
process_init();
struct process_t* idle_proc = process_create("idle", (void*)idle_main, 0); 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* pedicel = process_create("pedicel", (void*)pedicel_main, 0);
struct process_t* two = process_create("two", (void*)two_main, 0);
process_display_list(processes_list); process_display_list(processes_list);
scheduler_init(); scheduler_init();
@@ -128,16 +130,6 @@ void kmain()
current_process = idle_proc; current_process = idle_proc;
current_process->status = RUNNING; current_process->status = RUNNING;
SET_INTERRUPTS; kputs(PEPPEROS_SPLASH);
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. "));
idle(); idle();
} }
+30 -47
View File
@@ -23,40 +23,36 @@ static uintptr_t end;
// Kernel root table (level 4) // Kernel root table (level 4)
extern uint64_t *kernel_pml4; 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() void kheap_init()
{ {
kheap_start = ALIGN_UP(kernel_virt_base + KERNEL_SIZE, PAGE_SIZE); kheap_start = ALIGN_UP(kernel_virt_base + KERNEL_SIZE, PAGE_SIZE);
end = kheap_start;
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);
// At least 1 page must be mapped for it to work uintptr_t current_addr = kheap_start;
kheap_map_page();
// 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 // Give linked list head its properties
head = (struct heap_block_t*)kheap_start; 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->free = true;
head->next = NULL; 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) void* kmalloc(size_t size)
@@ -73,12 +69,12 @@ void* kmalloc(size_t size)
if (curr->free && curr->size >= size) if (curr->free && curr->size >= size)
{ {
// We split the block if it is big enough // 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* 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->free = true;
split->next = curr->next; split->next = curr->next;
@@ -94,25 +90,12 @@ void* kmalloc(size_t size)
curr = curr->next; curr = curr->next;
} }
// If we're here it means we didn't have enough memory // No growing. If we're here it means the initial pool
// for the block allocation. So we will allocate more.. // wasn't sufficient. Too bad.
uintptr_t old_end = end; DEBUG("Kernel heap is OUT OF MEMORY!");
kheap_grow(size + sizeof(struct heap_block_t)); // if we were terrorists maybe we should panic
// or just wait for others to free stuff?
struct heap_block_t* block = (struct heap_block_t*)old_end; return NULL;
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);
} }
void kfree(void* ptr) void kfree(void* ptr)
+4 -2
View File
@@ -14,13 +14,15 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
struct heap_block_t struct heap_block_t
{ {
size_t size; size_t size;
bool free; bool free; // 1byte
uint8_t reserved[7]; // (7+1 = 8 bytes)
struct heap_block_t* next; struct heap_block_t* next;
}; } __attribute__((aligned(16)));
void kheap_init(); void kheap_init();
void* kmalloc(size_t size); void* kmalloc(size_t size);
-49
View File
@@ -76,53 +76,4 @@ int memcmp(const void* s1, const void* s2, size_t n)
} }
return 0; 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);
} }
+1 -1
View File
@@ -123,7 +123,7 @@ void paging_init()
DEBUG("Kernel lives at virt=0x%p phys=0x%p", kernel_virt_base, kernel_phys_base); DEBUG("Kernel lives at virt=0x%p phys=0x%p", kernel_virt_base, kernel_phys_base);
kernel_pml4 = alloc_page_table(); kernel_pml4 = alloc_page_table();
// for debug // for debug
uint64_t page_count = 0; uint64_t page_count = 0;
+2 -1
View File
@@ -68,5 +68,6 @@ void vmm_setup_pt_root()
void vmm_init() void vmm_init()
{ {
vmm_setup_pt_root(); // NO U
//vmm_setup_pt_root();
} }
+6 -20
View File
@@ -13,6 +13,9 @@
#include "config.h" #include "config.h"
#include "io/serial/serial.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* processes_list;
struct process_t* current_process; 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) 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 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)); 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); process_add(&processes_list, proc);
SET_INTERRUPTS; /* SET_INTERRUPTS; */
return proc; return proc;
} }
@@ -139,23 +142,6 @@ struct process_t* process_get_next(struct process_t* process)
return process->next; 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) // 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. // Just mark as DEAD then idle. Scheduler will delete process at next timer interrupt % quantum.
void process_exit() void process_exit()
@@ -168,7 +154,7 @@ void process_exit()
} }
SET_INTERRUPTS; SET_INTERRUPTS;
outb(0x20, 0x20); //outb(0x20, 0x20);
for (;;) for (;;)
{ {
asm("hlt"); asm("hlt");
-1
View File
@@ -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_add(struct process_t** processes_list, struct process_t* process);
void process_delete(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); 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_exit();
void process_display_list(struct process_t* processes_list); void process_display_list(struct process_t* processes_list);
+12
View File
@@ -21,6 +21,18 @@ void scheduler_init()
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) 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->context = context;
//current_process->status = READY; //current_process->status = READY;
-7
View File
@@ -1,7 +0,0 @@
; Task (process) switching
bits 64
global switch_to_task
switch_to_task:
BIN
View File
Binary file not shown.