CRT library stuff

This commit is contained in:
Julian Barathieu 2019-01-19 22:36:38 +01:00
parent 2bf7929ce2
commit 98c2dd8502
15 changed files with 245 additions and 113 deletions

View File

@ -123,6 +123,7 @@ load_root:
mov di, BUFFER_OFF ; Set es:di to the disk buffer mov di, BUFFER_OFF ; Set es:di to the disk buffer
mov cx, word [rootDirEntries] ; Search through all of the root dir entries mov cx, word [rootDirEntries] ; Search through all of the root dir entries
xor ax, ax ; Clear ax for the file entry offset xor ax, ax ; Clear ax for the file entry offset
search_root: search_root:
xchg cx, dx ; Save cx because it's a loop counter xchg cx, dx ; Save cx because it's a loop counter
mov si, filename ; Load the filename mov si, filename ; Load the filename

View File

@ -101,7 +101,7 @@ read_sectors:
shl ah, 1 shl ah, 1
or cl, ah ; Now cx is set with respective track and sector numbers or cl, ah ; Now cx is set with respective track and sector numbers
mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h
mov di, 21 ; Try five times to read the sector because i love 21 mov di, 21 ; Try five times to read the sector because I love 21
.attempt_read: .attempt_read:
mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector
int 0x13 ; Call int 13h (BIOS disk I/O) int 0x13 ; Call int 13h (BIOS disk I/O)

View File

@ -10,59 +10,89 @@
#include <kaleid.h> #include <kaleid.h>
// //
// Digits table for bases <=36 // Digits table for bases <=36 (unused)
// //
static const char digits[] = static const char digits[] =
"0123456789abcdefghijklmnopqrstuvwxyz"; "0123456789abcdefghijklmnopqrstuvwxyz";
// //
// Integer to string in any base between 2 and 36 (included) // Integer to string in any base between 2 and 36 (included)
// //
#if defined(_NEED_ITOA) #if defined(_NEED_ITOA)
char *itoa(int i, char *str, int base) char *itoa(int i, char *str, int base)
#define _IL_MIN INT_MIN
#define _IL_MIN_STRING "-2147483648"
#elif defined(_NEED_LTOA) #elif defined(_NEED_LTOA)
char *ltoa(long i, char *str, int base) char *ltoa(long i, char *str, int base)
#define _IL_MIN LONG_MIN
#define _IL_MIN_STRING "-9223372036854775808"
#elif defined(_NEED_UTOA) #elif defined(_NEED_UTOA)
char *utoa(uint i, char *str, int base) char *utoa(uint i, char *str, int base)
#elif defined(_NEED_ULTOA) #elif defined(_NEED_ULTOA)
char *ultoa(ulong i, char *str, int base) char *ultoa(ulong i, char *str, int base)
#else #else
#error "What am I supposed to declare?" #error "What am I supposed to declare?"
#endif #endif
{ {
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
int neg = 0;
#endif
char *orig = str; char *orig = str;
//
// Only handle base 2 -> 36
//
if (base < 2 || base > 36)
return NULL;
#if defined(_NEED_ITOA) || defined(_NEED_LTOA) #if defined(_NEED_ITOA) || defined(_NEED_LTOA)
// //
// Deal with negatives // Deal with negatives
// //
if (i < 0) { int neg = 0;
neg = 1; if (i < 0 && base == 10) {
i = -i; //
// Handle INT_MIN and LONG_MIN...
//
if (__builtin_expect(i == _IL_MIN, 0)) {
strcpy(orig, _IL_MIN_STRING);
goto leave;
}
else {
neg = 1;
i = -i;
}
} }
#endif #endif
//
// Only handle base 2 -> 36
//
if (base < 2 || base > 36) {
__set_errno(EINVAL);
*orig = '\0;
goto leave;
}
// //
// Deal with zero separately // Deal with zero separately
// //
if (i == 0) { if (i == 0) {
*str++ = '0'; *str++ = '0';
*str = '\0';
goto leave;
} }
// //
// Compute digits... in reverse order // Compute digits... in reverse order
// //
while (i > 0) { while (i > 0) {
*str++ = digits[i % base]; rem = i % base;
*str++ = (rem > 9)
? (rem - 10) + 'a'
: rem + '0';
i /= base; i /= base;
} }
@ -75,7 +105,13 @@ char *ultoa(ulong i, char *str, int base)
// //
// Reverse the string // Reverse the string
// //
return strrev2(orig); orig = strrev2(orig);
//
// End of conversion
//
leave:
return orig;
} }

