diff --git a/Makefile b/Makefile index 42bb9ac..934ab3a 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,14 @@ CC=x86_64-elf-gcc run: image.bin qemu-system-i386 -drive format=raw,file=$< +debug-preboot: image.bin mbr.elf + qemu-system-i386 -drive format=raw,file=$< -s -S & + x86_64-elf-gdb mbr.elf \ + -ex "set architecture i8086" \ + -ex "target remote localhost:1234" \ + -ex "break *0x7c00" \ + -ex "continue" + debug-boot: image.bin mbr.elf qemu-system-i386 -drive format=raw,file=$< -s -S & x86_64-elf-gdb mbr.elf \ @@ -41,7 +49,7 @@ mbr.elf: mbr.o $(LD) -m elf_i386 -Ttext=0x7c00 $^ -o $@ clean: - rm -f *.elf *.bin *.o */*.o tools/mkfs + rm -f *.elf *.img *.bin *.o */*.o tools/mkfs tools/%: tools/%.c gcc -Wall -Werror -g $^ -o $@ diff --git a/console.c b/console.c index d358abe..b45f234 100644 --- a/console.c +++ b/console.c @@ -4,3 +4,11 @@ void printk(const char* msg) { vga_print_string(msg); } + +void panic(const char* msg) { + printk("Kernel panic: "); + printk(msg); + while (1) { + asm("hlt"); + } +} diff --git a/console.h b/console.h index d115f2a..2e5c22a 100644 --- a/console.h +++ b/console.h @@ -1,3 +1,4 @@ #pragma once void printk(const char* msg); +void panic(const char* msg); diff --git a/cpu/idt.c b/cpu/idt.c index 7b2f41b..218c88d 100644 --- a/cpu/idt.c +++ b/cpu/idt.c @@ -33,6 +33,9 @@ void set_idt_gate(int n, uint32_t handler) { extern uint32_t default_handlers[]; void init_idt() { + if (default_handlers[0] == 0) { + panic("handler table empty\n"); + } for (int i = 0; i < IDT_HANDLERS; i++) { set_idt_gate(i, default_handlers[i]); } @@ -126,11 +129,12 @@ static idt_register_t idt_reg; void load_idt() { init_idt(); - init_pic(); idt_reg.base = &idt; idt_reg.limit = sizeof(idt) - 1; - asm("lidt %0" : : "m"(idt_reg)); + asm("lidt (%0)" : : "r"(&idt_reg)); + + init_pic(); } void cli() { diff --git a/cpu/vectors.S b/cpu/vectors.S index ef92bfc..9fd80ed 100644 --- a/cpu/vectors.S +++ b/cpu/vectors.S @@ -45,7 +45,7 @@ vector\i : .global default_handlers default_handlers: .set i,0 -.rept 40 +.rept 256 irq_insertX %i .set i, i+1 .endr diff --git a/mbr.S b/mbr.S index 9b1b007..2451313 100644 --- a/mbr.S +++ b/mbr.S @@ -5,11 +5,19 @@ _start: mov $banner, %si call print_string + call get_drive_geometry call load_kernel call switch_to_32bit + hlt jmp . // loop forever +get_drive_geometry: + mov $8, %ah + mov boot_drive, %dl + int $0x13 + // TODO + .equ ELF32_ENTRY_OFFSET, 0x18 .equ ELF32_PHDR_OFFSET, 0x1c @@ -53,15 +61,30 @@ load_kernel: bios_disk_read: // expects %al to specify number of sectors, %cl the initial sector - mov $2, %ah // read mode + xor %ah, %ah + mov %ax, %si mov $0, %ch // cylinder 0 mov $0, %dh // head 0 mov $KERNEL_OFFSET, %bx // bx -> destination mov boot_drive, %dl // dl -> disk + mov $1, %al + +1: + mov $2, %ah // read mode int $0x13 - // no error checking, let's hope it works + test %ah, %ah + jnz fail + add $SECTOR_SIZE, %bx + inc %cl + dec %si + jnz 1b ret +fail: + mov $read_error, %si + call print_string + hlt + jmp . switch_to_32bit: mov $2, %al @@ -111,6 +134,8 @@ boot_drive: .byte 0 banner: .asciz "YABLOKO bootloader started\r\n" +read_error: + .asciz "Read error\r\n" .balign 2 entry: