Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
ColumnLimit: 100
Language: Cpp
IndentWidth: 4
UseTab: ForIndentation
TabWidth: 4
SpacesBeforeTrailingComments: 1
NamespaceIndentation: None
AlignConsecutiveAssignments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: Inline
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
DerivePointerAlignment: true
IndentCaseLabels: true
KeepEmptyLinesAtTheStartOfBlocks: false
PointerAlignment: Right
ContinuationIndentWidth: 4
SpacesInParentheses: false
SpacesInParens: Never
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: true
IndentPPDirectives: None
IncludeBlocks: Preserve
Cpp11BracedListStyle: false
Standard: Cpp11
Standard: Cpp11
ReflowComments: false
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Code editor files
.vscode

# Prerequisites
*.d

Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ SRCS := $(shell find kernel/ -name "*.c" -o -name "*.s")
OBJS := $(patsubst %.c, %.o, $(patsubst %.s, %.o, $(SRCS)))
$(shell mkdir -p $(dir $(OBJS)))

CFLAGS = -m64 -Wall -Werror -std=gnu2x -Ikernel/include -ffreestanding -O0 -fno-stack-protector
CFLAGS = -m64 -Wall -Werror -std=gnu2x -Ikernel/include -Ikernel/arch/include -ffreestanding -O0 -fno-stack-protector -Wno-format
ASFLAGS = -64

.PHONY: all run test clean format
Expand All @@ -23,7 +23,7 @@ kernel/kernel.elf: $(OBJS)
%.o: %.c
gcc $(CFLAGS) -c -o $@ $<

%.o: %.s
%.o: %.s %.S
as $(ASFLAGS) -o $@ $<

serial.log: cis-os.iso
Expand Down
68 changes: 68 additions & 0 deletions kernel/arch/amd64/cpu/control.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// NOTE: This file contains code derived from or inspired by:
// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX.
// Copyright (c) 2023-2025 NotYourFox, sigsegv
// SPDX-License-Identifier: GPL-3.0-or-later

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#include "arch/cpu/control.h"
#include "kreflock.h"
#include "kstdlib.h"

static inline void __cpu_enable_interrupt() {
asm volatile("sti");
}

static inline void __cpu_disable_interrupt() {
asm volatile("cli");
}

static reflock_t lock =
NEW_REFLOCK(__cpu_disable_interrupt, __cpu_enable_interrupt, false, true);

bool cpu_interrupt_lock_acquired() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}

return reflock_is_locked(&lock);
}

void cpu_interrupt_lock_acquire() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}

reflock_acquire(&lock);
}

void cpu_interrupt_lock_release() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}

reflock_release(&lock);
}

void cpu_interrupt_lock_force_release() {
if (unlikely(!reflock_validate(&lock))) {
reflock_make(&lock);
}

reflock_force_unlock(&lock);
}

void cpu_halt() {
asm("hlt");
}
24 changes: 24 additions & 0 deletions kernel/arch/amd64/cpu/regs.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#define __ASSEMBLY__

#include "arch/cpu/tables.h"

.code64

.global __asm_update_regs

get_flags:
pushfd
movq (%rsp), %rax
popfd

ret

get_rip:
movq (%rsp), %rax
ret

// TODO because I'm not familiar with x86-64 conventions
__asm_update_regs:
ret

#undef __ASSEMBLY__
11 changes: 11 additions & 0 deletions kernel/arch/amd64/cpu/regs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "amd64/cpu/regs.h"
#include "arch/cpu/strace.h"
#include "kstring.h"

extern void __asm_update_regs(asm_regs_t *regs);

// work in progress
void update_asm_regs(asm_regs_t *state) {
memset(state, 0x00, sizeof(asm_regs_t));
return;
}
48 changes: 48 additions & 0 deletions kernel/arch/amd64/cpu/state.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "amd64/cpu/regs.h"
#include "khal.h"

void cpu_state_print() {
asm_regs_t current_state;

serial_printf(
"The following register dump is a stub and a work-in-progress.\n");

update_asm_regs(&current_state);
serial_printf("Registers:\n");
serial_printf("\tRAX: 0x%x RBX: 0x%x RCX: 0x%x RDX: 0x%x\n",
current_state.eax, current_state.ebx, current_state.ecx,
current_state.edx);
serial_printf("\tRBP: 0x%x RSP: 0x%x RSI: 0x%x RDI: 0x%x\n",
current_state.ebp, current_state.esp, current_state.esi,
current_state.edi);
serial_printf("\tCS: 0x%x DS: 0x%x ES: 0x%x FS: 0x%x\n",
current_state.cs, current_state.ds, current_state.es,
current_state.fs);
serial_printf("\tGS: 0x%x SS: 0x%x\n", current_state.gs,
current_state.ss);
serial_printf("\tCR0: 0x%x CR2: 0x%x CR3: 0x%x CR4: 0x%x\n",
current_state.cr0, current_state.cr2, current_state.cr3,
current_state.cr4);

serial_printf("\tDR0: 0x%x DR1: 0x%x DR2: 0x%x DR3: 0x%x\n",
current_state.dr0, current_state.dr1, current_state.dr2,
current_state.dr3);
serial_printf("\tDR6: 0x%x DR7: 0x%x\n", current_state.dr6,
current_state.dr7);
serial_printf("\tGDTR: base=0x%x, limit=0x%x\n\tLDTR: base=0x%x, "
"limit=0x%x\n\tIDTR: base=0x%x, limit=0x%x\n",
current_state.gdtr.base, current_state.gdtr.limit,
current_state.ldtr.base, current_state.ldtr.limit,
current_state.idtr.base, current_state.idtr.limit);

// TODO: symbol names
serial_printf("\tRIP: 0x%x", current_state.rip);

// serial_printf("\tCode: ");
// for (int i = 0; i < 16; i++) {
// serial_printf("%x ", *(uint8_t *)(current_state.rip + i));
// }
// serial_printf("\n");

serial_printf("\n");
}
19 changes: 19 additions & 0 deletions kernel/arch/amd64/cpu/strace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "arch/cpu/strace.h"
#include <stdint.h>

struct stackframe *strace_get() {
struct stackframe *res;
asm("movq %%rbp, %0" : "=r"(res));
return res;
}

uint64_t strace_get_framep(int sf_offset) {
struct stackframe *stack = strace_get();

// skip get_x86_stack_trace(), 0 points to this function
for (int i = 0; stack && i < sf_offset + 1; i++) {
stack = stack->sp;
}

return stack->pc;
}
9 changes: 5 additions & 4 deletions kernel/arch/amd64/idt.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include <kstdint.h>
#include "kstdint.h"

// From https://wiki.osdev.org/Interrupt_Descriptor_Table#Structure_on_x86-64
struct idt_64 {
uint16_t offset_1; // offset bits 0..15
uint16_t selector; // a code segment selector in GDT or LDT
uint8_t ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero.
uint16_t offset_1; // offset bits 0..15
uint16_t selector; // a code segment selector in GDT or LDT
uint8_t
ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero.
uint8_t type_attributes; // gate type, dpl, and p fields
uint16_t offset_2; // offset bits 16..31
uint32_t offset_3; // offset bits 32..63
Expand Down
4 changes: 2 additions & 2 deletions kernel/arch/amd64/paging.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <kstdint.h>
#include "kstdint.h"

uint64_t paging_main[3][512] __attribute__((aligned(4096))) = { 0 };

int paging_init( ) {
int paging_init() {
return -1;
}
12 changes: 6 additions & 6 deletions kernel/arch/amd64/serial.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#include <kasm.h>
#include <kstdint.h>
#include "kasm.h"
#include "kstdint.h"

void serial_write_byte(uint8_t byte) {
// Wait until the transmit holding register is empty
while ((inb(0x3f8 + 5) & 0x20) == 0)
;
while ((inb(0x3f8 + 5) & 0x20) == 0);
outb(0x3f8, byte);
}

int serial_init( ) {
int serial_init() {
// Disable all interrupts
outb(0x3f8 + 1, 0x00);

Expand All @@ -19,7 +18,8 @@ int serial_init( ) {
outb(0x3f8, 0x0C); // Low byte of divisor
outb(0x3f8 + 1, 0x00); // High byte of divisor (0 for divisor < 256)

// Disable DLAB and set communication parameters: 8n1 (8 bits, no parity, 1 stop bit)
// Disable DLAB and set communication parameters: 8n1 (8 bits, no parity, 1
// stop bit)
outb(0x3f8 + 3, 0x03);

// Enable FIFOs
Expand Down
97 changes: 97 additions & 0 deletions kernel/arch/include/amd64/cpu/regs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#ifndef __ARCH_CPU_REGS
#define __ARCH_CPU_REGS

#include "amd64/cpu/tables.h"

#include <stdint.h>

typedef struct {
uint32_t eflags;

union {
struct {
uint8_t ah;
uint8_t al;
};
uint16_t ax;
uint32_t eax;
uint64_t rax;
};
union {
struct {
uint8_t bh;
uint8_t bl;
};
uint16_t bx;
uint32_t ebx;
uint64_t rbx;
};
union {
struct {
uint8_t ch;
uint8_t cl;
};
uint16_t cx;
uint32_t ecx;
uint64_t rcx;
};
union {
struct {
uint8_t dh;
uint8_t dl;
};
uint16_t dx;
uint32_t edx;
uint64_t rdx;
};

union {
uint16_t bp;
uint32_t ebp;
uint64_t rbp;
};
union {
uint16_t sp;
uint32_t esp;
uint64_t rsp;
};
union {
uint16_t si;
uint32_t esi;
uint64_t rsi;
};
union {
uint16_t di;
uint32_t edi;
uint64_t rdi;
};

uint64_t rip;

uint16_t cs;
uint16_t ds;
uint16_t es;
uint16_t fs;
uint16_t gs;
uint16_t ss;

uint32_t cr0;
uint32_t cr2;
uint32_t cr3;
uint32_t cr4;

uint32_t dr0;
uint32_t dr1;
uint32_t dr2;
uint32_t dr3;
uint32_t dr6;
uint32_t dr7;

struct desc_table gdtr;
struct desc_table ldtr;
struct desc_table idtr;
} __attribute__((packed)) asm_regs_t;

extern void update_asm_regs(asm_regs_t *state);

#endif
Loading
Loading