From ed4d960607d754c407a6964af86afcf0ad294123 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Fri, 30 Apr 2021 22:30:46 +0200 Subject: Some small fixes here and there --- kernel/drivers/fb.c | 13 ++++++++----- kernel/drivers/gdt.c | 33 ++++++++++++++++++++++++++------- kernel/drivers/interrupts.c | 2 +- kernel/features/proc.c | 8 +++++++- kernel/features/syscall.c | 4 ++-- kernel/inc/proc.h | 1 + 6 files changed, 45 insertions(+), 16 deletions(-) (limited to 'kernel') diff --git a/kernel/drivers/fb.c b/kernel/drivers/fb.c index 2a29eb7..8831a52 100644 --- a/kernel/drivers/fb.c +++ b/kernel/drivers/fb.c @@ -24,12 +24,11 @@ struct vbe_basic { PROTECTED static struct vbe_basic *vbe = NULL; -static void fb_map_buffer(struct page_dir *dir) +static u32 fb_map_buffer(struct page_dir *dir) { - // TODO: Return virtual mapped address assert(vbe); u32 size = vbe->height * vbe->pitch; - memory_map_identity(dir, memory_range_around((u32)vbe->fb, size), MEMORY_USER); + return virtual_alloc(dir, memory_range_around((u32)vbe->fb, size), MEMORY_USER).base; } static u32 fb_owner = 0; @@ -52,8 +51,9 @@ static res fb_ioctl(u32 request, void *arg1, void *arg2, void *arg3) else fb_owner = proc_current()->pid; + u32 fb = fb_map_buffer(proc_current()->page_dir); + vbe->fb = (u8 *)fb; memcpy_user(arg1, vbe, size); - fb_map_buffer(proc_current()->page_dir); return EOK; } default: @@ -69,5 +69,8 @@ CLEAR void fb_install(void) dev->control = fb_ioctl; io_add(IO_FRAMEBUFFER, dev); - fb_map_buffer(virtual_kernel_dir()); + // Identity map framebuffer to kernel to prevent unwanted writing + u32 size = vbe->height * vbe->pitch; + memory_map_identity(virtual_kernel_dir(), memory_range_around((u32)vbe->fb, size), + MEMORY_CLEAR); } diff --git a/kernel/drivers/gdt.c b/kernel/drivers/gdt.c index 66a9086..8209eaf 100644 --- a/kernel/drivers/gdt.c +++ b/kernel/drivers/gdt.c @@ -5,6 +5,17 @@ #include #include +#define GDT_MAX_LIMIT 0xffff +#define GDT_PRESENT (1 << 7) +#define GDT_RING3 (3 << 5) +#define GDT_DESCRIPTOR (1 << 4) +#define GDT_EXECUTABLE (1 << 3) +#define GDT_READWRITE (1 << 1) +#define GDT_ACCESSED (1 << 0) +#define GDT_GRANULARITY (0x80 | 0x00) +#define GDT_SIZE (0x40 | 0x00) +#define GDT_DATA_OFFSET 0x10 + static struct gdt_entry gdt[6] = { 0 }; static struct tss_entry tss = { 0 }; @@ -24,12 +35,14 @@ CLEAR static void gdt_set_gate(u32 num, u32 base, u32 limit, u8 access, u8 gran) gdt[num].access = access; } +// TODO: Fix GPF for in/out operations in userspace (not necessarily a TSS problem) CLEAR static void tss_write(u32 num, u16 ss0, u32 esp0) { u32 base = (u32)&tss; u32 limit = base + sizeof(tss); - gdt_set_gate(num, base, limit, 0xe9, 0x00); + gdt_set_gate(num, base, limit, GDT_PRESENT | GDT_RING3 | GDT_EXECUTABLE | GDT_ACCESSED, + GDT_SIZE); memset(&tss, 0, sizeof(tss)); @@ -41,7 +54,7 @@ CLEAR static void tss_write(u32 num, u16 ss0, u32 esp0) CLEAR static void tss_flush(void) { - __asm__ volatile("ltr %0" ::"r"((u16)0x2b)); + __asm__ volatile("ltr %0" ::"r"((u16)((u32)&gdt[5] - (u32)gdt))); } CLEAR static void gdt_flush(void) @@ -59,23 +72,29 @@ void tss_set_stack(u32 ss, u32 esp) CLEAR void gdt_install(u32 esp) { // Set GDT pointer and limit - gp.limit = (sizeof(struct gdt_entry) * 6) - 1; + gp.limit = sizeof(gdt) - 1; gp.base = &gdt; // NULL descriptor gdt_set_gate(0, 0, 0, 0, 0); // Code segment - gdt_set_gate(1, 0, 0xffffffff, 0x9a, 0xcf); + gdt_set_gate(1, 0, 0xffffffff, + GDT_PRESENT | GDT_DESCRIPTOR | GDT_EXECUTABLE | GDT_READWRITE, + GDT_GRANULARITY | GDT_SIZE); // Data segment - gdt_set_gate(2, 0, 0xffffffff, 0x92, 0xcf); + gdt_set_gate(2, 0, 0xffffffff, GDT_PRESENT | GDT_DESCRIPTOR | GDT_READWRITE, + GDT_GRANULARITY | GDT_SIZE); // User mode code segment - gdt_set_gate(3, 0, 0xffffffff, 0xfa, 0xcf); + gdt_set_gate(3, 0, 0xffffffff, + GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_EXECUTABLE | GDT_READWRITE, + GDT_GRANULARITY | GDT_SIZE); // User mode data segment - gdt_set_gate(4, 0, 0xffffffff, 0xf2, 0xcf); + gdt_set_gate(4, 0, 0xffffffff, GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_READWRITE, + GDT_GRANULARITY | GDT_SIZE); // Write TSS tss_write(5, GDT_SUPER_DATA_OFFSET, esp); diff --git a/kernel/drivers/interrupts.c b/kernel/drivers/interrupts.c index 5b94b94..7a57a91 100644 --- a/kernel/drivers/interrupts.c +++ b/kernel/drivers/interrupts.c @@ -188,7 +188,7 @@ void isr_panic(struct regs *r) } else { __asm__ volatile("cli\nhlt"); } - proc_yield(); + proc_yield_regs(r); } void isr_handler(struct regs *r); diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 36ee6b9..3039231 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -185,7 +185,7 @@ void proc_exit(struct proc *proc, struct regs *r, s32 status) free(proc); - proc_yield(); + proc_yield_regs(r); } void proc_yield(void) @@ -195,6 +195,12 @@ void proc_yield(void) __asm__ volatile("int $127"); } +void proc_yield_regs(struct regs *r) +{ + proc_reset_quantum(PROC(current)); + scheduler(r); +} + struct proc *proc_make(enum proc_priv priv) { struct proc *proc = zalloc(sizeof(*proc)); diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 23c8d37..b66cd2e 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -88,7 +88,7 @@ static void syscall_handler(struct regs *r) } else { // TODO: Reimplement argc,argv proc_stack_push(proc, 0); - proc_yield(); + proc_yield_regs(r); } break; } @@ -99,7 +99,7 @@ static void syscall_handler(struct regs *r) } case SYS_YIELD: { r->eax = EOK; - proc_yield(); + proc_yield_regs(r); break; } diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h index e74286c..000d77d 100644 --- a/kernel/inc/proc.h +++ b/kernel/inc/proc.h @@ -60,6 +60,7 @@ u8 proc_idle(void); struct proc *proc_from_pid(u32 pid); void proc_exit(struct proc *proc, struct regs *r, s32 status) NONNULL; void proc_yield(void); +void proc_yield_regs(struct regs *r) NONNULL; void proc_set_quantum(struct proc *proc, u32 value); void proc_reset_quantum(struct proc *proc); void proc_state(struct proc *proc, enum proc_state state); -- cgit v1.2.3