nibblebits / PeachOS

Simple kernel designed for a online course
GNU General Public License v2.0
133 stars 55 forks source link

Issues running in bochs emulator #20

Open SlidyBat opened 1 year ago

SlidyBat commented 1 year ago

Tried running in bochs emulator, and it seems to be a bit more strict than qemu, so it caught some issues. Here are issues that I spotted after trying bochs:

1) Data segment registers aren't set in boot.asm

This causes a crash when trying to read kernel code to 0x100000, since default segments don't allow using addresses larger than 0xFFFF. Fixed it by moving step2 code under load32 instead and using DATA_SEG instead of 0x00:

load32:
    mov ax, DATA_SEG
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7c00

2) PIC interrupt remapping in kernel.asm missing ICW3 command

ICW1, ICW2, and ICW4 are currently sent, but ICW3 is skipped, which bochs doesn't like. Fixed it just by copying code in the PIC page on OSDev (https://wiki.osdev.org/8259_PIC):

; Remap the master PIC
mov al, 00010001b ; ICW1: Start init sequence
out 0x20, al
mov al, 0x20 ; ICW2: Start at interrupt 0x20
out 0x21, al
mov al, 4 ; ICW3: Slave PIC IRQ line
out 0x21, al
mov al, 00000001b ; ICW4: Enable 8086 mode
out 0x21, al

3) tss struct is missing some fields

The ss1 and ssp fields aren't included in tss.h. These fields aren't used directly, but they affect the size of the struct, which is referenced in the GDT limit field. The error happens since bochs expects that size field to be at least 104 bytes.

Fixed by adding the 2 missing fields:

struct tss
{
    uint32_t link;
    uint32_t esp0;
    uint32_t ss0;
    uint32_t esp1;
+   uint32_t ss1;
    uint32_t esp2;
    uint32_t ss2;
    uint32_t cr3;
    uint32_t eip;
    uint32_t eflags;
    uint32_t eax;
    uint32_t ecx;
    uint32_t edx;
    uint32_t ebx;
    uint32_t esp;
    uint32_t ebp;
    uint32_t esi;
    uint32_t edi;
    uint32_t es;
    uint32_t cs;
    uint32_t ss;
    uint32_t ds;
    uint32_t fs;
    uint32_t gs;
    uint32_t ldtr;
    uint32_t iopb;
+   uint32_t ssp;
} __attribute__((packed);