Compare commits
9 Commits
memory
...
6e633b44b7
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e633b44b7 | |||
|
b8a155fada
|
|||
|
091f94f89e
|
|||
|
b469952d91
|
|||
|
9cbecc1689
|
|||
|
12ab12f1b2
|
|||
|
0f72987bc1
|
|||
|
d9dfd4c749
|
|||
| be1be41a64 |
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@ SOURCES = src/mem/heap/kheap.c src/mem/paging/vmm.c src/mem/paging/paging.c src/
|
||||
|
||||
build:
|
||||
rm -f *.o
|
||||
x86_64-elf-gcc -g -c -Isrc $(SOURCES) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
|
||||
x86_64-elf-gcc -g -c -Isrc $(SOURCES) -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
|
||||
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "io/serial/serial.h"
|
||||
#include "io/kbd/ps2.h"
|
||||
#include <kernel.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct interrupt_descriptor idt[256];
|
||||
struct idtr idt_reg;
|
||||
@@ -53,6 +54,64 @@ void idt_init()
|
||||
DEBUG("IDT initialized");
|
||||
}
|
||||
|
||||
static inline uint64_t read_cr2(void)
|
||||
{
|
||||
uint64_t val;
|
||||
asm volatile ("mov %%cr2, %0" : "=r"(val));
|
||||
return val;
|
||||
}
|
||||
|
||||
static void page_fault_handler(struct cpu_status_t* ctx)
|
||||
{
|
||||
// It could be used to remap pages etc. to fix the fault, but right now what I'm more
|
||||
// interested in is getting more info out of those numbers cause i'm lost each time i have
|
||||
// to read all this mess
|
||||
uint64_t cr2 = read_cr2();
|
||||
|
||||
DEBUG("\x1b[38;5;231mPage Fault at rip=0x%p, err=%u (%s%s%s%s%s%s%s%s) when accessing addr=0x%p\x1b[0m", ctx->iret_rip, ctx->error_code,
|
||||
CHECK_BIT(ctx->error_code, 0) ? "PAGE_PROTECTION_VIOLATION " : "PAGE_NOT_PRESENT ",
|
||||
CHECK_BIT(ctx->error_code, 1) ? "ON_WRITE " : "ON_READ ",
|
||||
CHECK_BIT(ctx->error_code, 2) ? "IN_USER_MODE" : "IN_KERNEL_MODE",
|
||||
CHECK_BIT(ctx->error_code, 3) ? " WAS_RESERVED" : "",
|
||||
CHECK_BIT(ctx->error_code, 4) ? " ON_INSTRUCTION_FETCH" : "",
|
||||
CHECK_BIT(ctx->error_code, 5) ? " PK_VIOLATION" : "",
|
||||
CHECK_BIT(ctx->error_code, 6) ? " ON_SHADOWSTACK_ACCESS" : "",
|
||||
CHECK_BIT(ctx->error_code, 7) ? " SGX_VIOLATION" : "",
|
||||
cr2);
|
||||
|
||||
/* if (CHECK_BIT(ctx->error_code, 0))
|
||||
{
|
||||
panic(ctx);
|
||||
} */
|
||||
panic(ctx);
|
||||
}
|
||||
|
||||
static void gp_fault_handler(struct cpu_status_t* ctx)
|
||||
{
|
||||
DEBUG("\x1b[38;5;231mGeneral Protection Fault at rip=0x%p, err=%u (%s)\x1b[0m",
|
||||
ctx->iret_rip,
|
||||
ctx->error_code,
|
||||
(ctx->error_code == 0) ? "NOT_SEGMENT_RELATED" : "SEGMENT_RELATED");
|
||||
|
||||
// Segment-related
|
||||
if (ctx->error_code != 0)
|
||||
{
|
||||
bool is_external = CHECK_BIT(ctx->error_code, 0);
|
||||
// is it IDT, GDT, LDT?
|
||||
uint8_t table = ctx->error_code & 0x6; // 0b110 (isolate table)
|
||||
uint16_t index = ctx->error_code & 0xFFF8; // 13*1 1111111111111 + 000 = 1111111111111000
|
||||
|
||||
char* table_names[4] = {"GDT", "IDT", "LDT", "IDT"};
|
||||
|
||||
DEBUG("\x1b[38;5;231m%s in %s index %u\x1b[0m",
|
||||
is_external ? "EXTERNAL" : "INTERNAL",
|
||||
table_names[table],
|
||||
index);
|
||||
}
|
||||
|
||||
panic(ctx);
|
||||
}
|
||||
|
||||
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||
{
|
||||
switch(context->vector_number)
|
||||
@@ -97,10 +156,11 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||
DEBUG("Stack-Segment Fault!");
|
||||
break;
|
||||
case 13:
|
||||
DEBUG("General Protection Fault!");
|
||||
gp_fault_handler(context);
|
||||
break;
|
||||
case 14:
|
||||
DEBUG("Page Fault!");
|
||||
// Better debugging for page faults...
|
||||
page_fault_handler(context);
|
||||
break;
|
||||
case 15:
|
||||
DEBUG("Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)");
|
||||
@@ -125,13 +185,14 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||
break;
|
||||
|
||||
case 32:
|
||||
//DEBUG("Tick!");
|
||||
//DEBUG("Timer Interrupt");
|
||||
ticks++;
|
||||
// Send an EOI so that we can continue having interrupts
|
||||
outb(0x20, 0x20);
|
||||
break;
|
||||
|
||||
case 33:
|
||||
DEBUG("Keyboard Interrupt");
|
||||
keyboard_handler();
|
||||
break;
|
||||
|
||||
|
||||
@@ -201,12 +201,11 @@ void keyboard_handler()
|
||||
|
||||
if (c)
|
||||
{
|
||||
// Should probably have a keyboard buffer here... instead of this
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skputs("key pressed!\n");
|
||||
}
|
||||
|
||||
// End of Interrupt (to master PIC)
|
||||
@@ -233,5 +232,11 @@ void keyboard_init(unsigned char layout)
|
||||
skputs("Unsupported layout.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Unmask IRQ1
|
||||
uint8_t mask = inb(0x21);
|
||||
mask &= ~(1 << 1);
|
||||
outb(0x21, mask);
|
||||
|
||||
DEBUG("PS/2 Keyboard initialized");
|
||||
}
|
||||
@@ -9,8 +9,9 @@ because this shitty implementation will be replaced one day by Flanterm
|
||||
#include <stddef.h>
|
||||
#include <kernel.h>
|
||||
#include "term.h"
|
||||
#include "mem/misc/utils.h"
|
||||
|
||||
extern struct limine_framebuffer* framebuffer;
|
||||
extern struct boot_context boot_ctx;
|
||||
|
||||
// Importing the PSF object file
|
||||
extern unsigned char _binary_zap_light16_psf_start[];
|
||||
@@ -22,61 +23,88 @@ uint8_t* glyphs = _binary_zap_light16_psf_start + sizeof(PSF1_Header);
|
||||
#define FONT_WIDTH 8
|
||||
#define FONT_HEIGHT font->characterSize
|
||||
|
||||
|
||||
|
||||
// Character cursor
|
||||
typedef struct
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
size_t x;
|
||||
size_t y;
|
||||
} Cursor;
|
||||
|
||||
Cursor cursor = {0};
|
||||
static Cursor cursor = {0, 0};
|
||||
|
||||
unsigned char* fb;
|
||||
static uint8_t* fb;
|
||||
static struct limine_framebuffer* framebuffer;
|
||||
|
||||
uint8_t lines_length[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 (framebuffer)
|
||||
if (!boot_ctx.fb)
|
||||
{
|
||||
fb = framebuffer->address;
|
||||
DEBUG("terminal initialized");
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
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 void putpixel(int x, int y, int color)
|
||||
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
|
||||
unsigned pos = x*4 + y*framebuffer->pitch;
|
||||
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
|
||||
}
|
||||
|
||||
static void draw_char(char c, int px, int py, int fg, int bg)
|
||||
static void draw_char(char c, size_t px, size_t py, uint32_t fg, uint32_t bg)
|
||||
{
|
||||
// So we cannot write past fb
|
||||
if (px+FONT_WIDTH > framebuffer->width || py+FONT_HEIGHT > framebuffer->height) return;
|
||||
|
||||
uint8_t* glyph = glyphs + ((unsigned char)c * FONT_HEIGHT);
|
||||
|
||||
for (size_t y=0; y<FONT_HEIGHT; y++)
|
||||
{
|
||||
uint8_t row = glyph[y];
|
||||
for (size_t x=0; x<8; x++)
|
||||
for (size_t x=0; x<FONT_WIDTH; x++)
|
||||
{
|
||||
int color = (row & (0x80 >> x)) ? fg : bg;
|
||||
uint32_t color = (row & (0x80 >> x)) ? fg : bg;
|
||||
putpixel(px+x, py+y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void erase_char(int px, int py)
|
||||
static void erase_char(size_t px, size_t py)
|
||||
{
|
||||
if (px+FONT_WIDTH > framebuffer->width || py+FONT_HEIGHT > framebuffer->height) return;
|
||||
|
||||
for (size_t y=0; y<FONT_HEIGHT; y++)
|
||||
{
|
||||
for (size_t x=0; x<8; x++)
|
||||
for (size_t x=0; x<FONT_WIDTH; x++)
|
||||
{
|
||||
// Black
|
||||
putpixel(px+x, py+y, 0);
|
||||
@@ -84,50 +112,81 @@ static void erase_char(int px, int py)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void putchar(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
const size_t max_cols = term_max_cols();
|
||||
const size_t max_lines = term_max_lines();
|
||||
|
||||
if (c == '\n') {
|
||||
lines_length[cursor.y] = cursor.x;
|
||||
cursor.x = 0;
|
||||
cursor.y++;
|
||||
|
||||
if (cursor.y + 1 >= max_lines)
|
||||
{
|
||||
term_scroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.y++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Improperly handled.
|
||||
// When we're on an empty line it should get to the upper line's last character
|
||||
// NOT just the last position possible; we would need to track the last line's character amount for that
|
||||
if (c == '\b')
|
||||
if (c == '\b')
|
||||
{
|
||||
if (cursor.x == 0 && cursor.y == 0)
|
||||
if (cursor.x > 0)
|
||||
{
|
||||
cursor.x--;
|
||||
}
|
||||
else if (cursor.y > 0)
|
||||
{
|
||||
cursor.y--;
|
||||
cursor.x = lines_length[cursor.y];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Top-left corner
|
||||
return;
|
||||
}
|
||||
|
||||
if (cursor.x == 0)
|
||||
{
|
||||
cursor.y--;
|
||||
cursor.x = (framebuffer->width / FONT_WIDTH) -1; // here
|
||||
}
|
||||
else {
|
||||
cursor.x--;
|
||||
}
|
||||
|
||||
int px = cursor.x * FONT_WIDTH;
|
||||
int py = cursor.y * FONT_HEIGHT;
|
||||
erase_char(px, py);
|
||||
erase_char(cursor.x * FONT_WIDTH, cursor.y * FONT_HEIGHT);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cursor.x+1)*FONT_WIDTH >= framebuffer->width)
|
||||
if (cursor.x >= max_cols)
|
||||
{
|
||||
cursor.x = 0;
|
||||
cursor.y++;
|
||||
if (cursor.y + 1 >= max_lines)
|
||||
{
|
||||
term_scroll();
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.y++;
|
||||
}
|
||||
}
|
||||
|
||||
int px = cursor.x * FONT_WIDTH;
|
||||
int py = cursor.y * FONT_HEIGHT;
|
||||
draw_char(c, px, py, WHITE, BLACK);
|
||||
draw_char(c, cursor.x * FONT_WIDTH, cursor.y * FONT_HEIGHT, WHITE, BLACK);
|
||||
cursor.x++;
|
||||
}
|
||||
|
||||
@@ -140,7 +199,7 @@ void _putchar(char character)
|
||||
// Debug-printing
|
||||
void kputs(const char* str)
|
||||
{
|
||||
unsigned int i=0;
|
||||
size_t i=0;
|
||||
while (str[i] != 0)
|
||||
{
|
||||
putchar(str[i]);
|
||||
|
||||
@@ -11,6 +11,8 @@ enum TermColors
|
||||
WHITE = 0xffffff
|
||||
};
|
||||
|
||||
#define MAX_LINES 256
|
||||
|
||||
#define PSF1_FONT_MAGIC 0x0436
|
||||
|
||||
typedef struct
|
||||
@@ -20,4 +22,7 @@ typedef struct
|
||||
uint8_t characterSize; // height
|
||||
} PSF1_Header;
|
||||
|
||||
// debug
|
||||
void term_scroll();
|
||||
|
||||
#endif
|
||||
|
||||
16
src/kernel.h
16
src/kernel.h
@@ -1,6 +1,10 @@
|
||||
#ifndef KERNEL_H
|
||||
#define KERNEL_H
|
||||
|
||||
#define PEPPEROS_VERSION_MAJOR "0"
|
||||
#define PEPPEROS_VERSION_MINOR "0"
|
||||
#define PEPPEROS_VERSION_PATCH "1"
|
||||
|
||||
enum ErrorCodes
|
||||
{
|
||||
ENOMEM,
|
||||
@@ -12,12 +16,24 @@ enum ErrorCodes
|
||||
|
||||
#include "io/serial/serial.h"
|
||||
#include "io/term/printf.h"
|
||||
#include "idt/idt.h"
|
||||
|
||||
#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__)
|
||||
|
||||
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
||||
|
||||
// printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__);
|
||||
|
||||
void panic(struct cpu_status_t* ctx);
|
||||
void hcf();
|
||||
#define assert(check) do { if(!(check)) hcf(); } while(0)
|
||||
|
||||
struct boot_context
|
||||
{
|
||||
struct limine_framebuffer* fb;
|
||||
struct limine_memmap_response* mmap;
|
||||
struct limine_hhdm_response* hhdm;
|
||||
struct limine_kernel_address_response* kaddr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
55
src/kmain.c
55
src/kmain.c
@@ -53,8 +53,6 @@ static volatile LIMINE_REQUESTS_START_MARKER;
|
||||
__attribute__((used, section(".limine_requests_end")))
|
||||
static volatile LIMINE_REQUESTS_END_MARKER;
|
||||
|
||||
struct limine_framebuffer* framebuffer;
|
||||
|
||||
// Panic (should dump registers etc. in the future)
|
||||
void hcf()
|
||||
{
|
||||
@@ -64,28 +62,36 @@ void hcf()
|
||||
}
|
||||
}
|
||||
|
||||
void panic(struct cpu_status_t* ctx)
|
||||
{
|
||||
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\nSomething went horribly wrong! vect=0x%.2x errcode=0x%x\nrax=%p rbx=%p rcx=%p rdx=%p\nrsi=%p rdi=%p r8=%p r9=%p\nr10=%p r11=%p r12=%p r13=%p\nr14=%p r15=%p\n\nflags=%p\nstack at rbp=%p\nHalting...",
|
||||
ctx->iret_rip,
|
||||
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
|
||||
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags,
|
||||
ctx->rbp);
|
||||
hcf();
|
||||
}
|
||||
|
||||
const char* splash = "pepperOS version "PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\n";
|
||||
|
||||
struct boot_context boot_ctx;
|
||||
|
||||
// This is our entry point
|
||||
void kmain()
|
||||
{
|
||||
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
|
||||
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) hcf();
|
||||
|
||||
// We should probably grab all the boot info in a boot context struct
|
||||
// that would be a bit cleaner than this mess
|
||||
|
||||
// Get the first framebuffer from the response
|
||||
framebuffer = framebuffer_request.response->framebuffers[0];
|
||||
// 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;
|
||||
|
||||
serial_init();
|
||||
|
||||
if (memmap_request.response == NULL) hcf();
|
||||
memmap_display(memmap_request.response);
|
||||
|
||||
if (hhdm_request.response == NULL) hcf();
|
||||
hhdm_display(hhdm_request.response);
|
||||
|
||||
if (kerneladdr_request.response == NULL) hcf();
|
||||
DEBUG("kernel: phys_base=0x%p virt_base=0x%p", kerneladdr_request.response->physical_base, kerneladdr_request.response->virtual_base);
|
||||
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();
|
||||
@@ -93,10 +99,10 @@ void kmain()
|
||||
timer_init();
|
||||
SET_INTERRUPTS;
|
||||
|
||||
pmm_init(memmap_request.response, hhdm_request.response);
|
||||
pmm_init(boot_ctx.mmap, boot_ctx.hhdm);
|
||||
|
||||
// Remap kernel , HHDM and framebuffer
|
||||
paging_init(kerneladdr_request.response, framebuffer);
|
||||
paging_init(boot_ctx.kaddr, boot_ctx.fb);
|
||||
|
||||
kheap_init();
|
||||
|
||||
@@ -110,10 +116,13 @@ void kmain()
|
||||
keyboard_init(FR);
|
||||
|
||||
term_init();
|
||||
// Draw something
|
||||
printf("%s, %s!\n", "Hello", "world");
|
||||
// Yoohoooooo!
|
||||
//DEBUG("kernel initialized successfully! hanging... wow=%d", 42);
|
||||
printf("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non justo a magna bibendum auctor viverra rutrum diam. In hac habitasse platea dictumst. Vestibulum suscipit ipsum eget tortor maximus lobortis. Donec vel ipsum id lacus fringilla bibendum id eget risus. Fusce vestibulum diam sit amet nunc ultricies, nec rutrum nibh congue. Donec fringilla a dui sit amet ullamcorper. Donec pharetra quis tortor id congue. Aliquam erat volutpat. Duis suscipit nulla vel ligula iaculis, in gravida mauris pellentesque. Vestibulum nunc nisl, posuere eu eros et, dictum molestie dolor. Donec posuere laoreet hendrerit. Suspendisse potenti. Proin fringilla vehicula malesuada. Quisque a dui est. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur nec aliquam lacus, at lacinia enim. ");
|
||||
kputs(splash);
|
||||
|
||||
for (int i=0; i<10; i++)
|
||||
{
|
||||
printf("testing, attention please %d\n", i);
|
||||
}
|
||||
// term_scroll();
|
||||
|
||||
hcf();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ void vmm_setup_pt_root()
|
||||
DEBUG("VMM setup: vmm_pt_root=0x%p (phys=0x%p)", vmm_pt_root, phys);
|
||||
}
|
||||
|
||||
void* vmm_alloc(size_t length, size_t flags)
|
||||
/* void* vmm_alloc(size_t length, size_t flags)
|
||||
{
|
||||
// We will try to allocate at least length bytes, which have to be rounded UP to
|
||||
// the next page so its coherent with the PMM
|
||||
@@ -58,7 +58,7 @@ void* vmm_alloc(size_t length, size_t flags)
|
||||
// Need to implement this (as linked list)
|
||||
// but for now kernel heap is sufficient
|
||||
// The VMM will prob be more useful when we have userspace
|
||||
}
|
||||
} */
|
||||
|
||||
void vmm_init()
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@ void pic_enable()
|
||||
// Enabling IRQ0 (unmasking it) but not the others
|
||||
uint8_t mask = inb(0x21);
|
||||
mask &= ~(1 << 0); // Set IRQ0 (timer, clear bit 0)
|
||||
mask &= ~(1 << 1); // Set IRQ1 (PS/2 Keyboard, clear bit 1)
|
||||
//mask &= ~(1 << 1); // Set IRQ1 (PS/2 Keyboard, clear bit 1)
|
||||
outb(0x21, mask);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,17 @@ void pit_init()
|
||||
outb(0x40, (divisor >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
// Wait n ticks
|
||||
// Given that there's a tick every 1ms, wait n milliseconds
|
||||
void timer_wait(uint64_t wait_ticks)
|
||||
{
|
||||
uint64_t then = ticks + wait_ticks;
|
||||
while (ticks < then)
|
||||
{
|
||||
asm("hlt");
|
||||
};
|
||||
}
|
||||
|
||||
void timer_init()
|
||||
{
|
||||
// Remapping the PIC, because at startup it conflicts with
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
#define TIMER_H
|
||||
|
||||
void timer_init();
|
||||
void timer_wait(unsigned int wait_ticks);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user