mostly improvements to malloc

This commit is contained in:
Gregory Kenneth Bowne 2025-07-01 11:20:04 -07:00
parent 109e554524
commit e1e30b511a
15 changed files with 276 additions and 30 deletions

View File

@ -14,4 +14,14 @@ SECTIONS {
*(.bss*) *(.bss*)
*(COMMON) *(COMMON)
} }
.stack (NOLOAD) : {
. = ALIGN(4);
. = . + 0x1000;
}
.heap (NOLOAD) : {
. = ALIGN(4);
. = . + 0x10000;
}
} }

View File

@ -2,6 +2,7 @@
#include "serial.h" #include "serial.h"
#include "terminal.h" #include "terminal.h"
#include "utils.h" #include "utils.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 volatile (

View File

@ -1,5 +1,5 @@
#include "fs.h" #include "fat12.h"
void fs_init() { void fat12_init() {
// Filesystem initialization code // Filesystem initialization code
} }

47
kernel/fat12.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef FAT12_H
#define FAT12_H
#include <stdint.h> /* Include standard integer types */
#include <stdio.h> /* Include standard I/O library */
#include <stdlib.h> /* Include standard library */
#define FAT12_SECTOR_SIZE 512 /* Sector size for FAT12 */
#define FAT12_MAX_FILES 128 /* Maximum number of files in root directory */
#define FAT12_ROOT_DIR_SECTORS 1 /* Number of sectors for root directory */
typedef struct {
uint8_t jump[3]; /* Jump instruction for boot */
char oem[8]; /* OEM name */
uint16_t bytes_per_sector; /* Bytes per sector */
uint8_t sectors_per_cluster; /* Sectors per cluster */
uint16_t reserved_sectors; /* Reserved sectors count */
uint8_t num_fats; /* Number of FATs */
uint16_t max_root_dir_entries; /* Max entries in root directory */
uint16_t total_sectors; /* Total sectors */
uint8_t media_descriptor; /* Media descriptor */
uint16_t fat_size; /* Size of each FAT */
uint16_t sectors_per_track; /* Sectors per track */
uint16_t num_heads; /* Number of heads */
uint32_t hidden_sectors; /* Hidden sectors count */
uint32_t total_sectors_large; /* Total sectors for large disks */
} __attribute__((packed)) FAT12_BootSector; /* Packed structure for boot sector */
typedef struct {
char name[11]; /* File name (8.3 format) */
uint8_t attr; /* File attributes */
uint16_t reserved; /* Reserved */
uint16_t time; /* Time of last write */
uint16_t date; /* Date of last write */
uint16_t start_cluster; /* Starting cluster number */
uint32_t file_size; /* File size in bytes */
} __attribute__((packed)) FAT12_DirEntry; /* Directory entry structure */
void initialize_fat12(const char *disk_image); /* Function to initialize FAT12 */
void read_fat12(const char *disk_image); /* Function to read FAT12 */
void write_fat12(const char *disk_image); /* Function to write FAT12 */
void list_files(const char *disk_image); /* Function to list files in root directory */
void read_file(const char *disk_image, const char *filename); /* Function to read a file */
void write_file(const char *disk_image, const char *filename, const uint8_t *data, size_t size); /* Function to write a file */
#endif
/* FAT12_H */

View File

@ -1,6 +0,0 @@
#ifndef FS_H
#define FS_H
void fs_init();
#endif // FS_H

View File

@ -1,6 +1,8 @@
#include "kmalloc.h" #include "kmalloc.h"
#include "terminal.h" // Optional: for debug output #include "terminal.h" // Optional: for debug output
#define HEAP_END 0xC0100000
static uint32_t current_heap = 0; static uint32_t current_heap = 0;
// Initialize the allocator with a starting heap address // Initialize the allocator with a starting heap address
@ -32,7 +34,18 @@ void* kmalloc_aligned(size_t size, uint32_t alignment) {
current_heap = (current_heap + alignment) & ~(alignment - 1); current_heap = (current_heap + alignment) & ~(alignment - 1);
} }
if (current_heap + size > HEAP_END) {
terminal_write("kmalloc_aligned: Out of memory!\n");
return 0;
}
void* addr = (void*)current_heap; void* addr = (void*)current_heap;
current_heap += size; current_heap += size;
return addr; return addr;
} }
void kfree(void* ptr) {
// In a bump allocator, we cannot free individual blocks.
// We can reset the allocator to the initial state.
current_heap = 0; // Reset the heap pointer
}

View File

@ -55,7 +55,15 @@ void mark_as_free(void *ptr) {
block->next = block->next->next; block->next = block->next->next;
} }
// TODO: Implement coalescing with previous block // Coalesce with previous block if it's free
struct memory_block *prev = free_blocks;
while (prev && prev->next != block) {
prev = prev->next;
}
if (prev && prev->is_free) {
prev->size += block->size + sizeof(struct memory_block);
prev->next = block->next;
}
} }
void *malloc(size_t size) void *malloc(size_t size)

View File

@ -1,6 +1,84 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include "print.h"
void print_string(const char *str) void my_putchar(char ch) {
{ // Write a single character to standard output
printf("%s", str); // In a freestanding environment, you might need to implement this differently
// For now, we will use the standard putchar for demonstration
// Replace this with your own implementation if needed
putchar(ch);
}
void print_string(const char *str) {
// Simple implementation to print a string
while (*str) {
my_putchar(*str++);
}
}
void my_printf(const char *format, ...) {
va_list args;
va_start(args, format);
while (*format) {
if (*format == '%') {
format++; // Move to the next character after '%'
switch (*format) {
case 's': { // String
char *str = va_arg(args, char *);
print_string(str);
break;
}
case 'd': { // Integer
int num = va_arg(args, int);
char buffer[20]; // Buffer to hold the string representation
snprintf(buffer, sizeof(buffer), "%d", num);
print_string(buffer);
break;
}
case 'c': { // Character
char ch = (char)va_arg(args, int); // Promote char to int
my_putchar(ch);
break;
}
default:
my_putchar('%'); // Print the '%' if no valid format specifier
my_putchar(*format);
break;
}
} else {
my_putchar(*format);
}
format++;
}
va_end(args);
}
void print_hex(unsigned int num) {
// Buffer to hold the hexadecimal representation
char buffer[9]; // 8 hex digits + null terminator
buffer[8] = '\0'; // Null-terminate the string
for (int i = 7; i >= 0; i--) {
int digit = num & 0xF; // Get the last 4 bits
buffer[i] = (digit < 10) ? (digit + '0') : (digit - 10 + 'A'); // Convert to hex character
num >>= 4; // Shift right by 4 bits
}
// Print the buffer, skipping leading zeros
int leading_zero = 1;
for (int i = 0; i < 8; i++) {
if (buffer[i] != '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'
}
} }

View File

@ -2,5 +2,8 @@
#define PRINT_H #define PRINT_H
void print_string(const char *str); void print_string(const char *str);
void my_printf(const char *format, ...);
void print_hex(unsigned int num);
void my_putchar(char ch);
#endif #endif

View File

@ -1,16 +1,18 @@
#include "shell.h" #include "shell.h"
#include "keyboard.h" #include "keyboard.h"
#include "terminal.h" #include "terminal.h"
#include "print.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "string_utils.h"
void execute(char *input) { void execute(char *input) {
if (strcmp(input, "help") == 0) { if (my_strcmp(input, "help") == 0) {
printf("Available commands: help, clear, exit\n"); my_printf("Available commands: help, clear, exit\n");
} else if (strcmp(input, "clear") == 0) { } else if (my_strcmp(input, "clear") == 0) {
terminal_clear(); terminal_clear();
} else { } else {
printf("Unknown command: %s\n", input); my_printf("Unknown command: %s\n", input);
} }
} }
@ -22,7 +24,7 @@ void shell_loop()
while (1) while (1)
{ {
printf("> "); my_printf("> ");
index = 0; index = 0;
while (1) while (1)
@ -32,7 +34,7 @@ void shell_loop()
if (c == '\n' || c == '\r') // Enter key if (c == '\n' || c == '\r') // Enter key
{ {
input[index] = '\0'; input[index] = '\0';
printf("\n"); my_printf("\n");
break; break;
} }
else if (c == '\b' || c == 127) // Backspace else if (c == '\b' || c == 127) // Backspace
@ -40,7 +42,7 @@ void shell_loop()
if (index > 0) if (index > 0)
{ {
index--; index--;
printf("\b \b"); // Erase last char on screen my_printf("\b \b"); // Erase last char on screen
} }
} }
else else
@ -52,7 +54,7 @@ void shell_loop()
} }
} }
if (strcmp(input, "exit") == 0) if (my_strcmp(input, "exit") == 0)
break; break;
execute(input); execute(input);

80
kernel/string_utils.c Normal file
View File

