From 950b5a698357b941da7bf0f4beb9bd3abd505854 Mon Sep 17 00:00:00 2001 From: Julian Barathieu Date: Sun, 24 Mar 2019 22:51:16 +0100 Subject: [PATCH 1/5] Buffer stuff --- Makefile | 6 +- kaleid/crtlib/mem.c | 1 + kaleid/include/base/crtlib.h | 1 + kaleid/include/base/errno.h | 2 +- kaleid/include/kernel/buf.h | 113 +++++++++++++++ kaleid/kernel/buf/buf.c | 263 +++++++++++++++++++++++++++++++++++ 6 files changed, 384 insertions(+), 2 deletions(-) create mode 100644 kaleid/include/kernel/buf.h create mode 100644 kaleid/kernel/buf/buf.c diff --git a/Makefile b/Makefile index 9ffbd33..ff578a4 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,8 @@ kal_kern_obj= $(KOBJDIR)/kernel/cpuid.o $(KOBJDIR)/kernel/init.o \ $(KOBJDIR)/kernel/table.o $(KOBJDIR)/kernel/cursor.o \ $(KOBJDIR)/kernel/term.o $(KOBJDIR)/kernel/vga.o \ $(KOBJDIR)/kernel/panic.o $(KOBJDIR)/kernel/map.o \ - $(KOBJDIR)/kernel/heap.o $(KOBJDIR)/kernel/malloc.o + $(KOBJDIR)/kernel/heap.o $(KOBJDIR)/kernel/malloc.o \ + $(KOBJDIR)/kernel/buf.o $(KOBJDIR)/kernel/cpuid.o: $(KERNELDIR)/kernel/cpu/cpuid.c $(KERNELDIR)/include/*/*.h @$(KCC) $< -o $@ @@ -160,6 +161,9 @@ $(KOBJDIR)/kernel/heap.o: $(KERNELDIR)/kernel/mm/heap.c $(KERNELDIR)/include/*/* $(KOBJDIR)/kernel/malloc.o: $(KERNELDIR)/kernel/mm/malloc.c $(KERNELDIR)/include/*/*.h @$(KCC) $< -o $@ @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/buf.o: $(KERNELDIR)/kernel/buf/buf.c $(KERNELDIR)/include/*/*.h + @$(KCC) $< -o $@ + @echo ${CL2}[$@] ${CL}Compiled.${CL3} ## MISC MAKEFILE ------------------------------------------------------------- # ./ProjectTree: ./.stylehlp_sh diff --git a/kaleid/crtlib/mem.c b/kaleid/crtlib/mem.c index 7d03682..208cffc 100644 --- a/kaleid/crtlib/mem.c +++ b/kaleid/crtlib/mem.c @@ -38,6 +38,7 @@ void *malloc(size_t n) rc = KalAllocMemory(&ptr, n, 0, 0); __set_errno(rc); + (void)rc; return ptr; } diff --git a/kaleid/include/base/crtlib.h b/kaleid/include/base/crtlib.h index 9aa697d..a62aa39 100644 --- a/kaleid/include/base/crtlib.h +++ b/kaleid/include/base/crtlib.h @@ -183,6 +183,7 @@ unsigned long strtoul(const char *restrict, char **restrict, int); //------------------------------------------// +void *calloc(size_t, size_t) __attribute__((__malloc__)); void *malloc(size_t) __attribute__((__malloc__)); void free(void *); diff --git a/kaleid/include/base/errno.h b/kaleid/include/base/errno.h index d063504..a6e2d33 100644 --- a/kaleid/include/base/errno.h +++ b/kaleid/include/base/errno.h @@ -54,7 +54,7 @@ // Not an executable format #define ENOEXEC 8 -// Bad file number +// Bad file #define EBADF 9 // Try again diff --git a/kaleid/include/kernel/buf.h b/kaleid/include/kernel/buf.h new file mode 100644 index 0000000..13520d5 --- /dev/null +++ b/kaleid/include/kernel/buf.h @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Buffer library // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#ifndef _KALKERN_BASE_H +#include +#endif + +#ifndef _KALKERN_BUF_H +#define _KALKERN_BUF_H + +typedef struct Buffer_t Buffer_t; + +// +// Buffer flags +// +enum +{ + BF_LINE = 1, // Line-buffered + BF_FILE = 2, // Linked to a file + BF_ALLOC = 4, // Buffer was malloc'd + BF_FONCLOSE = 8, // Don't flush on close +}; + +// +// Buffer states +// +enum +{ + BS_CLOSED = 0, // Buffer closed (need allocation) + BS_EOF, // Buffer closed, or end of file reached + BS_ERR, // Buffer not ready, an error happened + + // Buffer ready for... + BS_RDWR, // Both reading and writing + BS_RDONLY, // Only for reading + BS_WRONLY, // Only for writing +}; + +typedef error_t (*BFlusher_t)(Buffer_t *); + +struct Buffer_t +{ + uint initDone; + Lock_t lock; + + int flags; // Buffer flags + int state; // Buffer state + + size_t size; // Current size + + char *buf; // Beginning of buffer + char *rp; // Read pointer + char *wp; // Write pointer + + BFlusher_t flusher; // Called for flushing + + // The following parameters are only used in line buf mode + + int lastLF; // Characters since beginning of line + int lineLen; // Line length (for line buffers) + int nLines; // Number of lines in "true" buffer + // size/(lineLen*nLines) - 1 playback buffers +}; + +extern Buffer_t BStdOut, BStdErr; + +error_t BCloseBuf(Buffer_t *buf); +void BFlushOnClose(Buffer_t *buf); + +Buffer_t *BOpenPureBuf(char *source, size_t size); + +// Creates a lined buffer of pbCount*nLines lines each +// of lineLen length (pb = playback buffer, for scrolling up) +// If source==NULL, malloc the buffer +Buffer_t *BOpenLineBuf(char *source, int mode, int lineLen, + int nLines, int pbCount, BFlusher_t flusher); + +int BGetFlags(Buffer_t *buf); +int BGetState(Buffer_t *buf); +int BGetLineLen(Buffer_t *buf); +void BSetLineLen(Buffer_t *buf, int len); + +void BLockBuf(Buffer_t *buf); +void BUnlockBuf(Buffer_t *buf); +bool BTrylockBuf(Buffer_t *buf); + +error_t BFlushBuf(Buffer_t *buf); +error_t BPutOnBuf(Buffer_t *buf, uchar ch); +error_t BPrintOnBuf(Buffer_t *buf, size_t n, const char *fmt, ...); +error_t BPrintOnBufV(Buffer_t *buf, size_t n, const char *fmt, va_list ap); + +#endif diff --git a/kaleid/kernel/buf/buf.c b/kaleid/kernel/buf/buf.c new file mode 100644 index 0000000..3491ffd --- /dev/null +++ b/kaleid/kernel/buf/buf.c @@ -0,0 +1,263 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Buffer library // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include +#include + +// Straightforward functions +int BGetFlags(Buffer_t *buf) { return buf->flags; } +int BGetState(Buffer_t *buf) { return buf->state; } +int BGetLineLen(Buffer_t *buf) { return buf->lineLen; } +void BSetLineLen(Buffer_t *buf, int len) { buf->lineLen = len; } + +void BLockBuf(Buffer_t *buf) +{ + assert(buf && buf->initDone == INITOK); + ExAcquireLock(&buf->lock); +} + +void BUnlockBuf(Buffer_t *buf) { ExReleaseLock(&buf->lock); } +bool BTrylockBuf(Buffer_t *buf) { return ExAttemptLock(&buf->lock); } + +void BFlushOnClose(Buffer_t *buf) { buf->flags |= BF_FONCLOSE; } + +// +// Closes a buffer, not flushing unless the proper flag is set +// +error_t BCloseBuf(Buffer_t *buf) +{ + if (!buf) return EINVAL; + + assert(buf->initDone == INITOK); + ExAcquireLock(&buf->lock); + + if (buf->flags & BF_FONCLOSE) { + BFlushBuf(buf); + } + + if (buf->flags & BF_ALLOC) { + free(buf->buf); + } + + buf->buf = buf->rp = buf->wp = NULL; + buf->initDone = buf->flags = buf->state = buf->size = 0; + + ExReleaseLock(&buf->lock); + KalFreeMemory(buf); + + return EOK; +} + +// +// Opens a pure text buffer (for WRITING only) +// If source==NULL, malloc's the internal buffer +// +#if 0 +Buffer_t *BOpenPureBuf(char *source, size_t size) +{ + /*Buffer_t *buf = malloc(sizeof *buf); + buf->flags = 0; + ExInitLock(&buf->lock);*/ + + return NULL; +} +#endif + +extern BFlusher_t _VGA_BFlusher; + +// +// Creates a lined buffer of (nLines + pbCount*nLines) lines each +// of lineLen length (pb = playback buffer, for scrolling up) +// +Buffer_t *BOpenLineBuf(char *source, int mode, + int lineLen, int nLines, int pbCount, BFlusher_t flusher) +{ + assert(lineLen > 0 && nLines > 0 && pbCount >= 0); + assert(mode == BS_RDWR || mode == BS_RDONLY || mode == BS_WRONLY); + + Buffer_t *buf = malloc(sizeof *buf); + + ExInitLock(&buf->lock, KLOCK_MUTEX); + ExAcquireLock(&buf->lock); + + buf->lastLF = 0; + buf->state = mode; + buf->flags = BF_LINE; + buf->nLines = nLines; + buf->lineLen = lineLen; + buf->size = lineLen * nLines * (pbCount + 1); + + if (source == NULL) { + buf->buf = malloc(buf->size); + } else { + buf->buf = source; + } + + buf->wp = buf->rp = buf->buf; + buf->flusher = flusher; + buf->initDone = INITOK; + + ExReleaseLock(&buf->lock); + return buf; +} + +// +// Flushes a buffer, returns EBADF when not possible +// +error_t BFlushBuf(Buffer_t *buf) +{ + error_t rc; + + assert(buf && buf->initDone == INITOK); + + if (!buf) return EINVAL; + if (!buf->flusher || buf->state == BS_EOF || buf->state == BS_ERR) { + return EBADF; + } + + ExAcquireLock(&buf->lock); + rc = buf->flusher(buf); + ExReleaseLock(&buf->lock); + + return rc; +} + +static error_t bputc(Buffer_t *buf, uchar ch); + +// +// Writes a character on a buffer +// +error_t BPutOnBuf(Buffer_t *buf, uchar ch) +{ + error_t rc; + assert(buf && buf->initDone == INITOK); + + if (!buf) return EINVAL; + if (buf->state != BS_RDWR && buf->state != BS_WRONLY) { + return EBADF; + } + + ExAcquireLock(&buf->lock); + rc = bputc(buf, ch); + ExReleaseLock(&buf->lock); + return rc; +} + +// +// Internal, unlocked version of BPutOnBuf +// +static error_t bputc(Buffer_t *buf, uchar ch) +{ + error_t rc; + size_t bufSize, pbCount; + + // Implements playback / scrolling up when line buffering + // Note that '\n', '\r' and '\t' can never occur in the buffer + // That should change; there should be a flag for it + if (buf->flags & BF_LINE) { + + // Deal with carriage returns + if (ch == '\r') { + buf->wp -= buf->lastLF; + buf->lastLF = 0; + assert(buf->wp >= buf->buf); + } + + // Deal with tabs... we need a tabSize field + // We assume tabs are 4 characters long for now + else if (ch == '\t') { + rc = bputc(buf, ' '); + if (rc > 0) return rc; + + while (buf->lastLF % 4 > 0) { + rc = bputc(buf, ' '); + if (rc > 0) return rc; + } + } + + // Deal with line feeds by filling the rest of the line with spaces + // We need a field for choosing a different filler, e.g. '\0' + else if (ch == '\n') { + assert(buf->lastLF < buf->lineLen); + while (buf->lastLF > 0) { + rc = bputc(buf, ' '); + if (rc > 0) return rc; + } + } + + // Just a regular character + else { + // Do we have to scroll up? + if (buf->wp == buf->buf + buf->size) { + // Yes, so we give up a whole playback buffer worth + // of lines so we don't have to do this too often + // (basically we make the current buffer a pb one) + bufSize = buf->nLines * buf->lineLen; + pbCount = (buf->size / bufSize) - 1; + + // Paranoia check + assert(buf->size >= (size_t)(buf->nLines * buf->lineLen)); + + // If we only have one playback buffer we just give up a line + if (pbCount == 0) { + // Use of memcpy() is safe because the source occur + // after the destination + memcpy(buf->buf, buf->buf + buf->lineLen, + buf->size - buf->lineLen); + buf->wp -= buf->lineLen; + } + + // We do have a playback buffer worth of lines to give up + else { + memcpy(buf->buf, buf->buf + bufSize, + buf->size - bufSize); + buf->wp -= buf->lineLen; + } + } + + // Write the damn thing + *buf->wp++ = (char)ch; + + // Did we reach the end of line? + if (++buf->lastLF == buf->lineLen) { + buf->lastLF = 0; + } + } + + return EOK; + } + + // No scrolling up when not line-buffering + else { + if (buf->wp == buf->buf + buf->size) { + buf->state = BS_EOF; + } + + return ENOSYS; + } +} + +error_t BPrintOnBuf(Buffer_t *buf, size_t n, const char *fmt, ...); +error_t BPrintOnBufV(Buffer_t *buf, size_t n, const char *fmt, va_list ap); + From 5b70dfde0c05c4a956c90d8942b9d88587b5af6c Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Sun, 24 Mar 2019 23:08:12 +0100 Subject: [PATCH 2/5] update tree --- ProjectTree | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ProjectTree b/ProjectTree index 03a52e6..f44e941 100644 --- a/ProjectTree +++ b/ProjectTree @@ -56,6 +56,7 @@ │   │   │   └── loader.o │   │   └── kaleid │   │   ├── kernel +│   │   │   ├── buf.o │   │   │   ├── cpuid.o │   │   │   ├── cursor.o │   │   │   ├── heap.o @@ -115,6 +116,7 @@ │   │   │   └── prog.h │   │   ├── kernel │   │   │   ├── base.h +│   │   │   ├── buf.h │   │   │   ├── cpu.h │   │   │   ├── heap.h │   │   │   ├── iomisc.h @@ -128,6 +130,8 @@ │   │   ├── kaleid.h │   │   └── kalext.h │   └── kernel +│   ├── buf +│   │   └── buf.c │   ├── cpu │   │   └── cpuid.c │   ├── init @@ -158,4 +162,4 @@ ├── qemu.log └── Readme.md -27 directories, 106 files +28 directories, 109 files From 93d8a579f8df131cd58e1db9b7981970f82fd4bc Mon Sep 17 00:00:00 2001 From: Julian Barathieu Date: Mon, 25 Mar 2019 17:33:51 +0100 Subject: [PATCH 3/5] Buffer stuff: functional printf --- Makefile | 12 +- kaleid/crtlib/atoi.c | 4 +- kaleid/crtlib/itoa.c | 2 +- kaleid/crtlib/mem.c | 12 +- kaleid/crtlib/strtol.c | 4 +- kaleid/include/base/crtlib.h | 10 +- kaleid/include/base/types.h | 2 +- kaleid/include/extras/list.h | 26 +-- kaleid/include/extras/locks.h | 35 ++- kaleid/include/kernel/base.h | 9 +- kaleid/include/kernel/buf.h | 10 +- kaleid/include/kernel/heap.h | 2 +- kaleid/include/kernel/mm.h | 7 +- kaleid/include/kernel/multiboot.h | 7 +- kaleid/include/kernel/proc.h | 7 +- kaleid/include/kernel/sched.h | 20 +- kaleid/kernel/buf/bprint.c | 373 ++++++++++++++++++++++++++++++ kaleid/kernel/buf/bput.c | 141 +++++++++++ kaleid/kernel/buf/buf.c | 125 +--------- kaleid/kernel/init/init.c | 43 +++- kaleid/kernel/ke/panic.c | 8 +- kaleid/kernel/mm/heap.c | 5 +- kaleid/kernel/mm/malloc.c | 1 + kaleid/kernel/mm/map.c | 32 +-- kaleid/kernel/proc/sched.c | 256 ++++++++++---------- 25 files changed, 795 insertions(+), 358 deletions(-) create mode 100644 kaleid/kernel/buf/bprint.c create mode 100644 kaleid/kernel/buf/bput.c diff --git a/Makefile b/Makefile index ff578a4..2b68887 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,8 @@ kal_kern_obj= $(KOBJDIR)/kernel/cpuid.o $(KOBJDIR)/kernel/init.o \ $(KOBJDIR)/kernel/term.o $(KOBJDIR)/kernel/vga.o \ $(KOBJDIR)/kernel/panic.o $(KOBJDIR)/kernel/map.o \ $(KOBJDIR)/kernel/heap.o $(KOBJDIR)/kernel/malloc.o \ - $(KOBJDIR)/kernel/buf.o + $(KOBJDIR)/kernel/buf.o $(KOBJDIR)/kernel/sched.o \ + $(KOBJDIR)/kernel/bput.o $(KOBJDIR)/kernel/bprint.o \ $(KOBJDIR)/kernel/cpuid.o: $(KERNELDIR)/kernel/cpu/cpuid.c $(KERNELDIR)/include/*/*.h @$(KCC) $< -o $@ @@ -164,6 +165,15 @@ $(KOBJDIR)/kernel/malloc.o: $(KERNELDIR)/kernel/mm/malloc.c $(KERNELDIR)/include $(KOBJDIR)/kernel/buf.o: $(KERNELDIR)/kernel/buf/buf.c $(KERNELDIR)/include/*/*.h @$(KCC) $< -o $@ @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/bput.o: $(KERNELDIR)/kernel/buf/bput.c $(KERNELDIR)/include/*/*.h + @$(KCC) $< -o $@ + @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/bprint.o: $(KERNELDIR)/kernel/buf/bprint.c $(KERNELDIR)/include/*/*.h + @$(KCC) $< -o $@ + @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/sched.o: $(KERNELDIR)/kernel/proc/sched.c $(KERNELDIR)/include/*/*.h + @$(KCC) $< -o $@ + @echo ${CL2}[$@] ${CL}Compiled.${CL3} ## MISC MAKEFILE ------------------------------------------------------------- # ./ProjectTree: ./.stylehlp_sh diff --git a/kaleid/crtlib/atoi.c b/kaleid/crtlib/atoi.c index fba62ca..3b1b737 100644 --- a/kaleid/crtlib/atoi.c +++ b/kaleid/crtlib/atoi.c @@ -28,9 +28,9 @@ // Do not change errno #define _ATOI_IMPL(_Name, _Type, _Func) \ _Type _Name(const char *str) { \ - __get_errno(old); \ + error_t old; geterrno(old); \ _Type ret = (_Type)_Func(str, NULL, 0); \ - __set_errno(old); \ + seterrno(old); \ return ret; \ } diff --git a/kaleid/crtlib/itoa.c b/kaleid/crtlib/itoa.c index 95c1bd7..52d45a8 100644 --- a/kaleid/crtlib/itoa.c +++ b/kaleid/crtlib/itoa.c @@ -72,7 +72,7 @@ char *ultoa(ulong i, char *str, int base) // Only handle base 2 -> 36 if (base < 2 || base > 36) { - __set_errno(EINVAL); + seterrno(EINVAL); *orig = '\0'; goto leave; } diff --git a/kaleid/crtlib/mem.c b/kaleid/crtlib/mem.c index 208cffc..cd158e9 100644 --- a/kaleid/crtlib/mem.c +++ b/kaleid/crtlib/mem.c @@ -37,12 +37,18 @@ void *malloc(size_t n) error_t rc; rc = KalAllocMemory(&ptr, n, 0, 0); - __set_errno(rc); - (void)rc; + if (rc > 0) seterrno(rc); return ptr; } +void *calloc(size_t n, size_t m) +{ + char *mem = malloc(n * m); + memzero(mem, n * m); + return mem; +} + void free(void *ptr) { error_t rc = KalFreeMemory(ptr); @@ -132,7 +138,7 @@ void *memsetd(void *ptr, int val, size_t dwords) { (void)val; (void)dwords; - __set_errno(ENOSYS); + seterrno(ENOSYS); return ptr; } diff --git a/kaleid/crtlib/strtol.c b/kaleid/crtlib/strtol.c index dbde8ab..91c943d 100644 --- a/kaleid/crtlib/strtol.c +++ b/kaleid/crtlib/strtol.c @@ -28,7 +28,7 @@ long strtol(const char *str, char **endp, int base) { (void)str; (void)endp; (void)base; - __set_errno(ENOSYS); + seterrno(ENOSYS); return 0; } @@ -36,7 +36,7 @@ ulong strtoul(const char *str, char **endp, int base) { (void)str; (void)endp; (void)base; - __set_errno(ENOSYS); + seterrno(ENOSYS); return 0; } diff --git a/kaleid/include/base/crtlib.h b/kaleid/include/base/crtlib.h index a62aa39..8e7af7b 100644 --- a/kaleid/include/base/crtlib.h +++ b/kaleid/include/base/crtlib.h @@ -33,7 +33,7 @@ extern "C" { #ifndef __error_t_defined #define __error_t_defined -typedef int error_t; +typedef unsigned int error_t; #endif #ifndef __size_t_defined @@ -66,14 +66,14 @@ extern error_t __errno; #define errno __errno #endif -#define __get_errno(x) error_t x = errno -#define __set_errno(x) (errno = (x)) +#define geterrno(x) ((x) = errno) +#define seterrno(x) (errno = (x)) #else #define errno -#define __get_errno(x) -#define __set_errno(x) +#define geterrno(x) ((void)x) +#define seterrno(x) ((void)x) #endif diff --git a/kaleid/include/base/types.h b/kaleid/include/base/types.h index 0a1815a..ab3b547 100644 --- a/kaleid/include/base/types.h +++ b/kaleid/include/base/types.h @@ -119,7 +119,7 @@ typedef struct { long quot, rem; } ldiv_t; #ifndef __error_t_defined #define __error_t_defined -typedef int error_t; +typedef uint error_t; #endif #ifndef __port_t_defined diff --git a/kaleid/include/extras/list.h b/kaleid/include/extras/list.h index fea7f2a..7c51556 100644 --- a/kaleid/include/extras/list.h +++ b/kaleid/include/extras/list.h @@ -22,10 +22,6 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// -#ifdef _KALEID_KERNEL -#error "extra/list.h - Not ready for kernel compilation" -#endif - #ifndef _KALBASE_H #include #endif @@ -74,7 +70,7 @@ struct ListNode_t static inline ListHead_t *ExCreateListHeadWithLock(Lock_t *lock) { - ListHead_t *head = KalAllocMemory(sizeof(ListHead_t)); + ListHead_t *head = malloc(sizeof(ListHead_t)); if (head == NULL) return NULL; @@ -101,7 +97,7 @@ static inline ListHead_t static inline ListNode_t *ExCreateNode(void *data) { - ListNode_t *node = KalAllocMemory(sizeof(ListNode_t)); + ListNode_t *node = malloc(sizeof(ListNode_t)); if (node == NULL) return NULL; @@ -118,7 +114,7 @@ static inline ListNode_t static inline ListHead_t *ExPrependNode(ListHead_t *head, ListNode_t *node) { - KalAssert(head && node); + assert(head && node); node->head = head; node->prev = NULL; @@ -146,7 +142,7 @@ static inline ListHead_t static inline ListHead_t *ExAppendNode(ListHead_t *head, ListNode_t *node) { - KalAssert(head && node); + assert(head && node); node->head = head; node->next = NULL; @@ -174,7 +170,7 @@ static inline ListHead_t static inline ListHead_t *ExAddNodeBefore(ListHead_t *head, ListNode_t *node1, ListNode_t *node2) { - KalAssert(head && node1 && node2 && node1->head == head); + assert(head && node1 && node2 && node1->head == head); if (head->first == node1) { return ExPrependNode(head, node2); @@ -200,7 +196,7 @@ static inline ListHead_t static inline ListHead_t *ExAddNodeAfter(ListHead_t *head, ListNode_t *node1, ListNode_t *node2) { - KalAssert(head && node1 && node2 && node1->head == head); + assert(head && node1 && node2 && node1->head == head); if (head->last == node1) { return ExAppendNode(head, node2); @@ -224,7 +220,7 @@ static inline ListHead_t static inline ListHead_t *ExRemoveNode(ListHead_t *head, ListNode_t *node) { - KalAssert(head && node && head->length > 0 && node->head == head); + assert(head && node && head->length > 0 && node->head == head); if (head->length == 1) { head->first = head->last = NULL; @@ -259,8 +255,8 @@ leave: static inline void ExDestroyNode(ListNode_t *node) { - KalAssert(node); - KalFreeMemory(node); + assert(node); + free(node); } // @@ -269,8 +265,8 @@ ExDestroyNode(ListNode_t *node) static inline void ExDestroyListHead(ListHead_t *head) { - KalAssert(head); - KalFreeMemory(head); + assert(head); + free(head); } // diff --git a/kaleid/include/extras/locks.h b/kaleid/include/extras/locks.h index af41152..eba1e36 100644 --- a/kaleid/include/extras/locks.h +++ b/kaleid/include/extras/locks.h @@ -32,6 +32,10 @@ #include #endif +#ifndef _KALKERN_SCHED_H +#include +#endif + #endif #ifndef _KALEXTRAS_LOCKS_H @@ -62,8 +66,8 @@ enum LockType_t struct Lock_t { unsigned int initDone; - LockType_t type; volatile int locked; + LockType_t type; /* #ifdef _KALEID_KERNEL Thread_t *ownerThread; // unused @@ -83,8 +87,8 @@ int KalYieldCPU(void), static inline void ExInitLock(Lock_t *lock, LockType_t type) { + lock->locked = 0; lock->type = type; - lock->locked = FALSE; lock->initDone = INITOK; /* #ifdef _KALEID_KERNEL lock->ownerThread = NULL; @@ -96,9 +100,9 @@ void ExInitLock(Lock_t *lock, LockType_t type) // Alternative way to initalize a lock // #ifdef _KALEID_KERNEL -# define ExINITLOCK(type) { INITOK, FALSE, (type), /* NULL, NULL */ } +# define ExINITLOCK(type) { INITOK, 0, (type), /* NULL, NULL */ } #else -# define ExINITLOCK(type) { INITOK, FALSE, (type) } +# define ExINITLOCK(type) { INITOK, 0, (type) } #endif // @@ -119,18 +123,29 @@ void ExDestroyLock(Lock_t *lock) // until we have at least a basic scheduler // static inline +#if defined(_KALEID_KERNEL) && !defined(_NO_DEBUG) +#define ExAcquireLock(lock) \ + _ExAcquireLock(lock,__FILE__, __LINE__, __func__,#lock) +void _ExAcquireLock(Lock_t *lock, const char *file, int line, + const char *func, const char *obj) +#else void ExAcquireLock(Lock_t *lock) +#endif { KalAssert(lock->initDone == INITOK); while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) { -#ifdef _KALEID_KERNEL - KeStartPanic("AcquireLock on an already locked object"); -#else - if likely (lock->type == KLOCK_SPINLOCK) continue; - else (void)KalYieldCPU(); +#if defined(_KALEID_KERNEL) && !defined(_NO_DEBUG) + KeStartPanic( + "In function '%s', from '%s' line %d\n" + "Double ExAcquireLock on object: '%s'", + func, file, line, obj); #endif + /*if likely (lock->type == KLOCK_SPINLOCK)*/ + continue; + //else (void)KalYieldCPU(); } + PsDisablePreemption(); __sync_synchronize(); } @@ -146,7 +161,9 @@ void ExReleaseLock(Lock_t *lock) #endif*/ __sync_synchronize(); + lock->locked = 0; + PsEnablePreemption(); } // diff --git a/kaleid/include/kernel/base.h b/kaleid/include/kernel/base.h index d15b63a..7ae02d7 100644 --- a/kaleid/include/kernel/base.h +++ b/kaleid/include/kernel/base.h @@ -56,13 +56,12 @@ typedef enum TermColor_t TermColor_t; #endif // Current CPU number -// Will return a CPU-local variable later -#define _KeGetCurCPU() 0 +#define _KeCurCPU 0 -// Get Process_t structure of current CPU -#define KeGetCurCPU() (cpuTable[_KeGetCurCPU()]) +// Process_t structure of current CPU +#define KeCurCPU (cpuTable[_KeCurCPU]) -//Get the BootInfo_t structure +// Access the BootInfo_t structure #define BtGetBootInfo(x) (bootTab.x) //------------------------------------------// diff --git a/kaleid/include/kernel/buf.h b/kaleid/include/kernel/buf.h index 13520d5..eb6cf48 100644 --- a/kaleid/include/kernel/buf.h +++ b/kaleid/include/kernel/buf.h @@ -69,9 +69,9 @@ struct Buffer_t size_t size; // Current size - char *buf; // Beginning of buffer - char *rp; // Read pointer - char *wp; // Write pointer + uchar *buf; // Beginning of buffer + uchar *rp; // Read pointer + uchar *wp; // Write pointer BFlusher_t flusher; // Called for flushing @@ -107,7 +107,7 @@ bool BTrylockBuf(Buffer_t *buf); error_t BFlushBuf(Buffer_t *buf); error_t BPutOnBuf(Buffer_t *buf, uchar ch); -error_t BPrintOnBuf(Buffer_t *buf, size_t n, const char *fmt, ...); -error_t BPrintOnBufV(Buffer_t *buf, size_t n, const char *fmt, va_list ap); +error_t BPrintOnBuf(Buffer_t *buf, const char *fmt, ...); +error_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap); #endif diff --git a/kaleid/include/kernel/heap.h b/kaleid/include/kernel/heap.h index 9783c36..d8f4c78 100644 --- a/kaleid/include/kernel/heap.h +++ b/kaleid/include/kernel/heap.h @@ -31,7 +31,7 @@ //------------------------------------------// -#define _HEAP_START (4 * MB) +#define _HEAP_START (8 * MB) void MmInitHeap(void); diff --git a/kaleid/include/kernel/mm.h b/kaleid/include/kernel/mm.h index a70cdce..9fc07e1 100644 --- a/kaleid/include/kernel/mm.h +++ b/kaleid/include/kernel/mm.h @@ -44,7 +44,7 @@ struct MapEntry_t { void *addr; size_t length; // in bytes uint type; // reserved or not -} __attribute__((packed)); +} __attribute__((__packed__)); // the map structure struct MemoryMap_t { @@ -52,7 +52,7 @@ struct MemoryMap_t { size_t freeRamSize; size_t nonfreeRamSize; MapEntry_t entry[MAX_ENTRIES]; -} __attribute__((packed)); +} __attribute__((__packed__)); @@ -64,7 +64,8 @@ struct MemoryMap_t { error_t MmInitMemoryMap(void); // -// Returns the size of the first available memory zone from the start address pointer +// Returns the size of the first available memory zone +// from the start address pointer // size_t MmGetAvailZoneSize(void *start); diff --git a/kaleid/include/kernel/multiboot.h b/kaleid/include/kernel/multiboot.h index 896f23d..27da31f 100644 --- a/kaleid/include/kernel/multiboot.h +++ b/kaleid/include/kernel/multiboot.h @@ -96,7 +96,7 @@ typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; -typedef unsigned long long ullong; +typedef unsigned long ulong; struct multiboot_header { @@ -141,7 +141,8 @@ struct multiboot_elf_section_header_table uint addr; uint shndx; }; -typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; +typedef struct multiboot_elf_section_header_table + multiboot_elf_section_header_table_t; struct multiboot_info { @@ -193,7 +194,7 @@ struct multiboot_info ushort vbe_interface_off; ushort vbe_interface_len; - ullong framebuffer_addr; + ulong framebuffer_addr; uint framebuffer_pitch; uint framebuffer_width; uint framebuffer_height; diff --git a/kaleid/include/kernel/proc.h b/kaleid/include/kernel/proc.h index 68b4770..2e4e962 100644 --- a/kaleid/include/kernel/proc.h +++ b/kaleid/include/kernel/proc.h @@ -77,8 +77,11 @@ struct Process_t //------------------------------------------// -DEC_PER_CPU(Ps, CurProc, process, Process_t *); -DEC_PER_CPU(Ps, CurThread, thread, Thread_t *); +#define PsCurProc (KeCurCPU.process) +#define PsCurThread (KeCurCPU.thread) + +//DEC_PER_CPU(Ps, CurProc, process, Process_t *); +//DEC_PER_CPU(Ps, CurThread, thread, Thread_t *); //------------------------------------------// diff --git a/kaleid/include/kernel/sched.h b/kaleid/include/kernel/sched.h index 694aaff..76bd799 100644 --- a/kaleid/include/kernel/sched.h +++ b/kaleid/include/kernel/sched.h @@ -39,7 +39,7 @@ enum { PREEMPT_ON = 0 }; // Time in ticks a process should be run enum { - DEF_PROC_TSLICE = 5, // 20 ticks + DEF_PROC_TSLICE = 3, // 20 ticks TCR_PROC_TSLICE = 20000 // 20000 ticks (time critical) }; @@ -57,24 +57,14 @@ extern const char *PsPrioClassesNames[]; //------------------------------------------// -DEC_PER_CPU(Ps, ReSchedFlag, needReSched, bool); -DEC_PER_CPU(Ps, PreemptCount, preemptCount, ulong); - -DEC_PER_CPU(Ps, IdlePrioProcs, idlePrioProcs, ListHead_t *); -DEC_PER_CPU(Ps, ReglPrioProcs, reglPrioProcs, ListHead_t *); -DEC_PER_CPU(Ps, ServPrioProcs, servPrioProcs, ListHead_t *); -DEC_PER_CPU(Ps, TimeCritProcs, timeCritProcs, ListHead_t *); - -//------------------------------------------// - // // Re-scheduling and preemption // XXX atomic operations // -#define PsSetReSchedFlag(x) _PsSetReSchedFlag(x) -#define PsDisablePreemption() _PsSetPreemptCount(GetPreemptCount()+1) -#define PsEnablePreemption() do { KalAssert(GetPreemptCount() > 0); \ - _PsSetPreemptCount(GetPreemptCount()-1); } while(0) +#define PsRequestReSched() (++KeCurCPU.needReSched) +#define PsDisablePreemption() (++KeCurCPU.preemptCount) +#define PsEnablePreemption() do { assert(KeCurCPU.preemptCount > 0); \ + --KeCurCPU.preemptCount; } while(0) //------------------------------------------// diff --git a/kaleid/kernel/buf/bprint.c b/kaleid/kernel/buf/bprint.c new file mode 100644 index 0000000..749100a --- /dev/null +++ b/kaleid/kernel/buf/bprint.c @@ -0,0 +1,373 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Buffer library // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include + +#include //XXX + +error_t bputc(Buffer_t *buf, uchar ch); + +// +// Prints formatted string on buf according to fmt +// +error_t BPrintOnBuf(Buffer_t *buf, const char *fmt, ...) +{ + error_t rc; + va_list ap; + + va_start(ap, fmt); + rc = BPrintOnBufV(buf, fmt, ap); + va_end(ap); + + return rc; +} +// +// Prints 0 for octal, 0x for hexadecimal, 0b for binary +// +static error_t bprinthash(Buffer_t *buf, int base, int cap) +{ + error_t rc; + + if (base != 2 && base != 8 && base != 16) { + return EOK; + } + + rc = bputc(buf, '0'); + + if (!rc && base != 8) { + rc = bputc(buf, (base==2 ? 'b' : (cap ? 'X' : 'x'))); + } + + return rc; +} + +static error_t bdopadding(Buffer_t *buf, size_t width, size_t len, + char filler) +{ + error_t rc = EOK; + + for (; !rc && width > len ; width--) { + rc = bputc(buf, filler); + } + + return rc; +} + + +// Increase fmt while parsing a modifier +#define fmtnext() do{fmt++;if(*fmt==0){rc=EINVAL;goto leave;}}while(0) + +// +// Actually does BPrintOnBuf's job +// Quite a long function +// +error_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap) +{ + error_t rc = EOK; + int tmpwidth; + size_t width; + char type; + + uchar *s; + uchar uch; + + // Conversion buffer + uchar convbuf[100] = {0}; + size_t len; + + // Flags + int plus, minus, space, zero, hash; + + // Length modifiers + int l, h, hh; + + // Signed + bool sgn; + + // Capital digits + bool cap; + + // Base + int base; + + assert(buf && buf->initDone == INITOK); + + if (!buf) return EINVAL; + if (buf->state != BS_RDWR && buf->state != BS_WRONLY) { + return EBADF; + } + + ExAcquireLock(&buf->lock); + +//----------------------------------------------------------------------------// + + // We come back here after dealing with a modifier +loop: + + // Deal with all non-'%' characters + for (; !rc && *fmt && *fmt != '%' ; fmt++) { + rc = bputc(buf, *fmt); + continue; + } + + // Job's done / something bad happened + if (rc || !*fmt) goto leave; + +//----------------------------------------------------------------------------// + + // + // %[parameter][flags][width|*][.precision][length]type + // We aren't dealing with parameters and float stuff just yet + // + + // Skip the '%' + fmtnext(); + + // "%%" modifier + if (*fmt == '%') { + rc = bputc(buf, '%'); + + if (rc > 0) goto leave; + else { + fmt++; + goto loop; + } + } + + // Reset everything + width = 0; + cap = sgn = 0; + l = h = hh = 0; + plus = minus = space = zero = hash = 0; + +//----------------------------------------------------------------------------// + + // + // Flags field + // + while (1) { + if (*fmt == '#') hash++; + else if (*fmt == '0') zero++; + else if (*fmt == '+') plus++; + else if (*fmt == '-') minus++; + else if (*fmt == ' ') space++; + else break; + fmtnext(); + } + +//----------------------------------------------------------------------------// + + // + // Width field + // A width field of zero is ignored + // + + // '*' means we should extract it from the argument list + if (*fmt == '*') { + fmtnext(); + tmpwidth = va_arg(ap, int); + + // A width below 0 activates the "minus" flag + if (tmpwidth < 0) { + width = -tmpwidth; + minus++; + } else { + width = tmpwidth; + } + } else { + // Extract width field from fmt + while (isdigit(*fmt) && width < sizeof(convbuf)-10) { + width = 10 * width + (*fmt - '0'); + fmtnext(); + } + } + + if (width > sizeof(convbuf)) { + rc = EINVAL; + goto leave; + } + +//----------------------------------------------------------------------------// + + // + // Precision field + // Ignored until floats are implemented + // + +//----------------------------------------------------------------------------// + + // + // Length field + // + while (1) { + if (*fmt == 'l' || *fmt == 'z') l++; + else if (*fmt == 'h') h++; + else break; + fmtnext(); + } + + // Consistency check + assert(!(l > 0 && h > 0)); + assert(!(l > 2 || h > 2)); + +//----------------------------------------------------------------------------// + + // + // The type field, finally! + // + type = *fmt++; + + // Characters + if (type == 'c') { + uch = (uchar)va_arg(ap, int); + bputc(buf, uch); + + goto loop; + } + + // Strings + else if (type == 's') { + s = (uchar *)va_arg(ap, char *); + + for (; !rc && *s ; s++) { + rc = bputc(buf, *s); + } + + if (rc > 0) goto leave; + goto loop; + } + + // Decimal, unsigned decimal, hexadecimal, octal and binary numbers + else if (type == 'd' || type == 'i') { base = 10; sgn = 1; } + else if (type == 'X') { base = 16; cap = 1; } + else if (type == 'x') { base = 16; } + else if (type == 'u') { base = 10; } + else if (type == 'o') { base = 8; } + else if (type == 'b') { base = 2; } + + // Pointers: %p = %#012x + // (48-bit pointers have width 12 at least) + else if (type == 'p') { + type = 'x'; base = 16; zero++; hash++; + if (width < 12) width = 12; + } + + // Unknown/unsupported modifier + else { + rc = EINVAL; + goto leave; + } + +//----------------------------------------------------------------------------// + + // + // Numerical conversions + // + + // We re-use s to iterate convbuf + s = convbuf; + + // Deal with signed conversions + if (sgn) { + if (l) ltoa(va_arg(ap, long), (char *)s, base); + else if (h == 0) itoa(va_arg(ap, int), (char *)s, base); + else if (h == 1) itoa((short)va_arg(ap, int), (char *)s, base); + else /* h == 2 */ itoa((char)va_arg(ap, int), (char *)s, base); + } + + // Deal with unsigned conversions + else { + if (l) ultoa((ulong)va_arg(ap, long), (char *)s, base); + else if (h == 0) utoa((uint)va_arg(ap, int), (char *)s, base); + else if (h == 1) utoa((ushort)va_arg(ap, int), (char *)s, base); + else /* h == 2 */ utoa((uchar)va_arg(ap, int), (char *)s, base); + } + +//----------------------------------------------------------------------------// + + // + // Implement flags and %X + // + + // Capital letter digits + if (base > 10 && cap) { + for (; *s ; s++) + if (islower(*s)) *s = toupper(*s); + + // We use this "opportunity" to compute the length of s + len = s - convbuf; + + // Reset s + s = convbuf; + } + else len = strlen((char *)s); + + // Adjust width + if (sgn && (plus || space)) width--; + else if (hash) width -= (base==8 ? 1 : ((base==2||base==16) ? 2 : 0)); + + // When padding with spaces, we pad before +/-'s etc + if (!minus && !zero && width > len) + bdopadding(buf, width, len, ' '); + + // Deal with signs and the hash flag + if (*s == '-') { rc = bputc(buf, '-'); s++, len--; } + else if (sgn && plus) rc = bputc(buf, '+'); + else if (sgn && space) rc = bputc(buf, ' '); + else bprinthash(buf, base, cap); + + // Deal with padding by zeroes + // The 'minus' flag makes no sense with the 'zero' one + if (zero && width > len) + bdopadding(buf, width, len, '0'); + + // + // Output the actual number + // + for (; !rc && *s ; s++) { + rc = bputc(buf, *s); + } + + // 'minus' padding, only with spaces + if (minus && !zero && width > len) + bdopadding(buf, width, base, ' '); + + if (rc > 0) goto leave; + + +//----------------------------------------------------------------------------// + + // Make sure we leave convbuf filled with NULs + memzero(convbuf, sizeof(convbuf)); + + // Continue parsing fmt + goto loop; + +//----------------------------------------------------------------------------// + +leave: + ExReleaseLock(&buf->lock); + return rc; +} + diff --git a/kaleid/kernel/buf/bput.c b/kaleid/kernel/buf/bput.c new file mode 100644 index 0000000..46ce839 --- /dev/null +++ b/kaleid/kernel/buf/bput.c @@ -0,0 +1,141 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Buffer library // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include + +error_t bputc(Buffer_t *buf, uchar ch); + +// +// Writes a character on a buffer +// +error_t BPutOnBuf(Buffer_t *buf, uchar ch) +{ + error_t rc; + assert(buf && buf->initDone == INITOK); + + if (!buf) return EINVAL; + if (buf->state != BS_RDWR && buf->state != BS_WRONLY) { + return EBADF; + } + + ExAcquireLock(&buf->lock); + rc = bputc(buf, ch); + ExReleaseLock(&buf->lock); + return rc; +} + +// +// Internal, unlocked version of BPutOnBuf +// +error_t bputc(Buffer_t *buf, uchar ch) +{ + error_t rc; + size_t bufSize, pbCount; + + // Implements playback / scrolling up when line buffering + // Note that '\n', '\r' and '\t' can never occur in the buffer + // That should change; there should be a flag for it + if (buf->flags & BF_LINE) { + + // Deal with carriage returns + if (ch == '\r') { + buf->wp -= buf->lastLF; + buf->lastLF = 0; + assert(buf->wp >= buf->buf); + } + + // Deal with tabs... we need a tabSize field + // We assume tabs are 4 characters long for now + else if (ch == '\t') { + rc = bputc(buf, ' '); + if (rc > 0) return rc; + + while (buf->lastLF % 4 > 0) { + rc = bputc(buf, ' '); + if (rc > 0) return rc; + } + } + + // Deal with line feeds by filling the rest of the line with spaces + // We need a field for choosing a different filler, e.g. '\0' + else if (ch == '\n') { + assert(buf->lastLF < buf->lineLen); + while (buf->lastLF > 0) { + rc = bputc(buf, ' '); + if (rc > 0) return rc; + } + } + + // Just a regular character + else { + // Do we have to scroll up? + if (buf->wp == buf->buf + buf->size) { + // Yes, so we give up a whole playback buffer worth + // of lines so we don't have to do this too often + // (basically we make the current buffer a pb one) + bufSize = buf->nLines * buf->lineLen; + pbCount = (buf->size / bufSize) - 1; + + // Paranoia check + assert(buf->size >= (size_t)(buf->nLines * buf->lineLen)); + + // If we only have one playback buffer we just give up a line + if (pbCount == 0) { + // Use of memcpy() is safe because the source occur + // after the destination + memcpy(buf->buf, buf->buf + buf->lineLen, + buf->size - buf->lineLen); + buf->wp -= buf->lineLen; + } + + // We do have a playback buffer worth of lines to give up + else { + memcpy(buf->buf, buf->buf + bufSize, + buf->size - bufSize); + buf->wp -= buf->lineLen; + } + } + + // Write the damn thing + *buf->wp++ = ch; + + // Did we reach the end of line? + if (++buf->lastLF == buf->lineLen) { + buf->lastLF = 0; + } + } + + return EOK; + } + + // No scrolling up when not line-buffering + else { + if (buf->wp == buf->buf + buf->size) { + buf->state = BS_EOF; + } + + return ENOSYS; + } +} + diff --git a/kaleid/kernel/buf/buf.c b/kaleid/kernel/buf/buf.c index 3491ffd..0c42c10 100644 --- a/kaleid/kernel/buf/buf.c +++ b/kaleid/kernel/buf/buf.c @@ -47,9 +47,7 @@ void BFlushOnClose(Buffer_t *buf) { buf->flags |= BF_FONCLOSE; } // error_t BCloseBuf(Buffer_t *buf) { - if (!buf) return EINVAL; - - assert(buf->initDone == INITOK); + assert(buf && buf->initDone == INITOK); ExAcquireLock(&buf->lock); if (buf->flags & BF_FONCLOSE) { @@ -109,9 +107,9 @@ Buffer_t *BOpenLineBuf(char *source, int mode, buf->size = lineLen * nLines * (pbCount + 1); if (source == NULL) { - buf->buf = malloc(buf->size); + buf->buf = calloc(buf->size, 1); } else { - buf->buf = source; + buf->buf = (uchar *)source; } buf->wp = buf->rp = buf->buf; @@ -143,121 +141,4 @@ error_t BFlushBuf(Buffer_t *buf) return rc; } -static error_t bputc(Buffer_t *buf, uchar ch); - -// -// Writes a character on a buffer -// -error_t BPutOnBuf(Buffer_t *buf, uchar ch) -{ - error_t rc; - assert(buf && buf->initDone == INITOK); - - if (!buf) return EINVAL; - if (buf->state != BS_RDWR && buf->state != BS_WRONLY) { - return EBADF; - } - - ExAcquireLock(&buf->lock); - rc = bputc(buf, ch); - ExReleaseLock(&buf->lock); - return rc; -} - -// -// Internal, unlocked version of BPutOnBuf -// -static error_t bputc(Buffer_t *buf, uchar ch) -{ - error_t rc; - size_t bufSize, pbCount; - - // Implements playback / scrolling up when line buffering - // Note that '\n', '\r' and '\t' can never occur in the buffer - // That should change; there should be a flag for it - if (buf->flags & BF_LINE) { - - // Deal with carriage returns - if (ch == '\r') { - buf->wp -= buf->lastLF; - buf->lastLF = 0; - assert(buf->wp >= buf->buf); - } - - // Deal with tabs... we need a tabSize field - // We assume tabs are 4 characters long for now - else if (ch == '\t') { - rc = bputc(buf, ' '); - if (rc > 0) return rc; - - while (buf->lastLF % 4 > 0) { - rc = bputc(buf, ' '); - if (rc > 0) return rc; - } - } - - // Deal with line feeds by filling the rest of the line with spaces - // We need a field for choosing a different filler, e.g. '\0' - else if (ch == '\n') { - assert(buf->lastLF < buf->lineLen); - while (buf->lastLF > 0) { - rc = bputc(buf, ' '); - if (rc > 0) return rc; - } - } - - // Just a regular character - else { - // Do we have to scroll up? - if (buf->wp == buf->buf + buf->size) { - // Yes, so we give up a whole playback buffer worth - // of lines so we don't have to do this too often - // (basically we make the current buffer a pb one) - bufSize = buf->nLines * buf->lineLen; - pbCount = (buf->size / bufSize) - 1; - - // Paranoia check - assert(buf->size >= (size_t)(buf->nLines * buf->lineLen)); - - // If we only have one playback buffer we just give up a line - if (pbCount == 0) { - // Use of memcpy() is safe because the source occur - // after the destination - memcpy(buf->buf, buf->buf + buf->lineLen, - buf->size - buf->lineLen); - buf->wp -= buf->lineLen; - } - - // We do have a playback buffer worth of lines to give up - else { - memcpy(buf->buf, buf->buf + bufSize, - buf->size - bufSize); - buf->wp -= buf->lineLen; - } - } - - // Write the damn thing - *buf->wp++ = (char)ch; - - // Did we reach the end of line? - if (++buf->lastLF == buf->lineLen) { - buf->lastLF = 0; - } - } - - return EOK; - } - - // No scrolling up when not line-buffering - else { - if (buf->wp == buf->buf + buf->size) { - buf->state = BS_EOF; - } - - return ENOSYS; - } -} - -error_t BPrintOnBuf(Buffer_t *buf, size_t n, const char *fmt, ...); -error_t BPrintOnBufV(Buffer_t *buf, size_t n, const char *fmt, va_list ap); diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index bd07433..7ec185b 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -24,7 +24,10 @@ #include #include +#include #include +#include +#include #include // @@ -33,8 +36,8 @@ // void BtInitBootInfo(multiboot_info_t *mbi) { - extern ullong MB_header; - extern ullong kernelEnd; + extern ulong MB_header; + extern ulong kernelEnd; // We need the multiboot structure KalAlwaysAssert(mbi); @@ -43,19 +46,19 @@ void BtInitBootInfo(multiboot_info_t *mbi) BtGetBootInfo(btldr).grubFlags = mbi->flags; if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) { - BtGetBootInfo(btldr).grubName = (char*)(ullong)(mbi->boot_loader_name); + BtGetBootInfo(btldr).grubName = (char*)(ulong)(mbi->boot_loader_name); BtGetBootInfo(btldr).kernelAddr = (void*)&MB_header; BtGetBootInfo(btldr).kernelEndAddr = (void*)&kernelEnd; BtGetBootInfo(btldr).valid = 1; } if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MODS) { BtGetBootInfo(btldr).modulesCount = mbi->mods_count; - BtGetBootInfo(btldr).modulesAddr = (void*)(ullong)mbi->mods_addr; + BtGetBootInfo(btldr).modulesAddr = (void*)(ulong)mbi->mods_addr; } //Retrieves the drives informations if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_DRIVE_INFO) { BtGetBootInfo(drives).bufferLength = mbi->drives_length; - BtGetBootInfo(drives).bufferAddr = (void*)(ullong)mbi->drives_addr; + BtGetBootInfo(drives).bufferAddr = (void*)(ulong)mbi->drives_addr; BtGetBootInfo(drives).bufferValid = 1; } if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOTDEV) { @@ -70,15 +73,15 @@ void BtInitBootInfo(multiboot_info_t *mbi) BtGetBootInfo(memory).memValid = 1; } if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MEM_MAP) { - BtGetBootInfo(memory).mapAddr = (void*)(ullong)mbi->mmap_addr; + BtGetBootInfo(memory).mapAddr = (void*)(ulong)mbi->mmap_addr; BtGetBootInfo(memory).mapLength = mbi->mmap_length; BtGetBootInfo(memory).mapValid = 1; } // Retrieves video mode informations if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_VBE_INFO) { - BtGetBootInfo(video).vbeControl = (void*)(ullong)mbi->vbe_control_info; - BtGetBootInfo(video).vbeModeInfo = (void*)(ullong)mbi->vbe_mode_info; + BtGetBootInfo(video).vbeControl = (void*)(ulong)mbi->vbe_control_info; + BtGetBootInfo(video).vbeModeInfo = (void*)(ulong)mbi->vbe_mode_info; BtGetBootInfo(video).vbeMode = mbi->vbe_mode; BtGetBootInfo(video).vbeInterfaceSeg = mbi->vbe_interface_seg; BtGetBootInfo(video).vbeInterfaceOff = mbi->vbe_interface_off; @@ -86,7 +89,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) BtGetBootInfo(video).vbeValid = 1; } if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) { - BtGetBootInfo(video).framebufferAddr = (void*)(ullong)mbi->framebuffer_addr; + BtGetBootInfo(video).framebufferAddr = (void*)mbi->framebuffer_addr; BtGetBootInfo(video).framebufferPitch = mbi->framebuffer_pitch; BtGetBootInfo(video).framebufferWidth = mbi->framebuffer_width; BtGetBootInfo(video).framebufferHeight= mbi->framebuffer_height; @@ -106,6 +109,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) } } +extern void pstest(void); // // Entry point of the Kaleid kernel @@ -138,12 +142,27 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, int mbMagic) mapBad ); - KernLog("[Init] TEST First zone from %p : %p\n", (void*)0xB8010, MmGetFirstAvailZone((void*)0xB8010)); - KernLog("[Init] TEST Size of zone : %u Kio\n\n", MmGetAvailZoneSize(MmGetFirstAvailZone((void*)0xB8010)) / KB); + KernLog("[Init] TEST First zone from %p : %p\n", (void*)0xB8010, + MmGetFirstAvailZone((void*)0xB8010)); + KernLog("[Init] TEST Size of zone : %u Kio\n\n", + MmGetAvailZoneSize(MmGetFirstAvailZone((void*)0xB8010)) / KB); + MmInitHeap(); + PsInitSched(); + ClearTerm(StdOut); + + Buffer_t *buf = BOpenLineBuf(NULL, BS_WRONLY, 80, 24, 1, NULL); + + //BPrintOnBuf(buf, "xxx\nxxx\ry\tw\n%d %s\n%%%p", 1, "abcd", 0); + //int i; for(i=0;i<100;i++) BPrintOnBuf(buf,"%d\n",i); + + error_t rc = BPrintOnBuf(buf, "%+#05X", 0xcafeb00b); + if(rc)KernLog("error\n"); + + KernLog((char*)buf->buf); // We're out - KernLog("\n[Init] Evil never dies !\n"); + PsFiniSched(); KeCrashSystem(); //yay } diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c index 9c9f56b..181ab5b 100644 --- a/kaleid/kernel/ke/panic.c +++ b/kaleid/kernel/ke/panic.c @@ -35,10 +35,8 @@ noreturn void __assert_handler(const char *msg, { KeDisableIRQs(); - (void)file; (void)line; (void)func; - - KeStartPanic("In function '%s', from %s line %d - assertion failed: '%s'", - func, file, line, msg); + KeStartPanic("In function '%s', from '%s' line %d\nAssertion failed:\n" + "'%s'", func, file, line, msg); } // @@ -51,7 +49,7 @@ noreturn void KeStartPanic(const char *fmt, ...) KeDisableIRQs(); - if (PsGetCurProc()) _PsSetCurProc(NULL); + PsCurProc = NULL; if (StdOut == NULL) KeCrashSystem(); if (fmt == NULL) { diff --git a/kaleid/kernel/mm/heap.c b/kaleid/kernel/mm/heap.c index 54c700b..16c8fe9 100644 --- a/kaleid/kernel/mm/heap.c +++ b/kaleid/kernel/mm/heap.c @@ -34,7 +34,6 @@ static size_t _heap_max; // Lock NOT used internally, but used by KalAllocMemory() & co. static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK); - // // Initializes heap managment // @@ -100,7 +99,7 @@ error_t MmSetMaxHeapSize(size_t new) // error_t MmGrowHeap(size_t req) { - assert(req % alignof(QWORD)); + assert(req % alignof(QWORD) == 0); if ((size_t)_heap_end + req > _HEAP_START + _heap_max) { return ENOMEM; @@ -116,7 +115,7 @@ error_t MmGrowHeap(size_t req) // error_t MmShrinkHeap(size_t req) { - assert(req % alignof(QWORD)); + assert(req % alignof(QWORD) == 0); if (req > (size_t)_heap_end - _HEAP_START) { return EADDRINUSE; diff --git a/kaleid/kernel/mm/malloc.c b/kaleid/kernel/mm/malloc.c index 1c699a2..6d7262a 100644 --- a/kaleid/kernel/mm/malloc.c +++ b/kaleid/kernel/mm/malloc.c @@ -57,6 +57,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align) *ptr = (void *)brk; + assert(*ptr); return rc; } diff --git a/kaleid/kernel/mm/map.c b/kaleid/kernel/mm/map.c index 320a9b3..80759d4 100644 --- a/kaleid/kernel/mm/map.c +++ b/kaleid/kernel/mm/map.c @@ -52,23 +52,23 @@ error_t MmInitMemoryMap(void) currentEntry = (multiboot_memory_map_t*)BtGetBootInfo(memory).mapAddr; // End address of the map mapEnd = (multiboot_memory_map_t*) - ((ullong)currentEntry + (ullong)BtGetBootInfo(memory).mapLength); + ((ulong)currentEntry + (ulong)BtGetBootInfo(memory).mapLength); // fill the map while (currentEntry < mapEnd) { // memory zone address - memoryMap.entry[i].addr = (void*)( (ullong)currentEntry->addr_low + - (((ullong)currentEntry->addr_high) << 32 )); + memoryMap.entry[i].addr = (void*)((ulong)currentEntry->addr_low + + (((ulong)currentEntry->addr_high) << 32 )); // memory zone size in bytes - memoryMap.entry[i].length = (ullong)currentEntry->len_low + - (((ullong)currentEntry->len_high) << 32); + memoryMap.entry[i].length = (ulong)currentEntry->len_low + + (((ulong)currentEntry->len_high) << 32); // memory availability memoryMap.entry[i].type = (uint)currentEntry->type; // Adding the size to the size (yup) memoryMap.length++; // moving up ! - currentEntry = (multiboot_memory_map_t*) ((ullong)currentEntry + - currentEntry->size + sizeof(currentEntry->size)); + currentEntry = (multiboot_memory_map_t*) ((ulong)currentEntry + + currentEntry->size + sizeof(currentEntry->size)); i++; } @@ -108,11 +108,11 @@ size_t MmGetAvailZoneSize(void *start) { // if the address is in an available zone, we can return the length if ( memoryMap.entry[i].type == AVAILABLE_ZONE && - (ullong)start >= (ullong)memoryMap.entry[i].addr && - (ullong)start < ((ullong)memoryMap.entry[i].addr + - (ullong)memoryMap.entry[i].length) + (ulong)start >= (ulong)memoryMap.entry[i].addr && + (ulong)start < ((ulong)memoryMap.entry[i].addr + + (ulong)memoryMap.entry[i].length) ) { - return (size_t)((ullong)memoryMap.entry[i].length - (ullong)start); + return (size_t)((ulong)memoryMap.entry[i].length - (ulong)start); } } @@ -125,7 +125,7 @@ void *MmGetFirstAvailZone(void *start) { void *current = 0; // Because the kernel is the kernel - if ((ullong)start < (ullong)BtGetBootInfo(btldr).kernelEndAddr) { + if ((ulong)start < (ulong)BtGetBootInfo(btldr).kernelEndAddr) { return MmGetFirstAvailZone(BtGetBootInfo(btldr).kernelEndAddr); } @@ -134,9 +134,9 @@ void *MmGetFirstAvailZone(void *start) { // if the address is in an available zone, we can return the start address if ( memoryMap.entry[i].type == AVAILABLE_ZONE && - (ullong)start >= (ullong)memoryMap.entry[i].addr && - (ullong)start < ((ullong)memoryMap.entry[i].addr + - (ullong)memoryMap.entry[i].length) + (ulong)start >= (ulong)memoryMap.entry[i].addr && + (ulong)start < ((ulong)memoryMap.entry[i].addr + + (ulong)memoryMap.entry[i].length) ) { current = start; break; @@ -151,7 +151,7 @@ void *MmGetFirstAvailZone(void *start) { // Return the first zone that is after start if ( memoryMap.entry[i].type == AVAILABLE_ZONE && - (ullong)start <= (ullong)memoryMap.entry[i].addr + (ulong)start <= (ulong)memoryMap.entry[i].addr ) { current = memoryMap.entry[i].addr; break; diff --git a/kaleid/kernel/proc/sched.c b/kaleid/kernel/proc/sched.c index d8ba70d..2b75f5d 100644 --- a/kaleid/kernel/proc/sched.c +++ b/kaleid/kernel/proc/sched.c @@ -25,10 +25,7 @@ #include #include #include - -#ifndef _KALEID_KERNEL - -#include +#include // // For test purpose only @@ -47,18 +44,25 @@ Process_t procs[] = { { 9, 2, 2, 21, 21, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL, NULL, NULL }, }; -#endif +//------------------------------------------// + +#define ReSchedFlag (KeCurCPU.needReSched) +#define PreemptCount (KeCurCPU.preemptCount) + +#define IdlePrioProcs (KeCurCPU.idlePrioProcs) +#define ReglPrioProcs (KeCurCPU.reglPrioProcs) +#define ServPrioProcs (KeCurCPU.servPrioProcs) +#define TimeCritProcs (KeCurCPU.timeCritProcs) + +//------------------------------------------// // // Set current process -// TODO Select thread, context switch // static void SetCurProc(Process_t *proc) { - _SetCurProc(proc); - if (GetCurProc() != NULL) { - GetCurProc()->procState = STATE_RUNNING; - } + PsCurProc = proc; + if (PsCurProc) PsCurProc->procState = STATE_RUNNING; } // @@ -66,28 +70,24 @@ static void SetCurProc(Process_t *proc) // static inline -void SchedLock(void) { -#ifdef _KALEID_KERNEL - DisableIRQs(); -#endif +void PsLockSched(void) { + KeDisableIRQs(); } static inline -void SchedUnlock(void) { -#ifdef _KALEID_KERNEL - EnableIRQs(); -#endif +void PsUnlockSched(void) { + //KeEnableIRQs(); } // // The four priority classes of OS/2 // -CREATE_PER_CPU(TimeCritProcs, ListHead_t *); +/*CREATE_PER_CPU(TimeCritProcs, ListHead_t *); CREATE_PER_CPU(ServPrioProcs, ListHead_t *); CREATE_PER_CPU(ReglPrioProcs, ListHead_t *); -CREATE_PER_CPU(IdlePrioProcs, ListHead_t *); +CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);*/ -const char *PrioClassesNames[] = { +const char *PsPrioClassesNames[] = { "Time-critical class", "Server priority class", "Regular priority class", @@ -100,10 +100,10 @@ const char *PrioClassesNames[] = { static ListHead_t *GetPrioClassHead(int prioClass) { switch (prioClass) { - case TIME_CRIT_PROC: return GetTimeCritProcs(); - case SERV_PRIO_PROC: return GetServPrioProcs(); - case REGL_PRIO_PROC: return GetReglPrioProcs(); - case IDLE_PRIO_PROC: return GetIdlePrioProcs(); + case TIME_CRIT_PROC: return TimeCritProcs; + case SERV_PRIO_PROC: return ServPrioProcs; + case REGL_PRIO_PROC: return ReglPrioProcs; + case IDLE_PRIO_PROC: return IdlePrioProcs; default: KalAssert(FALSE && "Unknown priority class"); } @@ -134,23 +134,24 @@ static void SchedThisProcUnlocked(Process_t *proc) { KalAssert(proc && proc->procState == STATE_RUNNABLE && !proc->schedNode); - bool found = false; + bool found = 0; ListNode_t *iterNode = NULL; - ListNode_t *procNode = CreateNode(proc); + ListNode_t *procNode = ExCreateNode(proc); ListHead_t *head = GetPrioClassHead(proc->prioClass); - KalAssert(procNode && head); + KalAssert(head); + KalAssert(procNode); proc->schedNode = procNode; // Find a process with lesser priority for (iterNode = head->first; iterNode; iterNode = iterNode->next) { - if (proc->prioLevel > GetNodeData(iterNode, Process_t *)->prioLevel) { + if (proc->prioLevel > ExGetNodeData(iterNode, Process_t *)->prioLevel) { // Detect double insertions - KalAssert(proc->pid != GetNodeData(iterNode, Process_t *)->pid); + KalAssert(proc->pid != ExGetNodeData(iterNode, Process_t *)->pid); // Add process to schedule - AddNodeBefore(head, iterNode, procNode); + ExAddNodeBefore(head, iterNode, procNode); found = true; break; } @@ -158,20 +159,20 @@ static void SchedThisProcUnlocked(Process_t *proc) // Didn't find any process with lesser priority if (found == false) { - AppendNode(head, procNode); + ExAppendNode(head, procNode); } } // // Add process to schedule lists // -void SchedThisProc(Process_t *proc) +void PsSchedThisProc(Process_t *proc) { - SchedLock(); + PsLockSched(); SchedThisProcUnlocked(proc); - SchedUnlock(); + PsUnlockSched(); } // @@ -182,10 +183,17 @@ void SchedThisProc(Process_t *proc) // static Process_t *SelectSchedNext(void) { - if (GetTimeCritProcs()->length > 0) return GetNodeData(GetTimeCritProcs()->first, Process_t *); - if (GetServPrioProcs()->length > 0) return GetNodeData(GetServPrioProcs()->first, Process_t *); - if (GetReglPrioProcs()->length > 0) return GetNodeData(GetReglPrioProcs()->first, Process_t *); - if (GetIdlePrioProcs()->length > 0) return GetNodeData(GetIdlePrioProcs()->first, Process_t *); + if (TimeCritProcs->length > 0) + return ExGetNodeData(TimeCritProcs->first, Process_t *); + + if (ServPrioProcs->length > 0) + return ExGetNodeData(ServPrioProcs->first, Process_t *); + + if (ReglPrioProcs->length > 0) + return ExGetNodeData(ReglPrioProcs->first, Process_t *); + + if (IdlePrioProcs->length > 0) + return ExGetNodeData(IdlePrioProcs->first, Process_t *); return NULL; } @@ -194,82 +202,82 @@ static Process_t *SelectSchedNext(void) // Remove running process from schedule lists // and schedule next runnable process // -void BlockCurProc(void) +void PsBlockCurProc(void) { - KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING); + KalAssert(PsCurProc && PsCurProc->procState == STATE_RUNNING); - ListNode_t *procNode = GetCurProc()->schedNode; + ListNode_t *procNode = PsCurProc->schedNode; KalAssert(procNode && "Blocking non-scheduled process"); - GetCurProc()->procState = STATE_BLOCKED; - RemoveNode(procNode->head, procNode); + PsCurProc->procState = STATE_BLOCKED; + ExRemoveNode(procNode->head, procNode); - GetCurProc()->schedNode = NULL; + PsCurProc->schedNode = NULL; SetCurProc(SelectSchedNext()); } static void ReSchedCurProc(void) { - KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING); - KalAssert(GetCurProc()->schedNode); + KalAssert(PsCurProc && PsCurProc->procState == STATE_RUNNING); + KalAssert(PsCurProc->schedNode); // Restore default attributes, cancelling boosts - GetCurProc()->prioClass = GetCurProc()->defPrioClass; - GetCurProc()->prioLevel = GetCurProc()->defPrioLevel; - GetCurProc()->timeSlice = GetCurProc()->defTimeSlice; - GetCurProc()->procState = STATE_RUNNABLE; + PsCurProc->prioClass = PsCurProc->defPrioClass; + PsCurProc->prioLevel = PsCurProc->defPrioLevel; + PsCurProc->timeSlice = PsCurProc->defTimeSlice; + PsCurProc->procState = STATE_RUNNABLE; // Remove from list - RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode); - GetCurProc()->schedNode = NULL; + ExRemoveNode(PsCurProc->schedNode->head, PsCurProc->schedNode); + PsCurProc->schedNode = NULL; // Schedule again, with default attributes now - SchedThisProcUnlocked(GetCurProc()); + SchedThisProcUnlocked(PsCurProc); } // // Should we schedule another process? // Called at each tick // -void SchedOnTick(void) +void PsSchedOnTick(void) { - SchedLock(); + PsLockSched(); - Process_t *procNext, *winner, *previous = GetCurProc(); + Process_t *procNext, *winner, *previous = PsCurProc; // We're either idle or running something - KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING); + KalAssert(PsCurProc == NULL || PsCurProc->procState == STATE_RUNNING); // Have the current process spent its timeslice? // (To be handled in CPU decisions function) - if (GetCurProc() != NULL) { - if (GetCurProc()->timeSlice <= 1) { + if (PsCurProc != NULL) { + if (PsCurProc->timeSlice <= 1) { // Re-schedule ReSchedCurProc(); // See next 'if' statement - _SetCurProc(NULL); + PsCurProc = NULL; } // Otherwise, make it lose a tick else { - GetCurProc()->timeSlice--; + PsCurProc->timeSlice--; } } // Are we idle, or scheduling next process? - if (GetCurProc() == NULL) { + if (PsCurProc == NULL) { SetCurProc(SelectSchedNext()); goto leave; } // Is preemption on and a re-schedule is needed? - if (GetPreemptCount() == PREEMPT_ON && GetReSchedFlag()) { + if (PreemptCount == PREEMPT_ON && ReSchedFlag) { // Is there a higher priority process that is runnable? procNext = SelectSchedNext(); - winner = CompareProcs(GetCurProc(), procNext); + winner = CompareProcs(PsCurProc, procNext); // Yes, procNext should preempt current process if (winner == procNext) { @@ -283,9 +291,9 @@ void SchedOnTick(void) // Current process won't be preempted and has time remaining leave: - SchedUnlock(); + PsUnlockSched(); - if (GetCurProc() != NULL && GetCurProc() != previous) { + if (PsCurProc != NULL && PsCurProc != previous) { // XXX context switch } } @@ -293,55 +301,59 @@ leave: // // Initialize scheduler // -void InitSched(void) +void PsInitSched(void) { int pid; - SchedLock(); + PsLockSched(); - _SetTimeCritProcs(CreateListHead()); - _SetServPrioProcs(CreateListHead()); - _SetReglPrioProcs(CreateListHead()); - _SetIdlePrioProcs(CreateListHead()); + TimeCritProcs = ExCreateListHead(); + ServPrioProcs = ExCreateListHead(); + ReglPrioProcs = ExCreateListHead(); + IdlePrioProcs = ExCreateListHead(); + + KalAssert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs); -#ifndef _KALEID_KERNEL for (pid = 0; pid < procslen; pid++) { if (procs[pid].procState == STATE_RUNNABLE) { SchedThisProcUnlocked(&procs[pid]); } } -#endif - SchedUnlock(); + PsUnlockSched(); } // // Shutdown scheduler // -void FiniSched(void) +void PsFiniSched(void) { - KalAssert(GetIdlePrioProcs() && GetReglPrioProcs() && GetServPrioProcs() && GetTimeCritProcs()); + KalAssert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs); - SchedLock(); + PsLockSched(); - while (GetIdlePrioProcs()->length > 0) RemoveNode(GetIdlePrioProcs(), GetIdlePrioProcs()->first); - while (GetReglPrioProcs()->length > 0) RemoveNode(GetReglPrioProcs(), GetReglPrioProcs()->first); - while (GetServPrioProcs()->length > 0) RemoveNode(GetServPrioProcs(), GetServPrioProcs()->first); - while (GetTimeCritProcs()->length > 0) RemoveNode(GetTimeCritProcs(), GetTimeCritProcs()->first); + while (IdlePrioProcs->length > 0) + ExRemoveNode(IdlePrioProcs, IdlePrioProcs->first); - DestroyListHead(GetIdlePrioProcs()); _SetIdlePrioProcs(NULL); - DestroyListHead(GetReglPrioProcs()); _SetReglPrioProcs(NULL); - DestroyListHead(GetServPrioProcs()); _SetServPrioProcs(NULL); - DestroyListHead(GetTimeCritProcs()); _SetTimeCritProcs(NULL); + while (ReglPrioProcs->length > 0) + ExRemoveNode(ReglPrioProcs, ReglPrioProcs->first); - SchedUnlock(); + while (ServPrioProcs->length > 0) + ExRemoveNode(ServPrioProcs, ServPrioProcs->first); + + while (TimeCritProcs->length > 0) + ExRemoveNode(TimeCritProcs, TimeCritProcs->first); + + ExDestroyListHead(IdlePrioProcs); IdlePrioProcs = NULL; + ExDestroyListHead(ReglPrioProcs); ReglPrioProcs = NULL; + ExDestroyListHead(ServPrioProcs); ServPrioProcs = NULL; + ExDestroyListHead(TimeCritProcs); TimeCritProcs = NULL; + + PsUnlockSched(); } -#ifndef _KALEID_KERNEL - -#define PrintProc(proc) printf("{ %d, '%s', %d , %lu}\n", (proc)->pid, \ - PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice); - +#define PrintProc(proc) KernLog("{ %d, '%s', %d , %lu}\n", (proc)->pid, \ + PsPrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice); // // Print out process list // @@ -352,75 +364,65 @@ void PrintList(ListHead_t *head) Process_t *proc; ListNode_t *node = head->first; - printf("len: %lu\n", head->length); + KernLog("len: %lu\n", head->length); while (node) { - proc = GetNodeData(node, Process_t *); + proc = ExGetNodeData(node, Process_t *); PrintProc(proc); node = node->next; } - puts(""); + KernLog(""); } -int main(void) +void pstest(void) { - InitSched(); + ClearTerm(StdOut); - puts("---------------"); + KernLog("\nTime Critical: "); + PrintList(TimeCritProcs); - puts("Time Critical:"); - PrintList(GetTimeCritProcs()); + KernLog("\nServer: "); + PrintList(ServPrioProcs); - puts("Server:"); - PrintList(GetServPrioProcs()); + KernLog("\nRegular: "); + PrintList(ReglPrioProcs); - puts("Regular:"); - PrintList(GetReglPrioProcs()); - - puts("Idle:"); - PrintList(GetIdlePrioProcs()); - - puts("---------------"); - - getchar(); + KernLog("\nIdle:"); + PrintList(IdlePrioProcs); int tick = 0; - while (tick < 120) { + while (tick < 24) { + if (tick%25==0)ClearTerm(StdOut); if (tick > 0 && tick != 50 && tick % 10 == 0) { - puts("Blocking current process"); - BlockCurProc(); + KernLog("Blocking current process\n"); + PsBlockCurProc(); } if (tick == 50) { procs[0].procState = STATE_RUNNABLE; - SchedThisProc(&procs[0]); + PsSchedThisProc(&procs[0]); } - printf("Tick %d - Running: ", tick); + KernLog("Tick %d - Running: ", tick); - if (GetCurProc() == NULL) { - puts("IDLE"); + if (PsCurProc == NULL) { + KernLog("IDLE"); } else { - PrintProc(GetCurProc()); + PrintProc(PsCurProc); } - SchedOnTick(); + PsSchedOnTick(); if (tick == 50) // already done - puts("Re-scheduling process 0"); + KernLog("Re-scheduling process 0"); tick++; } - - FiniSched(); - - return 0; } -#endif From 4caefd028a419a19ce9dfa84083df270b6e43055 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 25 Mar 2019 23:10:06 +0100 Subject: [PATCH 4/5] Stack & heap stuff --- ProjectTree | 22 +++++++++-- boot/loader/loader.asm | 22 +++++++---- boot/loader/mem/management.inc | 33 ++++++++++++++++ boot/loader/mem/structures.inc | 9 ++++- boot/loader/multiboot/header.inc | 1 - build/kernel.ld | 4 +- kaleid/include/kernel/base.h | 9 +++++ kaleid/include/kernel/cpu.h | 66 +++++++++++++++++++++++++++++++- kaleid/include/kernel/heap.h | 3 +- kaleid/kernel/cpu/cpuid.c | 10 ++++- kaleid/kernel/cpu/idt.c | 37 ++++++++++++++++++ kaleid/kernel/init/init.c | 16 ++------ kaleid/kernel/mm/heap.c | 24 ++++++++---- kaleid/kernel/mm/malloc.c | 3 +- kaleid/kernel/mm/stack.c | 23 +++++++++++ 15 files changed, 243 insertions(+), 39 deletions(-) create mode 100644 kaleid/kernel/cpu/idt.c create mode 100644 kaleid/kernel/mm/stack.c diff --git a/ProjectTree b/ProjectTree index f44e941..4dee93e 100644 --- a/ProjectTree +++ b/ProjectTree @@ -56,6 +56,17 @@ │   │   │   └── loader.o │   │   └── kaleid │   │   ├── kernel +│   │   │   ├── init +│   │   │   │   ├── init.o +│   │   │   │   └── table.o +│   │   │   ├── io +│   │   │   │   ├── cursor.o +│   │   │   │   ├── term.o +│   │   │   │   └── vga.o +│   │   │   ├── ke +│   │   │   │   └── panic.o +│   │   │   ├── bprint.o +│   │   │   ├── bput.o │   │   │   ├── buf.o │   │   │   ├── cpuid.o │   │   │   ├── cursor.o @@ -64,6 +75,7 @@ │   │   │   ├── malloc.o │   │   │   ├── map.o │   │   │   ├── panic.o +│   │   │   ├── sched.o │   │   │   ├── table.o │   │   │   ├── term.o │   │   │   └── vga.o @@ -131,9 +143,12 @@ │   │   └── kalext.h │   └── kernel │   ├── buf +│   │   ├── bprint.c +│   │   ├── bput.c │   │   └── buf.c │   ├── cpu -│   │   └── cpuid.c +│   │   ├── cpuid.c +│   │   └── idt.c │   ├── init │   │   ├── init.c │   │   └── table.c @@ -147,7 +162,8 @@ │   ├── mm │   │   ├── heap.c │   │   ├── malloc.c -│   │   └── map.c +│   │   ├── map.c +│   │   └── stack.c │   └── proc │   ├── Makefile │   └── sched.c @@ -162,4 +178,4 @@ ├── qemu.log └── Readme.md -28 directories, 109 files +31 directories, 122 files diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 0e56cdc..0a3fc44 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -44,7 +44,7 @@ MB_header: dd MB_HEADER_MAGIC dd MB_HEADER_FLAGS dd CHECKSUM - times 5 dd 0x0 + times 5 dd 0x0 ; The unused section (provided for a.out) dd MB_VIDEO_MODE dd MB_VIDEO_WIDTH dd MB_VIDEO_HEIGHT @@ -52,7 +52,7 @@ MB_header: [section .text] -;;MULTIBOOT POINT ENTRY FOR GRUB ------------------------------------------- ;; +;;MULTIBOOT POINT ENTRY FOR GRUB -------------------------------------------- ;; MB_start: mov esp, KERNEL_STACK ; Setup the stack push 0 ; Reset EFLAGS @@ -133,8 +133,9 @@ lbegin: [BITS 64] -x64_K db "Now in x64 long mode", 0x0A, 0x0D, 0x0 +x64_K db "64 bits long mode activated !", 0x0A, 0x0D, 0x0 GoKernel db "Launching Kernel...", 0 +GoStack db "Initializing the stack...", 0x0A, 0x0D, 0x0 nokernel db 219, 219, 219, " Error 05 : Kernel returns",0 _loader64: @@ -154,14 +155,21 @@ _loader64: mov bl, 0x0A mov esi, x64_K call write + + ;; Initialize the stack + mov bl, 0x0F + mov esi, GoStack + call write + + call tritemporize ; Let time to see + call InitStack + + ;; Launch the kernel ! mov bl, 0x0F mov esi, GoKernel call write - ;; Launch the kernel ! - ;; XXX CHECK THE RAM BEFORE CALLING KERNEL ! - call tritemporize ; Let time to see - + mov qword [newKernelEnd], KERNEL_STACK mov rdi, [mbInfo] mov rsi, [mbMagic] call BtStartKern diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc index b44bf4f..cfdf3c4 100644 --- a/boot/loader/mem/management.inc +++ b/boot/loader/mem/management.inc @@ -106,3 +106,36 @@ CheckA20: .A20_err: mov ax, "04" ; ERROR 04 : A20 line failed jmp Error + +[BITS 64] +; ---------------------------------------------------------------------------- ; +; Initilizes the stack ; +; ---------------------------------------------------------------------------- ; +InitStack: + xor rax, rax ; "Fill pattern" + push rcx + push rdi + + ;; Begin address to fill and length + mov rdi, kernelEnd + mov rcx, KERNEL_STACK - kernelEnd - 16 + ; stop before the return address + + ;; If bit 0 is on, fill one byte + sar rcx, 1 ; Shift bit 0 into CY + jnc $ + 3 + stosb + ;; We are word aligned and if bit 1 was on fill another word + sar rcx, 1 ; Shift bit 1 into CY + jnc $ + 4 + stosw + ;; We are dword aligned and if bit 2 was on fill another dword + sar rcx, 1 ; Shift bit 2 into CY + jnc $ + 3 + stosd + ;; RCX now equals the number of qwords to fill + repnz stosq ; Finish by writing RCX qwords. + + pop rdi + pop rcx + ret diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc index 0c7bd8b..dc1c607 100644 --- a/boot/loader/mem/structures.inc +++ b/boot/loader/mem/structures.inc @@ -24,6 +24,13 @@ ;=----------------------------------------------------------------------------=; [BITS 32] +extern kernelEnd +global newKernelEnd + +[section .text] +KERNEL_STACK equ kernelEnd + 4096 * 2 * 1024 ; 8MB of stack +newKernelEnd dq 0x0 + [section .rodata] ;; GDT WITH DOC ALIGN 4096 @@ -43,6 +50,7 @@ GDT64: dw $ - GDT64 - 1 dq GDT64 + ;; EMPTY PAGE TABLES (identity of the first 1GiB) [section .bss] ALIGN 4096 @@ -52,4 +60,3 @@ PDP_table: resb 4096 PD_table: resb 4096 - diff --git a/boot/loader/multiboot/header.inc b/boot/loader/multiboot/header.inc index 0cfea0c..e7a8b1c 100644 --- a/boot/loader/multiboot/header.inc +++ b/boot/loader/multiboot/header.inc @@ -36,4 +36,3 @@ MB_HEADER_MAGIC equ 0x1badb002 MB_GRUB_MAGIC equ 0x2badb002 MB_HEADER_FLAGS equ MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO|MB_VIDEOINFO CHECKSUM equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) -KERNEL_STACK equ 0x00200000 ; Stack starts at the 2mb address & grows down diff --git a/build/kernel.ld b/build/kernel.ld index 50a5d81..7500a25 100644 --- a/build/kernel.ld +++ b/build/kernel.ld @@ -61,10 +61,10 @@ SECTIONS { *(.rodata) /* all rodata sections from all files */ } - kernelEnd = .; - /DISCARD/ : { *(.comment) } + + kernelEnd = .; } diff --git a/kaleid/include/kernel/base.h b/kaleid/include/kernel/base.h index 7ae02d7..2d7534b 100644 --- a/kaleid/include/kernel/base.h +++ b/kaleid/include/kernel/base.h @@ -74,6 +74,15 @@ struct Processor_t // CPU number, index in CPU list int index; + // CPU APIC id + int apicId; + // CPU Vendor String (always 12 characters) + char vendorStr[12]; + // CPU Model code (enum in cpu.h) + int modelCode; + // CPU Features flag + uint featureFlag; + // Number of ticks since boot time ulong ticks; diff --git a/kaleid/include/kernel/cpu.h b/kaleid/include/kernel/cpu.h index ae2c7b9..73dbb75 100644 --- a/kaleid/include/kernel/cpu.h +++ b/kaleid/include/kernel/cpu.h @@ -29,14 +29,76 @@ #ifndef _KALKERN_CPU_H #define _KALKERN_CPU_H -//------------------------------------------// +// -------------------------------------------------------------------------- // #define KeCPUID(in, a, b, c, d) asm("cpuid" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "a" (in) \ ); -//------------------------------------------// +// -------------------------------------------------------------------------- // +// CPU features masks +enum { + FEAT_ECX_SSE3 = 1 << 0, + FEAT_ECX_PCLMUL = 1 << 1, + FEAT_ECX_DTES64 = 1 << 2, + FEAT_ECX_MONITOR = 1 << 3, + FEAT_ECX_DS_CPL = 1 << 4, + FEAT_ECX_VMX = 1 << 5, + FEAT_ECX_SMX = 1 << 6, + FEAT_ECX_EST = 1 << 7, + FEAT_ECX_TM2 = 1 << 8, + FEAT_ECX_SSSE3 = 1 << 9, + FEAT_ECX_CID = 1 << 10, + FEAT_ECX_FMA = 1 << 12, + FEAT_ECX_CX16 = 1 << 13, + FEAT_ECX_ETPRD = 1 << 14, + FEAT_ECX_PDCM = 1 << 15, + FEAT_ECX_PCIDE = 1 << 17, + FEAT_ECX_DCA = 1 << 18, + FEAT_ECX_SSE4_1 = 1 << 19, + FEAT_ECX_SSE4_2 = 1 << 20, + FEAT_ECX_x2APIC = 1 << 21, + FEAT_ECX_MOVBE = 1 << 22, + FEAT_ECX_POPCNT = 1 << 23, + FEAT_ECX_AES = 1 << 25, + FEAT_ECX_XSAVE = 1 << 26, + FEAT_ECX_OSXSAVE = 1 << 27, + FEAT_ECX_AVX = 1 << 28, + + FEAT_EDX_FPU = 1 << 0, + FEAT_EDX_VME = 1 << 1, + FEAT_EDX_DE = 1 << 2, + FEAT_EDX_PSE = 1 << 3, + FEAT_EDX_TSC = 1 << 4, + FEAT_EDX_MSR = 1 << 5, + FEAT_EDX_PAE = 1 << 6, + FEAT_EDX_MCE = 1 << 7, + FEAT_EDX_CX8 = 1 << 8, + FEAT_EDX_APIC = 1 << 9, + FEAT_EDX_SEP = 1 << 11, + FEAT_EDX_MTRR = 1 << 12, + FEAT_EDX_PGE = 1 << 13, + FEAT_EDX_MCA = 1 << 14, + FEAT_EDX_CMOV = 1 << 15, + FEAT_EDX_PAT = 1 << 16, + FEAT_EDX_PSE36 = 1 << 17, + FEAT_EDX_PSN = 1 << 18, + FEAT_EDX_CLF = 1 << 19, + FEAT_EDX_DTES = 1 << 21, + FEAT_EDX_ACPI = 1 << 22, + FEAT_EDX_MMX = 1 << 23, + FEAT_EDX_FXSR = 1 << 24, + FEAT_EDX_SSE = 1 << 25, + FEAT_EDX_SSE2 = 1 << 26, + FEAT_EDX_SS = 1 << 27, + FEAT_EDX_HTT = 1 << 28, + FEAT_EDX_TM1 = 1 << 29, + FEAT_EDX_IA64 = 1 << 30, + FEAT_EDX_PBE = 1 << 31 +}; + +// -------------------------------------------------------------------------- // #endif diff --git a/kaleid/include/kernel/heap.h b/kaleid/include/kernel/heap.h index d8f4c78..062bf0a 100644 --- a/kaleid/include/kernel/heap.h +++ b/kaleid/include/kernel/heap.h @@ -31,7 +31,8 @@ //------------------------------------------// -#define _HEAP_START (8 * MB) +// Address of the heap +void *_heap_start; void MmInitHeap(void); diff --git a/kaleid/kernel/cpu/cpuid.c b/kaleid/kernel/cpu/cpuid.c index ef8b36a..d1f756b 100644 --- a/kaleid/kernel/cpu/cpuid.c +++ b/kaleid/kernel/cpu/cpuid.c @@ -22,4 +22,12 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// -int stub; + +char *KeGetVendorString(void) { + return "Null"; +} + + + + + diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c new file mode 100644 index 0000000..ae3c860 --- /dev/null +++ b/kaleid/kernel/cpu/idt.c @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Interrupt related functions // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + + +// +// Registers the new idt in the idtr register. +// +static inline void lidt(void* idtAddr, ushort size) +{ + struct { + ushort length; + void* base; + } __attribute__((packed)) IDTR = { size, idtAddr }; + + asm volatile( "lidt %0" : : "m"(IDTR) ); +} diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 7ec185b..4fd22bd 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -37,7 +37,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) { extern ulong MB_header; - extern ulong kernelEnd; + extern ulong newKernelEnd; // We need the multiboot structure KalAlwaysAssert(mbi); @@ -48,7 +48,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) { BtGetBootInfo(btldr).grubName = (char*)(ulong)(mbi->boot_loader_name); BtGetBootInfo(btldr).kernelAddr = (void*)&MB_header; - BtGetBootInfo(btldr).kernelEndAddr = (void*)&kernelEnd; + BtGetBootInfo(btldr).kernelEndAddr = (void*)newKernelEnd; BtGetBootInfo(btldr).valid = 1; } if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MODS) { @@ -142,22 +142,12 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, int mbMagic) mapBad ); - KernLog("[Init] TEST First zone from %p : %p\n", (void*)0xB8010, - MmGetFirstAvailZone((void*)0xB8010)); - KernLog("[Init] TEST Size of zone : %u Kio\n\n", - MmGetAvailZoneSize(MmGetFirstAvailZone((void*)0xB8010)) / KB); - MmInitHeap(); PsInitSched(); - ClearTerm(StdOut); - Buffer_t *buf = BOpenLineBuf(NULL, BS_WRONLY, 80, 24, 1, NULL); - //BPrintOnBuf(buf, "xxx\nxxx\ry\tw\n%d %s\n%%%p", 1, "abcd", 0); - //int i; for(i=0;i<100;i++) BPrintOnBuf(buf,"%d\n",i); - - error_t rc = BPrintOnBuf(buf, "%+#05X", 0xcafeb00b); + error_t rc = BPrintOnBuf(buf, "%+#05x", 0xcafeb00b); if(rc)KernLog("error\n"); KernLog((char*)buf->buf); diff --git a/kaleid/kernel/mm/heap.c b/kaleid/kernel/mm/heap.c index 16c8fe9..86c6878 100644 --- a/kaleid/kernel/mm/heap.c +++ b/kaleid/kernel/mm/heap.c @@ -24,6 +24,7 @@ #include #include +#include // Least address out of the heap static void *_heap_end; @@ -40,8 +41,17 @@ static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK); void MmInitHeap(void) { assert(_heap_end == NULL); - _heap_end = (void *)_HEAP_START; - _heap_max = lmin(8 * MB, MmGetAvailZoneSize((void *)_HEAP_START)); + + // Get the first available zone address + _heap_start = MmGetFirstAvailZone((void*)0); + // Align it + while ((size_t)_heap_start % alignof(QWORD)) { + _heap_start++; + } + // Initialize the heap + _heap_end = _heap_start; + _heap_max = lmin(8 * MB, MmGetAvailZoneSize(_heap_end)); + KernLog("[InitHeap] Start address : %p, Max length : %u Mio\n\n", _heap_start, _heap_max / MB); } // @@ -65,7 +75,7 @@ void MmUnlockHeap(void) // size_t MmGetHeapSize(void) { - return (size_t)_heap_end - _HEAP_START; + return (size_t)_heap_end - (size_t)_heap_start; } // @@ -81,11 +91,11 @@ size_t MmGetMaxHeapSize(void) // error_t MmSetMaxHeapSize(size_t new) { - if (new > MmGetAvailZoneSize((void *)_HEAP_START)) { + if (new > MmGetAvailZoneSize((void *)_heap_start)) { return ENOMEM; } - if (new < (size_t)_heap_end - _HEAP_START) { + if (new < (size_t)_heap_end - (size_t)_heap_start) { return EADDRINUSE; } @@ -101,7 +111,7 @@ error_t MmGrowHeap(size_t req) { assert(req % alignof(QWORD) == 0); - if ((size_t)_heap_end + req > _HEAP_START + _heap_max) { + if ((size_t)_heap_end + req > (size_t)_heap_start + _heap_max) { return ENOMEM; } @@ -117,7 +127,7 @@ error_t MmShrinkHeap(size_t req) { assert(req % alignof(QWORD) == 0); - if (req > (size_t)_heap_end - _HEAP_START) { + if (req > (size_t)_heap_end - (size_t)_heap_start) { return EADDRINUSE; } diff --git a/kaleid/kernel/mm/malloc.c b/kaleid/kernel/mm/malloc.c index 6d7262a..a510204 100644 --- a/kaleid/kernel/mm/malloc.c +++ b/kaleid/kernel/mm/malloc.c @@ -29,6 +29,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align) { error_t rc; size_t brk; + extern void *_heap_start; if (align == 0) align = M_DEFAULT_ALIGNMENT; @@ -38,7 +39,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align) MmLockHeap(); - brk = _HEAP_START + MmGetHeapSize(); + brk = (size_t)_heap_start + MmGetHeapSize(); req = _ALIGN_UP(req + brk, align) - brk; rc = MmGrowHeap(req); diff --git a/kaleid/kernel/mm/stack.c b/kaleid/kernel/mm/stack.c new file mode 100644 index 0000000..2bb1aaf --- /dev/null +++ b/kaleid/kernel/mm/stack.c @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Mapping and checking memory related functions // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// From bc8970c2d06bfa6031af317da0c5f251f4f7a5f0 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 25 Mar 2019 23:18:18 +0100 Subject: [PATCH 5/5] Stack & heap stuff --- ProjectTree | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ProjectTree b/ProjectTree index 4dee93e..6d8caf3 100644 --- a/ProjectTree +++ b/ProjectTree @@ -56,15 +56,6 @@ │   │   │   └── loader.o │   │   └── kaleid │   │   ├── kernel -│   │   │   ├── init -│   │   │   │   ├── init.o -│   │   │   │   └── table.o -│   │   │   ├── io -│   │   │   │   ├── cursor.o -│   │   │   │   ├── term.o -│   │   │   │   └── vga.o -│   │   │   ├── ke -│   │   │   │   └── panic.o │   │   │   ├── bprint.o │   │   │   ├── bput.o │   │   │   ├── buf.o @@ -178,4 +169,4 @@ ├── qemu.log └── Readme.md -31 directories, 122 files +28 directories, 116 files