Merge pull request #62 from vmttmv/main

begin fixing build errors for stage2
This commit is contained in:
2025-10-25 17:42:46 -07:00
committed by GitHub
18 changed files with 111 additions and 78 deletions

View File

@@ -1,5 +1,6 @@
AS = nasm AS = nasm
CC = gcc CC = gcc
CFLAGS = -std=c11 -m32 -ffreestanding -c -fno-stack-protector -fno-pie
LD = ld LD = ld
QEMU = qemu-system-i386 QEMU = qemu-system-i386
IMG_SIZE = 1440k IMG_SIZE = 1440k
@@ -10,8 +11,15 @@ BOOT_SRC = bootloader/boot.asm
BOOT_OBJ = $(BUILD_DIR)/boot.o BOOT_OBJ = $(BUILD_DIR)/boot.o
BOOT_ELF = $(BUILD_DIR)/boot.elf BOOT_ELF = $(BUILD_DIR)/boot.elf
BOOT_IMG = $(BUILD_DIR)/boot.img BOOT_IMG = $(BUILD_DIR)/boot.img
KERNEL_SRC = kernel/kmain.c
KERNEL_C_SRC = $(wildcard kernel/*.c)
KERNEL_ASM_SRC = $(wildcard kernel/*.asm)
KERNEL_OBJ = $(patsubst kernel/%.c, $(BUILD_DIR)/%.o, $(KERNEL_C_SRC))
KERNEL_OBJ += $(patsubst kernel/%.asm, $(BUILD_DIR)/asm_%.o, $(KERNEL_ASM_SRC))
KERNEL_OBJ += $(BUILD_DIR)/boot1.o
KERNEL_ELF = $(BUILD_DIR)/kernel.elf
KERNEL_BIN = $(BUILD_DIR)/kernel.bin KERNEL_BIN = $(BUILD_DIR)/kernel.bin
DISK_IMG = $(BUILD_DIR)/disk.img DISK_IMG = $(BUILD_DIR)/disk.img
all: $(BOOT_IMG) $(KERNEL_BIN) $(DISK_IMG) all: $(BOOT_IMG) $(KERNEL_BIN) $(DISK_IMG)
@@ -29,9 +37,17 @@ $(BOOT_IMG): $(BOOT_ELF)
objcopy -O binary $< $@ objcopy -O binary $< $@
truncate -s $(IMG_SIZE) $@ truncate -s $(IMG_SIZE) $@
$(KERNEL_BIN): $(KERNEL_SRC) | $(BUILD_DIR) $(BUILD_DIR)/boot1.o: bootloader/boot1.asm
$(CC) -ffreestanding -c $< -o $(BUILD_DIR)/kernel.o $(AS) -f elf32 -o $@ $<
$(LD) -T bootloader/linker.ld -o $@ $(BUILD_DIR)/kernel.o
$(BUILD_DIR)/asm_%.o: kernel/%.asm
$(AS) -f elf32 -o $@ $<
$(BUILD_DIR)/%.o: kernel/%.c
$(CC) $(CFLAGS) $< -o $@
$(KERNEL_BIN): $(KERNEL_OBJ) | $(BUILD_DIR)
$(LD) -melf_i386 --oformat binary -T bootloader/linker.ld -o $@ $(KERNEL_OBJ)
$(DISK_IMG): $(BOOT_IMG) $(KERNEL_BIN) $(DISK_IMG): $(BOOT_IMG) $(KERNEL_BIN)
dd if=$(BOOT_IMG) of=$@ bs=512 seek=4 dd if=$(BOOT_IMG) of=$@ bs=512 seek=4

View File

@@ -5,7 +5,7 @@
#include "print.h" #include "print.h"
void cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { void cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) {
asm volatile ( __asm__(
"cpuid" "cpuid"
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a"(function) : "a"(function)
@@ -32,6 +32,6 @@ void identify_cpu() {
serial_write("\n"); serial_write("\n");
terminal_write("CPUID max leaf: "); terminal_write("CPUID max leaf: ");
print_hex(eax); // You must implement this (see below) print_hex(eax, false, false); // You must implement this (see below)
terminal_write("\n"); terminal_write("\n");
} }

View File

@@ -52,7 +52,7 @@ void idt_set_gate(int n, uint32_t handler) {
// Load IDT via lidt // Load IDT via lidt
static void idt_load() { static void idt_load() {
asm volatile("lidt (%0)" : : "r" (&idt_ptr)); __asm__("lidt (%0)" : : "r" (&idt_ptr));
} }
// IDT initialization // IDT initialization

View File

@@ -4,12 +4,12 @@
#include <stdint.h> #include <stdint.h>
static inline void outb(uint16_t port, uint8_t val) { static inline void outb(uint16_t port, uint8_t val) {
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port)); __asm__("outb %0, %1" : : "a"(val), "Nd"(port));
} }
static inline uint8_t inb(uint16_t port) { static inline uint8_t inb(uint16_t port) {
uint8_t ret; uint8_t ret;
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); __asm__("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret; return ret;
} }

View File

@@ -1,8 +1,8 @@
[BITS 32] [BITS 32]
[GLOBAL isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9] GLOBAL isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9
[GLOBAL isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19] GLOBAL isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19
[GLOBAL isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29] GLOBAL isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29
[GLOBAL isr30, isr31, isr_default] GLOBAL isr30, isr31, isr_default
[EXTERN isr_handler] [EXTERN isr_handler]

View File

@@ -2,20 +2,20 @@
#include "serial.h" #include "serial.h"
#include "isr.h" #include "isr.h"
#include "io.h" #include "io.h"
#include "utils.h" #include "print.h"
static isr_callback_t interrupt_handlers[MAX_INTERRUPTS] = { 0 }; static isr_callback_t interrupt_handlers[MAX_INTERRUPTS] = { 0 };
void isr_handler(uint32_t int_num, uint32_t err_code) { void isr_handler(uint32_t int_num, uint32_t err_code) {
terminal_write("Interrupt occurred: "); terminal_write("Interrupt occurred: ");
print_hex(int_num); print_hex(int_num, true, false);
terminal_write("\n"); terminal_write("\n");
serial_write("INT triggered\n"); serial_write("INT triggered\n");
terminal_write("Error code: "); terminal_write("Error code: ");
print_hex(err_code); print_hex(err_code, true, false);
terminal_write("\n"); terminal_write("\n");
if (interrupt_handlers[int_num]) { if (interrupt_handlers[int_num]) {
@@ -33,7 +33,7 @@ void isr_handler(uint32_t int_num, uint32_t err_code) {
// Halt CPU // Halt CPU
while (1) { while (1) {
asm volatile ("hlt"); __asm__("hlt");
} }
} }

View File

@@ -1,5 +1,4 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "io.h" #include "io.h"
#include "serial.h" #include "serial.h"
#include "terminal.h" #include "terminal.h"
@@ -9,6 +8,7 @@
#include "gdt.h" #include "gdt.h"
#include "cpu.h" #include "cpu.h"
#include "kmalloc.h" #include "kmalloc.h"
#include "print.h"
#include "timer.h" #include "timer.h"
#include "utils.h" #include "utils.h"
#include "keyboard.h" #include "keyboard.h"
@@ -69,9 +69,9 @@ void kmain(void) {
char buf[32]; char buf[32];
for (uint32_t i = 0; i < mmap_size; i++) { for (uint32_t i = 0; i < mmap_size; i++) {
terminal_write(" - Base: "); terminal_write(" - Base: ");
print_hex((uint32_t)(mmap[i].base_addr & 0xFFFFFFFF)); // Lower 32 bits print_hex((uint32_t)(mmap[i].base_addr & 0xFFFFFFFF), true, false); // Lower 32 bits
terminal_write(", Length: "); terminal_write(", Length: ");
print_hex((uint32_t)(mmap[i].length & 0xFFFFFFFF)); // Lower 32 bits print_hex((uint32_t)(mmap[i].length & 0xFFFFFFFF), true, false); // Lower 32 bits
terminal_write(", Type: "); terminal_write(", Type: ");
itoa(mmap[i].type, buf, 10); itoa(mmap[i].type, buf, 10);
terminal_write(buf); terminal_write(buf);
@@ -82,6 +82,6 @@ void kmain(void) {
// Halt CPU in loop // Halt CPU in loop
while (1) { while (1) {
asm volatile("hlt"); __asm__("hlt");
} }
} }

View File

@@ -10,7 +10,7 @@ static mouse_data_t mouse_data;
// Read USB mouse data // Read USB mouse data
mouse_data_t usb_read_mouse(void) { mouse_data_t usb_read_mouse(void) {
uint8_t buffer[3]; // USB HID Mouse reports typically use 3 bytes uint8_t buffer[3]; // USB HID Mouse reports typically use 3 bytes
if (usb_interrupt_transfer(buffer, sizeof(buffer))) { // Ensure buffer is filled if (usb_interrupt_transfer()) { // Ensure buffer is filled
// Process the received data // Process the received data
mouse_data.x += buffer[1]; // X movement mouse_data.x += buffer[1]; // X movement
mouse_data.y += buffer[2]; // Y movement mouse_data.y += buffer[2]; // Y movement

View File

@@ -37,12 +37,12 @@ void enable_paging() {
uint32_t cr0; uint32_t cr0;
// Load page directory into CR3 // Load page directory into CR3
asm volatile("mov %0, %%cr3" : : "r"(page_directory)); __asm__("mov %0, %%cr3" : : "r"(page_directory));
// Enable paging (set the PG bit in CR0) // Enable paging (set the PG bit in CR0)
asm volatile("mov %%cr0, %0" : "=r"(cr0)); __asm__("mov %%cr0, %0" : "=r"(cr0));
cr0 |= 0x80000000; // Set the PG (paging) bit cr0 |= 0x80000000; // Set the PG (paging) bit
asm volatile("mov %0, %%cr0" : : "r"(cr0)); __asm__("mov %0, %%cr0" : : "r"(cr0));
} }
// Initialize paging: set up the page directory and enable paging // Initialize paging: set up the page directory and enable paging

View File

@@ -14,6 +14,6 @@ void panic(const char *message) {
// Halt the system // Halt the system
while (true) { while (true) {
asm volatile ("cli; hlt"); __asm__("cli; hlt");
} }
} }

View File

@@ -1,13 +1,14 @@
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include "print.h" #include "print.h"
#include "serial.h"
#include "terminal.h"
void my_putchar(char ch) { void my_putchar(char ch) {
// Write a single character to standard output // Write a single character to standard output
// In a freestanding environment, you might need to implement this differently // In a freestanding environment, you might need to implement this differently
// For now, we will use the standard putchar for demonstration // For now, we will use the standard putchar for demonstration
// Replace this with your own implementation if needed // Replace this with your own implementation if needed
putchar(ch); terminal_putchar(ch);
} }
void print_string(const char *str) { void print_string(const char *str) {
@@ -33,7 +34,9 @@ void my_printf(const char *format, ...) {
case 'd': { // Integer case 'd': { // Integer
int num = va_arg(args, int); int num = va_arg(args, int);
char buffer[20]; // Buffer to hold the string representation char buffer[20]; // Buffer to hold the string representation
snprintf(buffer, sizeof(buffer), "%d", num);
//TODO: implement `snprintf()`
//snprintf(buffer, sizeof(buffer), "%d", num);
print_string(buffer); print_string(buffer);
break; break;
} }
@@ -56,29 +59,44 @@ void my_printf(const char *format, ...) {
va_end(args); va_end(args);
} }
void print_hex(uint32_t val, int include_prefix, int suppress_leading_zeros) {
char hex_chars[] = "0123456789ABCDEF";
char buffer[11]; // 8 hex digits + "0x" + null terminator
int pos = 10; // Start from end of buffer (null terminator)
void print_hex(unsigned int num) { // Null-terminate the buffer
// Buffer to hold the hexadecimal representation buffer[pos--] = '\0';
char buffer[9]; // 8 hex digits + null terminator
buffer[8] = '\0'; // Null-terminate the string
// Convert value to hex digits
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {
int digit = num & 0xF; // Get the last 4 bits int digit = val & 0xF; // Get last 4 bits
buffer[i] = (digit < 10) ? (digit + '0') : (digit - 10 + 'A'); // Convert to hex character buffer[pos--] = hex_chars[digit];
num >>= 4; // Shift right by 4 bits val >>= 4; // Shift right by 4 bits
} }
// Print the buffer, skipping leading zeros // Add "0x" prefix if requested
int leading_zero = 1; if (include_prefix) {
for (int i = 0; i < 8; i++) { buffer[pos--] = 'x';
if (buffer[i] != '0') { buffer[pos--] = '0';
leading_zero = 0; // Found a non-zero digit
}
if (!leading_zero) {
my_putchar(buffer[i]);
}
} }
if (leading_zero) {
my_putchar('0'); // If all were zeros, print a single '0' // Determine start of output (skip leading zeros if requested)
int start = include_prefix ? 0 : 2; // Start after "0x" if prefix included
if (suppress_leading_zeros && !include_prefix) {
int i = start;
while (i < 9 && buffer[i] == '0') {
i++;
}
if (i == 10) {
// All zeros, output single '0'
terminal_write("0");
serial_write("0");
return;
}
start = i;
} }
// Output the result
terminal_write(buffer + start);
serial_write(buffer + start);
} }

View File

@@ -1,9 +1,11 @@
#ifndef PRINT_H #ifndef PRINT_H
#define PRINT_H #define PRINT_H
#include "types.h"
void print_string(const char *str); void print_string(const char *str);
void my_printf(const char *format, ...); void my_printf(const char *format, ...);
void print_hex(unsigned int num); void print_hex(uint32_t val, int include_prefix, int suppress_leading_zeros);
void my_putchar(char ch); void my_putchar(char ch);
#endif #endif

View File

@@ -2,8 +2,6 @@
#include "keyboard.h" #include "keyboard.h"
#include "terminal.h" #include "terminal.h"
#include "print.h" #include "print.h"
#include <stdio.h>
#include <string.h>
#include "string_utils.h" #include "string_utils.h"
void execute(char *input) { void execute(char *input) {
@@ -49,7 +47,7 @@ void shell_loop()
{ {
if (index < sizeof(input) - 1) { if (index < sizeof(input) - 1) {
input[index++] = c; input[index++] = c;
putchar(c); terminal_putchar(c);
} }
} }
} }

View File

@@ -1,8 +1,9 @@
#include "malloc.h"
#include "print.h"
#include "threading.h" #include "threading.h"
#include <stdlib.h> #include "types.h"
#include "utils.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string.h>
#define MAX_THREADS 16 // Maximum number of threads #define MAX_THREADS 16 // Maximum number of threads
#define THREAD_STACK_SIZE 8192 // Stack size for each thread #define THREAD_STACK_SIZE 8192 // Stack size for each thread
@@ -27,7 +28,7 @@ void thread_init(void) {
// Create a new thread // Create a new thread
void thread_create(Thread *thread __attribute__((unused)), void (*start_routine)(void *), void *arg) { void thread_create(Thread *thread __attribute__((unused)), void (*start_routine)(void *), void *arg) {
if (num_threads >= MAX_THREADS) { if (num_threads >= MAX_THREADS) {
printf("Error: Maximum thread count reached.\n"); my_printf("Error: Maximum thread count reached.\n");
return; return;
} }
@@ -98,7 +99,7 @@ void scheduler(void) {
void context_switch(Thread *next) { void context_switch(Thread *next) {
// For simplicity, context switching in this example would involve saving/restoring registers. // For simplicity, context switching in this example would involve saving/restoring registers.
// In a real system, you would need to save the CPU state (registers) and restore the next thread's state. // In a real system, you would need to save the CPU state (registers) and restore the next thread's state.
printf("Switching to thread...\n"); my_printf("Switching to thread...\n");
next->start_routine(next->arg); // Start running the next thread next->start_routine(next->arg); // Start running the next thread
} }

View File

@@ -3,6 +3,7 @@
#include "isr.h" #include "isr.h"
#include "terminal.h" #include "terminal.h"
#include "stdio.h" #include "stdio.h"
#include "utils.h"
static volatile uint32_t tick = 0; static volatile uint32_t tick = 0;

View File

@@ -1,9 +1 @@
#include "types.h" #include "types.h"
// Example: Basic memory helper (unnecessary if libc exists)
void *memset(void *dest, int value, size_t len) {
unsigned char *ptr = (unsigned char *)dest;
while (len-- > 0)
*ptr++ = (unsigned char)value;
return dest;
}

View File

@@ -1,6 +1,4 @@
#include "utils.h" #include "utils.h"
#include "serial.h"
#include "terminal.h"
static void reverse(char* str, int len) { static void reverse(char* str, int len) {
int start = 0; int start = 0;
@@ -79,13 +77,19 @@ char* utoa(unsigned int value, char* str, int base) {
return str; return str;
} }
void print_hex(uint32_t val) { int memcmp(const void *ptr1, const void *ptr2, size_t num) {
char hex_chars[] = "0123456789ABCDEF"; const uint8_t *p1 = ptr1, *p2 = ptr2;
char buf[11] = "0x00000000"; for (size_t i = 0; i < num; i++) {
for (int i = 9; i >= 2; i--) { if (p1[i] != p2[i]) {
buf[i] = hex_chars[val & 0xF]; return p1[i] < p2[i] ? -1 : 1;
val >>= 4; }
} }
terminal_write(buf); return 0;
serial_write(buf); }
void *memset(void *dest, int value, size_t len) {
unsigned char *ptr = (unsigned char *)dest;
while (len-- > 0)
*ptr++ = (unsigned char)value;
return dest;
} }

View File

@@ -1,7 +1,7 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#include <stdint.h>
#include "types.h"
// Convert integer to string (base is typically 10, 16, etc.) // Convert integer to string (base is typically 10, 16, etc.)
char* itoa(int value, char* str, int base); char* itoa(int value, char* str, int base);
@@ -9,6 +9,7 @@ char* itoa(int value, char* str, int base);
// Convert unsigned integer to string (base is typically 10, 16, etc.) // Convert unsigned integer to string (base is typically 10, 16, etc.)
char* utoa(unsigned int value, char* str, int base); char* utoa(unsigned int value, char* str, int base);
void print_hex(uint32_t val); int memcmp(const void *ptr1, const void *ptr2, size_t num);
void *memset(void *dest, int value, size_t len);
#endif // UTILS_H #endif // UTILS_H