dead@root fuck this shit

This commit is contained in:
assada 2024-05-23 20:59:18 +03:00
parent c355d80244
commit 5bd849abeb
Signed by: assada
GPG Key ID: D4860A938E541F06
23 changed files with 340 additions and 236 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 tss.s
SOURCES_ASM = boot.s idt_load.s gdt_flush.s irq_flush.s isr_flush.s tss_flush.s
OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o)
ISO_DIR = isodir

12
boot.s
View File

@ -12,24 +12,20 @@
.section .bss
.align 16
stack_bottom:
.skip 1024 * 32 # 32 KB
.skip 16384
stack_top:
stack_top:
.section .text
.global _start
.type _start, @function
_start:
cli
mov $stack_top, %esp
push %ebx
call kernel_main
hlt
jmp 1
1:
jmp 1
jmp 1b
.size _start, . - _start

50
gdt.c
View File

@ -4,14 +4,14 @@
#define GDT_ENTRY 6
Gdt_entry gdt[GDT_ENTRY];
Gdt_ptr gdtp;
Gdt_ptr gdt_ptr;
extern void gdt_flush(uint32_t);
extern void gdt_flush(void);
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)
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;
@ -25,45 +25,37 @@ static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t acc
gdt[num].access = access;
}
static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp)
void tss_set_gate(uint32_t num, uint16_t ss0, uint32_t esp0)
{
uint32_t base = (uint32_t)&tss;
uint32_t limit = base + sizeof(Tss_entry);
gdt_set_gate(num, base, limit, 0xE9, 0x0);
memset(&tss, 0x0, sizeof(Tss_entry));
tss.ss0 = ss0;
tss.esp0 = esp0;
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;
tss.cs = 0x1B;
tss.ss = 0x23;
tss.es = 0x23;
tss.ds = 0x23;
tss.fs = 0x23;
tss.gs = 0x23;
}
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
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xC0); // 0x08 Kernel code segment
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xC0); // 0x10 Kernel data segment
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xC0); // 0x18 User code segment
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xC0); // 0x20 User data segment
tss_install(5, 0x10, 0x0);
tss_set_gate(5, 0x10, 0);
gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
gdtp.base = (uint32_t)&gdt;
gdt_ptr.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
gdt_ptr.base = (uint32_t)&gdt;
gdt_flush((uint32_t)&gdtp);
gdt_flush();
tss_flush();
}

2
gdt.h
View File

@ -21,7 +21,7 @@ struct gdt_ptr_t
uint32_t base;
} __attribute__((packed));
static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity);
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);

View File

@ -1,19 +1,17 @@
.section .text
.align 4
.global gdt_flush
.type gdt_flush, @function
gdt_flush:
cli
lgdt gdt_ptr
jmp $0x08, $reload_cs
mov 4(%esp), %eax
lgdt (%eax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
jmp $0x08, $.flush
.flush:
ret
reload_cs:
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
ret

View File

@ -1,5 +1,8 @@
.section .text
.align 4
.global idt_load
.type idt_load, @function
idt_load:
lidt [idtp]
lidt idtp
ret

View File

@ -25,8 +25,8 @@ void isr_install(void);
#define NB_IRQ_ROUTINES 16
#define PIC1 0x20 /* master PIC */
#define PIC2 0xA0 /* slave PIC */
#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_CMD PIC1
#define PIC1_DATA (PIC1 + 1)
#define PIC2_CMD PIC2

16
io.c
View File

@ -1,18 +1,20 @@
#include "io.h"
void outb(uint16_t port, uint8_t val) {
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
void outb(uint16_t port, uint8_t val)
{
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
}
uint8_t inb(uint16_t port) {
uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
void io_wait(void)
{
asm volatile ( "jmp 1f\n\t"
"1:jmp 2f\n\t"
"2:" );
asm volatile("jmp 1f\n\t"
"1:jmp 2f\n\t"
"2:");
}

11
irq.c
View File

@ -4,6 +4,7 @@
#include "io.h"
#include "sys.h"
#include "idt.h"
#include "tty.h"
extern void irq0(void);
extern void irq1(void);
@ -42,24 +43,16 @@ void irq_call_handler(Stack *registers)
handler(registers);
}
static void irq_remap(void)
static void irq_remap(void) // PIC REMAP
{
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC1_DATA, PIC1_OFFSET);
io_wait();
outb(PIC2_DATA, PIC2_OFFSET);
io_wait();
outb(PIC1_DATA, 0x04);
io_wait();
outb(PIC2_DATA, 0x02);
io_wait();
outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
}
void irq_install(void)

View File

@ -30,7 +30,6 @@ IRQ 15, 47
irq_common_stub:
pusha
push %ds
push %es
push %fs
@ -56,4 +55,4 @@ irq_common_stub:
popa
add $8, %esp
iret
iret

13
isr.c
View File

@ -139,23 +139,20 @@ static const char *exception_messages[] =
void fault_handler(Stack *registers)
{
// check this
if (registers->id == 128)
{
isr_call_handler(registers);
}
if (registers->id < 32)
{
terminal_printc("Exception. System Halted!\n");
const char *message = exception_messages[registers->id];
while (*message)
{
terminal_putchar(*message);
message++;
}
isr_call_handler(registers);
for (;;)
{
sys_halt();
}
}
}

85
isr_e.s
View File

@ -1,85 +0,0 @@
.section .text
.align 4
.macro ISR_NO_ERR index
.global isr\index
isr\index:
cli
push $0
push $\index
jmp isr_common_stub
.endm
.macro ISR_ERR index
.global isr\index
isr\index:
cli
push $\index
jmp isr_common_stub
.endm
ISR_NO_ERR 0 # Division By Zero Exception
ISR_NO_ERR 1 # Debug Exception
ISR_NO_ERR 2 # Non Maskable Interrupt Exception
ISR_NO_ERR 3 # Breakpoint Exception
ISR_NO_ERR 4 # Into Detected Overflow Exception
ISR_NO_ERR 5 # Out of Bounds Exception
ISR_NO_ERR 6 # Invalid Opcode Exception
ISR_NO_ERR 7 # No Coprocessor Exception
ISR_ERR 8 # Double Fault Exception
ISR_NO_ERR 9 # Coprocessor Segment Overrun Exception
ISR_ERR 10 # Bad TSS Exception
ISR_ERR 11 # Segment Not Present Exception
ISR_ERR 12 # Stack Fault Exception
ISR_ERR 13 # General Protection Fault Exception
ISR_ERR 14 # Page Fault Exception
ISR_NO_ERR 15 # Unknown Interrupt Exception
ISR_NO_ERR 16 # Coprocessor Fault Exception
ISR_NO_ERR 17 # Alignment Check Exception
ISR_NO_ERR 18 # Machine Check Exception
ISR_NO_ERR 19 # Other
ISR_NO_ERR 20
ISR_NO_ERR 21
ISR_NO_ERR 22
ISR_NO_ERR 23
ISR_NO_ERR 24
ISR_NO_ERR 25
ISR_NO_ERR 26
ISR_NO_ERR 27
ISR_NO_ERR 28
ISR_NO_ERR 29
ISR_NO_ERR 30
ISR_NO_ERR 31
ISR_NO_ERR 128 # Syscal
isr_common_stub:
pusha
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %esp, %eax
push %eax
mov $fault_handler, %eax
call *%eax
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret

102
isr_flush.s Normal file
View File

@ -0,0 +1,102 @@
.section .text
.align 4
.macro ISR_NO_ERR index
.global isr\index
isr\index:
cli
push $0
push $\index
jmp isr_common_stub
.endm
.macro ISR_ERR index
.global isr\index
isr\index:
cli
push $\index
jmp isr_common_stub
.endm
/* Division By Zero Exception */
ISR_NO_ERR 0
/* Debug Exception */
ISR_NO_ERR 1
/* Non Maskable Interrupt Exception */
ISR_NO_ERR 2
/* Breakpoint Exception */
ISR_NO_ERR 3
/* Into Detected Overflow Exception */
ISR_NO_ERR 4
/* Out of Bounds Exception */
ISR_NO_ERR 5
/* Invalid Opcode Exception */
ISR_NO_ERR 6
/* No Coprocessor Exception */
ISR_NO_ERR 7
/* Double Fault Exception */
ISR_ERR 8
/* Coprocessor Segment Overrun Exception */
ISR_NO_ERR 9
/* Bad TSS Exception */
ISR_ERR 10
/* Segment Not Present Exception */
ISR_ERR 11
/* Stack Fault Exception */
ISR_ERR 12
/* General Protection Fault Exception */
ISR_ERR 13
/* Page Fault Exception */
ISR_ERR 14
/* Unknown Interrupt Exception */
ISR_NO_ERR 15
/* Coprocessor Fault Exception */
ISR_NO_ERR 16
/* Alignment Check Exception */
ISR_NO_ERR 17
/* Machine Check Exception */
ISR_NO_ERR 18
/* All the others are reserved */
ISR_NO_ERR 19
ISR_NO_ERR 20
ISR_NO_ERR 21
ISR_NO_ERR 22
ISR_NO_ERR 23
ISR_NO_ERR 24
ISR_NO_ERR 25
ISR_NO_ERR 26
ISR_NO_ERR 27
ISR_NO_ERR 28
ISR_NO_ERR 29
ISR_NO_ERR 30
ISR_NO_ERR 31
/* Syscall */
ISR_NO_ERR 128
isr_common_stub:
pusha
push %ds
push %es
push %fs
push %gs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %esp, %eax
push %eax
mov $fault_handler, %eax
call *%eax
pop %eax
pop %gs
pop %fs
pop %es
pop %ds
popa
add $8, %esp
iret

View File

@ -22,10 +22,9 @@ void kernel_main(void)
irq_install();
timer_install();
keyboard_install();
terminal_printc("Welcome to &cDeadOS&7.\n");
syscall_init();
for (int i = 0; i < 3; i++)
{
terminal_printc("&cDead &7");
@ -34,9 +33,22 @@ void kernel_main(void)
terminal_printc("\n");
delay(100);
}
syscall_init();
enter_user_space();
enter_user_space_v2();
}
void user_main(void)
{
terminal_printc("Welcome to &cDeadOS&7.\n");
for (int i = 0; i < 3; i++)
{
terminal_printc("&cDead2 &7");
terminal_putchar('0' + (i / 10));
terminal_putchar('0' + (i % 10));
terminal_printc("\n");
delay(100);
}
shell_init();
}

View File

@ -1,24 +1,43 @@
/* The bootloader will look at this image and start execution at the symbol
designated at the entry point. */
ENTRY(_start)
/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS
{
. = 1M;
/* The kernel is situated at 1 MiB */
. = 1M;
.text ALIGN(4K) :
{
*(.multiboot)
*(.text)
*(.rodata)
}
kernel_start = .;
.data ALIGN(4K) :
{
*(.data)
}
/* First put the multiboot header, as it is required to be put very early
early in the image or the bootloader won't recognize the file format.
Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
.bss ALIGN(4K) :
{
*(.bss)
*(COMMON)
}
}
/* Read-only data */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(.bss)
*(.stack)
}
kernel_end = .;
}

View File

@ -21,8 +21,6 @@ void *syscalls[NB_SYSCALL] = {
void syscall_handler(Stack *registers)
{
terminal_writestring("Syscall\n");
int sys_index = registers->eax;
if (sys_index >= NB_SYSCALL)
@ -51,4 +49,4 @@ void syscall_handler(Stack *registers)
void syscall_init(void)
{
isr_install_handler(128, syscall_handler);
}
}

43
timer.c
View File

@ -1,48 +1,20 @@
#include "timer.h"
#include "io.h"
#include "sys.h"
#include "idt.h"
#define PIT_FREQUENCY 1193182
#define PIT_CHANNEL_0 0x40
#define PIT_COMMAND 0x43
#include "interrupts.h"
volatile uint32_t tick = 0;
void pit_handler()
void pit_handler(Stack *registers)
{
tick++;
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);
++tick;
}
void delay(uint32_t milliseconds)
{
uint32_t end = tick + milliseconds;
while (tick < end)
{
sys_halt();
}
;
}
void pit_set_frequency(uint32_t frequency)
@ -50,12 +22,11 @@ void pit_set_frequency(uint32_t frequency)
uint32_t divisor = PIT_FREQUENCY / frequency;
outb(PIT_COMMAND, 0x36);
outb(PIT_CHANNEL_0, divisor & 0xFF);
outb(PIT_CHANNEL_0, (divisor >> 8) & 0xFF);
outb(PIT_CHANNEL_0, divisor >> 8);
}
void timer_install(void)
{
pic_remap(0x20, 0x28);
irq_install_handler(0, pit_handler);
pit_set_frequency(1000);
idt_set_gate(32, (uint32_t)pit_handler_asm, 0x08, 0x8E);
}
}

