commit
9ad4a83660
2
Makefile
2
Makefile
|
@ -171,7 +171,7 @@ $(KOBJDIR)/kernel/malloc.o: $(KERNELDIR)/kernel/mm/malloc.c $(KERNELDIR)/include
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: all
|
test: all
|
||||||
@qemu-system-x86_64 -m 5G -hda build/bin/disk.img -d cpu_reset,guest_errors,pcall,int -enable-kvm 2> qemu.log &
|
@qemu-system-x86_64 -m 5G -mem-prealloc -hda build/bin/disk.img -d cpu_reset,guest_errors,pcall,int -enable-kvm 2> qemu.log &
|
||||||
@ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 64 > loader_disasm64.asm
|
@ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 64 > loader_disasm64.asm
|
||||||
@ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 32 > loader_disasm32.asm
|
@ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 32 > loader_disasm32.asm
|
||||||
.PHONY: test32
|
.PHONY: test32
|
||||||
|
|
11
ProjectTree
11
ProjectTree
|
@ -56,15 +56,6 @@
|
||||||
│ │ │ └── loader.o
|
│ │ │ └── loader.o
|
||||||
│ │ └── kaleid
|
│ │ └── kaleid
|
||||||
│ │ ├── kernel
|
│ │ ├── kernel
|
||||||
│ │ │ ├── init
|
|
||||||
│ │ │ │ ├── init.o
|
|
||||||
│ │ │ │ └── table.o
|
|
||||||
│ │ │ ├── io
|
|
||||||
│ │ │ │ ├── cursor.o
|
|
||||||
│ │ │ │ ├── term.o
|
|
||||||
│ │ │ │ └── vga.o
|
|
||||||
│ │ │ ├── ke
|
|
||||||
│ │ │ │ └── panic.o
|
|
||||||
│ │ │ ├── cpuid.o
|
│ │ │ ├── cpuid.o
|
||||||
│ │ │ ├── cursor.o
|
│ │ │ ├── cursor.o
|
||||||
│ │ │ ├── heap.o
|
│ │ │ ├── heap.o
|
||||||
|
@ -167,4 +158,4 @@
|
||||||
├── qemu.log
|
├── qemu.log
|
||||||
└── Readme.md
|
└── Readme.md
|
||||||
|
|
||||||
30 directories, 112 files
|
27 directories, 106 files
|
||||||
|
|
|
@ -32,8 +32,7 @@ set -e #exit if error
|
||||||
|
|
||||||
## Create the image
|
## Create the image
|
||||||
echo ${CL2}[create_disk.sh]${NC} Creating image... \(dd\)${CL3}
|
echo ${CL2}[create_disk.sh]${NC} Creating image... \(dd\)${CL3}
|
||||||
dd if=/dev/zero of=$1 bs=512 count=131072 > /dev/null
|
dd if=/dev/zero of=$1 bs=512 count=131072 status=progress
|
||||||
|
|
||||||
echo ${CL2}[create_disk.sh]${NC} Partitionning image... \(fdisk\)${CL3}
|
echo ${CL2}[create_disk.sh]${NC} Partitionning image... \(fdisk\)${CL3}
|
||||||
## Partition the image
|
## Partition the image
|
||||||
# WARNING, DO NOT DELETE SPACES !
|
# WARNING, DO NOT DELETE SPACES !
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
global MB_start
|
global MB_start
|
||||||
global MB_header
|
global MB_header
|
||||||
extern StartKern
|
extern BtStartKern
|
||||||
|
|
||||||
[BITS 32]
|
[BITS 32]
|
||||||
[section .multiboot]
|
[section .multiboot]
|
||||||
|
@ -164,7 +164,7 @@ _loader64:
|
||||||
|
|
||||||
mov rdi, [mbInfo]
|
mov rdi, [mbInfo]
|
||||||
mov rsi, [mbMagic]
|
mov rsi, [mbMagic]
|
||||||
call StartKern
|
call BtStartKern
|
||||||
|
|
||||||
;; We must never reach this point ------------------------------------------- ;;
|
;; We must never reach this point ------------------------------------------- ;;
|
||||||
call tritemporize ; Let time to see
|
call tritemporize ; Let time to see
|
||||||
|
|
|
@ -61,6 +61,8 @@ SECTIONS {
|
||||||
*(.rodata) /* all rodata sections from all files */
|
*(.rodata) /* all rodata sections from all files */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kernelEnd = .;
|
||||||
|
|
||||||
/DISCARD/ :
|
/DISCARD/ :
|
||||||
{
|
{
|
||||||
*(.comment)
|
*(.comment)
|
||||||
|
|
|
@ -79,7 +79,7 @@ enum CmdOptionFlag_t
|
||||||
//
|
//
|
||||||
enum CmdParserFlags_t
|
enum CmdParserFlags_t
|
||||||
{
|
{
|
||||||
// Don't exit on errors=
|
// Don't exit on errors
|
||||||
KALOPT_NO_EXIT = (1 << 0),
|
KALOPT_NO_EXIT = (1 << 0),
|
||||||
|
|
||||||
// Don't react to --help
|
// Don't react to --help
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct ListNode_t
|
||||||
// Create a list head with an extern lock
|
// Create a list head with an extern lock
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*CreateListHeadWithLock(Lock_t *lock)
|
*ExCreateListHeadWithLock(Lock_t *lock)
|
||||||
{
|
{
|
||||||
ListHead_t *head = KalAllocMemory(sizeof(ListHead_t));
|
ListHead_t *head = KalAllocMemory(sizeof(ListHead_t));
|
||||||
|
|
||||||
|
@ -90,16 +90,16 @@ static inline ListHead_t
|
||||||
// Create a list head
|
// Create a list head
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*CreateListHead(void)
|
*ExCreateListHead(void)
|
||||||
{
|
{
|
||||||
return CreateListHeadWithLock(NULL);
|
return ExCreateListHeadWithLock(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a node
|
// Create a node
|
||||||
//
|
//
|
||||||
static inline ListNode_t
|
static inline ListNode_t
|
||||||
*CreateNode(void *data)
|
*ExCreateNode(void *data)
|
||||||
{
|
{
|
||||||
ListNode_t *node = KalAllocMemory(sizeof(ListNode_t));
|
ListNode_t *node = KalAllocMemory(sizeof(ListNode_t));
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ static inline ListNode_t
|
||||||
// Prepend node at beginning of list
|
// Prepend node at beginning of list
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*PrependNode(ListHead_t *head, ListNode_t *node)
|
*ExPrependNode(ListHead_t *head, ListNode_t *node)
|
||||||
{
|
{
|
||||||
KalAssert(head && node);
|
KalAssert(head && node);
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ static inline ListHead_t
|
||||||
// Append node at end of list
|
// Append node at end of list
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*AppendNode(ListHead_t *head, ListNode_t *node)
|
*ExAppendNode(ListHead_t *head, ListNode_t *node)
|
||||||
{
|
{
|
||||||
KalAssert(head && node);
|
KalAssert(head && node);
|
||||||
|
|
||||||
|
@ -172,12 +172,12 @@ static inline ListHead_t
|
||||||
// Insert node2 before node1
|
// Insert node2 before node1
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*AddNodeBefore(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
|
*ExAddNodeBefore(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
|
||||||
{
|
{
|
||||||
KalAssert(head && node1 && node2 && node1->head == head);
|
KalAssert(head && node1 && node2 && node1->head == head);
|
||||||
|
|
||||||
if (head->first == node1) {
|
if (head->first == node1) {
|
||||||
return PrependNode(head, node2);
|
return ExPrependNode(head, node2);
|
||||||
}
|
}
|
||||||
|
|
||||||
node2->head = head;
|
node2->head = head;
|
||||||
|
@ -198,12 +198,12 @@ static inline ListHead_t
|
||||||
// Insert node2 after node1
|
// Insert node2 after node1
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*AddNodeAfter(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
|
*ExAddNodeAfter(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
|
||||||
{
|
{
|
||||||
KalAssert(head && node1 && node2 && node1->head == head);
|
KalAssert(head && node1 && node2 && node1->head == head);
|
||||||
|
|
||||||
if (head->last == node1) {
|
if (head->last == node1) {
|
||||||
return AppendNode(head, node2);
|
return ExAppendNode(head, node2);
|
||||||
}
|
}
|
||||||
|
|
||||||
node2->head = head;
|
node2->head = head;
|
||||||
|
@ -222,7 +222,7 @@ static inline ListHead_t
|
||||||
// Remove node of list (and frees it)
|
// Remove node of list (and frees it)
|
||||||
//
|
//
|
||||||
static inline ListHead_t
|
static inline ListHead_t
|
||||||
*RemoveNode(ListHead_t *head, ListNode_t *node)
|
*ExRemoveNode(ListHead_t *head, ListNode_t *node)
|
||||||
{
|
{
|
||||||
KalAssert(head && node && head->length > 0 && node->head == head);
|
KalAssert(head && node && head->length > 0 && node->head == head);
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ leave:
|
||||||
// Free a node
|
// Free a node
|
||||||
//
|
//
|
||||||
static inline void
|
static inline void
|
||||||
DestroyNode(ListNode_t *node)
|
ExDestroyNode(ListNode_t *node)
|
||||||
{
|
{
|
||||||
KalAssert(node);
|
KalAssert(node);
|
||||||
KalFreeMemory(node);
|
KalFreeMemory(node);
|
||||||
|
@ -267,7 +267,7 @@ DestroyNode(ListNode_t *node)
|
||||||
// Free a list head
|
// Free a list head
|
||||||
//
|
//
|
||||||
static inline void
|
static inline void
|
||||||
DestroyListHead(ListHead_t *head)
|
ExDestroyListHead(ListHead_t *head)
|
||||||
{
|
{
|
||||||
KalAssert(head);
|
KalAssert(head);
|
||||||
KalFreeMemory(head);
|
KalFreeMemory(head);
|
||||||
|
@ -276,7 +276,7 @@ DestroyListHead(ListHead_t *head)
|
||||||
//
|
//
|
||||||
// Access a node's data
|
// Access a node's data
|
||||||
//
|
//
|
||||||
#define GetNodeData(node, type) ((type)(node)->data)
|
#define ExGetNodeData(node, type) ((type)(node)->data)
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -73,22 +73,15 @@ struct Lock_t
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
//
|
|
||||||
// Linux syscall vs unimplemented syscall...
|
|
||||||
//
|
|
||||||
#ifndef _KALEID_KERNEL
|
#ifndef _KALEID_KERNEL
|
||||||
#ifdef _OSK_SOURCE
|
|
||||||
int KalYieldCPU(void),
|
int KalYieldCPU(void),
|
||||||
#else
|
|
||||||
int sched_yield(void);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize a lock
|
// Initialize a lock
|
||||||
//
|
//
|
||||||
static inline
|
static inline
|
||||||
void InitLock(Lock_t *lock, LockType_t type)
|
void ExInitLock(Lock_t *lock, LockType_t type)
|
||||||
{
|
{
|
||||||
lock->type = type;
|
lock->type = type;
|
||||||
lock->locked = FALSE;
|
lock->locked = FALSE;
|
||||||
|
@ -103,16 +96,16 @@ void InitLock(Lock_t *lock, LockType_t type)
|
||||||
// Alternative way to initalize a lock
|
// Alternative way to initalize a lock
|
||||||
//
|
//
|
||||||
#ifdef _KALEID_KERNEL
|
#ifdef _KALEID_KERNEL
|
||||||
# define INITLOCK(type) { INITOK, FALSE, (type), /* NULL, NULL */ }
|
# define ExINITLOCK(type) { INITOK, FALSE, (type), /* NULL, NULL */ }
|
||||||
#else
|
#else
|
||||||
# define INITLOCK(type) { INITOK, FALSE, (type) }
|
# define ExINITLOCK(type) { INITOK, FALSE, (type) }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Destroy a lock
|
// Destroy a lock
|
||||||
//
|
//
|
||||||
static inline
|
static inline
|
||||||
void DestroyLock(Lock_t *lock)
|
void ExDestroyLock(Lock_t *lock)
|
||||||
{
|
{
|
||||||
KalAssert(lock->initDone);
|
KalAssert(lock->initDone);
|
||||||
|
|
||||||
|
@ -126,20 +119,16 @@ void DestroyLock(Lock_t *lock)
|
||||||
// until we have at least a basic scheduler
|
// until we have at least a basic scheduler
|
||||||
//
|
//
|
||||||
static inline
|
static inline
|
||||||
void AcquireLock(Lock_t *lock)
|
void ExAcquireLock(Lock_t *lock)
|
||||||
{
|
{
|
||||||
KalAssert(lock->initDone == INITOK);
|
KalAssert(lock->initDone == INITOK);
|
||||||
|
|
||||||
while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) {
|
while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) {
|
||||||
#ifdef _KALEID_KERNEL
|
#ifdef _KALEID_KERNEL
|
||||||
StartPanic("AcquireLock on an already locked object");
|
KeStartPanic("AcquireLock 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 (void)KalYieldCPU();
|
else (void)KalYieldCPU();
|
||||||
#else
|
|
||||||
else (void)sched_yield();
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
|
@ -150,7 +139,7 @@ void AcquireLock(Lock_t *lock)
|
||||||
// Panic if the lock was never acquired
|
// Panic if the lock was never acquired
|
||||||
//
|
//
|
||||||
static inline
|
static inline
|
||||||
void ReleaseLock(Lock_t *lock)
|
void ExReleaseLock(Lock_t *lock)
|
||||||
{
|
{
|
||||||
/*#ifdef _KALEID_KERNEL
|
/*#ifdef _KALEID_KERNEL
|
||||||
KalAssert(lock->ownerThread == GetCurThread());
|
KalAssert(lock->ownerThread == GetCurThread());
|
||||||
|
@ -164,7 +153,7 @@ void ReleaseLock(Lock_t *lock)
|
||||||
// Tries to acquire lock
|
// Tries to acquire lock
|
||||||
//
|
//
|
||||||
static inline
|
static inline
|
||||||
bool AttemptLock(Lock_t *lock)
|
bool ExAttemptLock(Lock_t *lock)
|
||||||
{
|
{
|
||||||
KalAssert(lock->initDone == INITOK);
|
KalAssert(lock->initDone == INITOK);
|
||||||
|
|
||||||
|
|
|
@ -57,13 +57,14 @@ typedef enum TermColor_t TermColor_t;
|
||||||
|
|
||||||
// Current CPU number
|
// Current CPU number
|
||||||
// Will return a CPU-local variable later
|
// Will return a CPU-local variable later
|
||||||
#define _GetCurCPU() 0
|
#define _KeGetCurCPU() 0
|
||||||
|
|
||||||
// Get Process_t structure of current CPU
|
// Get Process_t structure of current CPU
|
||||||
#define GetCurCPU() (cpuTable[_GetCurCPU()])
|
#define KeGetCurCPU() (cpuTable[_KeGetCurCPU()])
|
||||||
|
|
||||||
//Get the BootInfo_t structure
|
//Get the BootInfo_t structure
|
||||||
#define GetBootInfo(x) bootTab.x
|
#define BtGetBootInfo(x) (bootTab.x)
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -98,6 +99,7 @@ struct Processor_t
|
||||||
#define FB_INDEXED 0
|
#define FB_INDEXED 0
|
||||||
#define FB_RGB 1
|
#define FB_RGB 1
|
||||||
#define BINFO_SIZE 4096
|
#define BINFO_SIZE 4096
|
||||||
|
|
||||||
struct BootInfo_t
|
struct BootInfo_t
|
||||||
{
|
{
|
||||||
// The Bootloader infos (GRUB in our case)
|
// The Bootloader infos (GRUB in our case)
|
||||||
|
@ -108,6 +110,7 @@ struct BootInfo_t
|
||||||
void *modulesAddr; //mods_addr
|
void *modulesAddr; //mods_addr
|
||||||
char *grubName; //boot_loader_name
|
char *grubName; //boot_loader_name
|
||||||
void *kernelAddr;
|
void *kernelAddr;
|
||||||
|
void *kernelEndAddr;
|
||||||
} btldr;
|
} btldr;
|
||||||
|
|
||||||
// Informations about drives
|
// Informations about drives
|
||||||
|
@ -165,13 +168,15 @@ struct BootInfo_t
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
extern int cpuCount;
|
extern int cpuCount;
|
||||||
extern Processor_t cpuTable[NCPUS];
|
|
||||||
extern BootInfo_t bootTab;
|
extern BootInfo_t bootTab;
|
||||||
|
extern Processor_t cpuTable[NCPUS];
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
#define DEC_PER_CPU(name, field, type) \
|
#define DEC_PER_CPU(pref, name, field, type) \
|
||||||
static inline type Get##name() { return GetCurCPU().field; } \
|
static inline type pref##Get##name() { return KeGetCurCPU().field; } \
|
||||||
static inline void _Set##name(type __val) { GetCurCPU().field = __val; }
|
static inline void _##pref##Set##name(type __val) \
|
||||||
|
{ KeGetCurCPU().field = __val; }
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
#define cpuid(in, a, b, c, d) asm("cpuid" \
|
#define KeCPUID(in, a, b, c, d) asm("cpuid" \
|
||||||
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
|
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
|
||||||
: "a" (in) \
|
: "a" (in) \
|
||||||
);
|
);
|
||||||
|
|
|
@ -33,17 +33,17 @@
|
||||||
|
|
||||||
#define _HEAP_START (4 * MB)
|
#define _HEAP_START (4 * MB)
|
||||||
|
|
||||||
void InitHeap(void);
|
void MmInitHeap(void);
|
||||||
|
|
||||||
void LockHeap(void);
|
void MmLockHeap(void);
|
||||||
void UnlockHeap(void);
|
void MmUnlockHeap(void);
|
||||||
|
|
||||||
size_t GetHeapSize(void);
|
size_t MmGetHeapSize(void);
|
||||||
size_t GetMaxHeapSize(void);
|
size_t MmGetMaxHeapSize(void);
|
||||||
error_t SetMaxHeapSize(size_t);
|
error_t MmSetMaxHeapSize(size_t);
|
||||||
|
|
||||||
error_t GrowHeap(size_t);
|
error_t MmGrowHeap(size_t);
|
||||||
error_t ShrinkHeap(size_t);
|
error_t MmShrinkHeap(size_t);
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void WriteByteOnPort(port_t port, port_t val)
|
void IoWriteByteOnPort(port_t port, port_t val)
|
||||||
{
|
{
|
||||||
KalAssert(FALSE && ENOSYS);
|
KalAssert(FALSE && ENOSYS);
|
||||||
(void)port;
|
(void)port;
|
||||||
|
@ -40,7 +40,7 @@ void WriteByteOnPort(port_t port, port_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
uchar ReadByteFromPort(port_t port)
|
uchar IoReadByteFromPort(port_t port)
|
||||||
{
|
{
|
||||||
KalAssert(FALSE && ENOSYS);
|
KalAssert(FALSE && ENOSYS);
|
||||||
(void)port;
|
(void)port;
|
||||||
|
@ -48,7 +48,7 @@ uchar ReadByteFromPort(port_t port)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
ushort ReadWordFromPort(port_t port)
|
ushort IoReadWordFromPort(port_t port)
|
||||||
{
|
{
|
||||||
KalAssert(FALSE && ENOSYS);
|
KalAssert(FALSE && ENOSYS);
|
||||||
(void)port;
|
(void)port;
|
||||||
|
|
|
@ -22,19 +22,54 @@
|
||||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include <kernel/multiboot.h>
|
|
||||||
#include <kernel/base.h>
|
#include <kernel/base.h>
|
||||||
|
|
||||||
#define MINIMUM_RAM_SIZE 16 //Mio, the minimum RAM size.
|
#define MINIMUM_RAM_SIZE 16 // Mio, the minimum RAM size.
|
||||||
|
|
||||||
//
|
#define AVAILABLE_ZONE 1 // Fully usable RAM zone
|
||||||
// Returns a pointer to the first entry of the memory map
|
#define RESERVED_ZONE 2 // Used by the firmware
|
||||||
//
|
#define ACPI_ZONE 3 // Used by ACPI but can be freed
|
||||||
void *GetMemoryMap(void);
|
#define NVS_ZONE 4 // Dunno
|
||||||
|
#define BADRAM_ZONE 5 // Invalid zone because material problem...
|
||||||
|
#define MAX_ENTRIES 2048 // Max number of memory map entries
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
typedef struct MemoryMap_t MemoryMap_t;
|
||||||
|
typedef struct MapEntry_t MapEntry_t;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------- //
|
||||||
|
// The entry structure of the map
|
||||||
|
struct MapEntry_t {
|
||||||
|
void *addr;
|
||||||
|
size_t length; // in bytes
|
||||||
|
uint type; // reserved or not
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// the map structure
|
||||||
|
struct MemoryMap_t {
|
||||||
|
size_t length;
|
||||||
|
size_t freeRamSize;
|
||||||
|
size_t nonfreeRamSize;
|
||||||
|
MapEntry_t entry[MAX_ENTRIES];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------- //
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initializes the memory map structure
|
// Initializes the memory map structure
|
||||||
//
|
//
|
||||||
error_t InitMemoryMap(void);
|
error_t MmInitMemoryMap(void);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns the size of the first available memory zone from the start address pointer
|
||||||
|
//
|
||||||
|
size_t MmGetAvailZoneSize(void *start);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns the first available memory zone from the start address pointer
|
||||||
|
void *MmGetFirstAvailZone(void *start);
|
||||||
|
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
|
|
|
@ -232,15 +232,12 @@ struct multiboot_color
|
||||||
struct multiboot_mmap_entry
|
struct multiboot_mmap_entry
|
||||||
{
|
{
|
||||||
uint size;
|
uint size;
|
||||||
ullong addr;
|
uint addr_low;
|
||||||
ullong len;
|
uint addr_high;
|
||||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
uint len_low;
|
||||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
uint len_high;
|
||||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
|
||||||
#define MULTIBOOT_MEMORY_NVS 4
|
|
||||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
|
||||||
uint type;
|
uint type;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed)) __attribute__((aligned (4)));
|
||||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||||
|
|
||||||
struct multiboot_mod_list
|
struct multiboot_mod_list
|
||||||
|
|
|
@ -32,35 +32,35 @@
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
#define PANICSTR_SIZE 1024
|
#define PANICSTR_SIZE 1024
|
||||||
extern volatile char PanicStr[PANICSTR_SIZE];
|
extern volatile char KePanicStr[PANICSTR_SIZE];
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disable IRQs
|
// Disable IRQs
|
||||||
//
|
//
|
||||||
#define DisableIRQs() asm volatile ("cli")
|
#define KeDisableIRQs() asm volatile ("cli")
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enable IRQs
|
// Enable IRQs
|
||||||
//
|
//
|
||||||
#define EnableIRQs() asm volatile ("sti")
|
#define KeEnableIRQs() asm volatile ("sti")
|
||||||
|
|
||||||
//
|
//
|
||||||
// Pause CPU until next interuption
|
// Pause CPU until next interuption
|
||||||
// !!! Enables IRQs !!!
|
// !!! Enables IRQs !!!
|
||||||
//
|
//
|
||||||
#define PauseCPU() asm volatile ("sti\n\thlt")
|
#define KePauseCPU() asm volatile ("sti\n\thlt")
|
||||||
|
|
||||||
//
|
//
|
||||||
// Halt the CPU indefinitely
|
// Halt the CPU indefinitely
|
||||||
//
|
//
|
||||||
#define HaltCPU() do { asm volatile ("hlt"); } while (1)
|
#define KeHaltCPU() do { asm volatile ("hlt"); } while (1)
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
noreturn void StartPanic(const char *, ...);
|
noreturn void KeStartPanic(const char *, ...);
|
||||||
noreturn void CrashSystem(void);
|
noreturn void KeCrashSystem(void);
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -77,8 +77,8 @@ struct Process_t
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
DEC_PER_CPU(CurProc, process, Process_t *);
|
DEC_PER_CPU(Ps, CurProc, process, Process_t *);
|
||||||
DEC_PER_CPU(CurThread, thread, Thread_t *);
|
DEC_PER_CPU(Ps, CurThread, thread, Thread_t *);
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -53,17 +53,17 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
// Names of the priority classes
|
// Names of the priority classes
|
||||||
extern const char *PrioClassesNames[];
|
extern const char *PsPrioClassesNames[];
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
DEC_PER_CPU(ReSchedFlag, needReSched, bool);
|
DEC_PER_CPU(Ps, ReSchedFlag, needReSched, bool);
|
||||||
DEC_PER_CPU(PreemptCount, preemptCount, ulong);
|
DEC_PER_CPU(Ps, PreemptCount, preemptCount, ulong);
|
||||||
|
|
||||||
DEC_PER_CPU(IdlePrioProcs, idlePrioProcs, ListHead_t *);
|
DEC_PER_CPU(Ps, IdlePrioProcs, idlePrioProcs, ListHead_t *);
|
||||||
DEC_PER_CPU(ReglPrioProcs, reglPrioProcs, ListHead_t *);
|
DEC_PER_CPU(Ps, ReglPrioProcs, reglPrioProcs, ListHead_t *);
|
||||||
DEC_PER_CPU(ServPrioProcs, servPrioProcs, ListHead_t *);
|
DEC_PER_CPU(Ps, ServPrioProcs, servPrioProcs, ListHead_t *);
|
||||||
DEC_PER_CPU(TimeCritProcs, timeCritProcs, ListHead_t *);
|
DEC_PER_CPU(Ps, TimeCritProcs, timeCritProcs, ListHead_t *);
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
@ -71,18 +71,18 @@ DEC_PER_CPU(TimeCritProcs, timeCritProcs, ListHead_t *);
|
||||||
// Re-scheduling and preemption
|
// Re-scheduling and preemption
|
||||||
// XXX atomic operations
|
// XXX atomic operations
|
||||||
//
|
//
|
||||||
#define SetReSchedFlag(x) _SetReSchedFlag(x)
|
#define PsSetReSchedFlag(x) _PsSetReSchedFlag(x)
|
||||||
#define DisablePreemption() _SetPreemptCount(GetPreemptCount()+1)
|
#define PsDisablePreemption() _PsSetPreemptCount(GetPreemptCount()+1)
|
||||||
#define EnablePreemption() do { KalAssert(GetPreemptCount() > 0); \
|
#define PsEnablePreemption() do { KalAssert(GetPreemptCount() > 0); \
|
||||||
_SetPreemptCount(GetPreemptCount()-1); } while(0)
|
_PsSetPreemptCount(GetPreemptCount()-1); } while(0)
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
void SchedInit(void);
|
void PsInitSched(void);
|
||||||
void SchedFini(void);
|
void PsFiniSched(void);
|
||||||
|
|
||||||
void SchedThisProc(Process_t *);
|
void PsSchedThisProc(Process_t *);
|
||||||
void SchedOnTick(void);
|
void PsSchedOnTick(void);
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -22,84 +22,87 @@
|
||||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include <kernel/term.h>
|
#include <kernel/multiboot.h>
|
||||||
#include <kernel/panic.h>
|
#include <kernel/panic.h>
|
||||||
|
#include <kernel/term.h>
|
||||||
#include <kernel/mm.h>
|
#include <kernel/mm.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// BootInfo_t initialization. It is necessary because grub will potentially be
|
// BootInfo_t initialization. It is necessary because grub will potentially be
|
||||||
// wiped since it is below 1MB.... And we must reorganize all that stuff.
|
// wiped since it is below 1MB.... And we must reorganize all that stuff.
|
||||||
//
|
//
|
||||||
void InitBootInfo(multiboot_info_t *mbi)
|
void BtInitBootInfo(multiboot_info_t *mbi)
|
||||||
{
|
{
|
||||||
extern void MB_header(void);
|
extern ullong MB_header;
|
||||||
|
extern ullong kernelEnd;
|
||||||
|
|
||||||
// We need the multiboot structure
|
// We need the multiboot structure
|
||||||
KalAlwaysAssert(mbi);
|
KalAlwaysAssert(mbi);
|
||||||
|
|
||||||
//Retrieves the bootloader flags to ensure infos are valid
|
//Retrieves the bootloader flags to ensure infos are valid
|
||||||
GetBootInfo(btldr).grubFlags = mbi->flags;
|
BtGetBootInfo(btldr).grubFlags = mbi->flags;
|
||||||
|
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) {
|
||||||
GetBootInfo(btldr).grubName = (char*)(ullong)(mbi->boot_loader_name);
|
BtGetBootInfo(btldr).grubName = (char*)(ullong)(mbi->boot_loader_name);
|
||||||
GetBootInfo(btldr).kernelAddr = (void*)&MB_header;
|
BtGetBootInfo(btldr).kernelAddr = (void*)&MB_header;
|
||||||
GetBootInfo(btldr).valid = 1;
|
BtGetBootInfo(btldr).kernelEndAddr = (void*)&kernelEnd;
|
||||||
|
BtGetBootInfo(btldr).valid = 1;
|
||||||
}
|
}
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MODS) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MODS) {
|
||||||
GetBootInfo(btldr).modulesCount = mbi->mods_count;
|
BtGetBootInfo(btldr).modulesCount = mbi->mods_count;
|
||||||
GetBootInfo(btldr).modulesAddr = (void*)(ullong)mbi->mods_addr;
|
BtGetBootInfo(btldr).modulesAddr = (void*)(ullong)mbi->mods_addr;
|
||||||
}
|
}
|
||||||
//Retrieves the drives informations
|
//Retrieves the drives informations
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_DRIVE_INFO) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_DRIVE_INFO) {
|
||||||
GetBootInfo(drives).bufferLength = mbi->drives_length;
|
BtGetBootInfo(drives).bufferLength = mbi->drives_length;
|
||||||
GetBootInfo(drives).bufferAddr = (void*)(ullong)mbi->drives_addr;
|
BtGetBootInfo(drives).bufferAddr = (void*)(ullong)mbi->drives_addr;
|
||||||
GetBootInfo(drives).bufferValid = 1;
|
BtGetBootInfo(drives).bufferValid = 1;
|
||||||
}
|
}
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOTDEV) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOTDEV) {
|
||||||
GetBootInfo(drives).bootDrv = mbi->boot_device;
|
BtGetBootInfo(drives).bootDrv = mbi->boot_device;
|
||||||
GetBootInfo(drives).drvValid = 1;
|
BtGetBootInfo(drives).drvValid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Retrieves the memory informations
|
//Retrieves the memory informations
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MEMORY) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MEMORY) {
|
||||||
GetBootInfo(memory).lowMemory = mbi->mem_lower;
|
BtGetBootInfo(memory).lowMemory = mbi->mem_lower;
|
||||||
GetBootInfo(memory).upMemory = mbi->mem_upper;
|
BtGetBootInfo(memory).upMemory = mbi->mem_upper;
|
||||||
GetBootInfo(memory).memValid = 1;
|
BtGetBootInfo(memory).memValid = 1;
|
||||||
}
|
}
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MEM_MAP) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MEM_MAP) {
|
||||||
GetBootInfo(memory).mapAddr = (void*)(ullong)mbi->mmap_addr;
|
BtGetBootInfo(memory).mapAddr = (void*)(ullong)mbi->mmap_addr;
|
||||||
GetBootInfo(memory).mapLength = mbi->mmap_length;
|
BtGetBootInfo(memory).mapLength = mbi->mmap_length;
|
||||||
GetBootInfo(memory).mapValid = 1;
|
BtGetBootInfo(memory).mapValid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves video mode informations
|
// Retrieves video mode informations
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_VBE_INFO) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_VBE_INFO) {
|
||||||
GetBootInfo(video).vbeControl = (void*)(ullong)mbi->vbe_control_info;
|
BtGetBootInfo(video).vbeControl = (void*)(ullong)mbi->vbe_control_info;
|
||||||
GetBootInfo(video).vbeModeInfo = (void*)(ullong)mbi->vbe_mode_info;
|
BtGetBootInfo(video).vbeModeInfo = (void*)(ullong)mbi->vbe_mode_info;
|
||||||
GetBootInfo(video).vbeMode = mbi->vbe_mode;
|
BtGetBootInfo(video).vbeMode = mbi->vbe_mode;
|
||||||
GetBootInfo(video).vbeInterfaceSeg = mbi->vbe_interface_seg;
|
BtGetBootInfo(video).vbeInterfaceSeg = mbi->vbe_interface_seg;
|
||||||
GetBootInfo(video).vbeInterfaceOff = mbi->vbe_interface_off;
|
BtGetBootInfo(video).vbeInterfaceOff = mbi->vbe_interface_off;
|
||||||
GetBootInfo(video).vbeInterfaceLen = mbi->vbe_interface_len;
|
BtGetBootInfo(video).vbeInterfaceLen = mbi->vbe_interface_len;
|
||||||
GetBootInfo(video).vbeValid = 1;
|
BtGetBootInfo(video).vbeValid = 1;
|
||||||
}
|
}
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) {
|
||||||
GetBootInfo(video).framebufferAddr = (void*)(ullong)mbi->framebuffer_addr;
|
BtGetBootInfo(video).framebufferAddr = (void*)(ullong)mbi->framebuffer_addr;
|
||||||
GetBootInfo(video).framebufferPitch = mbi->framebuffer_pitch;
|
BtGetBootInfo(video).framebufferPitch = mbi->framebuffer_pitch;
|
||||||
GetBootInfo(video).framebufferWidth = mbi->framebuffer_width;
|
BtGetBootInfo(video).framebufferWidth = mbi->framebuffer_width;
|
||||||
GetBootInfo(video).framebufferHeight= mbi->framebuffer_height;
|
BtGetBootInfo(video).framebufferHeight= mbi->framebuffer_height;
|
||||||
GetBootInfo(video).framebufferBpp = mbi->framebuffer_bpp;
|
BtGetBootInfo(video).framebufferBpp = mbi->framebuffer_bpp;
|
||||||
GetBootInfo(video).framebufferType = mbi->framebuffer_type;
|
BtGetBootInfo(video).framebufferType = mbi->framebuffer_type;
|
||||||
GetBootInfo(video).fbuValid = 1;
|
BtGetBootInfo(video).fbuValid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves the firmware infos
|
// Retrieves the firmware infos
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_CONFIG_TABLE) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_CONFIG_TABLE) {
|
||||||
GetBootInfo(firmware).romTable = mbi->config_table;
|
BtGetBootInfo(firmware).romTable = mbi->config_table;
|
||||||
GetBootInfo(firmware).romValid = 1;
|
BtGetBootInfo(firmware).romValid = 1;
|
||||||
}
|
}
|
||||||
if (GetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_APM_TABLE) {
|
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_APM_TABLE) {
|
||||||
GetBootInfo(firmware).apmTable = mbi->apm_table;
|
BtGetBootInfo(firmware).apmTable = mbi->apm_table;
|
||||||
GetBootInfo(firmware).apmValid = 1;
|
BtGetBootInfo(firmware).apmValid = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,15 +110,15 @@ void InitBootInfo(multiboot_info_t *mbi)
|
||||||
//
|
//
|
||||||
// Entry point of the Kaleid kernel
|
// Entry point of the Kaleid kernel
|
||||||
//
|
//
|
||||||
noreturn void StartKern(multiboot_info_t *mbInfo, int mbMagic)
|
noreturn void BtStartKern(multiboot_info_t *mbInfo, int mbMagic)
|
||||||
{
|
{
|
||||||
error_t mapBad;
|
error_t mapBad;
|
||||||
|
|
||||||
// We're not ready to deal with interrupts
|
// We're not ready to deal with interrupts
|
||||||
DisableIRQs();
|
KeDisableIRQs();
|
||||||
|
|
||||||
//Initialize the BootInfo_t structure
|
//Initialize the BootInfo_t structure
|
||||||
InitBootInfo(mbInfo);
|
BtInitBootInfo(mbInfo);
|
||||||
|
|
||||||
// Kernel terminals
|
// Kernel terminals
|
||||||
InitTerms();
|
InitTerms();
|
||||||
|
@ -125,17 +128,22 @@ noreturn void StartKern(multiboot_info_t *mbInfo, int mbMagic)
|
||||||
|
|
||||||
KalAlwaysAssert(mbMagic == MULTIBOOT_BOOTLOADER_MAGIC);
|
KalAlwaysAssert(mbMagic == MULTIBOOT_BOOTLOADER_MAGIC);
|
||||||
KernLog("[Init] Kernel successfully loaded at %p with %x magic\n\n",
|
KernLog("[Init] Kernel successfully loaded at %p with %x magic\n\n",
|
||||||
GetBootInfo(btldr).kernelAddr,
|
BtGetBootInfo(btldr).kernelAddr,
|
||||||
mbMagic
|
mbMagic
|
||||||
);
|
);
|
||||||
|
|
||||||
//Memory mapping
|
//Memory mapping
|
||||||
if ((mapBad = InitMemoryMap()))
|
if ((mapBad = MmInitMemoryMap()))
|
||||||
StartPanic("[Init] The memory map failed to initialize. Error : %d",
|
KeStartPanic("[Init] The memory map failed to initialize. Error : %d",
|
||||||
mapBad
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// We're out
|
// We're out
|
||||||
KernLog("\n[Init] Evil never dies !\n");
|
KernLog("\n[Init] Evil never dies !\n");
|
||||||
CrashSystem(); //yay
|
KeCrashSystem(); //yay
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,5 +30,5 @@ Processor_t cpuTable[NCPUS] = {0};
|
||||||
BootInfo_t bootTab = {0};
|
BootInfo_t bootTab = {0};
|
||||||
Terminal_t *StdOut = 0, *StdDbg = 0;
|
Terminal_t *StdOut = 0, *StdDbg = 0;
|
||||||
|
|
||||||
volatile char PanicStr[PANICSTR_SIZE] = {0};
|
volatile char KePanicStr[PANICSTR_SIZE] = {0};
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,9 @@ error_t ClearTerm(Terminal_t *term)
|
||||||
if (term == NULL) return EINVAL;
|
if (term == NULL) return EINVAL;
|
||||||
KalAssert(term->initDone == INITOK);
|
KalAssert(term->initDone == INITOK);
|
||||||
|
|
||||||
AcquireLock(&term->lock);
|
ExAcquireLock(&term->lock);
|
||||||
retcode = term->clear(term);
|
retcode = term->clear(term);
|
||||||
ReleaseLock(&term->lock);
|
ExReleaseLock(&term->lock);
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,12 @@ error_t ChTermColor(Terminal_t *term, TermColor_t fgColor, TermColor_t bgColor)
|
||||||
if (term == NULL)
|
if (term == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
AcquireLock(&term->lock);
|
ExAcquireLock(&term->lock);
|
||||||
|
|
||||||
term->fgColor = fgColor;
|
term->fgColor = fgColor;
|
||||||
term->bgColor = bgColor;
|
term->bgColor = bgColor;
|
||||||
|
|
||||||
ReleaseLock(&term->lock);
|
ExReleaseLock(&term->lock);
|
||||||
|
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
@ -138,9 +138,9 @@ error_t PutOnTerm(Terminal_t *term, char ch)
|
||||||
if (term == NULL) return EINVAL;
|
if (term == NULL) return EINVAL;
|
||||||
KalAssert(term->initDone == INITOK);
|
KalAssert(term->initDone == INITOK);
|
||||||
|
|
||||||
AcquireLock(&term->lock);
|
ExAcquireLock(&term->lock);
|
||||||
rc = PutOnTermUnlocked(term, ch);
|
rc = PutOnTermUnlocked(term, ch);
|
||||||
ReleaseLock(&term->lock);
|
ExReleaseLock(&term->lock);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -169,9 +169,9 @@ error_t PrintOnTerm(Terminal_t *term, const char *str)
|
||||||
if (term == NULL) return EINVAL;
|
if (term == NULL) return EINVAL;
|
||||||
KalAssert(term->initDone == INITOK);
|
KalAssert(term->initDone == INITOK);
|
||||||
|
|
||||||
AcquireLock(&term->lock);
|
ExAcquireLock(&term->lock);
|
||||||
rc = PrintOnTermUnlocked(term, str);
|
rc = PrintOnTermUnlocked(term, str);
|
||||||
ReleaseLock(&term->lock);
|
ExReleaseLock(&term->lock);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,10 @@ error_t VGA_ClearTermUnlocked(Terminal_t *term)
|
||||||
error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch)
|
error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch)
|
||||||
{
|
{
|
||||||
ushort *buffer = (ushort *)term->data;
|
ushort *buffer = (ushort *)term->data;
|
||||||
const size_t offset = VGA_ComputeOffset(term, term->currentX, term->currentY);
|
const size_t offset =
|
||||||
buffer[offset] = VGA_ComputeEntry(ch, VGA_ComputeColorCode(term->fgColor, term->bgColor));
|
VGA_ComputeOffset(term, term->currentX, term->currentY);
|
||||||
|
buffer[offset] = VGA_ComputeEntry(ch,
|
||||||
|
VGA_ComputeColorCode(term->fgColor, term->bgColor));
|
||||||
|
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +73,7 @@ error_t VGA_PutOnTermUnlocked(Terminal_t *term, char ch)
|
||||||
//
|
//
|
||||||
Terminal_t VGA_Terminal = {
|
Terminal_t VGA_Terminal = {
|
||||||
.initDone = FALSE,
|
.initDone = FALSE,
|
||||||
.lock = INITLOCK(KLOCK_MUTEX),
|
.lock = ExINITLOCK(KLOCK_MUTEX),
|
||||||
|
|
||||||
.name = "VGA Output Terminal",
|
.name = "VGA Output Terminal",
|
||||||
.type = "VGA",
|
.type = "VGA",
|
||||||
|
@ -98,9 +100,9 @@ void VGA_Init(void)
|
||||||
KalAssert(VGA_Terminal.initDone != INITOK);
|
KalAssert(VGA_Terminal.initDone != INITOK);
|
||||||
|
|
||||||
//Use the infos provided in the BootInfo_t structure
|
//Use the infos provided in the BootInfo_t structure
|
||||||
VGA_Terminal.data = GetBootInfo(video).framebufferAddr;
|
VGA_Terminal.data = BtGetBootInfo(video).framebufferAddr;
|
||||||
VGA_Terminal.width = GetBootInfo(video).framebufferWidth;
|
VGA_Terminal.width = BtGetBootInfo(video).framebufferWidth;
|
||||||
VGA_Terminal.height = GetBootInfo(video).framebufferHeight;
|
VGA_Terminal.height = BtGetBootInfo(video).framebufferHeight;
|
||||||
|
|
||||||
VGA_Terminal.initDone = INITOK;
|
VGA_Terminal.initDone = INITOK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,11 @@ noreturn void __assert_handler(const char *msg,
|
||||||
int line,
|
int line,
|
||||||
const char *func)
|
const char *func)
|
||||||
{
|
{
|
||||||
DisableIRQs();
|
KeDisableIRQs();
|
||||||
|
|
||||||
(void)file; (void)line; (void)func;
|
(void)file; (void)line; (void)func;
|
||||||
|
|
||||||
StartPanic("In function '%s', from %s line %d - assertion failed: '%s'",
|
KeStartPanic("In function '%s', from %s line %d - assertion failed: '%s'",
|
||||||
func, file, line, msg);
|
func, file, line, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,42 +45,42 @@ noreturn void __assert_handler(const char *msg,
|
||||||
// Your best boy panic()
|
// Your best boy panic()
|
||||||
// This is CPU local...
|
// This is CPU local...
|
||||||
//
|
//
|
||||||
noreturn void StartPanic(const char *fmt, ...)
|
noreturn void KeStartPanic(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
DisableIRQs();
|
KeDisableIRQs();
|
||||||
|
|
||||||
if (GetCurProc()) _SetCurProc(NULL);
|
if (PsGetCurProc()) _PsSetCurProc(NULL);
|
||||||
if (StdOut == NULL) CrashSystem();
|
if (StdOut == NULL) KeCrashSystem();
|
||||||
|
|
||||||
if (fmt == NULL) {
|
if (fmt == NULL) {
|
||||||
fmt = "(no message given)";
|
fmt = "(no message given)";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PanicStr[0] != 0) {
|
if (KePanicStr[0] != 0) {
|
||||||
PrintOnTermUnlocked(StdOut, "\nDouble panic!");
|
PrintOnTermUnlocked(StdOut, "\nDouble panic!");
|
||||||
HaltCPU();
|
KeHaltCPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf((char *)PanicStr, PANICSTR_SIZE, fmt, ap);
|
vsnprintf((char *)KePanicStr, PANICSTR_SIZE, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
PrintOnTermUnlocked(StdOut, "\nPanic!\n\n");
|
PrintOnTermUnlocked(StdOut, "\nPanic!\n\n");
|
||||||
PrintOnTermUnlocked(StdOut, (char *)PanicStr);
|
PrintOnTermUnlocked(StdOut, (char *)KePanicStr);
|
||||||
|
|
||||||
HaltCPU();
|
KeHaltCPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Oh well
|
// Oh well
|
||||||
//
|
//
|
||||||
noreturn void CrashSystem(void)
|
noreturn void KeCrashSystem(void)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
DisableIRQs();
|
KeDisableIRQs();
|
||||||
HaltCPU();
|
KeHaltCPU();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
|
#include <kernel/mm.h>
|
||||||
|
|
||||||
// Least address out of the heap
|
// Least address out of the heap
|
||||||
static void *_heap_end;
|
static void *_heap_end;
|
||||||
|
@ -31,41 +32,39 @@ static void *_heap_end;
|
||||||
static size_t _heap_max;
|
static size_t _heap_max;
|
||||||
|
|
||||||
// Lock NOT used internally, but used by KalAllocMemory() & co.
|
// Lock NOT used internally, but used by KalAllocMemory() & co.
|
||||||
static Lock_t _heap_lock = INITLOCK(KLOCK_SPINLOCK);
|
static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK);
|
||||||
|
|
||||||
// Debugging stub
|
|
||||||
size_t GetAvailZoneSize(void *x) { (void)x; return 8 * MB; }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initializes heap managment
|
// Initializes heap managment
|
||||||
//
|
//
|
||||||
void InitHeap(void)
|
void MmInitHeap(void)
|
||||||
{
|
{
|
||||||
assert(_heap_end == NULL);
|
assert(_heap_end == NULL);
|
||||||
_heap_end = (void *)_HEAP_START;
|
_heap_end = (void *)_HEAP_START;
|
||||||
_heap_max = lmin(8 * MB, GetAvailZoneSize((void *)_HEAP_START));
|
_heap_max = lmin(8 * MB, MmGetAvailZoneSize((void *)_HEAP_START));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Acquires control of the heap's lock
|
// Acquires control of the heap's lock
|
||||||
//
|
//
|
||||||
void LockHeap(void)
|
void MmLockHeap(void)
|
||||||
{
|
{
|
||||||
AcquireLock(&_heap_lock);
|
ExAcquireLock(&_heap_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Releases control of the heap's lock
|
// Releases control of the heap's lock
|
||||||
//
|
//
|
||||||
void UnlockHeap(void)
|
void MmUnlockHeap(void)
|
||||||
{
|
{
|
||||||
ReleaseLock(&_heap_lock);
|
ExReleaseLock(&_heap_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Returns the heap's current size
|
// Returns the heap's current size
|
||||||
//
|
//
|
||||||
size_t GetHeapSize(void)
|
size_t MmGetHeapSize(void)
|
||||||
{
|
{
|
||||||
return (size_t)_heap_end - _HEAP_START;
|
return (size_t)_heap_end - _HEAP_START;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +72,7 @@ size_t GetHeapSize(void)
|
||||||
//
|
//
|
||||||
// Returns the heap's maximum size
|
// Returns the heap's maximum size
|
||||||
//
|
//
|
||||||
size_t GetMaxHeapSize(void)
|
size_t MmGetMaxHeapSize(void)
|
||||||
{
|
{
|
||||||
return _heap_max;
|
return _heap_max;
|
||||||
}
|
}
|
||||||
|
@ -81,9 +80,9 @@ size_t GetMaxHeapSize(void)
|
||||||
//
|
//
|
||||||
// Changes the heap's maximal size
|
// Changes the heap's maximal size
|
||||||
//
|
//
|
||||||
error_t SetMaxHeapSize(size_t new)
|
error_t MmSetMaxHeapSize(size_t new)
|
||||||
{
|
{
|
||||||
if (new > GetAvailZoneSize((void *)_HEAP_START)) {
|
if (new > MmGetAvailZoneSize((void *)_HEAP_START)) {
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ error_t SetMaxHeapSize(size_t new)
|
||||||
//
|
//
|
||||||
// Extends the heap's size
|
// Extends the heap's size
|
||||||
//
|
//
|
||||||
error_t GrowHeap(size_t req)
|
error_t MmGrowHeap(size_t req)
|
||||||
{
|
{
|
||||||
assert(req % alignof(QWORD));
|
assert(req % alignof(QWORD));
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ error_t GrowHeap(size_t req)
|
||||||
//
|
//
|
||||||
// Reduces the heap's size
|
// Reduces the heap's size
|
||||||
//
|
//
|
||||||
error_t ShrinkHeap(size_t req)
|
error_t MmShrinkHeap(size_t req)
|
||||||
{
|
{
|
||||||
assert(req % alignof(QWORD));
|
assert(req % alignof(QWORD));
|
||||||
|
|
||||||
|
|
|
@ -36,19 +36,19 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align)
|
||||||
return EALIGN;
|
return EALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockHeap();
|
MmLockHeap();
|
||||||
|
|
||||||
brk = _HEAP_START + GetHeapSize();
|
brk = _HEAP_START + MmGetHeapSize();
|
||||||
req = _ALIGN_UP(req + brk, align) - brk;
|
req = _ALIGN_UP(req + brk, align) - brk;
|
||||||
|
|
||||||
rc = GrowHeap(req);
|
rc = MmGrowHeap(req);
|
||||||
|
|
||||||
UnlockHeap();
|
MmUnlockHeap();
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if ((flags & M_CANFAIL) != 0)
|
if ((flags & M_CANFAIL) != 0)
|
||||||
return rc;
|
return rc;
|
||||||
StartPanic("Out of memory");
|
KeStartPanic("Out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & M_ZEROED) {
|
if (flags & M_ZEROED) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
// GNU GPL OS/K //
|
// GNU GPL OS/K //
|
||||||
// //
|
// //
|
||||||
// Desc: //
|
// Desc: Mapping and checking memory related functions //
|
||||||
// //
|
// //
|
||||||
// //
|
// //
|
||||||
// Copyright © 2018-2019 The OS/K Team //
|
// Copyright © 2018-2019 The OS/K Team //
|
||||||
|
@ -24,23 +24,139 @@
|
||||||
|
|
||||||
#include <kernel/mm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/term.h>
|
#include <kernel/term.h>
|
||||||
|
#include <kernel/multiboot.h>
|
||||||
|
|
||||||
error_t InitMemoryMap(void)
|
|
||||||
|
MemoryMap_t memoryMap = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initilization of the memory map, and computation of the available ram size
|
||||||
|
//
|
||||||
|
error_t MmInitMemoryMap(void)
|
||||||
{
|
{
|
||||||
if (!GetBootInfo(memory).memValid && GetBootInfo(memory).mapValid)
|
multiboot_memory_map_t *currentEntry;
|
||||||
return ENXIO;
|
multiboot_memory_map_t *mapEnd;
|
||||||
DebugLog("[InitMemoryMap] Memory map address : %p, length : %d\n",
|
uint i = 0;
|
||||||
GetBootInfo(memory).mapAddr, GetBootInfo(memory).mapLength);
|
|
||||||
|
|
||||||
if ((GetBootInfo(memory).upMemory / (MB/KB)) <= MINIMUM_RAM_SIZE)
|
// sanity checks
|
||||||
|
if (!BtGetBootInfo(memory).memValid && BtGetBootInfo(memory).mapValid)
|
||||||
|
return ENXIO;
|
||||||
|
|
||||||
|
if ((BtGetBootInfo(memory).upMemory / (MB/KB)) <= MINIMUM_RAM_SIZE)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
DebugLog("[InitMemoryMap] Low memory : %d Kio, Up memory : %d Mio\n",
|
|
||||||
GetBootInfo(memory).lowMemory, GetBootInfo(memory).upMemory / (MB/KB));
|
// Ok then we can work ------------------------------------------------------ //
|
||||||
|
|
||||||
|
// the memory map provided by GRUB via the BIOS
|
||||||
|
currentEntry = (multiboot_memory_map_t*)BtGetBootInfo(memory).mapAddr;
|
||||||
|
// End address of the map
|
||||||
|
mapEnd = (multiboot_memory_map_t*)
|
||||||
|
((ullong)currentEntry + (ullong)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 ));
|
||||||
|
// memory zone size in bytes
|
||||||
|
memoryMap.entry[i].length = (ullong)currentEntry->len_low +
|
||||||
|
(((ullong)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));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugLog("[InitMemoryMap] %d entries detected in the memory map\n",
|
||||||
|
memoryMap.length);
|
||||||
|
|
||||||
|
// compute the free ram size
|
||||||
|
for (i = 0; i < memoryMap.length; i++) {
|
||||||
|
if (memoryMap.entry[i].type == AVAILABLE_ZONE) {
|
||||||
|
memoryMap.freeRamSize += memoryMap.entry[i].length;
|
||||||
|
} else {
|
||||||
|
memoryMap.nonfreeRamSize += memoryMap.entry[i].length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trully strange if it happens...
|
||||||
|
if (memoryMap.freeRamSize < MINIMUM_RAM_SIZE)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
KernLog("[InitMemoryMap] Available Ram Size : %u Mio, Used Ram Size : %u Kio\n",
|
||||||
|
memoryMap.freeRamSize / MB, memoryMap.nonfreeRamSize / KB);
|
||||||
|
KernLog("[InitMemoryMap] Physical Ram Size : %d Mio\n\n",
|
||||||
|
(memoryMap.freeRamSize + memoryMap.nonfreeRamSize) / MB);
|
||||||
|
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *GetMemoryMap(void)
|
size_t MmGetAvailZoneSize(void *start) {
|
||||||
{
|
uint i;
|
||||||
return (void*)0;
|
|
||||||
|
// Because the kernel is the kernel
|
||||||
|
if (start < BtGetBootInfo(btldr).kernelEndAddr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Search the zone where the start address is
|
||||||
|
for (i = 0; i < memoryMap.length; i++) {
|
||||||
|
// 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)
|
||||||
|
) {
|
||||||
|
return (size_t)((ullong)memoryMap.entry[i].length - (ullong)start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is no zone, we return a 0 size
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MmGetFirstAvailZone(void *start) {
|
||||||
|
uint i;
|
||||||
|
void *current = 0;
|
||||||
|
|
||||||
|
// Because the kernel is the kernel
|
||||||
|
if ((ullong)start < (ullong)BtGetBootInfo(btldr).kernelEndAddr) {
|
||||||
|
return MmGetFirstAvailZone(BtGetBootInfo(btldr).kernelEndAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search the zone where the start address is
|
||||||
|
for (i = 0; i < memoryMap.length; i++) {
|
||||||
|
// 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)
|
||||||
|
) {
|
||||||
|
current = start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
// Search the first zone from start
|
||||||
|
for (i = 0; i < memoryMap.length; i++) {
|
||||||
|
// Return the first zone that is after start
|
||||||
|
if (
|
||||||
|
memoryMap.entry[i].type == AVAILABLE_ZONE &&
|
||||||
|
(ullong)start <= (ullong)memoryMap.entry[i].addr
|
||||||
|
) {
|
||||||
|
current = memoryMap.entry[i].addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue