dead@root fuck this shit
This commit is contained in:
parent
c355d80244
commit
5bd849abeb
2
Makefile
2
Makefile
@ -10,7 +10,7 @@ KERNEL = deados.bin
|
|||||||
ISO = deados.iso
|
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_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)
|
OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o)
|
||||||
|
|
||||||
ISO_DIR = isodir
|
ISO_DIR = isodir
|
||||||
|
12
boot.s
12
boot.s
@ -12,24 +12,20 @@
|
|||||||
|
|
||||||
.section .bss
|
.section .bss
|
||||||
.align 16
|
.align 16
|
||||||
|
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
.skip 1024 * 32 # 32 KB
|
.skip 16384
|
||||||
|
stack_top:
|
||||||
|
|
||||||
stack_top:
|
stack_top:
|
||||||
.section .text
|
.section .text
|
||||||
.global _start
|
.global _start
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
cli
|
|
||||||
mov $stack_top, %esp
|
mov $stack_top, %esp
|
||||||
|
push %ebx
|
||||||
call kernel_main
|
call kernel_main
|
||||||
|
|
||||||
hlt
|
|
||||||
jmp 1
|
|
||||||
1:
|
1:
|
||||||
jmp 1
|
jmp 1b
|
||||||
|
|
||||||
|
|
||||||
.size _start, . - _start
|
.size _start, . - _start
|
||||||
|
50
gdt.c
50
gdt.c
@ -4,14 +4,14 @@
|
|||||||
#define GDT_ENTRY 6
|
#define GDT_ENTRY 6
|
||||||
|
|
||||||
Gdt_entry gdt[GDT_ENTRY];
|
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;
|
Tss_entry tss;
|
||||||
extern void tss_flush(void);
|
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_low = base & 0xFFFF;
|
||||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
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;
|
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 base = (uint32_t)&tss;
|
||||||
uint32_t limit = base + sizeof(Tss_entry);
|
uint32_t limit = base + sizeof(Tss_entry);
|
||||||
|
|
||||||
gdt_set_gate(num, base, limit, 0xE9, 0x0);
|
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.cs = 0x1B;
|
||||||
|
tss.ss = 0x23;
|
||||||
tss.ss0 = kernel_ss;
|
tss.es = 0x23;
|
||||||
tss.esp0 = kernel_esp;
|
tss.ds = 0x23;
|
||||||
|
tss.fs = 0x23;
|
||||||
tss.cs = 0x0B;
|
tss.gs = 0x23;
|
||||||
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()
|
void gdt_install()
|
||||||
{
|
{
|
||||||
|
|
||||||
gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment
|
gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment
|
||||||
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment
|
gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xC0); // 0x08 Kernel code segment
|
||||||
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
|
gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xC0); // 0x10 Kernel data segment
|
||||||
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // User code segment
|
gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xC0); // 0x18 User code segment
|
||||||
gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // User data 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;
|
gdt_ptr.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1;
|
||||||
gdtp.base = (uint32_t)&gdt;
|
gdt_ptr.base = (uint32_t)&gdt;
|
||||||
|
|
||||||
gdt_flush((uint32_t)&gdtp);
|
gdt_flush();
|
||||||
tss_flush();
|
tss_flush();
|
||||||
}
|
}
|
||||||
|
2
gdt.h
2
gdt.h
@ -21,7 +21,7 @@ struct gdt_ptr_t
|
|||||||
uint32_t base;
|
uint32_t base;
|
||||||
} __attribute__((packed));
|
} __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 gdt_install();
|
||||||
|
|
||||||
void set_kernel_stack(uint32_t stack);
|
void set_kernel_stack(uint32_t stack);
|
||||||
|
30
gdt_flush.s
30
gdt_flush.s
@ -1,19 +1,17 @@
|
|||||||
|
.section .text
|
||||||
|
.align 4
|
||||||
|
|
||||||
.global gdt_flush
|
.global gdt_flush
|
||||||
|
.type gdt_flush, @function
|
||||||
gdt_flush:
|
gdt_flush:
|
||||||
cli
|
lgdt gdt_ptr
|
||||||
|
jmp $0x08, $reload_cs
|
||||||
|
|
||||||
mov 4(%esp), %eax
|
reload_cs:
|
||||||
lgdt (%eax)
|
movw $0x10, %ax
|
||||||
|
movw %ax, %ds
|
||||||
mov $0x10, %ax
|
movw %ax, %es
|
||||||
mov %ax, %ds
|
movw %ax, %fs
|
||||||
mov %ax, %es
|
movw %ax, %gs
|
||||||
mov %ax, %fs
|
movw %ax, %ss
|
||||||
mov %ax, %gs
|
ret
|
||||||
mov %ax, %ss
|
|
||||||
|
|
||||||
jmp $0x08, $.flush
|
|
||||||
|
|
||||||
.flush:
|
|
||||||
ret
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
.section .text
|
.section .text
|
||||||
|
.align 4
|
||||||
|
|
||||||
.global idt_load
|
.global idt_load
|
||||||
|
.type idt_load, @function
|
||||||
idt_load:
|
idt_load:
|
||||||
lidt [idtp]
|
lidt idtp
|
||||||
ret
|
ret
|
||||||
|
@ -25,8 +25,8 @@ void isr_install(void);
|
|||||||
|
|
||||||
#define NB_IRQ_ROUTINES 16
|
#define NB_IRQ_ROUTINES 16
|
||||||
|
|
||||||
#define PIC1 0x20 /* master PIC */
|
#define PIC1 0x20
|
||||||
#define PIC2 0xA0 /* slave PIC */
|
#define PIC2 0xA0
|
||||||
#define PIC1_CMD PIC1
|
#define PIC1_CMD PIC1
|
||||||
#define PIC1_DATA (PIC1 + 1)
|
#define PIC1_DATA (PIC1 + 1)
|
||||||
#define PIC2_CMD PIC2
|
#define PIC2_CMD PIC2
|
||||||
|
16
io.c
16
io.c
@ -1,18 +1,20 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
void outb(uint16_t port, uint8_t val) {
|
void outb(uint16_t port, uint8_t val)
|
||||||
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
{
|
||||||
|
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t inb(uint16_t port) {
|
uint8_t inb(uint16_t port)
|
||||||
|
{
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_wait(void)
|
void io_wait(void)
|
||||||
{
|
{
|
||||||
asm volatile ( "jmp 1f\n\t"
|
asm volatile("jmp 1f\n\t"
|
||||||
"1:jmp 2f\n\t"
|
"1:jmp 2f\n\t"
|
||||||
"2:" );
|
"2:");
|
||||||
}
|
}
|
||||||
|
11
irq.c
11
irq.c
@ -4,6 +4,7 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
|
#include "tty.h"
|
||||||
|
|
||||||
extern void irq0(void);
|
extern void irq0(void);
|
||||||
extern void irq1(void);
|
extern void irq1(void);
|
||||||
@ -42,24 +43,16 @@ void irq_call_handler(Stack *registers)
|
|||||||
handler(registers);
|
handler(registers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void irq_remap(void)
|
static void irq_remap(void) // PIC REMAP
|
||||||
{
|
{
|
||||||
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
|
outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4);
|
||||||
io_wait();
|
|
||||||
outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
|
outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
|
||||||
io_wait();
|
|
||||||
outb(PIC1_DATA, PIC1_OFFSET);
|
outb(PIC1_DATA, PIC1_OFFSET);
|
||||||
io_wait();
|
|
||||||
outb(PIC2_DATA, PIC2_OFFSET);
|
outb(PIC2_DATA, PIC2_OFFSET);
|
||||||
io_wait();
|
|
||||||
outb(PIC1_DATA, 0x04);
|
outb(PIC1_DATA, 0x04);
|
||||||
io_wait();
|
|
||||||
outb(PIC2_DATA, 0x02);
|
outb(PIC2_DATA, 0x02);
|
||||||
io_wait();
|
|
||||||
outb(PIC1_DATA, ICW4_8086);
|
outb(PIC1_DATA, ICW4_8086);
|
||||||
io_wait();
|
|
||||||
outb(PIC2_DATA, ICW4_8086);
|
outb(PIC2_DATA, ICW4_8086);
|
||||||
io_wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void irq_install(void)
|
void irq_install(void)
|
||||||
|
@ -30,7 +30,6 @@ IRQ 15, 47
|
|||||||
|
|
||||||
irq_common_stub:
|
irq_common_stub:
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
push %ds
|
push %ds
|
||||||
push %es
|
push %es
|
||||||
push %fs
|
push %fs
|
||||||
@ -56,4 +55,4 @@ irq_common_stub:
|
|||||||
popa
|
popa
|
||||||
|
|
||||||
add $8, %esp
|
add $8, %esp
|
||||||
iret
|
iret
|
13
isr.c
13
isr.c
@ -139,23 +139,20 @@ static const char *exception_messages[] =
|
|||||||
|
|
||||||
void fault_handler(Stack *registers)
|
void fault_handler(Stack *registers)
|
||||||
{
|
{
|
||||||
|
// check this
|
||||||
if (registers->id == 128)
|
if (registers->id == 128)
|
||||||
|
{
|
||||||
isr_call_handler(registers);
|
isr_call_handler(registers);
|
||||||
|
}
|
||||||
|
|
||||||
if (registers->id < 32)
|
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);
|
isr_call_handler(registers);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
{
|
||||||
sys_halt();
|
sys_halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
85
isr_e.s
85
isr_e.s
@ -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
102
isr_flush.s
Normal 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
|
20
kernel.c
20
kernel.c
@ -22,10 +22,9 @@ void kernel_main(void)
|
|||||||
irq_install();
|
irq_install();
|
||||||
|
|
||||||
timer_install();
|
timer_install();
|
||||||
|
|
||||||
keyboard_install();
|
keyboard_install();
|
||||||
|
|
||||||
terminal_printc("Welcome to &cDeadOS&7.\n");
|
syscall_init();
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
terminal_printc("&cDead &7");
|
terminal_printc("&cDead &7");
|
||||||
@ -34,9 +33,22 @@ void kernel_main(void)
|
|||||||
terminal_printc("\n");
|
terminal_printc("\n");
|
||||||
delay(100);
|
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();
|
shell_init();
|
||||||
}
|
}
|
53
linker.ld
53
linker.ld
@ -1,24 +1,43 @@
|
|||||||
|
/* The bootloader will look at this image and start execution at the symbol
|
||||||
|
designated at the entry point. */
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
|
/* Tell where the various sections of the object files will be put in the final
|
||||||
|
kernel image. */
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 1M;
|
/* The kernel is situated at 1 MiB */
|
||||||
|
. = 1M;
|
||||||
|
|
||||||
.text ALIGN(4K) :
|
kernel_start = .;
|
||||||
{
|
|
||||||
*(.multiboot)
|
|
||||||
*(.text)
|
|
||||||
*(.rodata)
|
|
||||||
}
|
|
||||||
|
|
||||||
.data ALIGN(4K) :
|
/* 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.
|
||||||
*(.data)
|
Next we'll put the .text section. */
|
||||||
}
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.multiboot)
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
.bss ALIGN(4K) :
|
/* Read-only data */
|
||||||
{
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
*(.bss)
|
{
|
||||||
*(COMMON)
|
*(.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 = .;
|
||||||
|
}
|
@ -21,8 +21,6 @@ void *syscalls[NB_SYSCALL] = {
|
|||||||
|
|
||||||
void syscall_handler(Stack *registers)
|
void syscall_handler(Stack *registers)
|
||||||
{
|
{
|
||||||
terminal_writestring("Syscall\n");
|
|
||||||
|
|
||||||
int sys_index = registers->eax;
|
int sys_index = registers->eax;
|
||||||
|
|
||||||
if (sys_index >= NB_SYSCALL)
|
if (sys_index >= NB_SYSCALL)
|
||||||
@ -51,4 +49,4 @@ void syscall_handler(Stack *registers)
|
|||||||
void syscall_init(void)
|
void syscall_init(void)
|
||||||
{
|
{
|
||||||
isr_install_handler(128, syscall_handler);
|
isr_install_handler(128, syscall_handler);
|
||||||
}
|
}
|
||||||
|
43
timer.c
43
timer.c
@ -1,48 +1,20 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "idt.h"
|
#include "interrupts.h"
|
||||||
|
|
||||||
#define PIT_FREQUENCY 1193182
|
|
||||||
#define PIT_CHANNEL_0 0x40
|
|
||||||
#define PIT_COMMAND 0x43
|
|
||||||
|
|
||||||
volatile uint32_t tick = 0;
|
volatile uint32_t tick = 0;
|
||||||
|
|
||||||
void pit_handler()
|
void pit_handler(Stack *registers)
|
||||||
{
|
{
|
||||||
tick++;
|
++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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void delay(uint32_t milliseconds)
|
void delay(uint32_t milliseconds)
|
||||||
{
|
{
|
||||||
uint32_t end = tick + milliseconds;
|
uint32_t end = tick + milliseconds;
|
||||||
while (tick < end)
|
while (tick < end)
|
||||||
{
|
;
|
||||||
sys_halt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pit_set_frequency(uint32_t frequency)
|
void pit_set_frequency(uint32_t frequency)
|
||||||
@ -50,12 +22,11 @@ void pit_set_frequency(uint32_t frequency)
|
|||||||
uint32_t divisor = PIT_FREQUENCY / frequency;
|
uint32_t divisor = PIT_FREQUENCY / frequency;
|
||||||
outb(PIT_COMMAND, 0x36);
|
outb(PIT_COMMAND, 0x36);
|
||||||
outb(PIT_CHANNEL_0, divisor & 0xFF);
|
outb(PIT_CHANNEL_0, divisor & 0xFF);
|
||||||
outb(PIT_CHANNEL_0, (divisor >> 8) & 0xFF);
|
outb(PIT_CHANNEL_0, divisor >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_install(void)
|
void timer_install(void)
|
||||||
{
|
{
|
||||||
pic_remap(0x20, 0x28);
|
irq_install_handler(0, pit_handler);
|
||||||
pit_set_frequency(1000);
|
pit_set_frequency(1000);
|
||||||
idt_set_gate(32, (uint32_t)pit_handler_asm, 0x08, 0x8E);
|
}
|
||||||
}
|
|
||||||
|
10
timer.h
10
timer.h
@ -3,12 +3,16 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#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 pit_handler();
|
||||||
void delay(uint32_t milliseconds);
|
void delay(uint32_t milliseconds);
|
||||||
void pit_set_frequency(uint32_t frequency);
|
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);
|
void timer_install(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
82
tty.c
82
tty.c
@ -4,6 +4,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
static const size_t VGA_WIDTH = 80;
|
static const size_t VGA_WIDTH = 80;
|
||||||
@ -138,6 +139,7 @@ void terminal_writestring(const char *data)
|
|||||||
terminal_write(data, strlen(data));
|
terminal_write(data, strlen(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Існуюча функція для виводу одного рядка
|
||||||
void terminal_printc(const char *data)
|
void terminal_printc(const char *data)
|
||||||
{
|
{
|
||||||
while (*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)
|
void terminal_update_cursor(void)
|
||||||
{
|
{
|
||||||
uint16_t pos = terminal_row * VGA_WIDTH + terminal_column;
|
uint16_t pos = terminal_row * VGA_WIDTH + terminal_column;
|
||||||
|
1
tty.h
1
tty.h
@ -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_putchar(char c);
|
||||||
void terminal_write(const char *data, size_t size);
|
void terminal_write(const char *data, size_t size);
|
||||||
void terminal_writestring(const char *data);
|
void terminal_writestring(const char *data);
|
||||||
|
void terminal_printf(const char *data, ...);
|
||||||
void terminal_printc(const char *data);
|
void terminal_printc(const char *data);
|
||||||
void terminal_update_cursor(void);
|
void terminal_update_cursor(void);
|
||||||
void terminal_clear(void);
|
void terminal_clear(void);
|
||||||
|
27
user_space.c
27
user_space.c
@ -1,9 +1,5 @@
|
|||||||
#include "user_space.h"
|
|
||||||
#include "gdt.h"
|
|
||||||
|
|
||||||
void enter_user_space(void)
|
void enter_user_space(void)
|
||||||
{
|
{
|
||||||
set_kernel_stack(0x110); // 128KB ?? WHY? ??
|
|
||||||
asm volatile("cli; \
|
asm volatile("cli; \
|
||||||
mov $0x23, %ax; \
|
mov $0x23, %ax; \
|
||||||
mov %ax, %ds; \
|
mov %ax, %ds; \
|
||||||
@ -22,4 +18,27 @@ void enter_user_space(void)
|
|||||||
iret; \
|
iret; \
|
||||||
1: \
|
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; \
|
||||||
|
");
|
||||||
}
|
}
|
@ -2,5 +2,6 @@
|
|||||||
#define _USER_SPACE_H
|
#define _USER_SPACE_H
|
||||||
|
|
||||||
void enter_user_space(void);
|
void enter_user_space(void);
|
||||||
|
void enter_user_space_v2(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user