From b8604932ebae3c63538d2e104f5d5d21d5e839de Mon Sep 17 00:00:00 2001 From: Alexander Myltsev Date: Sun, 20 Nov 2022 19:48:55 +0300 Subject: [PATCH] Load kernel with a .data segment. --- Makefile | 4 ++-- cpu/idt.c | 8 ++++++-- cpu/vectors.S | 2 +- drivers/port.h | 10 +++++----- kernel.c | 10 ++++++++-- mbr.S | 12 +++++++++++- 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index bda8f47..42bb9ac 100644 --- a/Makefile +++ b/Makefile @@ -25,11 +25,11 @@ fs.img: kernel.bin tools/mkfs image.bin: mbr.bin fs.img cat $^ >$@ -kernel.bin: kernel.o console.o drivers/vga.o string.o drivers/ata.o cpu/vectors.o cpu/idt.o +kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o string.o drivers/ata.o cpu/vectors.o cpu/idt.o $(LD) -m elf_i386 -o $@ -Ttext 0x1000 $^ %.o: %.c - $(CC) -m32 -ffreestanding -c -g $< -o $@ + $(CC) -m32 -ffreestanding -Wall -Werror -c -g $< -o $@ %.o: %.S $(AS) --32 -g $^ -o $@ diff --git a/cpu/idt.c b/cpu/idt.c index 715580a..7b2f41b 100644 --- a/cpu/idt.c +++ b/cpu/idt.c @@ -30,7 +30,7 @@ void set_idt_gate(int n, uint32_t handler) { } // defined in vectors.S -extern uint32_t default_handlers[IDT_HANDLERS]; +extern uint32_t default_handlers[]; void init_idt() { for (int i = 0; i < IDT_HANDLERS; i++) { @@ -64,7 +64,11 @@ const char *exception_messages[] = { #define ARRLEN(a) (sizeof(a) / sizeof(a[0])) -isr_t interrupt_handlers[IDT_HANDLERS]; +static isr_t interrupt_handlers[IDT_HANDLERS]; + +void register_interrupt_handler(uint8_t i, isr_t handler) { + interrupt_handlers[i] = handler; +} void trap(registers_t *r) { if (r->int_no < 32) { diff --git a/cpu/vectors.S b/cpu/vectors.S index 9fd80ed..ef92bfc 100644 --- a/cpu/vectors.S +++ b/cpu/vectors.S @@ -45,7 +45,7 @@ vector\i : .global default_handlers default_handlers: .set i,0 -.rept 256 +.rept 40 irq_insertX %i .set i, i+1 .endr diff --git a/drivers/port.h b/drivers/port.h index 283418b..380272a 100644 --- a/drivers/port.h +++ b/drivers/port.h @@ -1,25 +1,25 @@ #pragma once -static unsigned char port_byte_in(unsigned short port) { +static inline unsigned char port_byte_in(unsigned short port) { unsigned char result; __asm__("in %%dx, %%al" : "=a" (result) : "d" (port)); return result; } -static unsigned short port_word_in(unsigned short port) { +static inline unsigned short port_word_in(unsigned short port) { unsigned short result; __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); return result; } -static void port_byte_out(unsigned short port, unsigned char data) { +static inline void port_byte_out(unsigned short port, unsigned char data) { __asm__("outb %%al, %%dx" : : "a" (data), "d" (port)); } -static void port_word_out(unsigned short port, unsigned short data) { +static inline void port_word_out(unsigned short port, unsigned short data) { __asm__("outw %%ax, %%dx" : : "a" (data), "d" (port)); } -static void port_long_out(unsigned short port, unsigned int data) { +static inline void port_long_out(unsigned short port, unsigned int data) { __asm__("outl %%eax, %%dx" : : "a" (data), "d" (port)); } diff --git a/kernel.c b/kernel.c index 80ca3a3..35cb1af 100644 --- a/kernel.c +++ b/kernel.c @@ -1,21 +1,27 @@ asm(".asciz \"kernel start\""); +#include "console.h" #include "cpu/isr.h" +#include "drivers/keyboard.h" #include "drivers/vga.h" #include "drivers/ata.h" #include "drivers/misc.h" void _start() { + init_keyboard(); load_idt(); sti(); char buf[512]; vga_clear_screen(); - vga_print_string("YABLOKO\n"); + printk("YABLOKO\n"); read_sectors_ATA_PIO((uint32_t)buf, 10, 1); - vga_print_string(buf); + printk(buf); + while (1) { + asm("pause"); + } asm("hlt"); qemu_shutdown(); } diff --git a/mbr.S b/mbr.S index 6471c95..9b1b007 100644 --- a/mbr.S +++ b/mbr.S @@ -13,6 +13,9 @@ _start: .equ ELF32_ENTRY_OFFSET, 0x18 .equ ELF32_PHDR_OFFSET, 0x1c +.equ ELF32_PHENTSIZE_OFFSET, ELF32_PHDR_OFFSET + 14 +.equ ELF32_PHNUM_OFFSET, ELF32_PHENTSIZE_OFFSET + 2 +.equ ELF32_PHDR_P_OFFSET, 4 .equ ELF32_PHDR_FILESZ_OFFSET, 4*4 .equ KERNEL_OFFSET, 0x1000 @@ -31,8 +34,15 @@ load_kernel: mov KERNEL_OFFSET + ELF32_ENTRY_OFFSET, %si mov %si, entry // store entry point - mov KERNEL_OFFSET + ELF32_PHDR_OFFSET, %di + mov KERNEL_OFFSET + ELF32_PHNUM_OFFSET, %ax + dec %ax // no offset to the first entry + mulb KERNEL_OFFSET + ELF32_PHENTSIZE_OFFSET + mov %ax, %di + + add KERNEL_OFFSET + ELF32_PHDR_OFFSET, %di + // now di holds offset to the last phentry mov KERNEL_OFFSET + ELF32_PHDR_FILESZ_OFFSET(%di), %ax + add KERNEL_OFFSET + ELF32_PHDR_P_OFFSET(%di), %ax sub $0x1000, %ax // we won't load the header add $SECTOR_SIZE - 1, %ax shr $SECTOR_SHIFT, %ax // round up to sector count