Merge pull request #18 from os-k-team/kaleid

Kaleid
This commit is contained in:
Julian B 2019-01-21 08:55:40 +00:00 committed by GitHub
commit 7aefcf6784
26 changed files with 338 additions and 162 deletions

View File

@ -13,7 +13,7 @@
CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc" CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc"
CC2NAME=gcc CC2NAME=gcc
COPTIM=-O2 COPTIM=-O2
CWARNS=-Wall -Wextra -Wshadow -Wpedantic CWARNS=-Wall -Wextra -Wshadow // -Wpedantic
CINCLUDES=-isystem./kaleid/include CINCLUDES=-isystem./kaleid/include
CFLAGS1=-std=gnu11 -nostdlib -ffreestanding -mcmodel=large CFLAGS1=-std=gnu11 -nostdlib -ffreestanding -mcmodel=large

View File

@ -34,7 +34,7 @@
;; GLOBAL DATA ;; GLOBAL DATA
Bootdrv db 0 Bootdrv db 0
end db "[End of Sector]", 0x0A, 0x0D, 0x0 ended db "[End of Sector]", 0x0A, 0x0A, 0x0D, 0x0
buffer: times 513 db "_" buffer: times 513 db "_"
;; TEXT ;; TEXT
@ -124,12 +124,19 @@ still_going:
mov dx, 0x1f0 ; Data port - data comes in and out of here. mov dx, 0x1f0 ; Data port - data comes in and out of here.
rep insw rep insw
pop rdi pop rdi
%ifdef DEBUG
mov bl, 0x0F mov bl, 0x0F
mov esi, buffer mov esi, buffer
call dump call dump
mov bl, 0x0A mov bl, 0x0A
mov esi, end mov esi, ended
call write call write
add qword [NextTRAM], 120 ; Cursor moving : 1120 = 80 * 2 * 7 lignes
%else
mov bl, 0x0A
mov esi, Pass
call write
%endif
pop rdx pop rdx
pop rcx pop rcx
pop rbx pop rbx

View File

@ -93,9 +93,9 @@ write:
dump: dump:
;-----------------------------------------------------------------------; ;-----------------------------------------------------------------------;
; x64/LM Dump Printing Functions ; ; x64/LM Dump 512 bytes of a buffer ;
; bl : color code ; ; bl : color code ;
; esi : string address ; ; esi : buffer address ;
;-----------------------------------------------------------------------; ;-----------------------------------------------------------------------;
mov edi, [NextTRAM] ; TRAM ADDRESS mov edi, [NextTRAM] ; TRAM ADDRESS
push rsi push rsi
@ -107,10 +107,9 @@ dump:
stosb ; text subpixel stosb ; text subpixel
mov al, bl mov al, bl
stosb ; color subpixel stosb ; color subpixel
add qword [NextTRAM], 0x2 ; Cursor moving
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
loop .pLoop loop .pLoop
pop rcx pop rcx
pop rdi pop rdi
pop rsi pop rsi
add qword [NextTRAM], 1000 ; Cursor moving : 1120 = 80 * 2 * 7 lignes
ret ret

View File

