Files
claude-os/src/string.c
AI f63cd9eb3f Implement kernel memory allocator (kmalloc/kfree) and freestanding string library (AI)
- Added first-fit free-list allocator with block splitting and coalescing.
  Provides kmalloc(), kfree(), and kcalloc() for kernel-space dynamic memory.
- Each block carries an inline header with a magic value (0xCAFEBABE) for
  heap corruption detection, plus double-free checking.
- Memory is obtained from the paging subsystem in 4 KiB page increments.
  All allocations are 8-byte aligned with a 16-byte minimum block size.
- Created freestanding string.c with memset, memcpy, memmove, memcmp,
  strlen, strcmp, strncmp, strcpy, strncpy — replacing the unavailable
  libc implementations.
- Added documentation in docs/kmalloc.md.

Tested: kmalloc(64) returns 0xD0001010 (in kernel heap) and kfree succeeds.
Works with both 4 MiB and 128 MiB RAM.
2026-02-23 11:06:52 +00:00

173 lines
3.9 KiB
C

/**
* @file string.c
* @brief Minimal C string/memory functions for the freestanding kernel.
*
* These implementations replace the standard library versions since the
* kernel is compiled with -ffreestanding and does not link against libc.
*/
#include <stddef.h>
#include <stdint.h>
/**
* Fill a region of memory with a byte value.
*
* @param s Destination pointer.
* @param c Byte value to fill (only low 8 bits used).
* @param n Number of bytes to fill.
* @return The destination pointer.
*/
void *memset(void *s, int c, size_t n) {
unsigned char *p = (unsigned char *)s;
while (n--) {
*p++ = (unsigned char)c;
}
return s;
}
/**
* Copy a region of memory (non-overlapping).
*
* @param dest Destination pointer.
* @param src Source pointer.
* @param n Number of bytes to copy.
* @return The destination pointer.
*/
void *memcpy(void *dest, const void *src, size_t n) {
unsigned char *d = (unsigned char *)dest;
const unsigned char *s = (const unsigned char *)src;
while (n--) {
*d++ = *s++;
}
return dest;
}
/**
* Copy a region of memory, handling overlaps correctly.
*
* @param dest Destination pointer.
* @param src Source pointer.
* @param n Number of bytes to copy.
* @return The destination pointer.
*/
void *memmove(void *dest, const void *src, size_t n) {
unsigned char *d = (unsigned char *)dest;
const unsigned char *s = (const unsigned char *)src;
if (d < s) {
while (n--) {
*d++ = *s++;
}
} else {
d += n;
s += n;
while (n--) {
*--d = *--s;
}
}
return dest;
}
/**
* Compare two regions of memory.
*
* @param s1 First memory region.
* @param s2 Second memory region.
* @param n Number of bytes to compare.
* @return 0 if equal, negative if s1 < s2, positive if s1 > s2.
*/
int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *a = (const unsigned char *)s1;
const unsigned char *b = (const unsigned char *)s2;
while (n--) {
if (*a != *b) {
return *a - *b;
}
a++;
b++;
}
return 0;
}
/**
* Calculate the length of a null-terminated string.
*
* @param s The string.
* @return Number of characters before the null terminator.
*/
size_t strlen(const char *s) {
size_t len = 0;
while (*s++) {
len++;
}
return len;
}
/**
* Compare two null-terminated strings.
*
* @param s1 First string.
* @param s2 Second string.
* @return 0 if equal, negative if s1 < s2, positive if s1 > s2.
*/
int strcmp(const char *s1, const char *s2) {
while (*s1 && *s1 == *s2) {
s1++;
s2++;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
/**
* Compare at most n characters of two strings.
*
* @param s1 First string.
* @param s2 Second string.
* @param n Maximum number of characters to compare.
* @return 0 if equal, negative if s1 < s2, positive if s1 > s2.
*/
int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && *s1 == *s2) {
s1++;
s2++;
n--;
}
if (n == 0) {
return 0;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
/**
* Copy a null-terminated string.
*
* @param dest Destination buffer (must be large enough).
* @param src Source string.
* @return The destination pointer.
*/
char *strcpy(char *dest, const char *src) {
char *d = dest;
while ((*d++ = *src++))
;
return dest;
}
/**
* Copy at most n characters of a string, null-padding if shorter.
*
* @param dest Destination buffer.
* @param src Source string.
* @param n Maximum characters to copy.
* @return The destination pointer.
*/
char *strncpy(char *dest, const char *src, size_t n) {
char *d = dest;
while (n && (*d++ = *src++)) {
n--;
}
while (n--) {
*d++ = '\0';
}
return dest;
}