Added libc functions
This commit is contained in:
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@ CFLAGS = -nostdlib -O2 -g3 -Wall -Wextra -fno-stack-protector -ffreestanding
|
|||||||
LD_SCRIPT = kernel.ld
|
LD_SCRIPT = kernel.ld
|
||||||
LDFLAGS = -T$(LD_SCRIPT) -Wl,-Map=kernel.map
|
LDFLAGS = -T$(LD_SCRIPT) -Wl,-Map=kernel.map
|
||||||
|
|
||||||
SRC = kernel.c
|
SRC = kernel.c common.c
|
||||||
OUT = kernel.elf
|
OUT = kernel.elf
|
||||||
|
|
||||||
.PHONY: all clean run
|
.PHONY: all clean run
|
||||||
|
|||||||
122
common.c
Normal file
122
common.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
36
common.h
Normal file
36
common.h
Normal file
@@ -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_
|
||||||
13
kernel.c
13
kernel.c
@@ -1,4 +1,5 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
extern uint8_t __bss[], __bss_end[], __stack_top[];
|
extern uint8_t __bss[], __bss_end[], __stack_top[];
|
||||||
|
|
||||||
@@ -32,10 +33,14 @@ void putchar(char c)
|
|||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
const char *s = "\n\nHello World!\n";
|
const char *s = "Hello World!";
|
||||||
for (int i = 0; s[i] != '\0'; i++) {
|
printf("\nString = '%s'\n", s);
|
||||||
putchar(s[i]);
|
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) {
|
while(1) {
|
||||||
// wfi -> wait for interrupt
|
// wfi -> wait for interrupt
|
||||||
|
|||||||
Reference in New Issue
Block a user