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
|
||||
|
||||
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
12
boot.s
@ -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
50
gdt.c
@ -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
2
gdt.h
@ -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);
|
||||
|
30
gdt_flush.s
30
gdt_flush.s
@ -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
|
||||
|
@ -1,5 +1,8 @@
|
||||
.section .text
|
||||
.align 4
|
||||
|
||||
.global idt_load
|
||||
.type idt_load, @function
|
||||
idt_load:
|
||||
lidt [idtp]
|
||||
lidt idtp
|
||||
ret
|
||||
|
@ -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
16
io.c
@ -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
11
irq.c
@ -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)
|
||||
|
@ -30,7 +30,6 @@ IRQ 15, 47
|
||||
|
||||
irq_common_stub:
|
||||
pusha
|
||||
|
||||
push %ds
|
||||
push %es
|
||||
push %fs
|
13
isr.c
13
isr.c
@ -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
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();
|
||||
|
||||
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();
|
||||
}
|
51
linker.ld
51
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)
|
||||
|
||||
/* 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 = .;
|
||||
}
|
@ -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)
|
||||
|
41
timer.c
41
timer.c
@ -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);
|
||||
}
|
8
timer.h
8
timer.h
@ -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
|
82
tty.c
82
tty.c
@ -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
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_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);
|
||||
|
27
user_space.c
27
user_space.c
@ -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; \
|
||||
@ -23,3 +19,26 @@ void enter_user_space(void)
|
||||
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
|
||||
|
||||
void enter_user_space(void);
|
||||
void enter_user_space_v2(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user