multiboot is fixed but using multiboot v1 for now, should work fine, memory paging next

This commit is contained in:
Jack Halford 2019-06-25 22:35:52 +02:00
parent a6471bb147
commit f3285163e3
13 changed files with 127 additions and 95 deletions

10
grub.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/bash
exit_missing() {
printf "$_ must be installed\n" ; exit 1;
}
which xorriso || exit_missing
which grub-mkrescue || exit_missing
mkdir -p build/iso/boot
cp build/bzImage build/iso/boot
grub-mkrescue -o build/kernel.iso build/iso

41
qemu.sh Executable file
View file

@ -0,0 +1,41 @@
QEMU_SOCKET=/tmp/qemu.sock
QEMU_MONITOR="socat - UNIX-CONNECT:${QEMU_SOCKET}"
QEMU_GDB_PORT=4242
KERNEL=build/bzImage
start() {
sudo pkill -9 qemu
sudo qemu-system-i386 \
-gdb tcp::${QEMU_GDB_PORT} \
-monitor unix:${QEMU_SOCKET},server,nowait \
-enable-kvm \
-display curses \
-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no \
-kernel ${KERNEL}
# build/kernel.iso
"$@"
}
monitor() {
if [ "$1" == "" ]; then
sudo ${QEMU_MONITOR}
else
echo "$1" | sudo ${QEMU_MONITOR} >/dev/null
fi
}
reload() {
monitor stop
# monitor "change ide1-cd0 ${KERNEL}"
monitor system_reset
monitor cont
}
gdb() {
gdb -q \
-symbols "${KERNEL}" \
-ex "target remote :${QEMU_GDB_PORT}" \
-ex "set arch i386"
}
"$@"

44
run.sh
View file

@ -1,44 +0,0 @@
QEMU_SOCKET=/tmp/qemu.sock
QEMU_MONITOR="socat - unix-connect:${QEMU_SOCKET}"
QEMU_GDB_PORT=4242
KERNEL=build/bzImage
qemu() {
start() {
killqemu
sudo qemu-system-i386\
-kernel ${KERNEL}\
-gdb tcp::${QEMU_GDB_PORT}\
-monitor unix:${QEMU_SOCKET},server,nowait\
-display curses\
-enable-kvm\
-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no\
$*
}
monitor() {
sudo ${QEMU_MONITOR}
}
killqemu() {
sudo pkill -9 qemu
}
reload() {
echo "stop" | ${QEMU_MONITOR} &>/dev/null
echo "change ide1-cd0 ${KERNEL}" | ${QEMU_MONITOR} &>/dev/null
echo "system_reset" | ${QEMU_MONITOR} &>/dev/null
}
"$@"
}
gdb() {
gdb\
-q\
-symbols "${KERNEL}" \
-ex "target remote :${QEMU_GDB_PORT}"\
-ex "set arch i386"
}
"$@"

View file

@ -8,7 +8,7 @@ __start:
push %ebx // Pass multiboot info structure.
push %eax // Pass multiboot magic code.
call x86_main // Call the kernel.
call kmain // Call the kernel.
// Halt the CPU.
cli

View file

