diff --git a/README.md b/README.md index fc2edc7..c46298b 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ slowly porting from rust. `./qemu.sh monitor` `./qemu.sh gdb` -### todo +# Notes -- recycling allocator that wraps the bump allocator +## interrupts + +`interrupt` -> `idt[n]` -> `isrN` -> `isrDispatch` -> `handlers[n]` (default `unhandled()`) diff --git a/build.zig b/build.zig index b37b877..f13c969 100644 --- a/build.zig +++ b/build.zig @@ -2,7 +2,7 @@ const Builder = @import("std").build.Builder; const builtin = @import("builtin"); pub fn build(b: *Builder) void { - const kernel = b.addExecutable("bzImage", "src/arch/x86/main.zig"); + const kernel = b.addExecutable("kernel", "src/arch/x86/main.zig"); kernel.addPackagePath("kernel", "src/index.zig"); kernel.addPackagePath("arch", "src/arch/x86/lib/index.zig"); kernel.setOutputDir("build"); @@ -10,6 +10,7 @@ pub fn build(b: *Builder) void { kernel.addAssemblyFile("src/arch/x86/_start.s"); kernel.addAssemblyFile("src/arch/x86/gdt.s"); kernel.addAssemblyFile("src/arch/x86/isr.s"); + kernel.addAssemblyFile("src/arch/x86/paging.s"); kernel.setBuildMode(b.standardReleaseOptions()); kernel.setTarget(builtin.Arch.i386, builtin.Os.freestanding, builtin.Abi.none); diff --git a/qemu.sh b/qemu.sh index d989ffd..5291745 100755 --- a/qemu.sh +++ b/qemu.sh @@ -1,7 +1,7 @@ QEMU_SOCKET=/tmp/qemu.sock QEMU_MONITOR="socat - UNIX-CONNECT:${QEMU_SOCKET}" QEMU_GDB_PORT=4242 -KERNEL=build/bzImage +KERNEL=build/kernel start() { sudo pkill -9 qemu @@ -10,11 +10,11 @@ start() { -monitor unix:${QEMU_SOCKET},server,nowait \ -enable-kvm \ -m 1337M \ - -display curses \ + -curses \ -serial mon:stdio \ -append "Hello" \ - -device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no \ -kernel ${KERNEL} + # -device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no \ # build/kernel.iso "$@" } diff --git a/src/arch/x86/gdt.zig b/src/arch/x86/gdt.zig index ec1c08a..5974038 100644 --- a/src/arch/x86/gdt.zig +++ b/src/arch/x86/gdt.zig @@ -72,7 +72,7 @@ fn makeEntry(base: usize, limit: usize, access: u8, flags: u4) GDTEntry { } // Fill in the GDT. -var gdt align(4) = []GDTEntry{ +var gdt align(4) = [_]GDTEntry{ makeEntry(0, 0, 0, 0), makeEntry(0, 0xFFFFF, KERNEL | CODE, PROTECTED | BLOCKS_4K), makeEntry(0, 0xFFFFF, KERNEL | DATA, PROTECTED | BLOCKS_4K), @@ -92,7 +92,7 @@ var tss = TSS{ .unused1 = 0, .esp0 = undefined, .ss0 = KERNEL_DATA, - .unused2 = []u32{0} ** 22, + .unused2 = [_]u32{0} ** 22, .unused3 = 0, .iomap_base = @sizeOf(TSS), }; diff --git a/src/arch/x86/idt.zig b/src/arch/x86/idt.zig index ecd2bd5..f06a0b1 100644 --- a/src/arch/x86/idt.zig +++ b/src/arch/x86/idt.zig @@ -1,4 +1,5 @@ // https://wiki.osdev.org/IDT +usingnamespace @import("../../vga.zig"); const x86 = @import("lib/index.zig"); const interrupt = @import("interrupt.zig"); const gdt = @import("gdt.zig"); @@ -47,12 +48,18 @@ pub fn setGate(n: u8, flags: u8, offset: extern fn () void) void { idt[n].flags = flags; idt[n].zero = 0; idt[n].selector = gdt.KERNEL_CODE; + println("offset: 0x{x}", @ptrToInt(offset)); + println("low : 0x{x}", idt[n].offset_low); + println("high : 0x{x}", idt[n].offset_high); } //// // Initialize the Interrupt Descriptor Table. // pub fn initialize() void { + // configure PIC and set ISRs interrupt.initialize(); + + // load IDT x86.lidt(@ptrToInt(&idtr)); } diff --git a/src/arch/x86/interrupt.zig b/src/arch/x86/interrupt.zig index c7e2912..068bb30 100644 --- a/src/arch/x86/interrupt.zig +++ b/src/arch/x86/interrupt.zig @@ -1,5 +1,6 @@ const x86 = @import("lib/index.zig"); const isr = @import("isr.zig"); +const println = @import("../../vga.zig").println; // PIC ports. const PIC1_CMD = 0x20; @@ -31,11 +32,11 @@ var handlers = [_]fn () void{unhandled} ** 48; fn unhandled() noreturn { const n = isr.context.interrupt_n; - // if (n >= IRQ_0) { - // tty.panic("unhandled IRQ number {d}", n - IRQ_0); - // } else { - // tty.panic("unhandled exception number {d}", n); - // } + if (n < IRQ_0) { + println("unhandled exception number {d}", n); + } else { + println("unhandled IRQ number {d} (intr {d})", n - IRQ_0, n); + } x86.hang(); } @@ -177,6 +178,7 @@ pub fn maskIRQ(irq: u8, mask: bool) void { } else { x86.outb(port, old & ~(u8(1) << shift)); } + const new = x86.inb(port); // Retrieve the current mask. } //// diff --git a/src/arch/x86/isr.zig b/src/arch/x86/isr.zig index 68256c9..90abf13 100644 --- a/src/arch/x86/isr.zig +++ b/src/arch/x86/isr.zig @@ -135,24 +135,24 @@ pub fn install() void { idt.setGate(30, idt.INTERRUPT_GATE, isr30); idt.setGate(31, idt.INTERRUPT_GATE, isr31); - // // IRQs. + // IRQs. 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); - // idt.setGate(37, idt.INTERRUPT_GATE, isr37); - // idt.setGate(38, idt.INTERRUPT_GATE, isr38); - // idt.setGate(39, idt.INTERRUPT_GATE, isr39); - // idt.setGate(40, idt.INTERRUPT_GATE, isr40); - // idt.setGate(41, idt.INTERRUPT_GATE, isr41); - // idt.setGate(42, idt.INTERRUPT_GATE, isr42); - // idt.setGate(43, idt.INTERRUPT_GATE, isr43); - // idt.setGate(44, idt.INTERRUPT_GATE, isr44); - // idt.setGate(45, idt.INTERRUPT_GATE, isr45); - // idt.setGate(46, idt.INTERRUPT_GATE, isr46); - // idt.setGate(47, idt.INTERRUPT_GATE, isr47); + idt.setGate(34, idt.INTERRUPT_GATE, isr34); + idt.setGate(35, idt.INTERRUPT_GATE, isr35); + idt.setGate(36, idt.INTERRUPT_GATE, isr36); + idt.setGate(37, idt.INTERRUPT_GATE, isr37); + idt.setGate(38, idt.INTERRUPT_GATE, isr38); + idt.setGate(39, idt.INTERRUPT_GATE, isr39); + idt.setGate(40, idt.INTERRUPT_GATE, isr40); + idt.setGate(41, idt.INTERRUPT_GATE, isr41); + idt.setGate(42, idt.INTERRUPT_GATE, isr42); + idt.setGate(43, idt.INTERRUPT_GATE, isr43); + idt.setGate(44, idt.INTERRUPT_GATE, isr44); + idt.setGate(45, idt.INTERRUPT_GATE, isr45); + idt.setGate(46, idt.INTERRUPT_GATE, isr46); + idt.setGate(47, idt.INTERRUPT_GATE, isr47); - // // Syscalls. - // idt.setGate(128, idt.SYSCALL_GATE, isr128); + // Syscalls. + idt.setGate(128, idt.SYSCALL_GATE, isr128); } diff --git a/src/arch/x86/lib/instructions.zig b/src/arch/x86/lib/instructions.zig index 97787d4..99d302d 100644 --- a/src/arch/x86/lib/instructions.zig +++ b/src/arch/x86/lib/instructions.zig @@ -24,6 +24,9 @@ pub inline fn hang() noreturn { pub inline fn sti() void { asm volatile ("sti"); } +pub inline fn int3() void { + asm volatile ("int3"); +} //// // Load a new Interrupt Descriptor Table. diff --git a/src/arch/x86/linker.ld b/src/arch/x86/linker.ld index d90c28b..dabb1b9 100644 --- a/src/arch/x86/linker.ld +++ b/src/arch/x86/linker.ld @@ -8,7 +8,8 @@ SECTIONS { . = 0xb8000; . += 80 * 25 * 2; - . = 0x100000; + /* lower half kernel */ + . = 0x10000; /* ensure that the multiboot header is at the beginning */ .multiboot : @@ -67,16 +68,4 @@ SECTIONS { *(.bss .bss.*) . = ALIGN(4K); } - - /* .stab : */ - /* { */ - /* KEEP(*(.stab)) */ - /* . = ALIGN(4K); */ - /* } */ - - /* .stabstr : */ - /* { */ - /* KEEP(*(.stabstr)) */ - /* . = ALIGN(4K); */ - /* } */ } diff --git a/src/arch/x86/main.zig b/src/arch/x86/main.zig index 5adcdf4..68b2c56 100644 --- a/src/arch/x86/main.zig +++ b/src/arch/x86/main.zig @@ -1,18 +1,37 @@ usingnamespace @import("kernel").main; usingnamespace @import("kernel").multiboot; +const console = @import("../console.zig"); +const println = @import("../../vga.zig").println; + const idt = @import("idt.zig"); -const mem = @import("mem.zig"); +const memory = @import("memory.zig"); +const paging = @import("paging.zig"); const gdt = @import("gdt.zig"); const x86 = @import("lib/index.zig"); -const console = @import("../console.zig"); -const printf = @import("../../vga.zig").printf; /// x86 specific intialization /// first entry point (see linker.ld) pub fn x86_main(info: *const MultibootInfo) void { - var allocator = mem.initialize(info); + // set up the physical frame allocator + memory.initialize(info); - // gdt.initialize(); + println("{}", memory.allocator.allocate(1)); + // println("{}", memory.allocator.allocate(1)); + // println("{}", memory.allocator.allocate(1)); + // println("{}", memory.allocator.allocate(1)); + + // setup memory segmentation + gdt.initialize(); + + // setup interrupts idt.initialize(); + + // enable interrupts x86.sti(); + + // set up the virtual page mapper + paging.initialize(); + + // test breakpoint + // x86.int3(); } diff --git a/src/arch/x86/mem.zig b/src/arch/x86/memory.zig similarity index 50% rename from src/arch/x86/mem.zig rename to src/arch/x86/memory.zig index 4c4cd9a..d2a5f41 100644 --- a/src/arch/x86/mem.zig +++ b/src/arch/x86/memory.zig @@ -1,41 +1,43 @@ usingnamespace @import("kernel").multiboot; +usingnamespace @import("../../vga.zig"); const assert = @import("std").debug.assert; -const vga = @import("../../vga.zig"); const std = @import("std"); -const printf = @import("../../vga.zig").printf; -pub fn initialize(info: *const MultibootInfo) bumpAllocator { +pub var allocator: bumpAllocator = undefined; + +pub fn initialize(info: *const MultibootInfo) void { assert((info.flags & MULTIBOOT_INFO_MEMORY) != 0); assert((info.flags & MULTIBOOT_INFO_MEM_MAP) != 0); format_multibootinfo(info); - return bumpAllocator.new(info); + allocator = bumpAllocator.new(info); } -pub fn format_multibootentry(entry: *MultibootMMapEntry) void { +fn format_multibootentry(entry: *MultibootMMapEntry) void { if (entry.type == MULTIBOOT_MEMORY_AVAILABLE) { - vga.printf("AVAILABLE: "); + print(" AVAILABLE: "); } else { - vga.printf("NOT AVAILABLE: "); + print("NOT AVAILABLE: "); } - vga.printf("{x} ", entry.addr); + print("{x} ", entry.addr); if (entry.len / (1024 * 1024) > 0) { - vga.printf("({} MB)\n", entry.len / (1024 * 1024)); + println("({} MB)", entry.len / (1024 * 1024)); } else { - vga.printf("({} kB)\n", entry.len / (1024)); + println("({} kB)", entry.len / (1024)); } } -pub fn format_multibootinfo(info: *const MultibootInfo) void { +fn format_multibootinfo(info: *const MultibootInfo) void { var cmdline_ptr = @intToPtr([*c]const u8, info.cmdline); var cmdline = @ptrCast([*c]const u8, cmdline_ptr); // var cmdline = std.cstr.toSliceConst(info.cmdline); - 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); - vga.printf("cmdline: {x}\n", cmdline_ptr); - vga.printf("cmdline: {}\n", cmdline); + println("flags: {b}", info.flags); + println("lower: {x}", info.mem_lower); + println("upper: {x}", info.mem_upper); + println("mmap_l: {}", info.mmap_length); + println("mmap_a: {x}", info.mmap_addr); + println("cmdline: {x}", cmdline_ptr); + println("cmdline: {}", cmdline); var map: usize = info.mmap_addr; while (map < info.mmap_addr + info.mmap_length) { @@ -47,22 +49,21 @@ pub fn format_multibootinfo(info: *const MultibootInfo) void { // returns each available physical frame one by one in order pub const bumpAllocator = struct { - next_free_frame: physFrame, + next_free_frame: PhysFrame, current_area: ?*MultibootMMapEntry, info: *const MultibootInfo, pub fn new(info: *const MultibootInfo) bumpAllocator { const first_area = @intToPtr(*MultibootMMapEntry, info.mmap_addr); - var allocator = bumpAllocator{ + var allocato = bumpAllocator{ .current_area = first_area, - .next_free_frame = physFrame.from_addr(first_area.addr), + .next_free_frame = PhysFrame.from_addr(@intCast(u32, first_area.addr)), .info = info, }; - // allocator.choose_next_area(); - return allocator; + return allocato; } - pub fn allocate(self: var, count: u64) ?physFrame { + pub fn allocate(self: var, count: u32) ?PhysFrame { if (count == 0) { return null; } @@ -73,10 +74,15 @@ pub const bumpAllocator = struct { self.choose_next_area(); return self.allocate(count); } + // <4MB identity mapped kernel, lazy trick + if (PhysFrame.start_addr(self.next_free_frame) < 0x400000) { + self.next_free_frame.number += 1; + return self.allocate(count); + } const start_frame = self.next_free_frame; const end_frame = self.next_free_frame.add(count - 1); - const current_area_last_frame = physFrame.from_addr(self.current_area.?.addr + self.current_area.?.len); + const current_area_last_frame = PhysFrame.from_addr(@intCast(u32, self.current_area.?.addr + self.current_area.?.len)); if (end_frame.number > current_area_last_frame.number) { self.choose_next_area(); return self.allocate(count); @@ -86,72 +92,33 @@ pub const bumpAllocator = struct { } pub fn choose_next_area(self: var) void { - printf("choosing next area\n"); + println("choosing next area"); const current = self.current_area.?; var next_area = @ptrToInt(current) + current.size + @sizeOf(@typeOf(current)); if (next_area >= self.info.mmap_addr + self.info.mmap_length) { self.current_area = null; } else { - format_multibootentry(self.current_area.?); self.current_area = @intToPtr(*MultibootMMapEntry, next_area); format_multibootentry(self.current_area.?); - self.next_free_frame = physFrame.from_addr(self.current_area.?.addr); + self.next_free_frame = PhysFrame.from_addr(@intCast(u32, self.current_area.?.addr)); } } }; pub const PAGE_SIZE = 4096; -pub const physFrame = struct { - number: u64, +pub const PhysFrame = struct { + number: u32, - pub fn from_addr(addr: u64) physFrame { - return physFrame{ .number = @divTrunc(addr, PAGE_SIZE) }; + pub fn from_addr(addr: u32) PhysFrame { + return PhysFrame{ .number = @divTrunc(addr, PAGE_SIZE) }; } - pub fn add(self: physFrame, count: u64) physFrame { - return physFrame{ .number = self.number + count }; + pub fn add(self: PhysFrame, count: u32) PhysFrame { + return PhysFrame{ .number = self.number + count }; } - pub fn start_addr(self: physFrame) u64 { + pub fn start_addr(self: PhysFrame) u32 { return (self.number * PAGE_SIZE); } }; - -const PageDirectory = packed struct { - entries: [1024]PageDirectoryEntry, -}; - -const PageDirectoryEntry = packed struct { - address: u21, - available: u2, - ignored: u1, - size: u1, - zero: u1, - accessed: u1, - cache_disabled: u1, - write_through: u1, - user: u1, - writeable: u1, - present: u1, -}; - -const PageTable = packed struct { - entries: [1024]PageTableEntry, -}; - -const PageTableEntry = packed struct { - address: u21, - available: u2, - global: u1, - zero: u1, - dirty: u1, - accessed: u1, - cache_disabled: u1, - write_through: u1, - user: u1, - writeable: u1, - present: u1, -}; - -// assert(@sizeOf(PageTableEntry) == 32); diff --git a/src/arch/x86/paging.s b/src/arch/x86/paging.s new file mode 100644 index 0000000..c164a28 --- /dev/null +++ b/src/arch/x86/paging.s @@ -0,0 +1,24 @@ +.type setupPaging, @function +.global setupPaging + +//// +// Enable the paging system. +// +// Arguments: +// phys_pd: Physical pointer to the page directory. +// +setupPaging: + mov +4(%esp), %eax // Fetch the phys_pd parameter. + mov %eax, %cr3 // Point CR3 to the page directory. + + // Enable Page Size Extension and Page Global. + mov %cr4, %eax + or $0b00010000, %eax + mov %eax, %cr4 + + // Enable Paging. + mov %cr0, %eax + or $(1 << 31), %eax + mov %eax, %cr0 + + ret diff --git a/src/arch/x86/paging.zig b/src/arch/x86/paging.zig new file mode 100644 index 0000000..545456f --- /dev/null +++ b/src/arch/x86/paging.zig @@ -0,0 +1,89 @@ +const x86 = @import("lib/index.zig"); +const allocator = @import("memory.zig").allocator; +const assert = @import("std").debug.assert; +const println = @import("../../vga.zig").println; + +extern fn setupPaging(phys_pd: usize) void; + +pub var mapper: Mapper = undefined; +pub const PAGE_SIZE = 4096; + +pub fn initialize() void { + const empty_page = PageDirectoryEntry{}; + // var p2 = allocator.allocate(1); + var p2 = [_]PageDirectoryEntry{empty_page} ** 1024; + // var p2 = [_]u32{0} ** 1024; + + // identity map 0 -> 4MB + p2[0].pageTable = 0x0; + p2[0].present = true; + p2[0].read_write = true; + p2[0].huge = true; + // p2[0] = @bitReverse(u32, 0b10000011); + + println("p2[0] {b}", p2[0]); + println("p2[0] {b}", @bitCast(u32, p2[0])); + // x86.hang(); + // paging.s + // setupPaging(@ptrToInt(&p2)); + + // mapper = Mapper{ + // .p2 = p2, + // }; + const addr = mapper.translate(0xfffff000); +} + +const builtin = @import("builtin"); +const Mapper = struct { + p2: PageDirectory, + + // virt to phys + pub fn translate(self: Mapper, virt: u32) ?u32 { + const map = @bitCast(VirtAddr, virt); + println("{}", builtin.endian); + println("virt {x} -> {}-{}-{x}", virt, map.page_directory, map.page_table, map.offset); + return null; + } +}; + +pub const VirtAddr = packed struct { + page_directory: u10, + page_table: u10, + offset: u12, +}; + +pub const PageDirectoryEntry = packed struct { + pageTable: u20 = 0, + available: u3 = 0, + ignored: bool = false, + huge: bool = false, + zero: bool = false, + accessed: bool = false, + cache_disabled: bool = false, + write_thru: bool = false, + supervisor: bool = false, + read_write: bool = false, + present: bool = false, +}; + +pub const PageTableEntry = packed struct { + addr: u20 = 0, + available: u3 = 0, + global: bool = false, + zero: bool = false, + dirty: bool = false, + accessed: bool = false, + cache_disabled: bool = false, + write_thru: bool = false, + supervisor: bool = false, + read_write: bool = false, + present: bool = false, +}; + +pub const PageTable = [1024]PageTableEntry; +pub const PageDirectory = [1024]PageDirectoryEntry; + +comptime { + assert(@sizeOf(PageDirectoryEntry) == 4); //32 bits + assert(@sizeOf(PageTableEntry) == 4); //32 bits +} diff --git a/src/console.zig b/src/console.zig index 1ee615e..7ea8291 100644 --- a/src/console.zig +++ b/src/console.zig @@ -33,7 +33,7 @@ pub fn keypress(char: u8) void { } pub fn initialize() void { - vga.clear(); - // vga.writeString("> "); + // vga.clear(); interrupt.registerIRQ(1, ps2.keyboard_handler); + vga.writeString("> "); } diff --git a/src/main.zig b/src/main.zig index fc192d0..5f02270 100644 --- a/src/main.zig +++ b/src/main.zig @@ -9,17 +9,18 @@ const assert = @import("std").debug.assert; // arch independant initialization export fn kmain(magic: u32, info: *const MultibootInfo) noreturn { assert(magic == MULTIBOOT_BOOTLOADER_MAGIC); - console.initialize(); - - printf("--- hello x86_main ---\n"); + println("--- x86 initialization ---"); x86.x86_main(info); // pagefault_test(0xfeffc000); - printf("\n--- arch indepent boot ---\n"); + println("--- core initialization ---"); + console.initialize(); - while (true) {} + while (true) { + asm volatile ("hlt"); + } } fn pagefault_test(addr: u32) void { diff --git a/src/multiboot.zig b/src/multiboot.zig index d2630d0..2f217a3 100644 --- a/src/multiboot.zig +++ b/src/multiboot.zig @@ -13,29 +13,46 @@ 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. flags: u32, // Available memory from BIOS. + // present if flags[0] mem_lower: u32, mem_upper: u32, - // "root" partition. + // present if flags[1] boot_device: u32, - // Kernel command line. + // present if flags[2] cmdline: u32, // Boot-Module list. mods_count: u32, mods_addr: u32, - // TODO: use the real types here. - u: u128, + syms: extern union { + // present if flags[4] + nlist: extern struct { + tabsize: u32, + strsize: u32, + addr: u32, + _reserved: u32, + }, + // present if flags[5] + shdr: extern struct { + num: u32, + size: u32, + addr: u32, + shndx: u32, + }, + }, // Memory Mapping buffer. + // present if flags[6] mmap_length: u32, mmap_addr: u32, @@ -112,16 +129,22 @@ const MultibootHeader = packed struct { magic: u32, // Must be equal to header magic number. flags: u32, // Feature flags. checksum: u32, // Above fields plus this one must equal 0 mod 2^32. + // following fields are used if flag bit 16 is specified + header_addr: u32 = 0, + load_addr: u32 = 0, + load_end_addr: u32 = 0, + bss_end_addr: u32 = 0, + entry_addr: u32 = 0, }; // NOTE: this structure is incomplete. // Place the header at the very beginning of the binary. export const multiboot_header align(4) linksection(".multiboot") = multiboot: { const MAGIC = u32(0x1BADB002); // multiboot magic - const ALIGN = u32(1 << 0); // Align loaded modules. + const ALIGN = u32(1 << 0); // Align loaded modules at 4k const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader. - const CMDLINE = u32(1 << 2); // Receive a cmdline from the bootloader - const FLAGS = ALIGN | MEMINFO | CMDLINE; // Combine the flags. + const ADDR = u32(1 << 16); // Load specific addr + const FLAGS = ALIGN | MEMINFO; // Combine the flags. break :multiboot MultibootHeader { .magic = MAGIC, diff --git a/src/pci.zig b/src/pci.zig index 131e52a..624e0f0 100644 --- a/src/pci.zig +++ b/src/pci.zig @@ -2,7 +2,7 @@ const arch = @import("arch/x86/lib/index.zig"); const PCI_CONFIG_ADDRESS = 0xCF8; const PCI_CONFIG_DATA = 0xCFC; -const vga = @import("vga.zig"); +usingnamespace @import("vga.zig"); pub const PciAddress = packed struct { offset: u8, @@ -57,7 +57,7 @@ pub const PciDevice = struct { } pub fn format(self: PciDevice) void { - vga.printf("{}:{}.{} {x},{x}: {x} {x}\n", self.bus, self.slot, self.function, self.class, self.subclass, self.vendor, self.device); + println("{}:{}.{} {x},{x}: {x} {x}", self.bus, self.slot, self.function, self.class, self.subclass, self.vendor, self.device); } pub fn access(self: PciDevice, offset: u8) void { diff --git a/src/ps2.zig b/src/ps2.zig index 57731e2..84aced6 100644 --- a/src/ps2.zig +++ b/src/ps2.zig @@ -1,3 +1,4 @@ +usingnamespace @import("vga.zig"); const x86 = @import("arch/x86/lib/index.zig"); const console = @import("console.zig"); @@ -84,6 +85,7 @@ fn key_isrelease(scancode: u8) bool { pub fn keyboard_handler() void { const scancode = ps2_scancode(); const isrelease = key_isrelease(scancode); + println("keyboard scancode 0b{b}", scancode); if (isrelease) { return; } diff --git a/src/vga.zig b/src/vga.zig index 3a73c71..7b90ede 100644 --- a/src/vga.zig +++ b/src/vga.zig @@ -56,10 +56,14 @@ pub fn disableCursor() void { } const Errors = error{}; -pub fn printf(comptime format: []const u8, args: ...) void { +pub fn print(comptime format: []const u8, args: ...) void { var a = std.fmt.format({}, Errors, printCallback, format, args); } +pub fn println(comptime format: []const u8, args: ...) void { + var a = std.fmt.format({}, Errors, printCallback, format ++ "\n", args); +} + fn printCallback(context: void, string: []const u8) Errors!void { vga.writeString(string); }