zig: 0.5.0 -> 0.5.0+e6a812c82
This commit is contained in:
parent
8380a657ac
commit
22f05324fa
18 changed files with 101 additions and 104 deletions
2
qemu.sh
2
qemu.sh
|
|
@ -7,7 +7,7 @@ KERNEL=build/kernel
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
touch disk.img
|
touch disk.img
|
||||||
sudo pkill -9 qemu-system-i386
|
# sudo pkill -9 qemu-system-i386
|
||||||
sudo qemu-system-i386 \
|
sudo qemu-system-i386 \
|
||||||
-gdb tcp::${QEMU_GDB_PORT} \
|
-gdb tcp::${QEMU_GDB_PORT} \
|
||||||
-monitor unix:${QEMU_SOCKET},server,nowait \
|
-monitor unix:${QEMU_SOCKET},server,nowait \
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ var gdt align(4) = [_]GDTEntry{
|
||||||
|
|
||||||
// GDT descriptor register pointing at the GDT.
|
// GDT descriptor register pointing at the GDT.
|
||||||
var gdtr = GDTRegister{
|
var gdtr = GDTRegister{
|
||||||
.limit = u16(@sizeOf(@typeOf(gdt))),
|
.limit = @as(u16, @sizeOf(@TypeOf(gdt))),
|
||||||
.base = &gdt[0],
|
.base = &gdt[0],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ var idt_table: [256]IDTEntry = undefined;
|
||||||
|
|
||||||
// IDT descriptor register pointing at the IDT.
|
// IDT descriptor register pointing at the IDT.
|
||||||
const idtr = IDTRegister{
|
const idtr = IDTRegister{
|
||||||
.limit = u16(@sizeOf(@typeOf(idt_table))),
|
.limit = @as(u16, @sizeOf(@TypeOf(idt_table))),
|
||||||
.base = &idt_table,
|
.base = &idt_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -68,21 +68,21 @@ pub fn initialize() void {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn general_protection_fault() void {
|
fn general_protection_fault() void {
|
||||||
kernel.println("general protection fault");
|
kernel.println("general protection fault", .{});
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_trap() void {
|
fn debug_trap() void {
|
||||||
kernel.println("debug fault/trap");
|
kernel.println("debug fault/trap", .{});
|
||||||
kernel.println("dr7: 0b{b}", dr7());
|
kernel.println("dr7: 0b{b}", .{dr7()});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_fault() void {
|
fn page_fault() void {
|
||||||
const vaddr = cr2();
|
const vaddr = cr2();
|
||||||
kernel.println("cr2: 0x{x}", vaddr);
|
kernel.println("cr2: 0x{x}", .{vaddr});
|
||||||
kernel.println("phy: 0x{x}", paging.translate(vaddr));
|
kernel.println("phy: 0x{x}", .{paging.translate(vaddr)});
|
||||||
kernel.println("pde: 0x{x} ({})", paging.pde(vaddr), vaddr >> 22);
|
kernel.println("pde: 0x{x} ({})", .{ paging.pde(vaddr), vaddr >> 22 });
|
||||||
kernel.println("pte: 0x{x} ({})", paging.pte(vaddr), vaddr >> 12);
|
kernel.println("pte: 0x{x} ({})", .{ paging.pte(vaddr), vaddr >> 12 });
|
||||||
// paging.format();
|
// paging.format();
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,9 @@ var handlers = [_]fn () void{unhandled} ** 48;
|
||||||
|
|
||||||
fn unhandled() noreturn {
|
fn unhandled() noreturn {
|
||||||
const n = isr.context.interrupt_n;
|
const n = isr.context.interrupt_n;
|
||||||
kernel.print("unhandled interrupt number {d}", n);
|
kernel.print("unhandled interrupt number {d}", .{n});
|
||||||
if (n < IRQ_0) {
|
if (n < IRQ_0) kernel.println(" (exception)", .{});
|
||||||
kernel.println(" (exception)");
|
if (n >= IRQ_0) kernel.println(" (IRQ number {d})", .{n - IRQ_0});
|
||||||
} else {
|
|
||||||
kernel.println(" (IRQ number {d})", n - IRQ_0);
|
|
||||||
}
|
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,10 +54,11 @@ export fn interruptDispatch() void {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
// Exceptions.
|
// Exceptions.
|
||||||
EXCEPTION_0...EXCEPTION_31 => {
|
EXCEPTION_0...EXCEPTION_31 => {
|
||||||
kernel.println("");
|
kernel.println("", .{});
|
||||||
kernel.println("num: {}", isr.context.interrupt_n);
|
kernel.println("num: {}", .{n});
|
||||||
kernel.println("err: {}", isr.context.error_code);
|
kernel.println("err: {}", .{@truncate(u8, isr.context.error_code)});
|
||||||
kernel.println("ip: 0x{x}", isr.context.eip);
|
kernel.println("ip: 0x{x}", .{@truncate(u16, isr.context.eip)});
|
||||||
|
kernel.println("ip: 0x{x}", .{@truncate(u16, isr.context.eip >> 16)});
|
||||||
return handlers[n]();
|
return handlers[n]();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -171,16 +169,18 @@ pub fn remapPIC() void {
|
||||||
picwait();
|
picwait();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maskIRQ(irq: u8, mask: bool) void {
|
pub fn maskIRQ(irq: u8, comptime mask: bool) void {
|
||||||
if (irq > 15) return;
|
if (irq > 15) return;
|
||||||
// Figure out if master or slave PIC owns the IRQ.
|
// Figure out if master or slave PIC owns the IRQ.
|
||||||
const port = if (irq < 8) u16(PIC1_DATA) else u16(PIC2_DATA);
|
const port = @as(u16, if (irq < 8) PIC1_DATA else PIC2_DATA);
|
||||||
const old = inb(port); // Retrieve the current mask.
|
const old = inb(port); // Retrieve the current mask.
|
||||||
|
|
||||||
// Mask or unmask the interrupt.
|
// Mask or unmask the interrupt.
|
||||||
const shift = @intCast(u3, irq % 8);
|
const shift = @truncate(u3, irq % 8);
|
||||||
if (mask) outb(port, old | (u8(1) << shift));
|
// const shift = @truncate(u3, if (irq < 8) irq else irq - 8);
|
||||||
if (!mask) outb(port, old & ~(u8(1) << shift));
|
const bit = @as(u8, 1) << shift;
|
||||||
|
if (mask) outb(port, old | bit);
|
||||||
|
if (!mask) outb(port, old & ~bit);
|
||||||
const new = inb(port); // Retrieve the current mask.
|
const new = inb(port); // Retrieve the current mask.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ pub const Context = packed struct {
|
||||||
ss: u32,
|
ss: u32,
|
||||||
|
|
||||||
pub inline fn setReturnValue(self: *volatile Context, value: var) void {
|
pub inline fn setReturnValue(self: *volatile Context, value: var) void {
|
||||||
self.registers.eax = if (@typeOf(value) == bool) @boolToInt(value) else @intCast(u32, value);
|
self.registers.eax = if (@TypeOf(value) == bool) @boolToInt(value) else @intCast(u32, value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// usingnamespace @import("kernel");
|
|
||||||
usingnamespace @import("index.zig");
|
usingnamespace @import("index.zig");
|
||||||
|
|
||||||
/// x86 specific intialization
|
/// x86 specific intialization
|
||||||
|
|
@ -7,6 +6,5 @@ pub fn x86_main(info: *const kernel.multiboot.MultibootInfo) void {
|
||||||
idt.initialize();
|
idt.initialize();
|
||||||
pmem.initialize(info);
|
pmem.initialize(info);
|
||||||
paging.initialize();
|
paging.initialize();
|
||||||
// enable interrupts
|
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ pub fn unmap(virt: usize) void {
|
||||||
if (translate(virt)) |phys| {
|
if (translate(virt)) |phys| {
|
||||||
pmem.free(phys);
|
pmem.free(phys);
|
||||||
} else {
|
} else {
|
||||||
kernel.println("can't unmap 0x{x} because it is not mapped.", virt);
|
kernel.println("can't unmap 0x{x} because it is not mapped.", .{virt});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,12 +67,12 @@ pub fn format() void {
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < 1024) : (i += 1) {
|
while (i < 1024) : (i += 1) {
|
||||||
if (PD[i] == 0) continue;
|
if (PD[i] == 0) continue;
|
||||||
kernel.println("p2[{}] -> 0x{x}", i, PD[i]);
|
kernel.println("p2[{}] -> 0x{x}", .{ i, PD[i] });
|
||||||
if (PD[i] & HUGE != 0) continue;
|
if (PD[i] & HUGE != 0) continue;
|
||||||
var j: usize = 0;
|
var j: usize = 0;
|
||||||
while (j < 1024) : (j += 1) {
|
while (j < 1024) : (j += 1) {
|
||||||
var entry: PageEntry = PT[i * 1024 + j];
|
var entry: PageEntry = PT[i * 1024 + j];
|
||||||
if (entry != 0) kernel.println("p2[{}]p1[{}] -> 0x{x}", i, j, entry);
|
if (entry != 0) kernel.println("p2[{}]p1[{}] -> 0x{x}", .{ i, j, entry });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ pub inline fn available_MiB() usize {
|
||||||
//
|
//
|
||||||
pub fn allocate() !usize {
|
pub fn allocate() !usize {
|
||||||
if (available() == 0) {
|
if (available() == 0) {
|
||||||
kernel.println("out of memory");
|
kernel.println("out of memory", .{});
|
||||||
return error.OutOfMemory;
|
return error.OutOfMemory;
|
||||||
}
|
}
|
||||||
stack_index -= 1;
|
stack_index -= 1;
|
||||||
|
|
@ -82,12 +82,15 @@ pub fn initialize(info: *const kernel.multiboot.MultibootInfo) void {
|
||||||
free(start);
|
free(start);
|
||||||
|
|
||||||
// Go to the next entry in the memory map.
|
// Go to the next entry in the memory map.
|
||||||
map += entry.size + @sizeOf(@typeOf(entry.size));
|
map += entry.size + @sizeOf(@TypeOf(entry.size));
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel.println("available memory: {d} MiB ", available() / 1024 / 1024);
|
const a = available();
|
||||||
|
kernel.println("available memory: {} MiB ", .{a});
|
||||||
|
// kernel.println("available memory: {d} MiB ", .{available() / 1024 / 1024});
|
||||||
|
hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format() void {
|
pub fn format() void {
|
||||||
kernel.println("physframes left: {d} ({d} MiB)", stack_index, available_MiB());
|
kernel.println("physframes left: {d} ({d} MiB)", .{ stack_index, available_MiB() });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,17 @@ const commands = [_]Command{
|
||||||
|
|
||||||
fn execute(input: []u8) void {
|
fn execute(input: []u8) void {
|
||||||
for (commands) |c| if (std.mem.eql(u8, input, c.name)) return c.f();
|
for (commands) |c| if (std.mem.eql(u8, input, c.name)) return c.f();
|
||||||
println("{}: command not found, list of available commands:", input);
|
println("{}: command not found, list of available commands:", .{input});
|
||||||
for (commands) |c| println("{}", c.name);
|
for (commands) |c| println("{}", .{c.name});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keypress(char: u8) void {
|
pub fn keypress(char: u8) void {
|
||||||
// this is a custom "readline" capped at 10 characters
|
// this is a custom "readline" capped at 10 characters
|
||||||
switch (char) {
|
switch (char) {
|
||||||
'\n' => {
|
'\n' => {
|
||||||
print("\n");
|
print("\n", .{});
|
||||||
if (command_len > 0) execute(command[0..command_len]);
|
if (command_len > 0) execute(command[0..command_len]);
|
||||||
print("> ");
|
print("> ", .{});
|
||||||
command_len = 0;
|
command_len = 0;
|
||||||
},
|
},
|
||||||
'\x00' => return,
|
'\x00' => return,
|
||||||
|
|
@ -70,7 +70,7 @@ pub fn loop() void {
|
||||||
input_ring.init() catch unreachable;
|
input_ring.init() catch unreachable;
|
||||||
input_ring.task = task.current_task;
|
input_ring.task = task.current_task;
|
||||||
ps2.keyboard_callback = keyboard_callback;
|
ps2.keyboard_callback = keyboard_callback;
|
||||||
print("> ");
|
print("> ", .{});
|
||||||
while (true) {
|
while (true) {
|
||||||
while (input_ring.read()) |c| keypress(c);
|
while (input_ring.read()) |c| keypress(c);
|
||||||
task.block(.IOWait);
|
task.block(.IOWait);
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,14 @@ const ATA_CMD_IDENTIFY_PACKET = 0xA1;
|
||||||
const ATA_CMD_IDENTIFY = 0xEC;
|
const ATA_CMD_IDENTIFY = 0xEC;
|
||||||
|
|
||||||
// Status:
|
// Status:
|
||||||
const ATA_SR_BSY = 0x80; // Busy
|
const ATA_SR_BUSY = 0x80;
|
||||||
const ATA_SR_DRDY = 0x40; // Drive ready
|
const ATA_SR_DRDY = 0x40; // Drive ready
|
||||||
const ATA_SR_DF = 0x20; // Drive write fault
|
const ATA_SR_DF = 0x20; // Drive write fault
|
||||||
const ATA_SR_DSC = 0x10; // Drive seek complete
|
const ATA_SR_DSC = 0x10; // Drive seek complete
|
||||||
const ATA_SR_DRQ = 0x08; // Data request ready
|
const ATA_SR_DRQ = 0x08; // Data request ready
|
||||||
const ATA_SR_CORR = 0x04; // Corrected data
|
const ATA_SR_CORR = 0x04; // Corrected data
|
||||||
const ATA_SR_IDX = 0x02; // Index
|
const ATA_SR_IDX = 0x02;
|
||||||
const ATA_SR_ERR = 0x01; // Error
|
const ATA_SR_ERR = 0x01;
|
||||||
|
|
||||||
// Registers:
|
// Registers:
|
||||||
const ATA_REG_DATA = 0x00;
|
const ATA_REG_DATA = 0x00;
|
||||||
|
|
@ -116,7 +116,7 @@ const IDEDevice = struct {
|
||||||
err = 1;
|
err = 1;
|
||||||
break;
|
break;
|
||||||
} // If Err, Device is not ATA.
|
} // If Err, Device is not ATA.
|
||||||
if ((status & ATA_SR_BSY == 0) and (status & ATA_SR_DRQ != 0)) break; // Everything is right.
|
if ((status & ATA_SR_BUSY == 0) and (status & ATA_SR_DRQ != 0)) break; // Everything is right.
|
||||||
}
|
}
|
||||||
|
|
||||||
// (IV) Probe for ATAPI Devices:)
|
// (IV) Probe for ATAPI Devices:)
|
||||||
|
|
@ -163,7 +163,7 @@ const IDEDevice = struct {
|
||||||
|
|
||||||
inline fn poll(self: IDEDevice) void {
|
inline fn poll(self: IDEDevice) void {
|
||||||
for ([_]u8{ 0, 1, 2, 3 }) |_| _ = self.read(ATA_REG_ALTSTATUS); // wait 100ns per call
|
for ([_]u8{ 0, 1, 2, 3 }) |_| _ = self.read(ATA_REG_ALTSTATUS); // wait 100ns per call
|
||||||
while (self.read(ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait for BSY to be zero.
|
while (self.read(ATA_REG_STATUS) & ATA_SR_BUSY != 0) {} // Wait for BSY to be zero.
|
||||||
}
|
}
|
||||||
inline fn poll_check(self: IDEDevice) !void {
|
inline fn poll_check(self: IDEDevice) !void {
|
||||||
// (I) Delay 400 nanosecond for BSY to be set:
|
// (I) Delay 400 nanosecond for BSY to be set:
|
||||||
|
|
@ -230,12 +230,11 @@ const IDEDevice = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: IDEDevice) void {
|
pub fn format(self: IDEDevice) void {
|
||||||
kernel.println(
|
kernel.println("[ide] {} drive ({}MB) - {}", .{
|
||||||
"[ide] {} drive ({}MB) - {}",
|
if (self.idetype == 0) "ATA " else "ATAPI",
|
||||||
if (self.idetype == 0) "ATA" else "ATAPI",
|
|
||||||
self.size * 512 / 1024 / 1024,
|
self.size * 512 / 1024 / 1024,
|
||||||
self.model,
|
self.model,
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ata_access(self: *IDEDevice, direction: u8, lba: u64, numsects: u8, selector: u16, buf: usize) !void {
|
fn ata_access(self: *IDEDevice, direction: u8, lba: u64, numsects: u8, selector: u16, buf: usize) !void {
|
||||||
|
|
@ -279,7 +278,7 @@ const IDEDevice = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// (III) Wait if the drive is busy;
|
// (III) Wait if the drive is busy;
|
||||||
while (self.read(ATA_REG_STATUS) & ATA_SR_BSY != 0) {} // Wait if busy.)
|
while (self.read(ATA_REG_STATUS) & ATA_SR_BUSY != 0) {} // Wait if busy.)
|
||||||
|
|
||||||
// (IV) Select Drive from the controller;
|
// (IV) Select Drive from the controller;
|
||||||
if (lba_mode == 0) self.write(ATA_REG_HDDEVSEL, 0xA0 | (self.drive << 4) | head); // Drive & CHS.
|
if (lba_mode == 0) self.write(ATA_REG_HDDEVSEL, 0xA0 | (self.drive << 4) | head); // Drive & CHS.
|
||||||
|
|
@ -321,7 +320,6 @@ const IDEDevice = struct {
|
||||||
}
|
}
|
||||||
if (!dma and direction == 0) {
|
if (!dma and direction == 0) {
|
||||||
// PIO Read.
|
// PIO Read.
|
||||||
kernel.println("pio read");
|
|
||||||
var i: u8 = 0;
|
var i: u8 = 0;
|
||||||
while (i < numsects) : (i = i + 1) {
|
while (i < numsects) : (i = i + 1) {
|
||||||
var iedi = buf + i * (words * 2);
|
var iedi = buf + i * (words * 2);
|
||||||
|
|
@ -393,16 +391,16 @@ pub fn ide_block_read(lba: u64, buf: *[512]u8) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(dev: kernel.pci.PciDevice) void {
|
pub fn init(dev: kernel.pci.PciDevice) void {
|
||||||
kernel.println("-- ide init --");
|
kernel.println("-- ide init --", .{});
|
||||||
kernel.print("[ide] ");
|
kernel.print("[ide] ", .{});
|
||||||
dev.format();
|
dev.format();
|
||||||
assert(dev.header_type() == 0x0); // mass storage device
|
assert(dev.header_type() == 0x0); // mass storage device
|
||||||
|
|
||||||
dev.config_write(@intCast(u8, 0xfe), 0x3c);
|
dev.config_write(@intCast(u8, 0xfe), 0x3c);
|
||||||
if (dev.intr_line() == 0xfe) {
|
if (dev.intr_line() == 0xfe) {
|
||||||
kernel.println("[ide] detected ATA device");
|
kernel.println("[ide] detected ATA device", .{});
|
||||||
} else {
|
} else {
|
||||||
kernel.println("[ide] Potential SATA device. Not implemented. Hanging");
|
kernel.println("[ide] Potential SATA device. Not implemented. Hanging", .{});
|
||||||
x86.hang();
|
x86.hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
usingnamespace @import("index.zig");
|
usingnamespace @import("index.zig");
|
||||||
|
|
||||||
pub fn init(dev: kernel.pci.PciDevice) void {
|
pub fn init(dev: kernel.pci.PciDevice) void {
|
||||||
kernel.println("-- virtio-block init --");
|
kernel.println("-- virtio-block init --", .{});
|
||||||
dev.format();
|
dev.format();
|
||||||
assert(dev.header_type() == 0x0); // mass storage device
|
assert(dev.header_type() == 0x0); // mass storage device
|
||||||
assert(dev.subsystem() == 0x2); // virtio-block
|
assert(dev.subsystem() == 0x2); // virtio-block
|
||||||
|
|
@ -10,7 +10,7 @@ pub fn init(dev: kernel.pci.PciDevice) void {
|
||||||
const intr_pin = dev.config_read(u8, 0x3d);
|
const intr_pin = dev.config_read(u8, 0x3d);
|
||||||
const min_grant = dev.config_read(u8, 0x3e);
|
const min_grant = dev.config_read(u8, 0x3e);
|
||||||
const max_lat = dev.config_read(u8, 0x3f);
|
const max_lat = dev.config_read(u8, 0x3f);
|
||||||
kernel.println("{x} {} {} {}", intr_line, intr_pin, min_grant, max_lat);
|
kernel.println("{x} {} {} {}", .{ intr_line, intr_pin, min_grant, max_lat });
|
||||||
|
|
||||||
// all virtio
|
// all virtio
|
||||||
// 0 1 2 3
|
// 0 1 2 3
|
||||||
|
|
|
||||||
23
src/main.zig
23
src/main.zig
|
|
@ -2,10 +2,10 @@ usingnamespace @import("kernel");
|
||||||
|
|
||||||
// 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); // multiboot magic
|
const MAGIC = @as(u32, 0x1BADB002); // multiboot magic
|
||||||
const ALIGN = u32(1 << 0); // Align loaded modules at 4k
|
const ALIGN = @as(u32, 1 << 0); // Align loaded modules at 4k
|
||||||
const MEMINFO = u32(1 << 1); // Receive a memory map from the bootloader.
|
const MEMINFO = @as(u32, 1 << 1); // Receive a memory map from the bootloader.
|
||||||
const ADDR = u32(1 << 16); // Load specific addr
|
const ADDR = @as(u32, 1 << 16); // Load specific addr
|
||||||
const FLAGS = ALIGN | MEMINFO; // Combine the flags.
|
const FLAGS = ALIGN | MEMINFO; // Combine the flags.
|
||||||
|
|
||||||
break :multiboot multiboot.MultibootHeader{
|
break :multiboot multiboot.MultibootHeader{
|
||||||
|
|
@ -19,29 +19,30 @@ export const multiboot_header align(4) linksection(".multiboot") = multiboot: {
|
||||||
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
||||||
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
assert(magic == multiboot.MULTIBOOT_BOOTLOADER_MAGIC);
|
||||||
clear();
|
clear();
|
||||||
println("--- x86 initialization ---");
|
asm volatile ("movd %%edi, %%xmm0");
|
||||||
|
println("--- x86 initialization ---", .{});
|
||||||
x86.x86_main(info);
|
x86.x86_main(info);
|
||||||
println("--- core initialization ---");
|
println("--- core initialization ---", .{});
|
||||||
vmem.init();
|
vmem.init();
|
||||||
pci.scan();
|
pci.scan();
|
||||||
println("--- finished booting --- ");
|
println("--- finished booting --- ", .{});
|
||||||
|
|
||||||
task.cleaner_task = task.new(@ptrToInt(task.cleaner_loop)) catch unreachable;
|
task.cleaner_task = task.new(@ptrToInt(task.cleaner_loop)) catch unreachable;
|
||||||
_ = task.new(@ptrToInt(topbar)) catch unreachable;
|
_ = task.new(@ptrToInt(topbar)) catch unreachable;
|
||||||
_ = task.new(@ptrToInt(console.loop)) catch unreachable;
|
_ = task.new(@ptrToInt(console.loop)) catch unreachable;
|
||||||
|
|
||||||
var buf = vmem.create([512]u8) catch unreachable;
|
var buf = vmem.create([512]u8) catch unreachable;
|
||||||
println("buf at 0x{x}", @ptrToInt(buf));
|
println("buf at 0x{x}", .{@ptrToInt(buf)});
|
||||||
driver.ide.first_ide_drive.read(2, buf);
|
driver.ide.first_ide_drive.read(2, buf);
|
||||||
|
|
||||||
const sig = buf[56..58];
|
const sig = buf[56..58];
|
||||||
println("sig: {x}", sig);
|
println("sig: {x}", .{sig});
|
||||||
|
|
||||||
task.terminate();
|
task.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn panic(a: []const u8, b: ?*builtin.StackTrace) noreturn {
|
pub fn panic(a: []const u8, b: ?*builtin.StackTrace) noreturn {
|
||||||
println("{}", a);
|
println("{}", .{a});
|
||||||
println("{}", b);
|
println("{}", .{b});
|
||||||
while (true) asm volatile ("hlt");
|
while (true) asm volatile ("hlt");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,10 @@ pub const PciDevice = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: PciDevice) void {
|
pub fn format(self: PciDevice) void {
|
||||||
print("{}:{}.{}", self.bus, self.slot, self.function);
|
print("{}:{}.{}", .{ self.bus, self.slot, self.function });
|
||||||
print(" {x},{x:2}", self.class(), self.subclass());
|
print(" {x},{x:2}", .{ self.class(), self.subclass() });
|
||||||
print(" 0x{x} 0x{x}", self.vendor, self.device());
|
print(" 0x{x} 0x{x}", .{ self.vendor, self.device() });
|
||||||
if (self.driver()) |d| {
|
println(" {}", .{if (self.driver()) |d| d.name else " (none)"});
|
||||||
print(" {}", d.name);
|
|
||||||
} else {
|
|
||||||
print(" (none)");
|
|
||||||
}
|
|
||||||
println("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn driver(self: PciDevice) ?Driver {
|
pub fn driver(self: PciDevice) ?Driver {
|
||||||
|
|
@ -110,7 +105,7 @@ pub const PciDevice = struct {
|
||||||
pub inline fn config_write(self: PciDevice, value: var, comptime offset: u8) void {
|
pub inline fn config_write(self: PciDevice, value: var, comptime offset: u8) void {
|
||||||
// ask for access before writing config
|
// ask for access before writing config
|
||||||
x86.outl(PCI_CONFIG_ADDRESS, self.address(offset));
|
x86.outl(PCI_CONFIG_ADDRESS, self.address(offset));
|
||||||
switch (@typeOf(value)) {
|
switch (@TypeOf(value)) {
|
||||||
// read the correct size
|
// read the correct size
|
||||||
u8 => return x86.outb(PCI_CONFIG_DATA, value),
|
u8 => return x86.outb(PCI_CONFIG_DATA, value),
|
||||||
u16 => return x86.outw(PCI_CONFIG_DATA, value),
|
u16 => return x86.outw(PCI_CONFIG_DATA, value),
|
||||||
|
|
@ -177,7 +172,7 @@ pub fn scan() void {
|
||||||
|
|
||||||
pub fn lspci() void {
|
pub fn lspci() void {
|
||||||
var slot: u5 = 0;
|
var slot: u5 = 0;
|
||||||
println("b:s.f c, s vendor device driver");
|
println("b:s.f c, s vendor device driver", .{});
|
||||||
while (slot < 31) : (slot += 1) {
|
while (slot < 31) : (slot += 1) {
|
||||||
if (PciDevice.init(0, slot, 0)) |dev| {
|
if (PciDevice.init(0, slot, 0)) |dev| {
|
||||||
var function: u3 = 0;
|
var function: u3 = 0;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ usingnamespace @import("index.zig");
|
||||||
|
|
||||||
const PS2_DATA = 0x60;
|
const PS2_DATA = 0x60;
|
||||||
const PS2_STATUS = 0x64;
|
const PS2_STATUS = 0x64;
|
||||||
const KEYMAP_MAX = 59;
|
const KEYMAP_US = [_][]const u8{
|
||||||
const KEYMAP_US = [_][2]u8{
|
|
||||||
"\x00\x00",
|
"\x00\x00",
|
||||||
"\x00\x00", //escape
|
"\x00\x00", //escape
|
||||||
"1!",
|
"1!",
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ pub fn Ring(comptime T: type) type {
|
||||||
|
|
||||||
//TODO: allocator argument and remove the namespace
|
//TODO: allocator argument and remove the namespace
|
||||||
pub fn init(ring: *Self) !void {
|
pub fn init(ring: *Self) !void {
|
||||||
ring.buffer = try vmem.create(@typeOf(ring.buffer.*));
|
ring.buffer = try vmem.create(@TypeOf(ring.buffer.*));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(ring: *Self, elem: T) void {
|
pub fn write(ring: *Self, elem: T) void {
|
||||||
|
|
|
||||||
32
src/task.zig
32
src/task.zig
|
|
@ -175,11 +175,11 @@ pub fn terminate() noreturn {
|
||||||
pub fn cleaner_loop() noreturn {
|
pub fn cleaner_loop() noreturn {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (terminated_tasks.popFirst()) |n| {
|
if (terminated_tasks.popFirst()) |n| {
|
||||||
notify("DESTROYING {}", n.data.tid);
|
notify("DESTROYING {}", .{n.data.tid});
|
||||||
n.data.destroy();
|
n.data.destroy();
|
||||||
vmem.destroy(n);
|
vmem.destroy(n);
|
||||||
} else {
|
} else {
|
||||||
notify("NOTHING TO CLEAN");
|
notify("NOTHING TO CLEAN", .{});
|
||||||
block(.Paused);
|
block(.Paused);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +201,7 @@ fn unlock_scheduler() void {
|
||||||
postpone_task_switches_counter -= 1;
|
postpone_task_switches_counter -= 1;
|
||||||
if (postpone_task_switches_flag == true and postpone_task_switches_counter == 0) {
|
if (postpone_task_switches_flag == true and postpone_task_switches_counter == 0) {
|
||||||
postpone_task_switches_flag = false;
|
postpone_task_switches_flag = false;
|
||||||
notify("AFTER POSTPONE");
|
notify("AFTER POSTPONE", .{});
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
IRQ_disable_counter -= 1;
|
IRQ_disable_counter -= 1;
|
||||||
|
|
@ -215,7 +215,7 @@ pub fn preempt() void {
|
||||||
|
|
||||||
update_time_used();
|
update_time_used();
|
||||||
if (ready_tasks.first == null) {
|
if (ready_tasks.first == null) {
|
||||||
notify("NO PREEMPT SINGLE TASK");
|
notify("NO PREEMPT SINGLE TASK", .{});
|
||||||
time.task_slice_remaining = 0;
|
time.task_slice_remaining = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +251,11 @@ pub fn switch_to(chosen: *TaskNode) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't inline the asm function, it needs to ret
|
// don't inline the asm function, it needs to ret
|
||||||
@noInlineCall(switch_tasks, chosen.data.esp, @ptrToInt(old_task_esp_addr));
|
@call(
|
||||||
|
.{ .modifier = .never_inline },
|
||||||
|
switch_tasks,
|
||||||
|
.{ chosen.data.esp, @ptrToInt(old_task_esp_addr) },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub var CPU_idle_time: u64 = 0;
|
pub var CPU_idle_time: u64 = 0;
|
||||||
|
|
@ -267,7 +271,7 @@ pub fn schedule() void {
|
||||||
// postponed
|
// postponed
|
||||||
if (postpone_task_switches_counter != 0 and current_task.data.state == .Running) {
|
if (postpone_task_switches_counter != 0 and current_task.data.state == .Running) {
|
||||||
postpone_task_switches_flag = true;
|
postpone_task_switches_flag = true;
|
||||||
notify("POSTPONING SCHEDULE");
|
notify("POSTPONING SCHEDULE", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// next task
|
// next task
|
||||||
|
|
@ -284,7 +288,7 @@ pub fn schedule() void {
|
||||||
}
|
}
|
||||||
// single task
|
// single task
|
||||||
if (current_task.data.state == .Running) {
|
if (current_task.data.state == .Running) {
|
||||||
notify("SINGLE TASK");
|
notify("SINGLE TASK", .{});
|
||||||
time.task_slice_remaining = 0;
|
time.task_slice_remaining = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -297,7 +301,7 @@ fn idle_mode() void {
|
||||||
assert(current_task.data.state != .Running);
|
assert(current_task.data.state != .Running);
|
||||||
assert(current_task.data.state != .ReadyToRun);
|
assert(current_task.data.state != .ReadyToRun);
|
||||||
|
|
||||||
notify("IDLE");
|
notify("IDLE", .{});
|
||||||
|
|
||||||
// borrow the current task
|
// borrow the current task
|
||||||
const borrow = current_task;
|
const borrow = current_task;
|
||||||
|
|
@ -323,7 +327,7 @@ fn idle_mode() void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify(comptime message: []const u8, args: ...) void {
|
pub fn notify(comptime message: []const u8, args: var) void {
|
||||||
const bg = vga.background;
|
const bg = vga.background;
|
||||||
const fg = vga.foreground;
|
const fg = vga.foreground;
|
||||||
const cursor = vga.cursor;
|
const cursor = vga.cursor;
|
||||||
|
|
@ -341,18 +345,18 @@ pub fn notify(comptime message: []const u8, args: ...) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_short() void {
|
pub fn format_short() void {
|
||||||
print("{}R {}B {}S", ready_tasks.len, blocked_tasks.len, sleeping_tasks.len);
|
print("{}R {}B {}S", .{ ready_tasks.len, blocked_tasks.len, sleeping_tasks.len });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format() void {
|
pub fn format() void {
|
||||||
update_time_used();
|
update_time_used();
|
||||||
|
|
||||||
println("{}", current_task.data);
|
println("{}", .{current_task.data});
|
||||||
|
|
||||||
var it = ready_tasks.first;
|
var it = ready_tasks.first;
|
||||||
while (it) |node| : (it = node.next) println("{}", node.data);
|
while (it) |node| : (it = node.next) println("{}", .{node.data});
|
||||||
it = blocked_tasks.first;
|
it = blocked_tasks.first;
|
||||||
while (it) |node| : (it = node.next) println("{}", node.data);
|
while (it) |node| : (it = node.next) println("{}", .{node.data});
|
||||||
var sit = sleeping_tasks.first;
|
var sit = sleeping_tasks.first;
|
||||||
while (sit) |node| : (sit = node.next) println("{} {}", node.data.data, node.counter);
|
while (sit) |node| : (sit = node.next) println("{} {}", .{ node.data.data, node.counter });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ pub fn uptime() void {
|
||||||
const offset_s: u64 = offset_ms / 1000;
|
const offset_s: u64 = offset_ms / 1000;
|
||||||
offset_ms = @mod(offset_ms / 100, 10);
|
offset_ms = @mod(offset_ms / 100, 10);
|
||||||
|
|
||||||
print("{}.{:.3}", offset_s, offset_ms);
|
print("{}.{:.3}", .{ offset_s, offset_ms });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn utilisation() void {
|
pub fn utilisation() void {
|
||||||
print("{}%", 100 * (offset_us - task.CPU_idle_time) / offset_us);
|
print("{}%", .{100 * (offset_us - task.CPU_idle_time) / offset_us});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/vga.zig
11
src/vga.zig
|
|
@ -53,10 +53,10 @@ pub fn disableCursor() void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Errors = error{};
|
const Errors = error{};
|
||||||
pub fn print(comptime format: []const u8, args: ...) void {
|
pub fn print(comptime format: []const u8, args: var) void {
|
||||||
var a = std.fmt.format({}, Errors, printCallback, format, args);
|
var a = std.fmt.format({}, Errors, printCallback, format, args);
|
||||||
}
|
}
|
||||||
pub fn println(comptime format: []const u8, args: ...) void {
|
pub fn println(comptime format: []const u8, args: var) void {
|
||||||
var a = print(format ++ "\n", args);
|
var a = print(format ++ "\n", args);
|
||||||
}
|
}
|
||||||
pub fn clear() void {
|
pub fn clear() void {
|
||||||
|
|
@ -74,12 +74,11 @@ pub fn topbar() void {
|
||||||
vga.cursor_enabled = false;
|
vga.cursor_enabled = false;
|
||||||
|
|
||||||
time.uptime();
|
time.uptime();
|
||||||
print(" | ");
|
print(" | ", .{});
|
||||||
time.utilisation();
|
time.utilisation();
|
||||||
print(" | ");
|
print(" | ", .{});
|
||||||
task.format_short();
|
task.format_short();
|
||||||
// print(" ({})", task.IRQ_disable_counter);
|
println("", .{});
|
||||||
println("");
|
|
||||||
|
|
||||||
vga.cursor_enabled = true;
|
vga.cursor_enabled = true;
|
||||||
vga.cursor = cursor;
|
vga.cursor = cursor;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue