Refactoring assembly entry point

This commit is contained in:
Marco Cetica
2021-02-03 15:59:42 +01:00
parent dc3803491e
commit 1b207add8c
61 changed files with 4782 additions and 4779 deletions

View File

@@ -1,11 +1,11 @@
OBJS = stdio.o string.o panic.o time.o
VER := $(shell git rev-parse --short HEAD)
CC = i686-elf-gcc # cross-compiler
CFLAGS = -DVULCAN_VERSION=$(VER) -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c
all:${OBJS}
%.o: %.c
$(CC) $(CFLAGS) $< -o $@
OBJS = stdio.o string.o panic.o time.o
VER := $(shell git rev-parse --short HEAD)
CC = i686-elf-gcc # cross-compiler
CFLAGS = -DVULCAN_VERSION=$(VER) -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c
all:${OBJS}
%.o: %.c
$(CC) $(CFLAGS) $< -o $@

View File

@@ -1,51 +1,51 @@
#include "panic.h"
#include "../drivers/cpuid.h"
#include "../libc/stdio.h"
#include "../libc/string.h"
#define KINFO printf("["); printf_color(" I ", LIGHT_RED, BLACK); printf("]: ");
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
// We panic when we find a critical error, this function is called by assert macro
extern void panic(const char *message, const char *file, uint32_t line) {
uint8_t version[64];
#ifdef VULCAN_VERSION
strcpy(version, (uint8_t*)STRINGIZE_VALUE_OF(VULCAN_VERSION));
#else
#error "-DVULCAN_VERSION flag not set"
#endif
printf_color("=============================================\n", LIGHT_MAGENTA, BLACK);
printf_color(" .:: KERNEL PANIC ::. \n", LIGHT_RED, BLACK);
printf_color("Reason: ", LIGHT_BROWN, BLACK);
printf("'%s' at '%s':%d\n", message, file, line);
KINFO
printf_color("Disabling interrupts\n", LIGHT_GREEN, BLACK);
asm volatile("cli"); // Disable interrupts
KINFO
printf_color("Dropping you into an endless loop\n", LIGHT_GREEN, BLACK);
KINFO
printf_color("Your are on your own now...good luck.\n", LIGHT_GREEN, BLACK);
KINFO
printf_color("VulcanOS version: ", LIGHT_GREEN, BLACK);
printf_color((char*)version, LIGHT_CYAN, BLACK);
printf_color("\n\t\t (c) 2019-2021 Marco Cetica", LIGHT_BROWN, BLACK);
printf_color("\n=============================================\n", LIGHT_MAGENTA, BLACK);
for(;;);
}
// Check for assertion failed, this function is called by assert macro
extern void panic_assert(const char *file, uint32_t line, const char *desc) {
asm volatile("cli"); // Disable interrupts
kprint((uint8_t*)"ASSERTION-FAILED(");
kprint((uint8_t*)desc);
kprint((uint8_t*)") at ");
kprint((uint8_t*)file);
kprint((uint8_t*)":");
kprint_dec(line);
kprint((uint8_t*)"\n");
// Now hang on forever
for(;;);
}
#include "panic.h"
#include "../drivers/cpuid.h"
#include "../libc/stdio.h"
#include "../libc/string.h"
#define KINFO printf("["); printf_color(" I ", LIGHT_RED, BLACK); printf("]: ");
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
// We panic when we find a critical error, this function is called by assert macro
extern void panic(const char *message, const char *file, uint32_t line) {
uint8_t version[64];
#ifdef VULCAN_VERSION
strcpy(version, (uint8_t*)STRINGIZE_VALUE_OF(VULCAN_VERSION));
#else
#error "-DVULCAN_VERSION flag not set"
#endif
printf_color("=============================================\n", LIGHT_MAGENTA, BLACK);
printf_color(" .:: KERNEL PANIC ::. \n", LIGHT_RED, BLACK);
printf_color("Reason: ", LIGHT_BROWN, BLACK);
printf("'%s' at '%s':%d\n", message, file, line);
KINFO
printf_color("Disabling interrupts\n", LIGHT_GREEN, BLACK);
asm volatile("cli"); // Disable interrupts
KINFO
printf_color("Dropping you into an endless loop\n", LIGHT_GREEN, BLACK);
KINFO
printf_color("Your are on your own now...good luck.\n", LIGHT_GREEN, BLACK);
KINFO
printf_color("VulcanOS version: ", LIGHT_GREEN, BLACK);
printf_color((char*)version, LIGHT_CYAN, BLACK);
printf_color("\n\t\t (c) 2019-2021 Marco Cetica", LIGHT_BROWN, BLACK);
printf_color("\n=============================================\n", LIGHT_MAGENTA, BLACK);
for(;;);
}
// Check for assertion failed, this function is called by assert macro
extern void panic_assert(const char *file, uint32_t line, const char *desc) {
asm volatile("cli"); // Disable interrupts
kprint((uint8_t*)"ASSERTION-FAILED(");
kprint((uint8_t*)desc);
kprint((uint8_t*)") at ");
kprint((uint8_t*)file);
kprint((uint8_t*)":");
kprint_dec(line);
kprint((uint8_t*)"\n");
// Now hang on forever
for(;;);
}

View File

@@ -1,20 +1,20 @@
/**************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/iceOS *
***************************************/
#ifndef PANIC_H
#define PANIC_H
#include <stdint.h>
#include "../drivers/tty.h"
#define PANIC(msg) panic(msg, __FILE__, __LINE__);
#define ASSERT(b) ((b) ? (void)0 : panic_assert(__FILE__, __LINE__, #b))
extern void panic(const char *message, const char *file, uint32_t line);
extern void panic_assert(const char *file, uint32_t line, const char *desc);
#endif
/*****************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/vulcanos *
*****************************************/
#ifndef PANIC_H
#define PANIC_H
#include <stdint.h>
#include "../drivers/tty.h"
#define PANIC(msg) panic(msg, __FILE__, __LINE__);
#define ASSERT(b) ((b) ? (void)0 : panic_assert(__FILE__, __LINE__, #b))
extern void panic(const char *message, const char *file, uint32_t line);
extern void panic_assert(const char *file, uint32_t line, const char *desc);
#endif

View File

@@ -1,59 +1,59 @@
#include "stdio.h"
#include "string.h"
#include "../drivers/tty.h"
int printf(const char *format, ...) {
uint8_t buf[20],c,*s;
int val;
int32_t uval;
va_list ap;
va_start(ap, format);
for(size_t i = 0; i < strlen((uint8_t*)format); i++) {
if(format[i] == '%') {
i++;
while(format[i] == ' ')
i++;
switch(format[i]) {
case 'i':
val = va_arg(ap, int);
itoa(val, buf, 10);
kprint(buf);
break;
case 'x':
uval = va_arg(ap, uint32_t);
uitoa(uval, buf, 16);
kprint(buf);
break;
case 'd':
uval = va_arg(ap, uint32_t);
uitoa(uval, buf, 10);
kprint(buf);
break;
case 'c':
c = (uint8_t)va_arg(ap, uint32_t);
kprint_c(&c, 1, WHITE, BLACK);
break;
case 's':
s = va_arg(ap, uint8_t*);
kprint(s);
break;
default:
kprint_c((uint8_t*)format+i, 1, WHITE, BLACK);
}
} else
kprint_c((uint8_t*)format+i, 1, WHITE, BLACK);
}
va_end(ap);
return 0;
}
int printf_color(const char *format, uint8_t fg, uint8_t bg) {
kprint_c((uint8_t*)format, strlen((uint8_t*)format), fg, bg);
return 0;
}
void puts(const char *buf) {
printf("%s\n", buf);
}
#include "stdio.h"
#include "string.h"
#include "../drivers/tty.h"
int printf(const char *format, ...) {
uint8_t buf[20],c,*s;
int val;
int32_t uval;
va_list ap;
va_start(ap, format);
for(size_t i = 0; i < strlen((uint8_t*)format); i++) {
if(format[i] == '%') {
i++;
while(format[i] == ' ')
i++;
switch(format[i]) {
case 'i':
val = va_arg(ap, int);
itoa(val, buf, 10);
kprint(buf);
break;
case 'x':
uval = va_arg(ap, uint32_t);
uitoa(uval, buf, 16);
kprint(buf);
break;
case 'd':
uval = va_arg(ap, uint32_t);
uitoa(uval, buf, 10);
kprint(buf);
break;
case 'c':
c = (uint8_t)va_arg(ap, uint32_t);
kprint_c(&c, 1, WHITE, BLACK);
break;
case 's':
s = va_arg(ap, uint8_t*);
kprint(s);
break;
default:
kprint_c((uint8_t*)format+i, 1, WHITE, BLACK);
}
} else
kprint_c((uint8_t*)format+i, 1, WHITE, BLACK);
}
va_end(ap);
return 0;
}
int printf_color(const char *format, uint8_t fg, uint8_t bg) {
kprint_c((uint8_t*)format, strlen((uint8_t*)format), fg, bg);
return 0;
}
void puts(const char *buf) {
printf("%s\n", buf);
}

View File

@@ -1,19 +1,19 @@
/**************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/iceOS *
***************************************/
#ifndef _STDIO_H_
#define _STDIO_H_
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
int printf(const char *format, ...);
int printf_color(const char *format, uint8_t fg, uint8_t bg); // Only for string for now
void puts(const char *buf);
#endif
/*****************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/vulcanos *
*****************************************/
#ifndef _STDIO_H_
#define _STDIO_H_
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
int printf(const char *format, ...);
int printf_color(const char *format, uint8_t fg, uint8_t bg); // Only for string for now
void puts(const char *buf);
#endif

View File

@@ -1,150 +1,150 @@
#include "string.h"
// C library implementation
int32_t strcmp(const uint8_t *s1, const uint8_t *s2) {
while ((*s1) && (*s1 == *s2)) {
s1++;
s2++;
}
return (*(uint8_t*)s1 - *(uint8_t*)s2);
}
uint8_t *itoa(int32_t val, uint8_t *buf, uint32_t radix) {
uint32_t i = 0;
uint32_t start = i;
if(val < 0 && radix == 10) {
buf[i++] = '-';
start = i;
}
if(radix == 10) {
buf[i++] = '0';
buf[i++] = 'x';
start = i;
}
int x = val;
do {
int a = x % radix;
if(a < 10)
buf[i++] = a + '0';
else
buf[i++]= a + 'a' - 10;
} while(x /= radix);
uint8_t *s = buf+start;
uint8_t *e = buf+(i-1);
while(s < e) {
uint8_t t = *s;
*s = *e;
*e = t;
i++;
e--;
}
buf[i] = 0;
return buf;
}
uint8_t *uitoa(uint32_t val, uint8_t *buf, uint32_t radix) {
uint32_t i = 0;
uint32_t start = i;
uint32_t x = val;
if(radix == 16) {
buf[i++] = '0';
buf[i++] = 'x';
start = i;
}
do {
uint32_t a = x % radix;
if(a < 10)
buf[i++] = a + '0';
else
buf[i++] = a + 'a' - 10;
} while(x /= radix);
uint8_t *s = buf+start;
uint8_t *e = buf+(i-1);
while(s < e) {
uint8_t t = *s;
*s = *e;
*e = t;
s++;
e--;
}
buf[i] = 0;
return buf;
}
size_t strlen(const uint8_t *buf) {
uint32_t i = 0;
while(buf[i] != 0)
i++;
return i;
}
uint8_t *strcpy(uint8_t *dst, const uint8_t *src) {
uint8_t *dst_p = dst;
while((*dst++ = *src++));
return dst_p;
}
void strcat(void *dest, const void *src) {
uint8_t *end = (uint8_t*)dest + strlen(dest);
memcpy((uint8_t*)end, (uint8_t*)src, strlen((uint8_t*)src));
end += strlen((uint8_t*)src);
*end = '\0';
}
/* Worst memset implementation
* i could find on the net.
* however it works so... */
void *memset(void *s, uint32_t c, size_t n) {
char *mem = (char*)s;
for(size_t i = 0; i < n; i++)
mem[i] = (uint8_t)c;
return s;
}
void *memcpy(void *dst, void const *src, uint32_t n) {
uint8_t *ret = dst;
uint8_t *p = dst;
const uint8_t *q = src;
while(n--)
*p++ = *q++;
return ret;
}
void *memmove(void *dst, const void *src, size_t len) {
char *dstmem = (char*)dst;
char *srcmem = (char*)src;
for(size_t i = 0; i < len; i++)
dstmem[i] = srcmem[i];
return dstmem;
}
void strupper(uint8_t *str) {
for(unsigned int i = 0; i < strlen(str); i++) {
if(str[i] == 'a' && str[i] < 'z')
str[i] &= 0x4F;
}
}
void strlower(uint8_t *str) {
for(unsigned int i = 0; i < strlen(str); i++) {
if(str[i] == 'A' && str[i] < 'Z')
str[i] |= 0x60;
}
}
#include "string.h"
// C library implementation
int32_t strcmp(const uint8_t *s1, const uint8_t *s2) {
while ((*s1) && (*s1 == *s2)) {
s1++;
s2++;
}
return (*(uint8_t*)s1 - *(uint8_t*)s2);
}
uint8_t *itoa(int32_t val, uint8_t *buf, uint32_t radix) {
uint32_t i = 0;
uint32_t start = i;
if(val < 0 && radix == 10) {
buf[i++] = '-';
start = i;
}
if(radix == 10) {
buf[i++] = '0';
buf[i++] = 'x';
start = i;
}
int x = val;
do {
int a = x % radix;
if(a < 10)
buf[i++] = a + '0';
else
buf[i++]= a + 'a' - 10;
} while(x /= radix);
uint8_t *s = buf+start;
uint8_t *e = buf+(i-1);
while(s < e) {
uint8_t t = *s;
*s = *e;
*e = t;
i++;
e--;
}
buf[i] = 0;
return buf;
}
uint8_t *uitoa(uint32_t val, uint8_t *buf, uint32_t radix) {
uint32_t i = 0;
uint32_t start = i;
uint32_t x = val;
if(radix == 16) {
buf[i++] = '0';
buf[i++] = 'x';
start = i;
}
do {
uint32_t a = x % radix;
if(a < 10)
buf[i++] = a + '0';
else
buf[i++] = a + 'a' - 10;
} while(x /= radix);
uint8_t *s = buf+start;
uint8_t *e = buf+(i-1);
while(s < e) {
uint8_t t = *s;
*s = *e;
*e = t;
s++;
e--;
}
buf[i] = 0;
return buf;
}
size_t strlen(const uint8_t *buf) {
uint32_t i = 0;
while(buf[i] != 0)
i++;
return i;
}
uint8_t *strcpy(uint8_t *dst, const uint8_t *src) {
uint8_t *dst_p = dst;
while((*dst++ = *src++));
return dst_p;
}
void strcat(void *dest, const void *src) {
uint8_t *end = (uint8_t*)dest + strlen(dest);
memcpy((uint8_t*)end, (uint8_t*)src, strlen((uint8_t*)src));
end += strlen((uint8_t*)src);
*end = '\0';
}
/* Worst memset implementation
* i could find on the net.
* however it works so... */
void *memset(void *s, uint32_t c, size_t n) {
char *mem = (char*)s;
for(size_t i = 0; i < n; i++)
mem[i] = (uint8_t)c;
return s;
}
void *memcpy(void *dst, void const *src, uint32_t n) {
uint8_t *ret = dst;
uint8_t *p = dst;
const uint8_t *q = src;
while(n--)
*p++ = *q++;
return ret;
}
void *memmove(void *dst, const void *src, size_t len) {
char *dstmem = (char*)dst;
char *srcmem = (char*)src;
for(size_t i = 0; i < len; i++)
dstmem[i] = srcmem[i];
return dstmem;
}
void strupper(uint8_t *str) {
for(unsigned int i = 0; i < strlen(str); i++) {
if(str[i] == 'a' && str[i] < 'z')
str[i] &= 0x4F;
}
}
void strlower(uint8_t *str) {
for(unsigned int i = 0; i < strlen(str); i++) {
if(str[i] == 'A' && str[i] < 'Z')
str[i] |= 0x60;
}
}

View File

@@ -1,26 +1,26 @@
/**************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/iceOS *
***************************************/
#ifndef _STRING_H_
#define _STRING_H_
#include <stdint.h> // For uinx_t
#include <stddef.h> // For size_t
int32_t strcmp(const uint8_t *s1, const uint8_t *s2);
uint8_t *itoa(int32_t val, uint8_t *buf, uint32_t radix);
uint8_t *uitoa(uint32_t val, uint8_t *buf, uint32_t radix);
size_t strlen(const uint8_t *buf);
uint8_t *strcpy(uint8_t *dst, const uint8_t *src);
void strcat(void *dest, const void *src);
void *memset(void *s, uint32_t c, size_t n);
void *memmove(void *dst, const void *src, size_t len);
void *memcpy(void *dst, void const *src, uint32_t n);
void strupper(uint8_t *str);
void strlower(uint8_t *str);
#endif
/*****************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/vulcanos *
*****************************************/
#ifndef _STRING_H_
#define _STRING_H_
#include <stdint.h> // For uinx_t
#include <stddef.h> // For size_t
int32_t strcmp(const uint8_t *s1, const uint8_t *s2);
uint8_t *itoa(int32_t val, uint8_t *buf, uint32_t radix);
uint8_t *uitoa(uint32_t val, uint8_t *buf, uint32_t radix);
size_t strlen(const uint8_t *buf);
uint8_t *strcpy(uint8_t *dst, const uint8_t *src);
void strcat(void *dest, const void *src);
void *memset(void *s, uint32_t c, size_t n);
void *memmove(void *dst, const void *src, size_t len);
void *memcpy(void *dst, void const *src, uint32_t n);
void strupper(uint8_t *str);
void strlower(uint8_t *str);
#endif

