diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/console.zig | 84 | ||||
| -rw-r--r-- | src/grub.cfg | 3 | ||||
| -rw-r--r-- | src/linker.ld | 26 | ||||
| -rw-r--r-- | src/main.zig | 31 |
4 files changed, 144 insertions, 0 deletions
diff --git a/src/console.zig b/src/console.zig new file mode 100644 index 0000000..6fc5043 --- /dev/null +++ b/src/console.zig @@ -0,0 +1,84 @@ +const fmt = @import("std").fmt; +const Writer = @import("std").io.Writer; + +const VGA_WIDTH = 80; +const VGA_HEIGHT = 25; +const VGA_SIZE = VGA_WIDTH * VGA_HEIGHT; + +pub const ConsoleColors = enum(u8) { + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + LightMagenta = 13, + LightBrown = 14, + White = 15, +}; + +var row: usize = 0; +var column: usize = 0; +var color = vgaEntryColor(ConsoleColors.LightGray, ConsoleColors.Black); +var buffer = @as([*]volatile u16, @ptrFromInt(0xB8000)); + +fn vgaEntryColor(fg: ConsoleColors, bg: ConsoleColors) u8 { + return @enumToInt(fg) | (@enumToInt(bg) << 4); +} + +fn vgaEntry(uc: u8, new_color: u8) u16 { + var c: u16 = new_color; + + return uc | (c << 8); +} + +pub fn initialize() void { + clear(); +} + +pub fn setColor(new_color: u8) void { + color = new_color; +} + +pub fn clear() void { + @memset(u16, buffer[0..VGA_SIZE], vgaEntry(' ', color)); +} + +pub fn putCharAt(c: u8, new_color: u8, x: usize, y: usize) void { + const index = y * VGA_WIDTH + x; + buffer[index] = vgaEntry(c, new_color); +} + +pub fn putChar(c: u8) void { + putCharAt(c, color, column, row); + column += 1; + if (column == VGA_WIDTH) { + column = 0; + row += 1; + if (row == VGA_HEIGHT) + row = 0; + } +} + +pub fn puts(data: []const u8) void { + for (data) |c| + putChar(c); +} + +pub const writer = Writer(void, error{}, callback){ .context = {} }; + +fn callback(_: void, string: []const u8) error{}!usize { + puts(string); + return string.len; +} + +pub fn printf(comptime format: []const u8, args: anytype) void { + fmt.format(writer, format, args) catch unreachable; +} diff --git a/src/grub.cfg b/src/grub.cfg new file mode 100644 index 0000000..7904bf7 --- /dev/null +++ b/src/grub.cfg @@ -0,0 +1,3 @@ +menuentry "Zig Bare Bones" { + multiboot /boot/kernel.elf +} diff --git a/src/linker.ld b/src/linker.ld new file mode 100644 index 0000000..429da33 --- /dev/null +++ b/src/linker.ld @@ -0,0 +1,26 @@ +ENTRY(_start) + +SECTIONS { + . = 1M; + + .multiboot { + KEEP(*(.multiboot)) + } + + .text : ALIGN(4K) { + *(.text) + } + + .rodata : ALIGN(4K) { + *(.rodata) + } + + .data : ALIGN(4K) { + *(.data) + } + + .bss : ALIGN(4K) { + *(COMMON) + *(.bss) + } +} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..298e2c2 --- /dev/null +++ b/src/main.zig @@ -0,0 +1,31 @@ +const console = @import("console.zig"); + +const ALIGN = 1 << 0; +const MEMINFO = 1 << 1; +const MAGIC = 0x1BADB002; +const FLAGS = ALIGN | MEMINFO; + +const MultibootHeader = packed struct { + magic: i32 = MAGIC, + flags: i32, + checksum: i32, +}; + +export var multiboot align(4) linksection(".multiboot") = MultibootHeader{ + .flags = FLAGS, + .checksum = -(MAGIC + FLAGS), +}; + +export var stack_bytes: [16 * 1024]u8 align(16) linksection(".bss") = undefined; +const stack_bytes_slice = stack_bytes[0..]; + +export fn _start() callconv(.Naked) noreturn { + @call(.{ .stack = stack_bytes_slice }, kmain, .{}); + + while (true) {} +} + +fn kmain() void { + console.initialize(); + console.puts("Hello world!"); +} |