10
timer.h
View File

@ -3,12 +3,16 @@
#include <stdint.h>
extern void pit_handler_asm();
#define PIT_FREQUENCY 1193182
#define PIT_CHANNEL_0 0x40
#define PIT_COMMAND 0x43
extern void pit_handler_asm(); // defined in pit_handler.s remove this
void pit_handler();
void delay(uint32_t milliseconds);
void pit_set_frequency(uint32_t frequency);
void pic_remap(int offset1, int offset2);
void pic_remap(int offset1, int offset2); // moved to irq_remap
void timer_install(void);
#endif
#endif

View File

82
tty.c
View File

@ -4,6 +4,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include "string.h"
static const size_t VGA_WIDTH = 80;
@ -138,6 +139,7 @@ void terminal_writestring(const char *data)
terminal_write(data, strlen(data));
}
// Існуюча функція для виводу одного рядка
void terminal_printc(const char *data)
{
while (*data)
@ -156,6 +158,86 @@ void terminal_printc(const char *data)
}
}
void itoa(int value, char *str, int base)
{
char *rc;
char *ptr;
char *low;
if (value < 0 && base == 10)
{
*str++ = '-';
value = -value;
}
rc = ptr = str;
do
{
*ptr++ = "0123456789abcdef"[value % base];
value /= base;
} while (value);
*ptr-- = '\0';
for (low = rc; low < ptr; low++, ptr--)
{
char tmp = *low;
*low = *ptr;
*ptr = tmp;
}
}
void terminal_printf_int(int value)
{
char buffer[12];
itoa(value, buffer, 10);
terminal_printf(buffer);
}
void terminal_printf_hex(unsigned int value)
{
char buffer[12];
itoa(value, buffer, 16);
terminal_printf(buffer);
}
void terminal_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
const char *p = format;
while (*p)
{
if (*p == '%' && (*(p + 1) == 's' || *(p + 1) == 'd' || *(p + 1) == 'x'))
{
p++;
if (*p == 's')
{
const char *str = va_arg(args, const char *);
terminal_printc(str);
}
else if (*p == 'd')
{
int value = va_arg(args, int);
terminal_printf_int(value);
}
else if (*p == 'x')
{
unsigned int value = va_arg(args, unsigned int);
terminal_printf_hex(value);
}
}
else
{
terminal_putchar(*p);
}
p++;
}
va_end(args);
}
void terminal_update_cursor(void)
{
uint16_t pos = terminal_row * VGA_WIDTH + terminal_column;

1
tty.h
View File

@ -10,6 +10,7 @@ void terminal_putentryat(char c, uint8_t color, size_t x, size_t y);
void terminal_putchar(char c);
void terminal_write(const char *data, size_t size);
void terminal_writestring(const char *data);
void terminal_printf(const char *data, ...);
void terminal_printc(const char *data);
void terminal_update_cursor(void);
void terminal_clear(void);

View File

@ -1,9 +1,5 @@
#include "user_space.h"
#include "gdt.h"
void enter_user_space(void)
{
set_kernel_stack(0x110); // 128KB ?? WHY? ??
asm volatile("cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
@ -22,4 +18,27 @@ void enter_user_space(void)
iret; \
1: \
");
}
void enter_user_space_v2()
{
asm volatile("cli; \
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \
mov %ax, %fs; \
mov %ax, %gs; \
mov %esp, %eax; \
push $0x23; \
push %eax; \
pushf; \
pop %eax; \
or $0x200, %eax; \
push %eax; \
push $0x1B; \
push $user_code_entry; \
iret; \
user_code_entry: \
call user_main; \
");
}

View File

@ -2,5 +2,6 @@
#define _USER_SPACE_H
void enter_user_space(void);
void enter_user_space_v2(void);
#endif