View File

@ -58,7 +58,7 @@ void *memset(void *ptr, int val, size_t bytes)
} }
// //
// Set "words"-many words starting from ptr to val // Set "words"-many words starting from ptr to val
// //
void *memsetw(void *ptr, int val, size_t words) void *memsetw(void *ptr, int val, size_t words)
{ {
@ -99,8 +99,8 @@ void *memsetw(void *ptr, int val, size_t words)
} }
// //
// Set "dwords"-many dwords starting from ptr to val // Set "dwords"-many dwords starting from ptr to val
// XXX unimplemented // XXX unimplemented
// //
void *memsetd(void *ptr, int val, size_t dwords) void *memsetd(void *ptr, int val, size_t dwords)
{ {
@ -111,7 +111,7 @@ void *memsetd(void *ptr, int val, size_t dwords)
} }
// //
// Set "qwords"-many qwords starting from ptr to val // Set "qwords"-many qwords starting from ptr to val
// //
void *memsetq(void *ptr, long val, size_t qwords) void *memsetq(void *ptr, long val, size_t qwords)
{ {
@ -130,7 +130,7 @@ void *memsetq(void *ptr, long val, size_t qwords)
//------------------------------------------// //------------------------------------------//
// //
// Set "bytes"-many bytes starting from ptr to 0 // Set "bytes"-many bytes starting from ptr to 0
// //
void *memzero(void *ptr, size_t bytes) void *memzero(void *ptr, size_t bytes)
{ {
@ -138,8 +138,8 @@ void *memzero(void *ptr, size_t bytes)
} }
// //
// Copy "bytes"-many bytes of src to dst // Copy "bytes"-many bytes of src to dst
// Does not deal with overlapping blocks (memmove's job) // Does not deal with overlapping blocks (memmove's job)
// //
void *memcpy(void *restrict dst, const void *restrict src, size_t bytes) void *memcpy(void *restrict dst, const void *restrict src, size_t bytes)
{ {
@ -203,7 +203,7 @@ void *memcpy(void *restrict dst, const void *restrict src, size_t bytes)
} }
// //
// Move memory from src to dest, even if they overlap // Move memory from src to dest, even if they overlap
// //
void *memmove(void *dst, const void *src, size_t bytes) void *memmove(void *dst, const void *src, size_t bytes)
{ {
@ -228,7 +228,7 @@ void *memmove(void *dst, const void *src, size_t bytes)
} }
// //
// Compare memory areas // Compare memory areas
// //
int memcmp(const void *ptr1, const void *ptr2, size_t bytes) int memcmp(const void *ptr1, const void *ptr2, size_t bytes)
{ {

View File

@ -235,7 +235,7 @@ char *strncpy(char *restrict dest, const char *restrict src, size_t n)
// Returns TRUE if dest would have been null-terminated // Returns TRUE if dest would have been null-terminated
// by ordinary strncpy(), and FALSE otherwise // by ordinary strncpy(), and FALSE otherwise
// //
int xstrncpy(char *restrict dest, const char *restrict src, size_t n) int strnzcpy(char *restrict dest, const char *restrict src, size_t n)
{ {
size_t it; size_t it;
@ -243,9 +243,7 @@ int xstrncpy(char *restrict dest, const char *restrict src, size_t n)
dest[it] = src[it]; dest[it] = src[it];
} }
//
// Was the copy complete? // Was the copy complete?
//
if (it == n) { if (it == n) {
if (dest[n] == 0) { if (dest[n] == 0) {
return TRUE; return TRUE;
@ -261,11 +259,63 @@ int xstrncpy(char *restrict dest, const char *restrict src, size_t n)
} }
// //
// XXX strcat family // Appends a copy of src at the end of dest
// //
char *strcat (char *restrict, const char *restrict); char *strcat(char *restrict dest, const char *restrict src)
char *strncat (char *restrict, const char *restrict, size_t); {
int *xstrncat(char *restrict, const char *restrict, size_t); char *base = dest;
while (*dest) dest++;
while ((*dest++ = *src++));
return base;
}
//
// Appends a copy of at most n bytes of src at the end of dest
//
char *strncat(char *restrict dest, const char *restrict src, size_t n)
{
size_t it, off = 0;
while (dest[off]) off++;
for (it = 0; it < n && src[it]; it++) {
dest[it+off] = src[it];
}
while (it++ < n) dest[it+off] = 0;
return dest;
}
//
// Appends a copy of at most n bytes of src at the end of dest
// Always null-terminates, and returne TRUE or FALSE depending on whether
// regular strcat() would have null-terminated this string, or not
//
int *strnzcat(char *restrict dest, const char *restrict src, size_t n)
{
size_t it, off = 0;
while (dest[off]) off++;
for (it = 0; it < n - 1 && src[it]; it++) {
dest[it+off] = src[it];
}
// Was the copy complete?
if (it == n) {
if (dest[n+off] == 0) {
return TRUE;
}
dest[n+off] = 0;
return FALSE;
}
while (it++ < n) dest[it+off] = 0;
return TRUE;
}
// //
// Reverses the string src, putting the result into dest // Reverses the string src, putting the result into dest

View File

@ -143,11 +143,11 @@ char *strtok_r(char *restrict, const char *restrict, char **restrict);
char *strcpy (char *restrict, const char *restrict); char *strcpy (char *restrict, const char *restrict);
char *strncpy (char *restrict, const char *restrict, size_t); char *strncpy (char *restrict, const char *restrict, size_t);
int xstrncpy(char *restrict, const char *restrict, size_t); int strnzcpy(char *restrict, const char *restrict, size_t);
char *strcat (char *restrict, const char *restrict); char *strcat (char *restrict, const char *restrict);
char *strncat (char *restrict, const char *restrict, size_t); char *strncat (char *restrict, const char *restrict, size_t);
int *xstrncat(char *restrict, const char *restrict, size_t); int *strnzcat(char *restrict, const char *restrict, size_t);
char *strrev(char *restrict, const char *restrict); char *strrev(char *restrict, const char *restrict);
char *strrev2(char *); char *strrev2(char *);

View File

@ -23,11 +23,7 @@
#endif #endif
#ifndef NULL #ifndef NULL
#define NULL ((void *)0) #define NULL 0L
#endif
#ifndef INITOK
#define INITOK ((unsigned int)0xCAFEBABE)
#endif #endif
//------------------------------------------// //------------------------------------------//
@ -61,8 +57,8 @@
// Attributes and macros // // Attributes and macros //
//------------------------------------------// //------------------------------------------//
#ifndef PACKED #ifndef _PACKED
#define PACKED __attribute__((__packed__)) #define _PACKED __attribute__((__packed__))
#endif #endif
#ifndef noreturn #ifndef noreturn
@ -77,6 +73,14 @@
#define unlikely(x) (__builtin_expect((x), 0)) #define unlikely(x) (__builtin_expect((x), 0))
#endif #endif
#ifndef _STR
#define _STR(x) #x
#endif
#ifndef _XSTR
#define _XSTR(x) _STR(x)
#endif
//------------------------------------------// //------------------------------------------//
// API specific macros // // API specific macros //
//------------------------------------------// //------------------------------------------//

View File

@ -11,7 +11,7 @@
#define _KALERROR_H #define _KALERROR_H
//------------------------------------------// //------------------------------------------//
// Preprocessor constants // // "errno" values //
//------------------------------------------// //------------------------------------------//
// Everything went fine // Everything went fine

View File

@ -204,7 +204,7 @@ static inline ListHead_t
} }
// //
// Remove node of list // Remove node of list (and frees it)
// //
static inline ListHead_t static inline ListHead_t
*RemoveNode(ListHead_t *head, ListNode_t *node) *RemoveNode(ListHead_t *head, ListNode_t *node)

View File

@ -51,11 +51,11 @@
#define strcpy _osk_strcpy #define strcpy _osk_strcpy
#define strncpy _osk_strncpy #define strncpy _osk_strncpy
#define xstrncpy _osk_xstrncpy #define strnzcpy _osk_strnzcpy
#define strcat _osk_strcat #define strcat _osk_strcat
#define strncat _osk_strncat #define strncat _osk_strncat
#define xstrncat _osk_xstrncat #define strnzcat _osk_strnzcat
#define strrev _osk_strrev #define strrev _osk_strrev
#define strrev2 _osk_strrev2 #define strrev2 _osk_strrev2
@ -105,7 +105,7 @@
//------------------------------------------// //------------------------------------------//
#define strerror _osk_strerror #define strerror _osk_strerror
//------------------------------------------// //------------------------------------------//
// End of header // // End of header //

View File

@ -59,6 +59,11 @@ typedef enum {
// Multiprocessor misc. // // Multiprocessor misc. //
//------------------------------------------// //------------------------------------------//
#ifndef INITOK
#define INITOK ((unsigned int)0xCAFEBABE)
#endif
#ifndef NCPU #ifndef NCPU
#define NCPU 4 #define NCPU 4
#endif #endif
@ -108,12 +113,6 @@ DECLARE_PER_CPU(CurThread, Thread_t *);
// global constants // // global constants //
//------------------------------------------// //------------------------------------------//
#define SetPanicStr(str) \
do { \
SetKernState(KSTATE_PANIC); \
_SetPanicStr(str); \
} while (0)
#define SetKernState(x) \ #define SetKernState(x) \
do { \ do { \
_SetKernState(x); \ _SetKernState(x); \
@ -184,7 +183,6 @@ void WriteByteOnPort(port_t port, port_t val)
static inline static inline
uchar ReadByteFromPort(port_t port) uchar ReadByteFromPort(port_t port)
{ {
KalAssert(FALSE && ENOSYS); KalAssert(FALSE && ENOSYS);
(void)port; (void)port;
return 0; return 0;

View File

@ -70,11 +70,15 @@ typedef struct sLock_t {
//------------------------------------------// //------------------------------------------//
// //
// Linux syscall... // Linux syscall vs unimplemented syscall...
// //
#ifndef _KALEID_KERNEL #ifndef _KALEID_KERNEL
#ifdef _OSK_SOURCE
int KalYieldCPU(void),
#else
int sched_yield(void); int sched_yield(void);
#endif #endif
#endif
// //
// Initialize a lock // Initialize a lock
@ -127,7 +131,11 @@ void AquireLock(Lock_t *lock)
StartPanic("AquireLock on an already locked object"); StartPanic("AquireLock on an already locked object");
#else #else
if likely (lock->type == KLOCK_SPINLOCK) continue; if likely (lock->type == KLOCK_SPINLOCK) continue;
#ifdef _OSK_SOURCE
else KalYieldCPU();
#else
else sched_yield(); else sched_yield();
#endif
#endif #endif
} }
__sync_synchronize(); __sync_synchronize();

View File

@ -30,9 +30,10 @@
// Preprocessor // // Preprocessor //
//------------------------------------------// //------------------------------------------//
//
// Debug stuff
//
#define printdbg printf #define printdbg printf
#define _STR(x) #x
#define _XSTR(x) _STR(x)
// //
// States for a process // States for a process
@ -56,6 +57,8 @@ DECLARE_PER_CPU(ReglPrioProcs, ListHead_t *);
DECLARE_PER_CPU(ServPrioProcs, ListHead_t *); DECLARE_PER_CPU(ServPrioProcs, ListHead_t *);
DECLARE_PER_CPU(TimeCritProcs, ListHead_t *); DECLARE_PER_CPU(TimeCritProcs, ListHead_t *);
extern const char *PrioClassesNames[];
//------------------------------------------// //------------------------------------------//
// Data types // // Data types //
//------------------------------------------// //------------------------------------------//
@ -63,7 +66,7 @@ DECLARE_PER_CPU(TimeCritProcs, ListHead_t *);
// //
// A process // A process
// //
typedef struct sProcess_t{ typedef struct sProcess_t {
// Identifier // Identifier
int pid; int pid;
@ -94,6 +97,16 @@ typedef struct sProcess_t{
} Process_t; } Process_t;
//------------------------------------------//
// Functions //
//------------------------------------------//
void SchedInit(void);
void SchedFini(void);
void SchedThisProc(Process_t *);
void SchedOnTick(void);
//------------------------------------------// //------------------------------------------//
// End of header // // End of header //
//------------------------------------------// //------------------------------------------//

View File

@ -34,6 +34,7 @@ noreturn void StartPanic(const char *str)
{ {
DisableIRQs(); DisableIRQs();
// This should be made atomic
SetKernState(KSTATE_PANIC); SetKernState(KSTATE_PANIC);
if (GetCurProc()) __CurProc[GetCurCPU()] = NULL; if (GetCurProc()) __CurProc[GetCurCPU()] = NULL;
@ -46,11 +47,11 @@ noreturn void StartPanic(const char *str)
} }
if (GetPanicStr()) { if (GetPanicStr()) {
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "double panic!\n"); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nDouble panic!\n");
HaltCPU(); HaltCPU();
} }
SetPanicStr(str); _SetPanicStr(str);
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - "); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - ");
GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str);

View File

@ -66,12 +66,13 @@ void SchedUnlock(void) {
// //
// The four priority classes of OS/2 // The four priority classes of OS/2
// //
CREATE_PER_CPU(IdlePrioProcs, ListHead_t *); CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);
CREATE_PER_CPU(ReglPrioProcs, ListHead_t *); CREATE_PER_CPU(ReglPrioProcs, ListHead_t *);
CREATE_PER_CPU(ServPrioProcs, ListHead_t *); CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
CREATE_PER_CPU(TimeCritProcs, ListHead_t *); CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
char *PrioClassesNames[] = { const char *PrioClassesNames[] = {
"Idle priority class", "Idle priority class",
"Regular priority class", "Regular priority class",
"Server priority class", "Server priority class",
@ -203,47 +204,55 @@ void BlockCurProc(void)
SetCurProc(SelectSchedNext()); SetCurProc(SelectSchedNext());
} }
static inline
void ReSchedCurProc(void)
{
KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING);
// Restore default attributes, cancelling boosts
GetCurProc()->prioClass = GetCurProc()->defPrioClass;
GetCurProc()->prioLevel = GetCurProc()->defPrioLevel;
GetCurProc()->timeSlice = GetCurProc()->defTimeSlice;
GetCurProc()->procState = STATE_RUNNABLE;
// Remove from list
RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode);
GetCurProc()->schedNode = NULL;
// Schedule again, with default attributes now
SchedThisProcUnlocked(GetCurProc());
}
// //
// Should we schedule another process? // Should we schedule another process?
// Called at each tick // Called at each tick
// //
void SchedOnTick(void) void SchedOnTick(void)
{ {
Process_t *procNext;
Process_t *winner;
SchedLock(); SchedLock();
Process_t *procNext, *winner, *previous = GetCurProc();
// //
// We're either idle or running something // We're either idle or running something
// //
KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING); KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING);
// //
// Has current process spent his timeslice? // Have the current process spent its timeslice?
// (To be handled in CPU decisions function) // (To be handled in CPU decisions function)
// //
if (GetCurProc() != NULL) { if (GetCurProc() != NULL) {
if (GetCurProc()->timeSlice <= 1) { if (GetCurProc()->timeSlice <= 1) {
// Re-schedule
ReSchedCurProc();
// Restore default attributes, cancelling boosts // See next 'if' statement
GetCurProc()->prioClass = GetCurProc()->defPrioClass; _SetCurProc(NULL);
GetCurProc()->prioLevel = GetCurProc()->defPrioLevel;
GetCurProc()->timeSlice = GetCurProc()->defTimeSlice;
GetCurProc()->procState = STATE_RUNNABLE;
// Remove from list
RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode);
// Schedule again, with default attributes now
SchedThisProcUnlocked(GetCurProc());
// Mark as idle
SetCurProc(NULL);
} }
// //
// Otherwise, make him lose a tick // Otherwise, make it lose a tick
// //
else { else {
GetCurProc()->timeSlice--; GetCurProc()->timeSlice--;
@ -268,8 +277,10 @@ void SchedOnTick(void)
// Yes, procNext should preempt current process // Yes, procNext should preempt current process
// //
if (winner == procNext) { if (winner == procNext) {
GetCurProc()->procState = STATE_RUNNABLE; // Re-schedule
SchedThisProcUnlocked(GetCurProc()); ReSchedCurProc();
// Switch to procNext
SetCurProc(procNext); SetCurProc(procNext);
} }
@ -278,32 +289,10 @@ void SchedOnTick(void)
// //
leave: leave:
SchedUnlock(); SchedUnlock();
}
#define PrintProc(proc) printdbg("{ %d, '%s', %d , %d}\n", (proc)->pid, \ if (GetCurProc() != NULL && GetCurProc() != previous) {
PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice); // XXX context switch
//
// Print out process list
//
void PrintList(ListHead_t *head)
{
KalAssert(head);
Process_t *proc;
ListNode_t *node = head->first;
printdbg("len: %d\n", head->length);
while (node) {
proc = GetNodeData(node, Process_t *);
PrintProc(proc);
node = node->next;
} }
puts("");
} }
// //
@ -355,6 +344,33 @@ void FiniSched(void)
} }
#ifndef _KALEID_KERNEL #ifndef _KALEID_KERNEL
#define PrintProc(proc) printdbg("{ %d, '%s', %d , %d}\n", (proc)->pid, \
PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice);
//
// Print out process list
//
void PrintList(ListHead_t *head)
{
KalAssert(head);
Process_t *proc;
ListNode_t *node = head->first;
printdbg("len: %d\n", head->length);
while (node) {
proc = GetNodeData(node, Process_t *);
PrintProc(proc);
node = node->next;
}
puts("");
}
int main(void) int main(void)
{ {
InitSched(); InitSched();
@ -379,7 +395,17 @@ int main(void)
int tick = 0; int tick = 0;
while (tick < 20) { while (tick < 120) {
if (tick > 0 && tick != 50 && tick % 10 == 0) {
puts("Blocking current process");
BlockCurProc();
}
if (tick == 50) {
procs[2].procState = STATE_RUNNABLE;
SchedThisProc(&procs[2]);
}
printf("Tick %d - Running: ", tick); printf("Tick %d - Running: ", tick);
if (GetCurProc() == NULL) { if (GetCurProc() == NULL) {
@ -390,14 +416,8 @@ int main(void)
PrintProc(GetCurProc()); PrintProc(GetCurProc());
} }
if (tick == 9 || tick == 14) {
puts("Blocking current process");
BlockCurProc();
}
SchedOnTick(); SchedOnTick();
//puts("\n---------------");
tick++; tick++;
} }
@ -405,5 +425,6 @@ int main(void)
return 0; return 0;
} }
#endif #endif