View File

@@ -1,38 +1,38 @@
#include "time.h"
#include "../drivers/ports.h"
// Check whether CMOS is updated or not
static uint8_t is_cmos_updated() {
outb(CMOS_ADDRESS, 0x0A);
return (inb(CMOS_DATA) & 0x80);
}
// Get CMOS register's status
static uint8_t reg_status(int32_t reg) {
outb(CMOS_ADDRESS, reg);
return inb(CMOS_DATA);
}
time_t cmos_reader() {
while(is_cmos_updated()); // Wait until the CMOS is being updated
time_t tm;
tm.second = BCD_CONVERTER(reg_status(TIME_R_SECOND));
tm.minute = BCD_CONVERTER(reg_status(TIME_R_MINUTE));
tm.hour = BCD_CONVERTER(reg_status(TIME_R_HOUR));
tm.day = BCD_CONVERTER(reg_status(TIME_R_DAY));
tm.month = BCD_CONVERTER(reg_status(TIME_R_MONTH));
tm.year = BCD_CONVERTER(reg_status(TIME_R_YEAR));
return tm;
}
uint32_t get_time(uint32_t field) {
while(is_cmos_updated()); // Wait the CMOS is being updated
return BCD_CONVERTER(reg_status(field));
}
#include "time.h"
#include "../drivers/ports.h"
// Check whether CMOS is updated or not
static uint8_t is_cmos_updated() {
outb(CMOS_ADDRESS, 0x0A);
return (inb(CMOS_DATA) & 0x80);
}
// Get CMOS register's status
static uint8_t reg_status(int32_t reg) {
outb(CMOS_ADDRESS, reg);
return inb(CMOS_DATA);
}
time_t cmos_reader() {
while(is_cmos_updated()); // Wait until the CMOS is being updated
time_t tm;
tm.second = BCD_CONVERTER(reg_status(TIME_R_SECOND));
tm.minute = BCD_CONVERTER(reg_status(TIME_R_MINUTE));
tm.hour = BCD_CONVERTER(reg_status(TIME_R_HOUR));
tm.day = BCD_CONVERTER(reg_status(TIME_R_DAY));
tm.month = BCD_CONVERTER(reg_status(TIME_R_MONTH));
tm.year = BCD_CONVERTER(reg_status(TIME_R_YEAR));
return tm;
}
uint32_t get_time(uint32_t field) {
while(is_cmos_updated()); // Wait the CMOS is being updated
return BCD_CONVERTER(reg_status(field));
}

View File

@@ -1,42 +1,42 @@
/**************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/iceOS *
***************************************/
/* Get time reading the RTC(real time clock) CMOS on the motherboard */
#ifndef TIME_H
#define TIME_H
#include <stdint.h>
// Define RTC field registers
#define TIME_R_YEAR 0x09
#define TIME_R_MONTH 0x08
#define TIME_R_DAY 0x07
#define TIME_R_HOUR 0x06
#define TIME_R_MINUTE 0x05
#define TIME_R_SECOND 0x04
//#define TIME_R_CENTURY 0x32
// Define RTC address
#define CMOS_ADDRESS 0x70
#define CMOS_DATA 0x71
// Convert BCD encoed values to binary
#define BCD_CONVERTER(n) ((n / 16) * 10 + (n & 0xF))
typedef struct {
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t month;
uint8_t year;
} time_t;
time_t cmos_reader();
uint32_t get_time(uint32_t field);
#endif
/*****************************************
* VulcanOS Kernel *
* Developed by Marco 'icebit' Cetica *
* (c) 2019-2021 *
* Released under GPLv3 *
* https://github.com/ice-bit/vulcanos *
*****************************************/
/* Get time reading the RTC(real time clock) CMOS on the motherboard */
#ifndef TIME_H
#define TIME_H
#include <stdint.h>
// Define RTC field registers
#define TIME_R_YEAR 0x09
#define TIME_R_MONTH 0x08
#define TIME_R_DAY 0x07
#define TIME_R_HOUR 0x06
#define TIME_R_MINUTE 0x05
#define TIME_R_SECOND 0x04
//#define TIME_R_CENTURY 0x32
// Define RTC address
#define CMOS_ADDRESS 0x70
#define CMOS_DATA 0x71
// Convert BCD encoed values to binary
#define BCD_CONVERTER(n) ((n / 16) * 10 + (n & 0xF))
typedef struct {
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t month;
uint8_t year;
} time_t;
time_t cmos_reader();
uint32_t get_time(uint32_t field);
#endif