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.
This commit is contained in:
172
src/string.c
Normal file
172
src/string.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
Reference in New Issue
Block a user