@ -8,6 +8,8 @@
; (x86_64 architecture only) ; ; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=; ;=----------------------------------------------------------------------------=;
%define DEBUG
[BITS 16] [BITS 16]
[ORG 0x1000] [ORG 0x1000]
@ -92,13 +94,13 @@ main32:
;; VERIFY A20 ;; VERIFY A20
pushad pushad
mov edi,0x112345 ;odd megabyte address. mov edi,0x112345 ;odd megabyte address.
mov esi,0x012345 ;even megabyte address. mov esi,0x012345 ;even megabyte address.
mov [esi],esi ;making sure that both addresses contain diffrent values. mov [esi],esi ;making sure that both addresses contain diffrent values.
mov [edi],edi ;(if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi)) mov [edi],edi ;(if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi))
cmpsd ;compare addresses to see if the're equivalent. cmpsd ;compare addresses to see if the're equivalent.
popad popad
jne .A20_on ;if not equivalent , A20 line is set. jne .A20_on ;if not equivalent , A20 line is set.
mov WORD [A20_OK], 0 mov WORD [A20_OK], 0
jmp .A20_end jmp .A20_end
.A20_on: .A20_on:
@ -161,18 +163,23 @@ main32:
[BITS 64] [BITS 64]
;; DATA ;; DATA
Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0 Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0
CPUIDD db 0x09, " Checking CPUID...", 0 CPUIDD db 0x09, " Checking CPUID...", 0
EnA20 db 0x09, " Enabling A20 line...", 0 EnA20 db 0x09, " Enabling A20 line...", 0
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D,0 %ifdef DEBUG
txt db 0x09, " Switching to Long Mode... ", 0 ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D, 0
Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0 %else
Pass db " OK", 0x0A, 0x0D, 0 ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0
Fail db " FAIL!", 0x0A, 0x0D, 0 %endif
msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0 txt db 0x09, " Switching to Long Mode... ", 0
FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0 EndOfLoader db "End of loader.bin. System will halt !", 0x0A, 0x0D, 0
DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0 Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0
filename db "KERNEL BIN" Pass db " OK", 0x0A, 0x0D, 0
Fail db " FAIL!", 0x0A, 0x0D, 0
msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0
FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0
DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0
filename db "KERNEL BIN"
%include "boot/loader/io/lmmem.asm" %include "boot/loader/io/lmmem.asm"
%include "boot/loader/io/lmterm.asm" %include "boot/loader/io/lmterm.asm"
@ -229,10 +236,10 @@ main64:
mov bh, 1 mov bh, 1
call ata_read call ata_read
call bitemporize ; Temporized because the ATA drive must be ready mov bl, 0x0D
mov esi, EndOfLoader
call write
jmp Die jmp Die
; times 1024 nop times 20 db 0
; XXX ;
; It seems impossible to have an executable > 2.0 kB...

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)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -10,59 +10,97 @@
#include <kaleid.h> #include <kaleid.h>
// //
// Digits table for bases <=36 // Digits table for bases <=36 (unused)
// //
#if 0
static const char digits[] = static const char digits[] =
"0123456789abcdefghijklmnopqrstuvwxyz"; "0123456789abcdefghijklmnopqrstuvwxyz";
#endif
// //
// 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)
#define _IL_MIN INT_MIN
#define _IL_MIN_STRING "-2147483648"
char *itoa(int i, char *str, int base) char *itoa(int i, char *str, int base)
{
int rem;
#elif defined(_NEED_LTOA) #elif defined(_NEED_LTOA)
#define _IL_MIN LONG_MIN
#define _IL_MIN_STRING "-9223372036854775808"
char *ltoa(long i, char *str, int base) char *ltoa(long i, char *str, int base)
{
long rem;
#elif defined(_NEED_UTOA) #elif defined(_NEED_UTOA)
char *utoa(uint i, char *str, int base) char *utoa(uint i, char *str, int base)
{
uint rem;
#elif defined(_NEED_ULTOA) #elif defined(_NEED_ULTOA)
char *ultoa(ulong i, char *str, int base) char *ultoa(ulong i, char *str, int base)
{
ulong rem;
#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 +113,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

@ -20,8 +20,8 @@ static ulong next = 7756;
// //
int rand(void) int rand(void)
{ {
next = next * 1103515245 + 12345; next = next * 1103515245 + 12347;
return (uint)(next / 65536) % INT_MAX; return (uint)(next / 65536);
} }
// //

View File

@ -12,6 +12,9 @@
// //
// Format str according to fmt using ellipsed arguments // Format str according to fmt using ellipsed arguments
// //
// BE CAREFUL when using this
// you need to know for sure an overflow won't happen
//
int sprintf(char *str, const char *fmt, ...) int sprintf(char *str, const char *fmt, ...)
{ {
int ret; int ret;
@ -31,6 +34,7 @@ int vsprintf(char *str, const char *fmt, va_list ap)
// //
// (v)sprintf() but with a size limit: no more than n bytes are written in str // (v)sprintf() but with a size limit: no more than n bytes are written in str
// Always null-terminate str
// //
int snprintf(char *str, size_t n, const char *fmt, ...) int snprintf(char *str, size_t n, const char *fmt, ...)
{ {

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,7 +23,7 @@
#endif #endif
#ifndef NULL #ifndef NULL
#define NULL ((void *)0) #define NULL 0L
#endif #endif
#ifndef INITOK #ifndef INITOK
@ -61,8 +61,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 +77,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

@ -38,6 +38,13 @@
#include <kernel/kernterm.h> #include <kernel/kernterm.h>
#endif #endif
// not ready for kernel compilation
#ifndef _KALEID_KERNEL
#ifndef _KALKERN_SCHED_H
#include <kernel/kernsched.h>
#endif
#endif
//------------------------------------------// //------------------------------------------//
// End of header // // End of header //
//------------------------------------------// //------------------------------------------//

View File

@ -59,6 +59,10 @@ 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 +112,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 +182,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

@ -1,4 +1,4 @@
sched-test: sched-test:
gcc -O2 -masm=intel -I../../include ./sched.c gcc -O2 -Wall -Wextra -Wshadow -std=gnu11 -masm=intel -I../../include ./sched.c

View File

@ -7,7 +7,7 @@
// Desc: Scheduling algorithm // // Desc: Scheduling algorithm //
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#include <kernel/kernsched.h> #include <kalkern.h>
#ifndef _KALEID_KERNEL #ifndef _KALEID_KERNEL
@ -17,17 +17,18 @@ CREATE_PER_CPU(CurProc, Process_t *);
// //
// For test purpose only // For test purpose only
// //
int procslen = 9; int procslen = 10;
Process_t procs[] = { Process_t procs[] = {
{ 0, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 0, 0, 0, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 1, 2, 2, 16, 16, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 1, 2, 2, 16, 16, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 2, 3, 3, 31, 31, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 2, 3, 3, 31, 31, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 3, 2, 2, 1, 1, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 3, 2, 2, 1, 1, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 4, 0, 0, 5, 5, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 4, 3, 3, 5, 5, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 5, 0, 0, 30, 30, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 5, 0, 0, 30, 30, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 6, 1, 1, 19, 19, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 6, 1, 1, 19, 19, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 7, 1, 1, 0, 0, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 7, 1, 1, 0, 0, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 8, 3, 3, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL }, { 8, 3, 3, 12, 12, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
{ 9, 2, 2, 21, 21, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL },
}; };
#endif #endif
@ -66,22 +67,23 @@ 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(ReglPrioProcs, ListHead_t *);
CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
char *PrioClassesNames[] = { CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
"Idle priority class", CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
"Regular priority class", CREATE_PER_CPU(ReglPrioProcs, ListHead_t *);
"Server priority class", CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);
const char *PrioClassesNames[] = {
"Time-critical class", "Time-critical class",
"Server priority class",
"Regular priority class",
"Idle priority class",
}; };
enum { IDLE_PRIO_PROC = 0, enum { TIME_CRIT_PROC = 0,
REGL_PRIO_PROC = 1, SERV_PRIO_PROC = 1,
SERV_PRIO_PROC = 2, REGL_PRIO_PROC = 2,
TIME_CRIT_PROC = 3, IDLE_PRIO_PROC = 3,
}; };
// //
@ -110,8 +112,8 @@ Process_t *CompareProcs(Process_t *proc1, Process_t *proc2)
{ {
KalAssert(proc1 && proc2); KalAssert(proc1 && proc2);
if (proc1->prioClass > proc2->prioClass) return proc1; if (proc1->prioClass < proc2->prioClass) return proc1;
if (proc1->prioClass < proc2->prioClass) return proc2; if (proc1->prioClass > proc2->prioClass) return proc2;
if (proc1->prioLevel > proc2->prioLevel) return proc1; if (proc1->prioLevel > proc2->prioLevel) return proc1;
if (proc1->prioLevel < proc2->prioLevel) return proc2; if (proc1->prioLevel < proc2->prioLevel) return proc2;
@ -125,7 +127,7 @@ Process_t *CompareProcs(Process_t *proc1, Process_t *proc2)
static inline static inline
void SchedThisProcUnlocked(Process_t *proc) void SchedThisProcUnlocked(Process_t *proc)
{ {
KalAssert(proc && proc->procState == STATE_RUNNABLE); KalAssert(proc && proc->procState == STATE_RUNNABLE && !proc->schedNode);
bool found = false; bool found = false;
ListNode_t *iterNode = NULL; ListNode_t *iterNode = NULL;
@ -136,13 +138,15 @@ void SchedThisProcUnlocked(Process_t *proc)
proc->schedNode = procNode; proc->schedNode = procNode;
//printdbg("Adding process %d to '%s'\n", proc->pid, PrioClassesNames[proc->prioClass]);
// //
// Find a process with lesser priority // Find a process with lesser priority
// //
for (iterNode = head->first; iterNode; iterNode = iterNode->next) { for (iterNode = head->first; iterNode; iterNode = iterNode->next) {
if (proc->prioLevel > GetNodeData(iterNode, Process_t *)->prioLevel) { if (proc->prioLevel > GetNodeData(iterNode, Process_t *)->prioLevel) {
// Detect double insertions
KalAssert(proc->pid != GetNodeData(iterNode, Process_t *)->pid);
// Add process to schedule
AddNodeBefore(head, iterNode, procNode); AddNodeBefore(head, iterNode, procNode);
found = true; found = true;
break; break;
@ -197,53 +201,65 @@ void BlockCurProc(void)
ListNode_t *procNode = GetCurProc()->schedNode; ListNode_t *procNode = GetCurProc()->schedNode;
KalAssert(procNode && "Blocking non-scheduled process");
GetCurProc()->procState = STATE_BLOCKED; GetCurProc()->procState = STATE_BLOCKED;
RemoveNode(procNode->head, procNode); RemoveNode(procNode->head, procNode);
GetCurProc()->schedNode = NULL;
SetCurProc(SelectSchedNext()); SetCurProc(SelectSchedNext());
} }
static inline
void ReSchedCurProc(void)
{
KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING);
KalAssert(GetCurProc()->schedNode);
// 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 +284,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 +296,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("");
} }
// //
@ -312,7 +308,6 @@ void PrintList(ListHead_t *head)
void InitSched(void) void InitSched(void)
{ {
int pid; int pid;
Process_t *proc;
SchedLock(); SchedLock();
@ -355,6 +350,33 @@ void FiniSched(void)
} }
#ifndef _KALEID_KERNEL #ifndef _KALEID_KERNEL
#define PrintProc(proc) printdbg("{ %d, '%s', %d , %lu}\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: %lu\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 +401,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[0].procState = STATE_RUNNABLE;
SchedThisProc(&procs[0]);
}
printf("Tick %d - Running: ", tick); printf("Tick %d - Running: ", tick);
if (GetCurProc() == NULL) { if (GetCurProc() == NULL) {
@ -390,14 +422,11 @@ int main(void)
PrintProc(GetCurProc()); PrintProc(GetCurProc());
} }
if (tick == 9 || tick == 14) {
puts("Blocking current process");
BlockCurProc();
}
SchedOnTick(); SchedOnTick();
//puts("\n---------------"); if (tick == 50) // already done
puts("Re-scheduling process 0");
tick++; tick++;
} }
@ -405,5 +434,6 @@ int main(void)
return 0; return 0;
} }
#endif #endif