Compare commits

..

9 Commits

20 changed files with 117 additions and 35 deletions

View File

@ -12,9 +12,6 @@
"C_Cpp.default.includePath": ["src/kernel/include", "sysroot/usr/include"],
"C_Cpp.default.cStandard": "c17",
"files.associations": {
"cpu.h": "c"
},
"[c]": {
"editor.tabSize": 2,
},

View File

@ -27,7 +27,7 @@ endif
musllib: $(SYSROOT)/usr/lib/libc.a
$(SYSROOT)/usr/lib/libc.a:
${BUILDROOT}/toolchain/build-musl.sh
$(BUILDROOT)/toolchain/ports/musl/build.sh
libmittos: $(SYSROOT)/usr/lib/libmittos.a
$(SYSROOT)/usr/lib/libmittos.a: FORCE
@ -46,4 +46,7 @@ distclean:
$(MAKE) clean
rm -rf $(SYSROOT)
love: FORCE
@echo Not war?
.PHONY: all dist sysroot FORCE

View File

@ -2,6 +2,7 @@
> - [PIC data sheet](http://pdos.csail.mit.edu/6.828/2005/readings/hardware/8259A.pdf)
> - [IOAPIC data sheet](http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf)
The Advanced Programmable Interrupt Controller (APIC) is not to be confused with (ACPI).
It's quite literally an upgrade to the legacy PIC and handles hardware interrupts and IRQs.

View File

@ -1,7 +1,7 @@
ENTRY(_start)
KERNEL_OFFSET = 0xFFFFFF8000000000;
KERNEL_START = 0x10000;
KERNEL_START = 0x100000;
SECTIONS
{
@ -10,20 +10,20 @@ SECTIONS
.text : AT(ADDR(.text) - KERNEL_OFFSET)
{
*(.multiboot)
*(.text)
*(.text*)
}
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET)
{
*(.rodata*)
}
.data : AT(ADDR(.data) - KERNEL_OFFSET)
.data ALIGN(0x1000) : AT(ADDR(.data) - KERNEL_OFFSET)
{
*(.data)
*(.data*)
}
.bss : AT(ADDR(.bss) - KERNEL_OFFSET)
{
*(.COMMON)
*(.bss)
*(.bss*)
}
kernel_end = .;
}

View File

@ -3,6 +3,7 @@
#include <mittos/graphics.h>
#include <memory.h>
#include <cpu.h>
#include <math.h>
extern gfx_context *term_fb;
extern gfx_context kernel_fb;
@ -11,8 +12,10 @@ int *position = (void *)0x20000;
void thread1() {
int a = 1;
double prev = 0;
gfx_context *ctx =
framebuffer_make_subcontext(&kernel_fb, 700, 300, 100, 100);
__asm__("sti");
while(1) {
putCharacter(term_fb,
*position, *position,
@ -20,14 +23,19 @@ void thread1() {
'0'+(a++%10)
);
int s = (current_cpu->timer_ticks/1000)%10;
double cur = (double)(current_cpu->timer_ticks/100);
putCharacter(term_fb,
0, 0,
RGB(255,255,0), RGB(0,0,0),
'0'+(s%10)
);
flip(term_fb);
draw_line(ctx, 0, 100, 50, ((a-1)%100), RGB(0,0,0));
draw_line(ctx, 0, 100, 50, (a%100), RGB(255,0,0));
double angle = cur/3.14*2;
draw_line(ctx, 50, 50 + (int)(50*cos(prev)), 50, 50 + (int)(50*sin(prev)), RGB(0,0,0));
draw_line(ctx, 50, 50 + (int)(50*cos(angle)), 50, 50 + (int)(50*sin(angle)), RGB(255,0,0));
prev = angle;
flip(ctx);
sched_yield();
}
@ -35,7 +43,17 @@ void thread1() {
void thread2() {
int a = 0;
gfx_context *ctx =
framebuffer_make_subcontext(&kernel_fb, 800, 400, 100, 100);
__asm__("sti");
while(1) {
double pos = (double)(current_cpu->timer_ticks/100);
fill_rect(ctx, 0, 0, 100, 100, 0);
for(int i = 0; i < 10000; i++) {
putpixel(ctx, i/100, 50 + (int)(50.0*sin(pos + ((double)i)/1000.0)), RGB(0,0,255));
putpixel(ctx, i/100, 50 + (int)(50.0*cos(pos + ((double)i)/1000.0)), RGB(255,0,0));
}
flip(ctx);
putCharacter(term_fb,
*position, *position,
RGB(0,255,255), RGB(0,0,0),

View File

@ -41,8 +41,6 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) {
cpu_init();
__asm__("sti");
debug_info("Boot complete\n");
@ -50,6 +48,7 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) {
irq_unmask(IRQ_PS2_KBD);
TEMP_test_scheduler();
__asm__("sti");
start_scheduler();

View File

@ -27,4 +27,5 @@ void cpu_init() {
apic_init();
ioapic_init();
timer_init();
sse_init();
}

30
src/kernel/cpu/sse.S Normal file
View File

@ -0,0 +1,30 @@
.intel_syntax noprefix
.global sse_init
sse_init:
//; Enable bits 9 and 10 in cr4
//; 9: Enable SSE instructions
//; 10: Enable SSE exceptions
mov rax, cr4
or rax, 1<<9 | 1<<10
mov cr4, rax
//; Set bit 1 and unset bit 2 in cr0
//; 1: Coprocessor monitoring
//; 2: Coprocessor emulation
mov rax, cr0
or rax, 1<<1
and rax, ~(1<<2)
mov cr0, rax
ret
.global sse_save
sse_save:
fxsave [rdi]
ret
.global sse_restore
sse_restore:
fxrstor [rdi]
ret

View File

@ -69,6 +69,7 @@ volatile int ctr = 0;
registers *apic_timer_handler(registers *r) {
current_cpu->timer_ticks++;
irq_ack();
// k_sched_yield();
return r;
}

View File

@ -99,3 +99,8 @@ void ioapic_init();
// cpu/timer.c
void timer_init();
// cpu/sse.S
void sse_init();
void sse_save(void *addr);
void sse_restore(void *addr);

View File

@ -7,6 +7,7 @@ struct process {
uint64_t state;
uint64_t P4;
struct process *q_next;
void *sse;
uint8_t stack[];
};

View File

@ -1,5 +1,7 @@
#include <memory.h>
#include <debug.h>
#include <sys/mman.h>
#include <string.h>
static long _brk = KERNEL_BRK0;
static long _mmap = KERNEL_MMAP;
@ -33,14 +35,22 @@ long k_mmap(
if(fd != -1)
PANIC("Unknown mmap request\n");
long retval = _mmap;
while(length > 0) {
long pos = (flags & MAP_FIXED) ? addr : _mmap;
long retval = pos;
uint64_t p;
while(length >= 0) {
p = pmm_alloc();
vmm_set_page(kernel_P4,
_mmap, pmm_alloc(),
pos, p,
PAGE_GLOBAL | PAGE_WRITE | PAGE_PRESENT
);
_mmap += PAGE_SIZE;
if(flags & MAP_ANONYMOUS) {
memset((void *)pos, 0, PAGE_SIZE);
}
pos += PAGE_SIZE;
length -= PAGE_SIZE;
}
if(!(flags & MAP_FIXED))
_mmap = pos;
return retval;
}

View File

@ -1,6 +1,7 @@
#include <stdint.h>
#include <proc.h>
#include <memory.h>
#include <stdlib.h>
struct swtch_stack {
uint64_t RBP;
@ -24,6 +25,10 @@ struct process *new_process(void (*function)(void)) {
p->q_next = 0;
p->P4 = new_P4();
// Storage for SSE registers must be 16 byte aligned
void *sse = malloc(512+15);
p->sse = (void *) (((uintptr_t)sse + 15) & ~0xF);
struct swtch_stack *stck = p->stack_ptr;
stck->RBP = (uint64_t)&stck->RBP2;
stck->ret = (uint64_t)function;

View File

@ -32,8 +32,11 @@ void scheduler() {
current_proc = new;
write_cr3(new->P4);
sse_restore(current_proc->sse);
switch_stack(&scheduler_proc->stack_ptr, &new->stack_ptr);
sse_save(current_proc->sse);
scheduler_insert(current_proc);
current_proc = 0;
}

View File

@ -19,7 +19,7 @@ libmittos.a: $(OBJ)
graphics/graphics.o: graphics/u_vga16.termfont.inc
graphics/u_vga16.termfont.inc:
${BUILDROOT}/toolchain/build-uni_vga.sh
${BUILDROOT}/toolchain/ports/uni_vga/build.sh
# Automatic dependency tracking
DEP := $(OBJ:.o=.d)
@ -31,7 +31,7 @@ $(OBJ): CPPFLAGS += $(DEPFLAGS)
# Installation
DESTDIR ?= $(BUILDROOT)/sysroot
LIBDIR := $(DESTDIR)/usr/lib
INCDIR := $(DESTDIR)/usr/include/mittos
INCDIR := $(DESTDIR)/usr/include
$(LIBDIR)/libmittos.a: libmittos.a
install -D $< $@

View File

@ -1,7 +1,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <graphics.h>
#include <mittos/graphics.h>
#define incptr(p, n) ((void *)(((uintptr_t)(p)) + (n)))
@ -27,23 +27,32 @@ void draw_line(
uint64_t y0, uint64_t y1,
uint32_t clr
) {
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
int64_t dx = x1 > x0 ? x1 - x0 : x0 - x1;
int sx = x0 < x1 ? 1 : -1;
int64_t dy = y1 > y0 ? y1 - y0 : y0 - y1;
int sx = x1 > x0 ? 1 : -1;
int sy = y1 > y0 ? 1 : -1;
uint64_t x = x0, y = y0;
int64_t diff = dx - dy;
dy = -dy;
int sy = y0 < y1 ? 1 : -1;
int64_t err = dx + dy;
uint32_t *fb = (uint32_t *)ctx->buffer;
while(1) {
fb[PXL(ctx, x, y)] = clr;
if(x == x1 && y == y1) break;
if(0 < x0 && x0 < ctx->width &&
0 < y0 && y0 < ctx->height)
fb[PXL(ctx, x0, y0)] = clr;
if(x0 == x1 && y0 == y1) break;
if((2*diff) > -dy) {
diff -= dy;
x += sx;
} else {
diff += dx;
y += sy;
int64_t e2 = 2*err;
if(e2 >= dy) {
if(x0 == x1) break;
err += dy;
x0 += sx;
}
if(e2 <= dx) {
if(y0 == y1) break;
err += dx;
y0 += sy;
}
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <stdlib.h>
#include <stdint.h>
typedef struct {
uint32_t width;

View File

@ -58,7 +58,5 @@ mkdir gcc-build && cd gcc-build
make all-gcc all-target-libgcc -j 4
make install-gcc install-target-libgcc
apk del build-base
cd /
rm -rf /opt