dead@root user mode fail

This commit is contained in:
assada 2024-05-22 00:15:05 +03:00
parent 208a80104f
commit c355d80244
Signed by: assada
GPG Key ID: D4860A938E541F06
14 changed files with 219 additions and 78 deletions

View File

@ -10,7 +10,7 @@ KERNEL = deados.bin
ISO = deados.iso
SOURCES_C = kernel.c tty.c idt.c timer.c io.c vga.c gdt.c sys.c irq.c isr.c keyboard.c shell.c string.c user_space.c syscall.c
SOURCES_ASM = boot.s idt_load.s gdt_flush.s pit_handler.s irq_e.s isr_e.s
SOURCES_ASM = boot.s idt_load.s gdt_flush.s pit_handler.s irq_e.s isr_e.s tss.s
OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o)
ISO_DIR = isodir

66
gdt.c
View File

@ -1,29 +1,69 @@
#include "gdt.h"
#include "string.h"
struct gdt_entry gdt[3];
struct gdt_ptr gdtp;
#define GDT_ENTRY 6
Gdt_entry gdt[GDT_ENTRY];
Gdt_ptr gdtp;
extern void gdt_flush(uint32_t);
void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) {
gdt[num].base_low = (base & 0xFFFF);
Tss_entry tss;
extern void tss_flush(void);
static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity)
{
gdt[num].base_low = base & 0xFFFF;
gdt[num].base_middle = (base >> 16) & 0xFF;
gdt[num].base_high = (base >> 24) & 0xFF;
gdt[num].limit_low = (limit & 0xFFFF);
gdt[num].granularity = (limit >> 16) & 0x0F;
gdt[num].limit_low = limit & 0xFFFF;
gdt[num].granularity = (limit >> 16) & 0xF;
gdt[num].granularity |= (granularity & 0xF0);
gdt[num].granularity |= gran & 0xF0;
gdt[num].access = access;
}
void gdt_install() {
gdtp.limit = (sizeof(struct gdt_entry) * 3) - 1;
static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp)
{
uint32_t base = (uint32_t)&tss;
uint32_t limit = base + sizeof(Tss_entry);
gdt_set_gate(num, base, limit, 0xE9, 0x0);
memset(&tss, 0, sizeof(Tss_entry));
tss.ss0 = kernel_ss;
tss.esp0 = kernel_esp;
tss.cs = 0x0B;
tss.ss = 0x13;
tss.es = 0x13;
tss.ds = 0x13;
tss.fs = 0x13;
tss.gs = 0x13;
}
void set_kernel_stack(uint32_t stack)
{
tss.esp0 = stack;
}
void gdt_install()
{
gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // User code segment
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // User data segment
tss_install(5, 0x10, 0x0);
gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
gdtp.base = (uint32_t)&gdt;
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_flush((uint32_t)&gdtp);
tss_flush();
}

47
gdt.h
View File

@ -3,7 +3,9 @@
#include <stdint.h>
struct gdt_entry {
typedef struct gdt_entry_t Gdt_entry;
struct gdt_entry_t
{
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
@ -12,15 +14,48 @@ struct gdt_entry {
uint8_t base_high;
} __attribute__((packed));
struct gdt_ptr {
typedef struct gdt_ptr_t Gdt_ptr;
struct gdt_ptr_t
{
uint16_t limit;
uint32_t base;
} __attribute__((packed));
extern struct gdt_entry gdt[3];
extern struct gdt_ptr gdtp;
void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran);
static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity);
void gdt_install();
void set_kernel_stack(uint32_t stack);
typedef struct tss_entry_t Tss_entry;
struct tss_entry_t
{
uint32_t prevTss;
uint32_t esp0;
uint32_t ss0;
uint32_t esp1;
uint32_t ss1;
uint32_t esp2;
uint32_t ss2;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint32_t es;
uint32_t cs;
uint32_t ss;
uint32_t ds;
uint32_t fs;
uint32_t gs;
uint32_t ldt;
uint16_t trap;
uint16_t iomap;
} __attribute__((packed));
#endif

View File

@ -1,3 +1,6 @@
default=0
timeout=0
menuentry "deadOS" {
multiboot /boot/deados.bin
}

36
idt.c
View File

@ -1,10 +1,12 @@
#include "idt.h"
#include "io.h"
#include "string.h"
#include <stdint.h>
#define IDT_ENTRIES 256
struct idt_entry {
struct idt_entry
{
uint16_t base_lo;
uint16_t sel;
uint8_t always0;
@ -12,7 +14,8 @@ struct idt_entry {
uint16_t base_hi;
} __attribute__((packed));
struct idt_ptr {
struct idt_ptr
{
uint16_t limit;
uint32_t base;
} __attribute__((packed));
@ -20,7 +23,8 @@ struct idt_ptr {
struct idt_entry idt[IDT_ENTRIES];
struct idt_ptr idtp;
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
{
idt[num].base_lo = base & 0xFFFF;
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt[num].sel = sel;
@ -28,28 +32,12 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
idt[num].flags = flags | 0x60;
}
void idt_install() {
void idt_install()
{
idtp.limit = (sizeof(struct idt_entry) * IDT_ENTRIES) - 1;
idtp.base = (uint32_t)&idt;
memset(&idt, 0, sizeof(struct idt_entry) * IDT_ENTRIES);
idt_load();
}
void pic_remap(int offset1, int offset2) {
unsigned char a1, a2;
a1 = inb(0x21);
a2 = inb(0xA1);
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, offset1);
outb(0xA1, offset2);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, a1);
outb(0xA1, a2);
}

View File

@ -18,7 +18,6 @@ void kernel_main(void)
gdt_install();
idt_install();
isr_install();
irq_install();
@ -26,20 +25,18 @@ void kernel_main(void)
keyboard_install();
sys_enable_interrupts();
terminal_printc("Hello, &ekernel &7World!\n&5Magenta String Example\nThis is a &4red string&7.\n");
terminal_printc("Welcome to &cDeadOS&7.\n");
for (int i = 0; i < 3; i++)
{
terminal_printc("&cDead &7");
terminal_putchar('0' + (i / 10));
terminal_putchar('0' + (i % 10));
terminal_printc("\n");
delay(500);
delay(100);
}
// syscall_init();
syscall_init();
// enter_user_space();
enter_user_space();
shell_init();
}

View File

@ -80,7 +80,7 @@ void shell_echo_command(char *input)
void shell_parse_input(char *input)
{
char *command = strtok(input, " \n");
char *first_param = strtok(NULL, " \n");
char *args = input + strlen(command) + 1;
if (command == NULL || *command == '\0')
{
@ -93,7 +93,7 @@ void shell_parse_input(char *input)
}
else if (strcmp(command, "echo") == 0)
{
shell_echo_command(first_param);
shell_echo_command(args);
}
else if (strcmp(command, "exit") == 0)
{

View File

@ -1,6 +1,26 @@
#include "string.h"
#include <stddef.h>
size_t strlen(const char *str)
{
size_t len = 0;
while (str[len])
++len;
return len;
}
void *memset(void *ptr, int value, size_t size)
{
unsigned char *buf = (unsigned char *)ptr;
for (size_t i = 0; i < size; ++i)
buf[i] = (unsigned char)value;
return ptr;
}
int strcmp(const char *str1, const char *str2)
{
while (*str1 && (*str1 == *str2))
@ -11,17 +31,17 @@ int strcmp(const char *str1, const char *str2)
return *(const unsigned char *)str1 - *(const unsigned char *)str2;
}
char *strchr(const char *str, int c)
char *strchr(const char *str, int character)
{
while (*str != '\0')
size_t i = 0;
while (str[i] != (char)character)
{
if (*str == c)
{
return (char *)str;
}
str++;
if (str[i] == '\0')
return NULL;
++i;
}
return NULL;
return (char *)(str + i);
}
char *strtok(char *str, const char *delim)

View File

@ -1,8 +1,13 @@
#ifndef STRING_H
#define STRING_H
#include <stddef.h>
char *strchr(const char *str, int c);
char *strtok(char *str, const char *delim);
int strcmp(const char *str1, const char *str2);
size_t strlen(const char *str);
void *memset(void *ptr, int value, size_t size);
#endif

View File

@ -1,23 +1,51 @@
#include <stdint.h>
#include "interrupts.h"
#include "keyboard.h"
#include "sys.h"
#include "syscall.h"
#include "tty.h"
void test_syscall()
{
terminal_printc("Test syscall called\n");
}
#define NB_SYSCALL 8
void *syscalls[NB_SYSCALL] = {
terminal_writestring,
keyboard_getchar,
terminal_printc,
terminal_clear,
terminal_putchar,
terminal_putentryat,
keyboard_clear_buffer,
sys_halt};
void syscall_handler(Stack *registers)
{
terminal_writestring("Syscall\n");
int sys_index = registers->eax;
if (sys_index != 0)
{
if (sys_index >= NB_SYSCALL)
return;
}
test_syscall();
void *function = syscalls[sys_index];
int ret;
asm volatile(" push %1; \
push %2; \
push %3; \
push %4; \
push %5; \
call *%6; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
pop %%ebx; \
" : "=a"(ret) : "r"(registers->edi), "r"(registers->esi),
"r"(registers->edx), "r"(registers->ecx),
"r"(registers->ebx), "r"(function));
registers->eax = ret;
}
void syscall_init(void)

21
timer.c
View File

@ -15,6 +15,27 @@ void pit_handler()
outb(0x20, 0x20);
}
void pic_remap(int offset1, int offset2)
{
unsigned char a1, a2;
a1 = inb(0x21);
a2 = inb(0xA1);
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, offset1);
outb(0xA1, offset2);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, a1);
outb(0xA1, a2);
}
void delay(uint32_t milliseconds)
{
uint32_t end = tick + milliseconds;

9
tss.s Normal file
View File

@ -0,0 +1,9 @@
.section .text
.align 4
.global tss_flush
.type tss_flush, @function
tss_flush:
mov $0x2B, %ax
ltr %ax
ret

9
tty.c
View File

@ -4,14 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
size_t strlen(const char *str)
{
size_t len = 0;
while (str[len])
len++;
return len;
}
#include "string.h"
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;

View File

@ -1,8 +1,10 @@
#include "user_space.h"
#include "gdt.h"
void enter_user_space(void)
{
asm volatile(" cli; \
set_kernel_stack(0x110); // 128KB ?? WHY? ??
asm volatile("cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \