printf spinlock + remove DEPRECATED stuff + begin separating x86 stuff

This commit is contained in:
2026-03-20 09:01:57 +01:00
parent 424b4c4632
commit 3607a7179c
12 changed files with 77 additions and 138 deletions

View File

@@ -12,13 +12,13 @@ CC_PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
LD := x86_64-elf-ld
$(ELFFILE): $(BUILDDIR) $(OBJFILES)
nasm -f elf64 src/idt/idt.S -o $(BUILDDIR)/idt_stub.o
nasm -f elf64 src/arch/x86/idt.S -o $(BUILDDIR)/idt_stub.o
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
# Get the symbols for debugging
nm -n $(ELFFILE) | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
python3 symbols.py
nasm -f elf64 symbols.S -o $(BUILDDIR)/symbols.o
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o $(BUILDDIR)/symbols.o
$(BUILDDIR):
@mkdir -p $(BUILDDIR)

View File

@@ -10,4 +10,53 @@ void wrmsr(uint32_t msr, uint64_t value);
bool x86_has_msr();
void x86_arch_init();
/* Interrupt Descriptor Table */
void idt_init(void);
struct interrupt_descriptor {
uint16_t address_low;
uint16_t selector;
uint8_t ist;
uint8_t flags;
uint16_t address_mid;
uint32_t address_high;
uint32_t reserved;
} __attribute__((packed));
struct idtr {
uint16_t limit;
uint64_t base;
} __attribute__((packed));
// All general-purpose registers (except rsp) as stored on the stack,
// plus the values we pushed (vector number, error code) and the iret frame
// In reverse order because the stack grows downwards.
struct cpu_status_t {
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rbp;
uint64_t rdi;
uint64_t rsi;
uint64_t rdx;
uint64_t rcx;
uint64_t rbx;
uint64_t rax;
uint64_t vector_number;
uint64_t error_code;
uint64_t iret_rip;
uint64_t iret_cs;
uint64_t iret_flags;
uint64_t iret_rsp;
uint64_t iret_ss;
};
#endif

View File

@@ -1,59 +0,0 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Interrupt Descriptor Table setup and dispatching
* @license GPL-3.0-only
*/
#ifndef IDT_H
#define IDT_H
#include <stdint.h>
void idt_init(void);
struct interrupt_descriptor {
uint16_t address_low;
uint16_t selector;
uint8_t ist;
uint8_t flags;
uint16_t address_mid;
uint32_t address_high;
uint32_t reserved;
} __attribute__((packed));
struct idtr {
uint16_t limit;
uint64_t base;
} __attribute__((packed));
// All general-purpose registers (except rsp) as stored on the stack,
// plus the values we pushed (vector number, error code) and the iret frame
// In reverse order because the stack grows downwards.
struct cpu_status_t {
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rbp;
uint64_t rdi;
uint64_t rsi;
uint64_t rdx;
uint64_t rcx;
uint64_t rbx;
uint64_t rax;
uint64_t vector_number;
uint64_t error_code;
uint64_t iret_rip;
uint64_t iret_cs;
uint64_t iret_flags;
uint64_t iret_rsp;
uint64_t iret_ss;
};
#endif

View File

@@ -8,8 +8,8 @@
#define TERM_H
void kputs(const char* str);
void _putchar(char character);
void term_init(void);
int printf(const char* fmt, ...);
void internal_putc(int c, void *_);
#endif

View File

@@ -17,7 +17,7 @@ enum ErrorCodes {
#include <io/serial/serial.h>
#include <io/term/term.h>
#include <idt/idt.h>
#include <arch/x86.h>
#include <stdbool.h>
extern volatile uint64_t ticks;

View File

@@ -4,7 +4,7 @@
* @license GPL-3.0-only
*/
#include <idt/idt.h>
#include <arch/x86.h>
#include <stdint.h>
#include <stddef.h>
#include <io/serial/serial.h>

View File

@@ -5,7 +5,7 @@
*/
#include <stddef.h>
#include <idt/idt.h>
#include <arch/x86.h>
#include <io/serial/serial.h>
#include <kernel.h>

View File

@@ -216,10 +216,10 @@ void keyboard_handler()
if (c) {
if (c == '\n') {
_putchar('\r');
internal_putc('\r', NULL);
}
// Should probably have a keyboard buffer here... instead of this
_putchar(c);
internal_putc(c, NULL);
keyboard_putchar(c);
}
}

View File

@@ -30,19 +30,10 @@ extern struct flanterm_context* ft_ctx;
extern struct init_status init;
struct spinlock_t term_lock = {0};
struct spinlock_t printf_lock = {0};
extern int panic_count;
/*
* _putchar - Writes a character to terminal (DEPRECATED)
* @character: character to write
*/
void _putchar(char character)
{
// TODO: Spinlock here (terminal access)
flanterm_write(ft_ctx, &character, 1);
}
/*
* internal_putc - Internal putchar function
* @c: char to print
@@ -83,14 +74,26 @@ void internal_putc(int c, void *_)
*
* Return:
* <ret> - number of characters sent to the callback
* %-1 - error
*/
int printf(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args);
return ret;
if (panic_count == 0) {
spinlock_acquire(&printf_lock);
va_list args;
va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args);
spinlock_release(&printf_lock);
return ret;
} else {
va_list args;
va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args);
return ret;
}
return -1;
}
/*
@@ -103,30 +106,14 @@ void kputs(const char* str)
{
size_t i=0;
while (str[i] != 0) {
_putchar(str[i]);
internal_putc(str[i], NULL);
i++;
}
_putchar('\r');
}
extern struct flanterm_context* ft_ctx;
extern struct boot_context boot_ctx;
/*
* flanterm_free_wrapper - free() wrapper for Flanterm (DEPRECATED)
* @ptr: pointer to free
* @size: amount of bytes to free
*
* This function exists solely because the Flanterm initialization
* function only accepts a free() function with a size parameter,
* and the default one doesn't have it.
*/
void flanterm_free_wrapper(void* ptr, size_t size)
{
(void)size;
kfree(ptr);
}
/*
* term_init - Video output/terminal initialization
*

View File

@@ -12,7 +12,6 @@
#include <io/serial/serial.h>
#include <mem/gdt.h>
#include <mem/utils.h>
#include <idt/idt.h>
#include <kernel.h>
#include <time/timer.h>
#include <io/kbd/ps2.h>

View File

@@ -25,43 +25,6 @@ First we'll have to discover the physical memory layout,
and for that we can use a Limine request.
*/
// DEPRECATED
struct limine_memmap_entry* biggest_entry;
/*
* pmm_find_biggest_usable_region - Finding the biggest free memory region (DEPRECATED)
* @memmap: Limine memory map
* @hhdm: Limine HHDM offset
*
* This function uses the memory map provided by the bootloader
* to find the single biggest free memory region we can use.
*/
static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
{
// Max length of a usable memory region
uint64_t length_max = 0;
uint64_t offset = hhdm->offset;
DEBUG("Usable Memory:");
for (size_t i=0; i<memmap->entry_count; i++) {
struct limine_memmap_entry* entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) {
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", entry->base, entry->base+entry->length,
entry->base+offset, entry->base+entry->length+offset);
if (entry->length > length_max)
{
length_max = entry->length;
biggest_entry = entry;
}
}
}
DEBUG("Biggest usable memory region:");
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", biggest_entry->base, biggest_entry->base + biggest_entry->length,
biggest_entry->base+offset, biggest_entry->base+biggest_entry->length+offset);
}
// Offset from Higher Half Direct Map
uint64_t hhdm_off;