@ -25,9 +25,9 @@ const IRQ_15 = IRQ_0 + 15;
const SYSCALL = 128;
// Registered interrupt handlers. (see isr.s)
var handlers = []fn () void{unhandled} ** 48;
var handlers = [_]fn () void{unhandled} ** 48;
// Registered IRQ subscribers. (see isr.s)
var irq_subscribers = []MailboxId{MailboxId.Kernel} ** 16;
// var irq_subscribers = []MailboxId{MailboxId.Kernel} ** 16;
fn unhandled() noreturn {
const n = isr.context.interrupt_n;

View file

@ -2,7 +2,10 @@
KERNEL_STACK = 0x80000
// GDT selectors.
KERNEL_DS = 0x10
USER_DS = 0x23
// not USER stack yet
// USER_DS = 0x23
USER_DS = 0x10
// Template for the Interrupt Service Routines.
.macro isrGenerate n
@ -42,6 +45,7 @@ isrCommon:
mov %ax, %ds
mov %ax, %es
popa // Restore the registers state.
add $8, %esp // Remove interrupt number and error code from stack.
iret

View file

@ -103,41 +103,41 @@ pub export var context: *volatile Context = undefined;
pub fn install() void {
// Exceptions.
idt.setGate(0, idt.INTERRUPT_GATE, isr0);
// idt.setGate(1, idt.INTERRUPT_GATE, isr1);
// idt.setGate(2, idt.INTERRUPT_GATE, isr2);
// idt.setGate(3, idt.INTERRUPT_GATE, isr3);
// idt.setGate(4, idt.INTERRUPT_GATE, isr4);
// idt.setGate(5, idt.INTERRUPT_GATE, isr5);
// idt.setGate(6, idt.INTERRUPT_GATE, isr6);
// idt.setGate(7, idt.INTERRUPT_GATE, isr7);
// idt.setGate(8, idt.INTERRUPT_GATE, isr8);
// idt.setGate(9, idt.INTERRUPT_GATE, isr9);
// idt.setGate(10, idt.INTERRUPT_GATE, isr10);
// idt.setGate(11, idt.INTERRUPT_GATE, isr11);
// idt.setGate(12, idt.INTERRUPT_GATE, isr12);
// idt.setGate(13, idt.INTERRUPT_GATE, isr13);
// idt.setGate(14, idt.INTERRUPT_GATE, isr14);
// idt.setGate(15, idt.INTERRUPT_GATE, isr15);
// idt.setGate(16, idt.INTERRUPT_GATE, isr16);
// idt.setGate(17, idt.INTERRUPT_GATE, isr17);
// idt.setGate(18, idt.INTERRUPT_GATE, isr18);
// idt.setGate(19, idt.INTERRUPT_GATE, isr19);
// idt.setGate(20, idt.INTERRUPT_GATE, isr20);
// idt.setGate(21, idt.INTERRUPT_GATE, isr21);
// idt.setGate(22, idt.INTERRUPT_GATE, isr22);
// idt.setGate(23, idt.INTERRUPT_GATE, isr23);
// idt.setGate(24, idt.INTERRUPT_GATE, isr24);
// idt.setGate(25, idt.INTERRUPT_GATE, isr25);
// idt.setGate(26, idt.INTERRUPT_GATE, isr26);
// idt.setGate(27, idt.INTERRUPT_GATE, isr27);
// idt.setGate(28, idt.INTERRUPT_GATE, isr28);
// idt.setGate(29, idt.INTERRUPT_GATE, isr29);
// idt.setGate(30, idt.INTERRUPT_GATE, isr30);
// idt.setGate(31, idt.INTERRUPT_GATE, isr31);
idt.setGate(1, idt.INTERRUPT_GATE, isr1);
idt.setGate(2, idt.INTERRUPT_GATE, isr2);
idt.setGate(3, idt.INTERRUPT_GATE, isr3);
idt.setGate(4, idt.INTERRUPT_GATE, isr4);
idt.setGate(5, idt.INTERRUPT_GATE, isr5);
idt.setGate(6, idt.INTERRUPT_GATE, isr6);
idt.setGate(7, idt.INTERRUPT_GATE, isr7);
idt.setGate(8, idt.INTERRUPT_GATE, isr8);
idt.setGate(9, idt.INTERRUPT_GATE, isr9);
idt.setGate(10, idt.INTERRUPT_GATE, isr10);
idt.setGate(11, idt.INTERRUPT_GATE, isr11);
idt.setGate(12, idt.INTERRUPT_GATE, isr12);
idt.setGate(13, idt.INTERRUPT_GATE, isr13);
idt.setGate(14, idt.INTERRUPT_GATE, isr14);
idt.setGate(15, idt.INTERRUPT_GATE, isr15);
idt.setGate(16, idt.INTERRUPT_GATE, isr16);
idt.setGate(17, idt.INTERRUPT_GATE, isr17);
idt.setGate(18, idt.INTERRUPT_GATE, isr18);
idt.setGate(19, idt.INTERRUPT_GATE, isr19);
idt.setGate(20, idt.INTERRUPT_GATE, isr20);
idt.setGate(21, idt.INTERRUPT_GATE, isr21);
idt.setGate(22, idt.INTERRUPT_GATE, isr22);
idt.setGate(23, idt.INTERRUPT_GATE, isr23);
idt.setGate(24, idt.INTERRUPT_GATE, isr24);
idt.setGate(25, idt.INTERRUPT_GATE, isr25);
idt.setGate(26, idt.INTERRUPT_GATE, isr26);
idt.setGate(27, idt.INTERRUPT_GATE, isr27);
idt.setGate(28, idt.INTERRUPT_GATE, isr28);
idt.setGate(29, idt.INTERRUPT_GATE, isr29);
idt.setGate(30, idt.INTERRUPT_GATE, isr30);
idt.setGate(31, idt.INTERRUPT_GATE, isr31);
// // IRQs.
// idt.setGate(32, idt.INTERRUPT_GATE, isr32);
// idt.setGate(33, idt.INTERRUPT_GATE, isr33);
idt.setGate(32, idt.INTERRUPT_GATE, isr32);
idt.setGate(33, idt.INTERRUPT_GATE, isr33);
// idt.setGate(34, idt.INTERRUPT_GATE, isr34);
// idt.setGate(35, idt.INTERRUPT_GATE, isr35);
// idt.setGate(36, idt.INTERRUPT_GATE, isr36);

View file

@ -1,16 +1,16 @@
usingnamespace @import("kernel").main;
usingnamespace @import("kernel").multiboot;
const idt = @import("idt.zig");
const mem = @import("mem.zig");
const gdt = @import("gdt.zig");
const x86 = @import("lib/index.zig");
const assert = @import("std").debug.assert;
const console = @import("../console.zig");
/// x86 specific intialization
/// first entry point (see linker.ld)
export nakedcc fn x86_main(magic: u32, info: *const MultibootInfo) noreturn {
// assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
gdt.initialize();
pub fn x86_main(info: *const MultibootInfo) void {
mem.initialize(info);
// gdt.initialize();
idt.initialize();
x86.sti();
kmain(magic, info);
// x86.sti();
}

13
src/arch/x86/mem.zig Normal file
View file

@ -0,0 +1,13 @@
usingnamespace @import("kernel").multiboot;
const assert = @import("std").debug.assert;
const vga = @import("../../vga.zig");
pub fn initialize(info: *const MultibootInfo) void {
assert((info.flags & MULTIBOOT_INFO_MEMORY) != 0);
assert((info.flags & MULTIBOOT_INFO_MEM_MAP) != 0);
vga.printf("lower: {x}\n", info.mem_lower);
vga.printf("upper: {x}\n", info.mem_upper);
vga.printf("mmap_l: {}\n", info.mmap_length);
vga.printf("mmap_a: {x}\n", info.mmap_addr);
}

View file

@ -4,7 +4,7 @@ const ps2 = @import("ps2.zig");
const pci = @import("pci.zig");
const std = @import("std");
const mem = std.mem;
use @import("vga.zig");
usingnamespace @import("vga.zig");
var command: [10]u8 = undefined;
var command_len: usize = 0;
@ -34,6 +34,6 @@ pub fn keypress(char: u8) void {
pub fn initialize() void {
vga.clear();
vga.writeString("> ");
// vga.writeString("> ");
interrupt.registerIRQ(1, ps2.keyboard_handler);
}

View file

@ -3,10 +3,19 @@ const pci = @import("pci.zig");
const arch = @import("arch/x86/lib/index.zig");
const console = @import("console.zig");
const vga = @import("vga.zig");
const x86 = @import("arch/x86/main.zig");
const assert = @import("std").debug.assert;
// platform independant initialization
pub fn kmain(magic: u32, info: *const MultibootInfo) noreturn {
// arch independant initialization
export fn kmain(magic: u32, info: *const MultibootInfo) noreturn {
assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
console.initialize();
vga.printf("magic 0x{x}\n", magic);
vga.printf("--- x86_main ---\n");
x86.x86_main(info);
vga.printf("--- arch indepent boot ---\n");
while (true) {}
}

View file

@ -10,7 +10,6 @@ pub const MULTIBOOT_BOOTLOADER_MAGIC = 0x2BADB002;
pub const MULTIBOOT_INFO_MEMORY = 0x00000001;
// Is there a full memory map?
pub const MULTIBOOT_INFO_MEM_MAP = 0x00000040;
// System information structure passed by the bootloader.
pub const MultibootInfo = packed struct {
// Multiboot info version number.
@ -115,7 +114,7 @@ const MultibootHeader = packed struct {
// Place the header at the very beginning of the binary.
export const multiboot_header align(4) linksection(".multiboot") = multiboot: {
const MAGIC = u32(0x1BADB002); // Magic number for validation.
const MAGIC = u32(0x1BADB002); // multiboot magic
const ALIGN = u32(1 << 0); // Align loaded modules.
const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader.
const FLAGS = ALIGN | MEMINFO; // Combine the flags.

View file

@ -4,7 +4,7 @@ const console = @import("console.zig");
const PS2_DATA = 0x60;
const PS2_STATUS = 0x64;
const KEYMAP_MAX = 59;
const KEYMAP_US = [][2]u8{
const KEYMAP_US = [_][2]u8{
"\x00\x00",
"\x00\x00", //escape
"1!",