multiboot is fixed but using multiboot v1 for now, should work fine, memory paging next
This commit is contained in:
parent
a6471bb147
commit
f3285163e3
13 changed files with 127 additions and 95 deletions
10
grub.sh
Executable file
10
grub.sh
Executable 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
41
qemu.sh
Executable 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
44
run.sh
|
|
@ -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"
|
||||
}
|
||||
|
||||
"$@"
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
13
src/arch/x86/mem.zig
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
15
src/main.zig
15
src/main.zig
|
|
@ -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) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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!",
|
||||
|
|
|
|||
Loading…
Reference in a new issue