diff --git a/kernel/Makefile b/kernel/Makefile index 42c80c2..2711f7c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -29,8 +29,7 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS) KERNEL_OBJS=\ $(KERNEL_ARCH_OBJS) \ -kernel/kernel.o \ -gdt/gdt.o +kernel/kernel.o OBJS=\ $(ARCHDIR)/crti.o \ @@ -66,11 +65,16 @@ $(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o: .S.o: $(CC) -MD -c $< -o $@ $(CFLAGS) $(CPPFLAGS) +%.o: %.asm + nasm -f elf $< -o $@ + + clean: rm -f myos.kernel rm -f $(OBJS) *.o */*.o */*/*.o rm -f $(OBJS:.o=.d) *.d */*.d */*/*.d - + rm -f ${ARCHDIR} *.o */*.o */*/*/*.o + rm -f kernel/kernel/ *.d *.o install: install-headers install-kernel install-headers: diff --git a/kernel/arch/i386/boot.S b/kernel/arch/i386/boot.S index c2fdc88..823ab4c 100644 --- a/kernel/arch/i386/boot.S +++ b/kernel/arch/i386/boot.S @@ -19,6 +19,7 @@ stack_bottom: .skip 16384 stack_top: + #kernel entry point .section .text .global _start @@ -33,7 +34,6 @@ _start: mov %ax, %fs mov %ax, %gs call kernel_main - cli 1: hlt jmp 1b diff --git a/kernel/arch/i386/make.config b/kernel/arch/i386/make.config index 03e2f24..3834435 100644 --- a/kernel/arch/i386/make.config +++ b/kernel/arch/i386/make.config @@ -6,4 +6,5 @@ KERNEL_ARCH_LIBS= KERNEL_ARCH_OBJS=\ $(ARCHDIR)/boot.o \ $(ARCHDIR)/tty.o \ - +${ARCHDIR}/x86_int.o \ +${ARCHDIR}/x86.o \ diff --git a/kernel/arch/i386/x86.c b/kernel/arch/i386/x86.c new file mode 100644 index 0000000..36c8e3a --- /dev/null +++ b/kernel/arch/i386/x86.c @@ -0,0 +1,155 @@ +#include +#include +#include +struct gdtdesc kgdt[5]; +struct gdtr kgdtr; +struct idtr kidtr; +struct idtdesc kidt[256]; +uint8_t stack[STACKSIZE]; + + +void read_gdtr(uint32_t* tgdtr) { + asm("sgdt %0" : "=m" (*tgdtr)); +} + +void load_gdt(struct gdtr *gdtr) { + asm volatile("lgdt %0" : : "m" (*gdtr)); +} + +void load_idt(struct idtr *idtr) { + asm volatile("lidt %0" : : "m" (*idtr)); +} + +void gdt_init(void) { + + create_gdt_descriptor(0x0, 0x0, 0x0, 0x0, &kgdt[0]); + create_gdt_descriptor(0x0, 0xFFFF, 0x9A, 0xCF, &kgdt[1]); + create_gdt_descriptor(0x0, 0xFFFF, 0x92, 0xCF, &kgdt[2]); + create_gdt_descriptor(0x0, 0xFFFF, 0xFA, 0xCF, &kgdt[3]); + create_gdt_descriptor(0x0, 0xFFFF, 0xF2, 0xCF, &kgdt[4]); +// create_gdt_descriptor(0x0, 0xFFFF, 0xF2, 0xCF, &kgdt[5]); +// create_gdt_descriptor(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]); + kgdtr.limit = sizeof(kgdt) -1; + kgdtr.base = (uint32_t)&kgdt; + + load_gdt(&kgdtr); +} + +void create_gdt_descriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags, struct gdtdesc *desc) { + if (desc == NULL) { + printf("NULL"); + } + desc->limit0_15 = (limit & 0xFFFF); + desc->base0_15 = (base & 0xFFFF); + desc->base16_23 = (base & 0xFF) >> 16; + desc->access_bytes = access; + desc->limit16_19 = (limit & 0xF) >> 16; + desc->flags = (flags & 0xF); + return; +} + +void create_idt_descriptor(uint16_t select, uint32_t offset, uint8_t type, struct idtdesc * desc) { + printf("select: %d, offset: %d, type: %d\n", select, offset, type); + desc->offset0_15 = (offset & 0xFFFF); + desc->select = select; + desc->access_gran = type; + desc->alwaysZero = 0; + desc->offset16_31 = (offset & 0xFFFF0000) >> 16; + return; +} + +extern void _asm_int_0(); +extern void _asm_int_1(); +extern void isr0(); + +void outb(uint32_t ad, uint8_t v) +{ + asm volatile("outb %%al, %%dx" :: "d" (ad), "a" (v)); +} + +uint8_t inb(uint32_t ad) +{ + uint8_t v; + asm volatile("inb %%dx, %%al" : "=a" (v) : "d" (ad)); + return v; +} + +void isr_default_int(int id) +{ + printf("default int %d", id); + asm volatile("hlt"); +} + +void init_pic(void) +{ + outb(0x20, 0x11); + outb(0xA0, 0x11); + + outb(0x21, 0x20); + outb(0xA1, 0x28); + + outb(0x21, 0x04); + outb(0xA1, 0x02); + + outb(0x21, 0x01); + outb(0xA1, 0x01); + + outb(0x21, 0x0); + outb(0xA1, 0x0); + printf("PIC initialised\n"); +} + + +extern void idt_load(); + +void init_idt(void) { + + kidtr.limit = (sizeof(struct idtdesc) * 256) - 1; + kidtr.base = (uint32_t)&kidt; + //memset(&kidt, 0, sizeof(struct idtdesc) * 256); +// idt_load(); + load_idt(&kidtr); + printf("IDT initialized\n"); +} + +struct regs{ + unsigned int gs, fs, es, ds; /* pushed the segs last */ + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ + unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ + unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ +}; + +void *irq_routines[16] ={ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void fault_handler(struct regs *r) +{ + printf("ERROR everywhere\n"); + /* Is this a fault whose number is from 0 to 31? */ + if (r->int_no < 32) + { + printf("ERROR here\n"); + asm("hlt"); +// bsodmsg(exception_messages[r->int_no]); + } else { + printf("ERROR there\n"); + asm("hlt"); + } +} + +void irq_install_handler(int irq, void (*handler)(struct regs *r)){ + irq_routines[irq] = handler; +} + +void setup_isr(void) { + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[0]); + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[1]); + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[2]); + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[3]); + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[4]); + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[5]); + create_idt_descriptor(0x08, (uint32_t)isr0, INTGATE, &kidt[6]); +} + diff --git a/kernel/arch/i386/x86_int.asm b/kernel/arch/i386/x86_int.asm new file mode 100644 index 0000000..4f8b6ce --- /dev/null +++ b/kernel/arch/i386/x86_int.asm @@ -0,0 +1,177 @@ + +global idt_load +extern kidtr +idt_load: + lidt [kidtr] + ret + +global isr0 +global isr1 +global isr2 +global isr3 +global isr4 +global isr5 +global isr6 +global isr7 +global isr8 +global isr9 +global isr10 +global isr11 +global isr12 +global isr13 +global isr14 +global isr15 +global isr16 +global isr17 +global isr18 +global isr19 +global isr20 +global isr21 +global isr22 +global isr23 +global isr24 +global isr25 +global isr26 +global isr27 +global isr28 +global isr29 +global isr30 +global isr31 + +%macro ISR_NOCODE 1 + isr%1: + cli + push byte 0 + push byte %1 + jmp isr_common_stub +%endmacro + +%macro ISR_CODE 1 + isr%1: + cli + push byte %1 + jmp isr_common_stub +%endmacro + + +;Divide By Zero Exception +ISR_NOCODE 0 + +;Debug Exception +ISR_NOCODE 1 + +;Non Maskable Interrrupt Exception +ISR_NOCODE 2 + +;Breakpoint Exception +ISR_NOCODE 3 + +;Into Detected Overflow Exception +ISR_NOCODE 4 + +;Out of Bounds Exception +ISR_NOCODE 5 + +;Invalid Opcode Exception +ISR_NOCODE 6 + +;No Coprocessor Exception +ISR_NOCODE 7 + +;Double Fault Exception +ISR_CODE 8 + +;Coprocessor Segment Overrun Exception +ISR_NOCODE 9 + +;Bad TSS Exception +ISR_CODE 10 + +;Segment Not Present Exception +ISR_CODE 11 + +;Stack Fault Exception +ISR_CODE 12 + +;General Protection Fault Exception +ISR_CODE 13 + +;Page Fault Exception +ISR_CODE 14 + +;Unknown Interrupt Exception +ISR_NOCODE 15 + +;Coprocessor Fault Exception +ISR_NOCODE 16 + +;Alignment Check Exception +ISR_NOCODE 17 + +;Machine Check Exception +ISR_NOCODE 18 + +;Reserved +ISR_NOCODE 19 + +;Reserved +ISR_NOCODE 20 + +;Reserved +ISR_NOCODE 21 + +;Reserved +ISR_NOCODE 22 + +;Reserved +ISR_NOCODE 23 + +;Reserved +ISR_NOCODE 24 + +;Reserved +ISR_NOCODE 25 + +;Reserved +ISR_NOCODE 26 + +;Reserved +ISR_NOCODE 27 + +;Reserved +ISR_NOCODE 28 + +;Reserved +ISR_NOCODE 29 + +;Reserved +ISR_NOCODE 30 + +;Reserved +ISR_NOCODE 31 + +extern fault_handler +isr_common_stub: + pusha + push ds + push es + push fs + push gs + mov ax, 0x10 ; Load the Kernel Data Segment descriptor! + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov eax, esp ; Push us the stack + push eax + mov eax, fault_handler + call eax ; A special call, preserves the 'eip' register + pop eax + pop gs + pop fs + pop es + pop ds + popa + add esp, 8 ; Cleans up the pushed error code and pushed ISR number + iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP! + diff --git a/kernel/arch/i386/x86_int_1.asm b/kernel/arch/i386/x86_int_1.asm new file mode 100644 index 0000000..5721d1e --- /dev/null +++ b/kernel/arch/i386/x86_int_1.asm @@ -0,0 +1,41 @@ +%macro SAVE_REGS 0 + pushad + push ds + push es + push fs + push gs + push ebx + mov bx, 0x10 + mov ds, bx + pop ebx +%endmacro + +%macro RESTORE_REGS 0 + pop gs + pop fs + pop es + pop ds + popad +%endmacro + +%macro INTERRUPT 1 +global _asm_int_%1 +_asm_int_%1: + hlt + SAVE_REGS + push %1 + push eax + call fault_handler + pop eax + mov al, 0x20 + out 0x20, al + RESTORE_REGS + add esp, 8 + ret +%endmacro + +extern fault_handler + +INTERRUPT 1 +INTERRUPT 0 + diff --git a/kernel/gdt/gdt.c b/kernel/gdt/gdt.c deleted file mode 100644 index eb0dc63..0000000 --- a/kernel/gdt/gdt.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include "gdt.h" -#include -struct gdtdesc kgdt[5]; -struct gdtr kgdtr; - - -void read_gdtr(uint32_t* tgdtr) { - asm("sgdt %0" : "=m" (*tgdtr)); -} - -void load_gdt(struct gdtr *gdtr) { - asm volatile("lgdt %0" : : "m" (*gdtr)); -} -void gdt_init(void) { - - create_gdt_descriptor(0x0, 0x0, 0x0, 0x0, &kgdt[0]); - create_gdt_descriptor(0x0, 0xFFFF, 0x9A, 0xCF, &kgdt[1]); - create_gdt_descriptor(0x0, 0xFFFF, 0x92, 0xCF, &kgdt[2]); - create_gdt_descriptor(0x0, 0xFFFF, 0xFA, 0xCF, &kgdt[3]); - create_gdt_descriptor(0x0, 0xFFFF, 0xF2, 0xCF, &kgdt[4]); -// create_gdt_descriptor(0x0, 0xFFFF, 0xF2, 0xCF, &kgdt[5]); -// create_gdt_descriptor(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]); - kgdtr.limit = sizeof(kgdt) -1; - kgdtr.base = (uint32_t)&kgdt; - - load_gdt(&kgdtr); -} - -void create_gdt_descriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags, struct gdtdesc *desc) { - if (desc == NULL) { - printf("NULL"); - } - desc->limit0_15 = (limit & 0xFFFF); - desc->base0_15 = (base & 0xFFFF); - desc->base16_23 = (base & 0xFF) >> 16; - desc->access_bytes = access; - desc->limit16_19 = (limit & 0xF) >> 16; - desc->flags = (flags & 0xF); - return; -} diff --git a/kernel/gdt/gdt.h b/kernel/include/arch/i386/x86.h similarity index 51% rename from kernel/gdt/gdt.h rename to kernel/include/arch/i386/x86.h index 8034144..952562b 100644 --- a/kernel/gdt/gdt.h +++ b/kernel/include/arch/i386/x86.h @@ -1,5 +1,5 @@ -#ifndef _GDT_H -#define _GDT_H +#ifndef ARCH_I386_X86_H +#define ARCH_I386_X86_H #include #include @@ -18,9 +18,32 @@ struct gdtdesc { uint8_t limit16_19; } __attribute__ ((packed)); +struct idtr { + uint16_t limit; + uint32_t base; +} __attribute ((packed)); + +struct idtdesc { + uint16_t offset0_15; + uint16_t select; + uint8_t alwaysZero; + uint8_t access_gran; + uint16_t offset16_31; +} __attribute__ ((packed)); + #define GDTSIZE 0xFF +#define IDTSIZE 0xFF +#define STACKSIZE 4096 + + #define GDT_BASE 0x00000 +#define IDT_BASE 0x00000 + + +#define INTGATE 0x8E +#define TRAPGATE 0xEF + #define DESC_NULL 0x0000 #define DESC_KERNEL_CODE 0x0008 #define DESC_KERNEL_DATA 0x0010 @@ -32,5 +55,14 @@ void create_gdt_descriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_ void init_gdt(void); +void init_idt(void); + +void create_idt_descriptor(uint16_t, uint32_t, uint8_t, struct idtdesc *); + +void install_irq(unsigned int num, unsigned int irq); + +void init_pic(void); + +void setup_isr(void); #endif diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index 4101f58..4b98f3e 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -1,8 +1,23 @@ #include #include +#include + +void divide_by_zero(void); void kernel_main(void) { terminal_initialize(); + init_idt(); + setup_isr(); + // isrs_install(); printf("Terminal initialization compelete\n"); - printf("Tesing formating, %c \t%d %s", 'Q', 1234, "Hello world from format"); + printf("Tesing formating, %c \t%d %s\n", 'Q', 1234, "Hello world from format"); + divide_by_zero(); + printf("DONE"); +} + +void divide_by_zero(void) { + //asm("hlt"); + int i = 10/0; + + printf("%d", i); } diff --git a/qemu.sh b/qemu.sh index accec2a..cbe431c 100755 --- a/qemu.sh +++ b/qemu.sh @@ -1,5 +1,7 @@ #!/bin/sh set -e +./clean.sh + . ./iso.sh - -qemu-system-$(./target-triplet-to-arch.sh $HOST) -cdrom myos.iso \ No newline at end of file + +qemu-system-$(./target-triplet-to-arch.sh $HOST) -cdrom myos.iso