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 %ebx // Pass multiboot info structure.
|
||||||
push %eax // Pass multiboot magic code.
|
push %eax // Pass multiboot magic code.
|
||||||
call x86_main // Call the kernel.
|
call kmain // Call the kernel.
|
||||||
|
|
||||||
// Halt the CPU.
|
// Halt the CPU.
|
||||||
cli
|
cli
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ const IRQ_15 = IRQ_0 + 15;
|
||||||
const SYSCALL = 128;
|
const SYSCALL = 128;
|
||||||
|
|
||||||
// Registered interrupt handlers. (see isr.s)
|
// Registered interrupt handlers. (see isr.s)
|
||||||
var handlers = []fn () void{unhandled} ** 48;
|
var handlers = [_]fn () void{unhandled} ** 48;
|
||||||
// Registered IRQ subscribers. (see isr.s)
|
// Registered IRQ subscribers. (see isr.s)
|
||||||
var irq_subscribers = []MailboxId{MailboxId.Kernel} ** 16;
|
// var irq_subscribers = []MailboxId{MailboxId.Kernel} ** 16;
|
||||||
|
|
||||||
fn unhandled() noreturn {
|
fn unhandled() noreturn {
|
||||||
const n = isr.context.interrupt_n;
|
const n = isr.context.interrupt_n;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
KERNEL_STACK = 0x80000
|
KERNEL_STACK = 0x80000
|
||||||
// GDT selectors.
|
// GDT selectors.
|
||||||
KERNEL_DS = 0x10
|
KERNEL_DS = 0x10
|
||||||
USER_DS = 0x23
|
|
||||||
|
// not USER stack yet
|
||||||
|
// USER_DS = 0x23
|
||||||
|
USER_DS = 0x10
|
||||||
|
|
||||||
// Template for the Interrupt Service Routines.
|
// Template for the Interrupt Service Routines.
|
||||||
.macro isrGenerate n
|
.macro isrGenerate n
|
||||||
|
|
@ -42,6 +45,7 @@ isrCommon:
|
||||||
mov %ax, %ds
|
mov %ax, %ds
|
||||||
mov %ax, %es
|
mov %ax, %es
|
||||||
|
|
||||||
|
|
||||||
popa // Restore the registers state.
|
popa // Restore the registers state.
|
||||||
add $8, %esp // Remove interrupt number and error code from stack.
|
add $8, %esp // Remove interrupt number and error code from stack.
|
||||||
iret
|
iret
|
||||||
|
|
|
||||||
|
|
@ -103,41 +103,41 @@ pub export var context: *volatile Context = undefined;
|
||||||
pub fn install() void {
|
pub fn install() void {
|
||||||
// Exceptions.
|
// Exceptions.
|
||||||
idt.setGate(0, idt.INTERRUPT_GATE, isr0);
|
idt.setGate(0, idt.INTERRUPT_GATE, isr0);
|
||||||
// idt.setGate(1, idt.INTERRUPT_GATE, isr1);
|
idt.setGate(1, idt.INTERRUPT_GATE, isr1);
|
||||||
// idt.setGate(2, idt.INTERRUPT_GATE, isr2);
|
idt.setGate(2, idt.INTERRUPT_GATE, isr2);
|
||||||
// idt.setGate(3, idt.INTERRUPT_GATE, isr3);
|
idt.setGate(3, idt.INTERRUPT_GATE, isr3);
|
||||||
// idt.setGate(4, idt.INTERRUPT_GATE, isr4);
|
idt.setGate(4, idt.INTERRUPT_GATE, isr4);
|
||||||
// idt.setGate(5, idt.INTERRUPT_GATE, isr5);
|
idt.setGate(5, idt.INTERRUPT_GATE, isr5);
|
||||||
// idt.setGate(6, idt.INTERRUPT_GATE, isr6);
|
idt.setGate(6, idt.INTERRUPT_GATE, isr6);
|
||||||
// idt.setGate(7, idt.INTERRUPT_GATE, isr7);
|
idt.setGate(7, idt.INTERRUPT_GATE, isr7);
|
||||||
// idt.setGate(8, idt.INTERRUPT_GATE, isr8);
|
idt.setGate(8, idt.INTERRUPT_GATE, isr8);
|
||||||
// idt.setGate(9, idt.INTERRUPT_GATE, isr9);
|
idt.setGate(9, idt.INTERRUPT_GATE, isr9);
|
||||||
// idt.setGate(10, idt.INTERRUPT_GATE, isr10);
|
idt.setGate(10, idt.INTERRUPT_GATE, isr10);
|
||||||
// idt.setGate(11, idt.INTERRUPT_GATE, isr11);
|
idt.setGate(11, idt.INTERRUPT_GATE, isr11);
|
||||||
// idt.setGate(12, idt.INTERRUPT_GATE, isr12);
|
idt.setGate(12, idt.INTERRUPT_GATE, isr12);
|
||||||
// idt.setGate(13, idt.INTERRUPT_GATE, isr13);
|
idt.setGate(13, idt.INTERRUPT_GATE, isr13);
|
||||||
// idt.setGate(14, idt.INTERRUPT_GATE, isr14);
|
idt.setGate(14, idt.INTERRUPT_GATE, isr14);
|
||||||
// idt.setGate(15, idt.INTERRUPT_GATE, isr15);
|
idt.setGate(15, idt.INTERRUPT_GATE, isr15);
|
||||||
// idt.setGate(16, idt.INTERRUPT_GATE, isr16);
|
idt.setGate(16, idt.INTERRUPT_GATE, isr16);
|
||||||
// idt.setGate(17, idt.INTERRUPT_GATE, isr17);
|
idt.setGate(17, idt.INTERRUPT_GATE, isr17);
|
||||||
// idt.setGate(18, idt.INTERRUPT_GATE, isr18);
|
idt.setGate(18, idt.INTERRUPT_GATE, isr18);
|
||||||
// idt.setGate(19, idt.INTERRUPT_GATE, isr19);
|
idt.setGate(19, idt.INTERRUPT_GATE, isr19);
|
||||||
// idt.setGate(20, idt.INTERRUPT_GATE, isr20);
|
idt.setGate(20, idt.INTERRUPT_GATE, isr20);
|
||||||
// idt.setGate(21, idt.INTERRUPT_GATE, isr21);
|
idt.setGate(21, idt.INTERRUPT_GATE, isr21);
|
||||||
// idt.setGate(22, idt.INTERRUPT_GATE, isr22);
|
idt.setGate(22, idt.INTERRUPT_GATE, isr22);
|
||||||
// idt.setGate(23, idt.INTERRUPT_GATE, isr23);
|
idt.setGate(23, idt.INTERRUPT_GATE, isr23);
|
||||||
// idt.setGate(24, idt.INTERRUPT_GATE, isr24);
|
idt.setGate(24, idt.INTERRUPT_GATE, isr24);
|
||||||
// idt.setGate(25, idt.INTERRUPT_GATE, isr25);
|
idt.setGate(25, idt.INTERRUPT_GATE, isr25);
|
||||||
// idt.setGate(26, idt.INTERRUPT_GATE, isr26);
|
idt.setGate(26, idt.INTERRUPT_GATE, isr26);
|
||||||
// idt.setGate(27, idt.INTERRUPT_GATE, isr27);
|
idt.setGate(27, idt.INTERRUPT_GATE, isr27);
|
||||||
// idt.setGate(28, idt.INTERRUPT_GATE, isr28);
|
idt.setGate(28, idt.INTERRUPT_GATE, isr28);
|
||||||
// idt.setGate(29, idt.INTERRUPT_GATE, isr29);
|
idt.setGate(29, idt.INTERRUPT_GATE, isr29);
|
||||||
// idt.setGate(30, idt.INTERRUPT_GATE, isr30);
|
idt.setGate(30, idt.INTERRUPT_GATE, isr30);
|
||||||
// idt.setGate(31, idt.INTERRUPT_GATE, isr31);
|
idt.setGate(31, idt.INTERRUPT_GATE, isr31);
|
||||||
|
|
||||||
// // IRQs.
|
// // IRQs.
|
||||||
// idt.setGate(32, idt.INTERRUPT_GATE, isr32);
|
idt.setGate(32, idt.INTERRUPT_GATE, isr32);
|
||||||
// idt.setGate(33, idt.INTERRUPT_GATE, isr33);
|
idt.setGate(33, idt.INTERRUPT_GATE, isr33);
|
||||||
// idt.setGate(34, idt.INTERRUPT_GATE, isr34);
|
// idt.setGate(34, idt.INTERRUPT_GATE, isr34);
|
||||||
// idt.setGate(35, idt.INTERRUPT_GATE, isr35);
|
// idt.setGate(35, idt.INTERRUPT_GATE, isr35);
|
||||||
// idt.setGate(36, idt.INTERRUPT_GATE, isr36);
|
// idt.setGate(36, idt.INTERRUPT_GATE, isr36);
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
usingnamespace @import("kernel").main;
|
usingnamespace @import("kernel").main;
|
||||||
usingnamespace @import("kernel").multiboot;
|
usingnamespace @import("kernel").multiboot;
|
||||||
const idt = @import("idt.zig");
|
const idt = @import("idt.zig");
|
||||||
|
const mem = @import("mem.zig");
|
||||||
const gdt = @import("gdt.zig");
|
const gdt = @import("gdt.zig");
|
||||||
const x86 = @import("lib/index.zig");
|
const x86 = @import("lib/index.zig");
|
||||||
const assert = @import("std").debug.assert;
|
const console = @import("../console.zig");
|
||||||
|
|
||||||
/// x86 specific intialization
|
/// x86 specific intialization
|
||||||
/// first entry point (see linker.ld)
|
/// first entry point (see linker.ld)
|
||||||
export nakedcc fn x86_main(magic: u32, info: *const MultibootInfo) noreturn {
|
pub fn x86_main(info: *const MultibootInfo) void {
|
||||||
// assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
|
mem.initialize(info);
|
||||||
gdt.initialize();
|
// gdt.initialize();
|
||||||
idt.initialize();
|
idt.initialize();
|
||||||
x86.sti();
|
// x86.sti();
|
||||||
kmain(magic, info);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
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 pci = @import("pci.zig");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
use @import("vga.zig");
|
usingnamespace @import("vga.zig");
|
||||||
|
|
||||||
var command: [10]u8 = undefined;
|
var command: [10]u8 = undefined;
|
||||||
var command_len: usize = 0;
|
var command_len: usize = 0;
|
||||||
|
|
@ -34,6 +34,6 @@ pub fn keypress(char: u8) void {
|
||||||
|
|
||||||
pub fn initialize() void {
|
pub fn initialize() void {
|
||||||
vga.clear();
|
vga.clear();
|
||||||
vga.writeString("> ");
|
// vga.writeString("> ");
|
||||||
interrupt.registerIRQ(1, ps2.keyboard_handler);
|
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 arch = @import("arch/x86/lib/index.zig");
|
||||||
const console = @import("console.zig");
|
const console = @import("console.zig");
|
||||||
const vga = @import("vga.zig");
|
const vga = @import("vga.zig");
|
||||||
|
const x86 = @import("arch/x86/main.zig");
|
||||||
|
const assert = @import("std").debug.assert;
|
||||||
|
|
||||||
// platform independant initialization
|
// arch independant initialization
|
||||||
pub fn kmain(magic: u32, info: *const MultibootInfo) noreturn {
|
export fn kmain(magic: u32, info: *const MultibootInfo) noreturn {
|
||||||
|
assert(magic == MULTIBOOT_BOOTLOADER_MAGIC);
|
||||||
console.initialize();
|
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) {}
|
while (true) {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ pub const MULTIBOOT_BOOTLOADER_MAGIC = 0x2BADB002;
|
||||||
pub const MULTIBOOT_INFO_MEMORY = 0x00000001;
|
pub const MULTIBOOT_INFO_MEMORY = 0x00000001;
|
||||||
// Is there a full memory map?
|
// Is there a full memory map?
|
||||||
pub const MULTIBOOT_INFO_MEM_MAP = 0x00000040;
|
pub const MULTIBOOT_INFO_MEM_MAP = 0x00000040;
|
||||||
|
|
||||||
// System information structure passed by the bootloader.
|
// System information structure passed by the bootloader.
|
||||||
pub const MultibootInfo = packed struct {
|
pub const MultibootInfo = packed struct {
|
||||||
// Multiboot info version number.
|
// Multiboot info version number.
|
||||||
|
|
@ -115,7 +114,7 @@ const MultibootHeader = packed struct {
|
||||||
|
|
||||||
// Place the header at the very beginning of the binary.
|
// Place the header at the very beginning of the binary.
|
||||||
export const multiboot_header align(4) linksection(".multiboot") = multiboot: {
|
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 ALIGN = u32(1 << 0); // Align loaded modules.
|
||||||
const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader.
|
const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader.
|
||||||
const FLAGS = ALIGN | MEMINFO; // Combine the flags.
|
const FLAGS = ALIGN | MEMINFO; // Combine the flags.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const console = @import("console.zig");
|
||||||
const PS2_DATA = 0x60;
|
const PS2_DATA = 0x60;
|
||||||
const PS2_STATUS = 0x64;
|
const PS2_STATUS = 0x64;
|
||||||
const KEYMAP_MAX = 59;
|
const KEYMAP_MAX = 59;
|
||||||
const KEYMAP_US = [][2]u8{
|
const KEYMAP_US = [_][2]u8{
|
||||||
"\x00\x00",
|
"\x00\x00",
|
||||||
"\x00\x00", //escape
|
"\x00\x00", //escape
|
||||||
"1!",
|
"1!",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue