mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2025-07-03 09:42:57 -07:00
mostly improvements to malloc
This commit is contained in:
parent
109e554524
commit
e1e30b511a
@ -14,4 +14,14 @@ SECTIONS {
|
|||||||
*(.bss*)
|
*(.bss*)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stack (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
. = . + 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heap (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
. = . + 0x10000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 (
|
||||||
|
@ -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
47
kernel/fat12.h
Normal 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 */
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef FS_H
|
|
||||||
#define FS_H
|
|
||||||
|
|
||||||
void fs_init();
|
|
||||||
|
|
||||||
#endif // FS_H
|
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
@ -94,4 +102,4 @@ void free(void *ptr)
|
|||||||
|
|
||||||
// Mark the block as free
|
// Mark the block as free
|
||||||
mark_as_free(block);
|
mark_as_free(block);
|
||||||
}
|
}
|
||||||
|
@ -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'
|
||||||
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
|
@ -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
80
kernel/string_utils.c
Normal 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
11
kernel/string_utils.h
Normal 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
|
@ -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);
|
||||||
|
@ -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, ...);
|
||||||
|
|
||||||
|
10
kernel/vga.c
10
kernel/vga.c
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user