diff --git a/boot/mbr/mbr.asm b/boot/mbr/mbr.asm index 42f0dbd..f94c713 100644 --- a/boot/mbr/mbr.asm +++ b/boot/mbr/mbr.asm @@ -123,6 +123,7 @@ load_root: mov di, BUFFER_OFF ; Set es:di to the disk buffer mov cx, word [rootDirEntries] ; Search through all of the root dir entries xor ax, ax ; Clear ax for the file entry offset + search_root: xchg cx, dx ; Save cx because it's a loop counter mov si, filename ; Load the filename diff --git a/boot/mbr/mbr.inc b/boot/mbr/mbr.inc index dc11db1..a5f396d 100644 --- a/boot/mbr/mbr.inc +++ b/boot/mbr/mbr.inc @@ -101,7 +101,7 @@ read_sectors: shl ah, 1 or cl, ah ; Now cx is set with respective track and sector numbers 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: mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector int 0x13 ; Call int 13h (BIOS disk I/O) diff --git a/kaleid/common/itoa.c b/kaleid/common/itoa.c index e24a41a..a5e3383 100644 --- a/kaleid/common/itoa.c +++ b/kaleid/common/itoa.c @@ -10,59 +10,89 @@ #include // -// Digits table for bases <=36 +// Digits table for bases <=36 (unused) // static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + // // Integer to string in any base between 2 and 36 (included) // + #if defined(_NEED_ITOA) + char *itoa(int i, char *str, int base) +#define _IL_MIN INT_MIN +#define _IL_MIN_STRING "-2147483648" + #elif defined(_NEED_LTOA) + char *ltoa(long i, char *str, int base) +#define _IL_MIN LONG_MIN +#define _IL_MIN_STRING "-9223372036854775808" + #elif defined(_NEED_UTOA) + char *utoa(uint i, char *str, int base) + #elif defined(_NEED_ULTOA) + char *ultoa(ulong i, char *str, int base) + #else #error "What am I supposed to declare?" #endif + { -#if defined(_NEED_ITOA) || defined(_NEED_LTOA) - int neg = 0; -#endif - char *orig = str; - // - // Only handle base 2 -> 36 - // - if (base < 2 || base > 36) - return NULL; - #if defined(_NEED_ITOA) || defined(_NEED_LTOA) // // Deal with negatives // - if (i < 0) { - neg = 1; - i = -i; + int neg = 0; + if (i < 0 && base == 10) { + // + // 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 + // + // Only handle base 2 -> 36 + // + if (base < 2 || base > 36) { + __set_errno(EINVAL); + *orig = '\0; + goto leave; + } + // // Deal with zero separately // if (i == 0) { *str++ = '0'; + *str = '\0'; + goto leave; } // // Compute digits... in reverse order // while (i > 0) { - *str++ = digits[i % base]; + rem = i % base; + *str++ = (rem > 9) + ? (rem - 10) + 'a' + : rem + '0'; i /= base; } @@ -75,7 +105,13 @@ char *ultoa(ulong i, char *str, int base) // // Reverse the string // - return strrev2(orig); + orig = strrev2(orig); + + // + // End of conversion + // +leave: + return orig; } diff --git a/kaleid/common/memory.c b/kaleid/common/memory.c index 3497a38..20a9dd2 100644 --- a/kaleid/common/memory.c +++ b/kaleid/common/memory.c @@ -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) { @@ -99,8 +99,8 @@ void *memsetw(void *ptr, int val, size_t words) } // -// Set "dwords"-many dwords starting from ptr to val -// XXX unimplemented +// Set "dwords"-many dwords starting from ptr to val +// XXX unimplemented // 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) { @@ -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) { @@ -138,8 +138,8 @@ void *memzero(void *ptr, size_t bytes) } // -// Copy "bytes"-many bytes of src to dst -// Does not deal with overlapping blocks (memmove's job) +// Copy "bytes"-many bytes of src to dst +// Does not deal with overlapping blocks (memmove's job) // 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) { @@ -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) { diff --git a/kaleid/common/string.c b/kaleid/common/string.c index fafaf89..d7c391d 100644 --- a/kaleid/common/string.c +++ b/kaleid/common/string.c @@ -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 // 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; @@ -243,9 +243,7 @@ int xstrncpy(char *restrict dest, const char *restrict src, size_t n) dest[it] = src[it]; } - // // Was the copy complete? - // if (it == n) { if (dest[n] == 0) { 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 *strncat (char *restrict, const char *restrict, size_t); -int *xstrncat(char *restrict, const char *restrict, size_t); +char *strcat(char *restrict dest, const char *restrict src) +{ + 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 diff --git a/kaleid/include/common/kalcrt.h b/kaleid/include/common/kalcrt.h index 167ab52..165ba90 100644 --- a/kaleid/include/common/kalcrt.h +++ b/kaleid/include/common/kalcrt.h @@ -143,11 +143,11 @@ char *strtok_r(char *restrict, const char *restrict, char **restrict); char *strcpy (char *restrict, const char *restrict); 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 *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 *strrev2(char *); diff --git a/kaleid/include/common/kaldefs.h b/kaleid/include/common/kaldefs.h index 9dbf1be..cc43ee9 100644 --- a/kaleid/include/common/kaldefs.h +++ b/kaleid/include/common/kaldefs.h @@ -23,11 +23,7 @@ #endif #ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef INITOK -#define INITOK ((unsigned int)0xCAFEBABE) +#define NULL 0L #endif //------------------------------------------// @@ -61,8 +57,8 @@ // Attributes and macros // //------------------------------------------// -#ifndef PACKED -#define PACKED __attribute__((__packed__)) +#ifndef _PACKED +#define _PACKED __attribute__((__packed__)) #endif #ifndef noreturn @@ -77,6 +73,14 @@ #define unlikely(x) (__builtin_expect((x), 0)) #endif +#ifndef _STR +#define _STR(x) #x +#endif + +#ifndef _XSTR +#define _XSTR(x) _STR(x) +#endif + //------------------------------------------// // API specific macros // //------------------------------------------// diff --git a/kaleid/include/common/kalerror.h b/kaleid/include/common/kalerror.h index ce8b2c4..b29c660 100644 --- a/kaleid/include/common/kalerror.h +++ b/kaleid/include/common/kalerror.h @@ -11,7 +11,7 @@ #define _KALERROR_H //------------------------------------------// -// Preprocessor constants // +// "errno" values // //------------------------------------------// // Everything went fine diff --git a/kaleid/include/common/kallist.h b/kaleid/include/common/kallist.h index 96c5f9d..8257b64 100644 --- a/kaleid/include/common/kallist.h +++ b/kaleid/include/common/kallist.h @@ -204,7 +204,7 @@ static inline ListHead_t } // -// Remove node of list +// Remove node of list (and frees it) // static inline ListHead_t *RemoveNode(ListHead_t *head, ListNode_t *node) diff --git a/kaleid/include/common/kalmask.h b/kaleid/include/common/kalmask.h index 0295bd0..c185354 100644 --- a/kaleid/include/common/kalmask.h +++ b/kaleid/include/common/kalmask.h @@ -51,11 +51,11 @@ #define strcpy _osk_strcpy #define strncpy _osk_strncpy -#define xstrncpy _osk_xstrncpy +#define strnzcpy _osk_strnzcpy #define strcat _osk_strcat #define strncat _osk_strncat -#define xstrncat _osk_xstrncat +#define strnzcat _osk_strnzcat #define strrev _osk_strrev #define strrev2 _osk_strrev2 @@ -105,7 +105,7 @@ //------------------------------------------// -#define strerror _osk_strerror +#define strerror _osk_strerror //------------------------------------------// // End of header // diff --git a/kaleid/include/kernel/kernbase.h b/kaleid/include/kernel/kernbase.h index baf8e95..54307c7 100644 --- a/kaleid/include/kernel/kernbase.h +++ b/kaleid/include/kernel/kernbase.h @@ -59,6 +59,11 @@ typedef enum { // Multiprocessor misc. // //------------------------------------------// + +#ifndef INITOK +#define INITOK ((unsigned int)0xCAFEBABE) +#endif + #ifndef NCPU #define NCPU 4 #endif @@ -108,12 +113,6 @@ DECLARE_PER_CPU(CurThread, Thread_t *); // global constants // //------------------------------------------// -#define SetPanicStr(str) \ - do { \ - SetKernState(KSTATE_PANIC); \ - _SetPanicStr(str); \ - } while (0) - #define SetKernState(x) \ do { \ _SetKernState(x); \ @@ -184,7 +183,6 @@ void WriteByteOnPort(port_t port, port_t val) static inline uchar ReadByteFromPort(port_t port) { - KalAssert(FALSE && ENOSYS); (void)port; return 0; diff --git a/kaleid/include/kernel/kernlocks.h b/kaleid/include/kernel/kernlocks.h index f3dd7e2..6d32224 100644 --- a/kaleid/include/kernel/kernlocks.h +++ b/kaleid/include/kernel/kernlocks.h @@ -70,11 +70,15 @@ typedef struct sLock_t { //------------------------------------------// // -// Linux syscall... +// Linux syscall vs unimplemented syscall... // #ifndef _KALEID_KERNEL +#ifdef _OSK_SOURCE +int KalYieldCPU(void), +#else int sched_yield(void); #endif +#endif // // Initialize a lock @@ -127,7 +131,11 @@ void AquireLock(Lock_t *lock) StartPanic("AquireLock on an already locked object"); #else if likely (lock->type == KLOCK_SPINLOCK) continue; +#ifdef _OSK_SOURCE + else KalYieldCPU(); +#else else sched_yield(); +#endif #endif } __sync_synchronize(); diff --git a/kaleid/include/kernel/kernsched.h b/kaleid/include/kernel/kernsched.h index 1026d53..d99f8de 100644 --- a/kaleid/include/kernel/kernsched.h +++ b/kaleid/include/kernel/kernsched.h @@ -30,9 +30,10 @@ // Preprocessor // //------------------------------------------// +// +// Debug stuff +// #define printdbg printf -#define _STR(x) #x -#define _XSTR(x) _STR(x) // // States for a process @@ -56,6 +57,8 @@ DECLARE_PER_CPU(ReglPrioProcs, ListHead_t *); DECLARE_PER_CPU(ServPrioProcs, ListHead_t *); DECLARE_PER_CPU(TimeCritProcs, ListHead_t *); +extern const char *PrioClassesNames[]; + //------------------------------------------// // Data types // //------------------------------------------// @@ -63,7 +66,7 @@ DECLARE_PER_CPU(TimeCritProcs, ListHead_t *); // // A process // -typedef struct sProcess_t{ +typedef struct sProcess_t { // Identifier int pid; @@ -94,6 +97,16 @@ typedef struct sProcess_t{ } Process_t; +//------------------------------------------// +// Functions // +//------------------------------------------// + +void SchedInit(void); +void SchedFini(void); + +void SchedThisProc(Process_t *); +void SchedOnTick(void); + //------------------------------------------// // End of header // //------------------------------------------// diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c index 72fe089..79c9a89 100644 --- a/kaleid/kernel/ke/panic.c +++ b/kaleid/kernel/ke/panic.c @@ -34,6 +34,7 @@ noreturn void StartPanic(const char *str) { DisableIRQs(); + // This should be made atomic SetKernState(KSTATE_PANIC); if (GetCurProc()) __CurProc[GetCurCPU()] = NULL; @@ -46,11 +47,11 @@ noreturn void StartPanic(const char *str) } if (GetPanicStr()) { - GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "double panic!\n"); + GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nDouble panic!\n"); HaltCPU(); } - SetPanicStr(str); + _SetPanicStr(str); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - "); GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str); diff --git a/kaleid/kernel/proc/sched.c b/kaleid/kernel/proc/sched.c index b81ec45..ad040b1 100644 --- a/kaleid/kernel/proc/sched.c +++ b/kaleid/kernel/proc/sched.c @@ -66,12 +66,13 @@ void SchedUnlock(void) { // // The four priority classes of OS/2 // + CREATE_PER_CPU(IdlePrioProcs, ListHead_t *); CREATE_PER_CPU(ReglPrioProcs, ListHead_t *); CREATE_PER_CPU(ServPrioProcs, ListHead_t *); CREATE_PER_CPU(TimeCritProcs, ListHead_t *); -char *PrioClassesNames[] = { +const char *PrioClassesNames[] = { "Idle priority class", "Regular priority class", "Server priority class", @@ -203,47 +204,55 @@ void BlockCurProc(void) 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? // Called at each tick // void SchedOnTick(void) { - Process_t *procNext; - Process_t *winner; - SchedLock(); + Process_t *procNext, *winner, *previous = GetCurProc(); + // // We're either idle or running something // 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) // if (GetCurProc() != NULL) { if (GetCurProc()->timeSlice <= 1) { + // Re-schedule + ReSchedCurProc(); - // 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); - - // Schedule again, with default attributes now - SchedThisProcUnlocked(GetCurProc()); - - // Mark as idle - SetCurProc(NULL); + // See next 'if' statement + _SetCurProc(NULL); } // - // Otherwise, make him lose a tick + // Otherwise, make it lose a tick // else { GetCurProc()->timeSlice--; @@ -268,8 +277,10 @@ void SchedOnTick(void) // Yes, procNext should preempt current process // if (winner == procNext) { - GetCurProc()->procState = STATE_RUNNABLE; - SchedThisProcUnlocked(GetCurProc()); + // Re-schedule + ReSchedCurProc(); + + // Switch to procNext SetCurProc(procNext); } @@ -278,32 +289,10 @@ void SchedOnTick(void) // leave: SchedUnlock(); -} -#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; + if (GetCurProc() != NULL && GetCurProc() != previous) { + // XXX context switch } - - puts(""); } // @@ -355,6 +344,33 @@ void FiniSched(void) } #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) { InitSched(); @@ -379,7 +395,17 @@ int main(void) 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); if (GetCurProc() == NULL) { @@ -390,14 +416,8 @@ int main(void) PrintProc(GetCurProc()); } - if (tick == 9 || tick == 14) { - puts("Blocking current process"); - BlockCurProc(); - } - SchedOnTick(); - //puts("\n---------------"); tick++; } @@ -405,5 +425,6 @@ int main(void) return 0; } + #endif