From 3a102f1e61e3ad41199de616aa20d25d415af9cf Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Sun, 30 Nov 2025 18:37:12 +0100 Subject: [PATCH] Added libc functions --- Makefile | 2 +- common.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ common.h | 36 ++++++++++++++++ kernel.c | 13 ++++-- kernel.h | 4 -- 5 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 common.c create mode 100644 common.h diff --git a/Makefile b/Makefile index 686521e..08b0893 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS = -nostdlib -O2 -g3 -Wall -Wextra -fno-stack-protector -ffreestanding LD_SCRIPT = kernel.ld LDFLAGS = -T$(LD_SCRIPT) -Wl,-Map=kernel.map -SRC = kernel.c +SRC = kernel.c common.c OUT = kernel.elf .PHONY: all clean run diff --git a/common.c b/common.c new file mode 100644 index 0000000..1ed4d43 --- /dev/null +++ b/common.c @@ -0,0 +1,122 @@ +#include "common.h" + +void putchar(char c); + +size_t align_up(size_t value, size_t align) +{ + /* To align means to compute the smallest value which is greater than a + * given number and that is an exact multiple of another specified + * number */ + size_t remainder = value % align; + if (remainder == 0) + return value; + + return value + (align - remainder); +} + +size_t is_aligned(size_t value, size_t align) +{ + return value % align == 0; +} + +void *memcpy(void *dst, const void *src, size_t n) +{ + uint8_t *d = (uint8_t*)dst; + const uint8_t *s = (uint8_t*)src; + while (n--) { + *d++ = *s++; + } + return dst; +} + +void *memset(void *buf, char c, size_t n) +{ + uint8_t *p = (uint8_t*)buf; + while (n--) { + *p++ = c; + } + return buf; +} + +char *strcpy(char *dst, const char *src) +{ + char *d = dst; + while (*src != '\0') { + *d++ = *src++; + } + *d = '\0'; + return dst; +} + +int strcmp(const char *s1, const char *s2) +{ + while (*s1 && *s2 && *s1 == *s2) { + s1++; + s2++; + } + return *((unsigned char *)s1) - *((unsigned char *)s2); +} + +void printf(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + while (*fmt != '\0') { + if (*fmt != '%') { + putchar(*fmt); + fmt++; + } else { + fmt++; // consume % + switch (*fmt) { + case '\0': + putchar('%'); + goto end; + case '%': + putchar('%'); + break; + case 's': + const char *s = va_arg(args, const char*); + while (*s != '\0') { + putchar(*s); + s++; + } + break; + case 'd': + int num = va_arg(args, int); + unsigned int magnitude = num; + unsigned int power = 1; + if (num < 0) { + putchar('-'); + magnitude = -magnitude; + } + + while ((magnitude / power) > 9) { + power *= 10; + } + + while (power > 0) { + putchar('0' + (magnitude / power)); + magnitude %= power; + power /= 10; + } + break; + case 'x': + unsigned int hex = va_arg(args, unsigned int); + putchar('0'); + putchar('x'); + for (int i = 7; i >= 0; i--) { + unsigned int nibble = (hex >> (4 * i)) & 0xf; + putchar("0123456789abcdef"[nibble]); + } + break; + } + + fmt++; // consume modifier + } + } + +end: + va_end(args); + + return; +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..999a40e --- /dev/null +++ b/common.h @@ -0,0 +1,36 @@ +#ifndef COMMON_H_ +#define COMMON_H_ + +#define true 1 +#define false 0 + +#define NULL ((void*)0) + +#define va_list __builtin_va_list +#define va_start __builtin_va_start +#define va_end __builtin_va_end +#define va_arg __builtin_va_arg + +#define offsetof(type, member) ((size_t)&(((type*)0)->member)) + +typedef int bool; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t ; +typedef unsigned int uint32_t; + +typedef uint32_t size_t; +typedef uint32_t paddr_t; +typedef uint32_t vaddr_t ; + +void printf(const char *fmt, ...); + +size_t align_up(size_t value, size_t align); +size_t is_aligned(size_t value, size_t align); + +void *memcpy(void *dst, const void *src, size_t n); +void *memset(void *buf, char c, size_t n); + +char *strcpy(char *dst, const char *src); +int strcmp(const char *s1, const char *s2); + +#endif // COMMON_H_ diff --git a/kernel.c b/kernel.c index 21d4d8f..85dc8da 100644 --- a/kernel.c +++ b/kernel.c @@ -1,4 +1,5 @@ #include "kernel.h" +#include "common.h" extern uint8_t __bss[], __bss_end[], __stack_top[]; @@ -32,10 +33,14 @@ void putchar(char c) void kernel_main(void) { - const char *s = "\n\nHello World!\n"; - for (int i = 0; s[i] != '\0'; i++) { - putchar(s[i]); - } + const char *s = "Hello World!"; + printf("\nString = '%s'\n", s); + printf("\nPositive Integer = %d\n", 42); + printf("\nNegative Integer = %d\n", -42); + printf("\nHexadecimal = %x\n", 0xdeadbeef); + + printf("offsetof(sbiret, error) = %x\n", offsetof(sbiret, error)); + printf("offsetof(sbiret, value) = %x\n", offsetof(sbiret, value)); while(1) { // wfi -> wait for interrupt diff --git a/kernel.h b/kernel.h index d432b27..574f227 100644 --- a/kernel.h +++ b/kernel.h @@ -1,10 +1,6 @@ #ifndef KERNEL_H_ #define KERNEL_H_ -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef uint32_t size_t; - typedef struct { long error; long value;