@ -0,0 +1,80 @@
#include "string_utils.h"
#include <stddef.h>
#include <stdarg.h>
size_t my_strlen(const char *str) {
const char *s = str;
while (*s) s++;
return s - str;
}
// Forward declaration of my_itoa
static size_t my_itoa(int value, char *str, size_t size);
int my_vsnprintf(char *str, size_t size, const char *format, ...) {
va_list args;
va_start(args, format);
size_t written = 0; // Change to size_t
for (const char *p = format; *p != '\0' && written < size - 1; p++) {
if (*p == '%') {
p++;
if (*p == 's') {
const char *s = va_arg(args, const char *);
while (*s && written < size - 1) {
str[written++] = *s++;
}
} else if (*p == 'd') {
// Handle integer formatting
written += my_itoa(va_arg(args, int), str + written, size - written);
} else {
// Handle other formats as needed
str[written++] = *p; // Just copy the character
}
} else {
str[written++] = *p;
}
}
str[written] = '\0'; // Null-terminate the string
va_end(args);
return written;
}
static size_t my_itoa(int value, char *str, size_t size) {
size_t written = 0; // Change to size_t
if (value < 0) {
if (written < size - 1) {
str[written++] = '-';
}
value = -value;
}
// Convert integer to string
int temp = value;
int digits = 0;
do {
digits++;
temp /= 10;
} while (temp);
if (written + digits >= size) {
digits = size - written - 1; // Prevent overflow
}
str += written + digits; // Move pointer to the end
*str-- = '\0'; // Null-terminate the string
do {
*str-- = (value % 10) + '0';
value /= 10;
} while (value && str >= str - digits);
return written + digits; // Return total written characters
}
int my_strcmp(const char *str1, const char *str2) {
while (*str1 && (*str1 == *str2)) {
str1++;
str2++;
}
return *(unsigned char *)str1 - *(unsigned char *)str2;
}

11
kernel/string_utils.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef STRING_UTILS_H
#define STRING_UTILS_H
#include <stddef.h>
#include <stdarg.h> // Include for va_list and related macros
size_t my_strlen(const char *str); // Renamed to avoid conflict
int my_vsnprintf(char *str, size_t size, const char *format, ...); // Renamed to avoid conflict
int my_strcmp(const char *str1, const char *str2);
#endif // STRING_UTILS_H

View File

@ -21,8 +21,7 @@ void syscall_handler(int code, va_list args) {
} }
} }
void syscall(int code, ...) void syscall(int code, ...) {
{
va_list args; va_list args;
va_start(args, code); va_start(args, code);
syscall_handler(code, args); syscall_handler(code, args);

View File

@ -1,6 +1,7 @@
#ifndef SYSCALLS_H #ifndef SYSCALLS_H
#define SYSCALLS_H #define SYSCALLS_H
#include <stdarg.h>
// Syscall numbers // Syscall numbers
typedef enum { typedef enum {
SYSCALL_INIT = 0, SYSCALL_INIT = 0,
@ -9,8 +10,7 @@ typedef enum {
} syscall_code_t; } syscall_code_t;
// Syscall dispatcher // Syscall dispatcher
void syscall_handler(); void syscall_handler(int code, va_list args);
// Syscall interface // Syscall interface
void syscall(int code, ...); void syscall(int code, ...);

View File

@ -1,9 +1,9 @@
#include "vga.h" #include "vga.h"
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> // Include for vsnprintf #include <string.h>
#include <string.h> // Include for strlen #include <stdarg.h>
#include <stdarg.h> // Include for va_list, va_start, etc. #include "string_utils.h"
void outb(uint16_t port, uint8_t value) { void outb(uint16_t port, uint8_t value) {
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port)); __asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
@ -130,11 +130,11 @@ void vga_printf(const char* format, ...) {
char buffer[256]; // Buffer to store the formatted string char buffer[256]; // Buffer to store the formatted string
va_list args; va_list args;
va_start(args, format); va_start(args, format);
vsnprintf(buffer, sizeof(buffer), format, args); my_vsnprintf(buffer, sizeof(buffer), format, args); // Use my_vsnprintf instead of vsnprintf
va_end(args); va_end(args);
// Now you can use the buffer with vga_write_string // Now you can use the buffer with vga_write_string
vga_write_string(buffer, strlen(buffer)); vga_write_string(buffer, my_strlen(buffer)); // Use my_strlen instead of strlen
} }
void vga_init(void) { void vga_init(void) {