diff --git a/Makefile b/Makefile index 5a09c9f..ca4eeb9 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,20 @@ -#TODO make the makefile use targets instead of this mess -all: +objects = entry.o kernel.o handler.o interrupt.o v86.o print.o +CFLAGS = -target "i686-elf" -m32 -ffreestanding -march=pentium-m -fno-stack-protector -nostdlib -c + +%.o: %.nasm + nasm -f elf32 -o $@ $< + +%.o: %.c + clang $(CFLAGS) -O2 $< + +all: $(objects) nasm boot.nasm -o boot.bin - nasm -f elf32 -o entry.o entry.nasm - nasm -f elf32 -o handler.o handler.nasm - nasm -f elf32 -o v86.o v86.nasm - clang -target "i686-elf" -ffreestanding -m32 -O2 -march=pentium-m -fno-stack-protector -nostdlib -c kernel.c - clang -target "i686-elf" -ffreestanding -m32 -O2 -mgeneral-regs-only -march=pentium-m -fno-stack-protector -nostdlib -c print.c # not sure why but if interrupt.c has any optimization everything just breaks immediately - clang -target "i686-elf" -ffreestanding -m32 -mgeneral-regs-only -march=pentium-m -fno-stack-protector -nostdlib -c interrupt.c - #clang -target "i686-elf" -ffreestanding -m32 -mgeneral-regs-only -march=i386 -fno-stack-protector -nostdlib -c -o kernel.o kernel.c - gcc -Tlink.ld -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin entry.o v86.o handler.o kernel.o print.o interrupt.o + gcc -Tlink.ld -m32 -ffreestanding -nostartfiles -nostdlib -o kernel.bin\ + $(objects) dd bs=256 count=1 conv=notrunc if=boot.bin of=virtdisk.bin dd bs=512 seek=1 conv=notrunc if=kernel.bin of=virtdisk.bin virtdisk: dd bs=1M count=32 if=/dev/zero of=virtdisk.bin echo -n -e '\x55\xaa' | dd bs=1 seek=510 conv=notrunc of=virtdisk.bin + diff --git a/entry.nasm b/entry.nasm index f36f21b..48868bc 100644 --- a/entry.nasm +++ b/entry.nasm @@ -93,6 +93,9 @@ ret extern tss_data +global ivt +ivt: dd 0x00000000 + gdt_desc: dw gdt_end - gdt dd gdt diff --git a/interrupt.c b/interrupt.c index 92e7ddc..cb6612c 100644 --- a/interrupt.c +++ b/interrupt.c @@ -66,18 +66,20 @@ void IRQ_clear_mask(char IRQline) { } char v86_if = 0; +extern uint16_t *ivt; extern void real_test(); +__attribute((__no_caller_saved_registers__)) extern void kbd_wait(); +extern void jmp_usermode_test(); #define VALID_FLAGS 0xDFF __attribute__ ((interrupt)) void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { asm volatile("mov %%ax,%%ds"::"a"(0x10)); uint8_t *ip; - uint16_t *stack, *ivt; + uint16_t *stack; uint32_t *stack32; char is_operand32 = 0, is_address32 = 0; - ip = (size_t)(((frame->cs << 4) + frame->eip) & 0xFFFFF); - ivt = (uint16_t*)0x0000; + ip = (uint8_t*)(size_t)(((frame->cs << 4) + frame->eip) & 0xFFFFF); stack = FP_TO_LINEAR(frame->ss, frame->esp); stack32 = (uint32_t*)stack; @@ -156,37 +158,28 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { goto done; case 0xCD: // INT n vga[0] = 'I'; vga[2]++; if (vga[2] < '0') vga[2] = '0'; - asm volatile("nop\nnop"); switch (ip[1]) { - case 0x30: // Exit V86 Mode? - asm volatile("nop\nnop"); - asm volatile("jmp jmp_usermode_test"); - //__builtin_unreachable(); - break; - //case 0x20: // ??? - //case 0x21: // ??? - case 0x3: // Debugger trap + case 0x30: + asm("jmp jmp_usermode_test"); + for(;;); + case 0x3: kbd_wait(); - asm volatile("nop"); default: - stack -= 3; + stack = &stack[-3]; frame->esp = ((frame->esp & 0xffff) - 6) & 0xffff; stack[0] = (uint16_t) (frame->eip + 2); stack[1] = frame->cs; stack[2] = (uint16_t) frame->eflags; - if (v86_if) - stack[2] |= EFLAG_IF; - else - stack[2] &= ~EFLAG_IF; + //if (v86_if) + // stack[2] |= EFLAG_IF; + //else + // stack[2] &= ~EFLAG_IF; frame->cs = ivt[ip[1] * 2 + 1]; frame->eip = ivt[ip[1] * 2]; - asm volatile("nop"); - //frame->cs = 0; - //frame->eip = real_test; - goto done; + break; } goto done; case 0xCF: // IRET @@ -206,7 +199,6 @@ void gpf_handler_v86(struct interrupt_frame *frame, unsigned long error_code) { goto done; default: for(;;); - goto done; } } done: diff --git a/kernel.c b/kernel.c index 8bfbcbe..01ba120 100644 --- a/kernel.c +++ b/kernel.c @@ -98,6 +98,7 @@ void start() { if (!sse) return; enable_sse(); + // edit setup_interrupts(); setup_tss(); print_flags(); diff --git a/print.c b/print.c index 97f8011..8a49bc2 100644 --- a/print.c +++ b/print.c @@ -1,20 +1,24 @@ #include "print.h" __attribute((__always_inline__)) +__attribute((__no_caller_saved_registers__)) char nibbleToHex(uint8_t n) { return n > 9 ? (n - 10) + 'A' : n + '0'; } __attribute((__always_inline__)) +__attribute((__no_caller_saved_registers__)) void printByte(uint8_t v, uint16_t *buff) { *(char *)&buff[0] = nibbleToHex((v >> 4) & 0xF); *(char *)&buff[1] = nibbleToHex(v & 0xF); } __attribute((__always_inline__)) +__attribute((__no_caller_saved_registers__)) void printWord(uint16_t v, uint16_t *buff) { printByte(v >> 8, buff); printByte(v, &buff[2]); } __attribute((__always_inline__)) +__attribute((__no_caller_saved_registers__)) void printDword(uint32_t v, uint16_t *buff) { printWord(v >> 16, buff); printWord(v, &buff[4]); diff --git a/print.h b/print.h index ade22fe..22f018c 100644 --- a/print.h +++ b/print.h @@ -1,6 +1,9 @@ #pragma once #include +__attribute((__no_caller_saved_registers__)) void printByte(uint8_t v, uint16_t *buff); +__attribute((__no_caller_saved_registers__)) void printWord(uint16_t v, uint16_t *buff); +__attribute((__no_caller_saved_registers__)) void printDword(uint32_t v, uint16_t *buff); diff --git a/v86.nasm b/v86.nasm index ddea9b8..cea6508 100644 --- a/v86.nasm +++ b/v86.nasm @@ -54,6 +54,7 @@ inc byte [0] ;mov ax, 0x6666 ;mov sp, ax int 3 +int 3 ;jmp .loop mov ax, 0x13 int 0x10