1
0
mirror of https://gitlab.os-k.eu/os-k-team/os-k.git synced 2023-08-25 14:03:10 +02:00

Merge pull request #56 from os-k-team/master

master
This commit is contained in:
Adrien Bourmault 2019-03-24 21:25:58 +01:00 committed by GitHub
commit 9ad4a83660
26 changed files with 369 additions and 226 deletions

View File

@ -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

View File

@ -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

View File

@ -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 !

View File

@ -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

View File

@ -61,6 +61,8 @@ SECTIONS {
*(.rodata) /* all rodata sections from all files */ *(.rodata) /* all rodata sections from all files */
} }
kernelEnd = .;
/DISCARD/ : /DISCARD/ :
{ {
*(.comment) *(.comment)

View File

@ -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

View File

@ -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)
//------------------------------------------// //------------------------------------------//

View File

@ -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);

View File

@ -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; }
//------------------------------------------// //------------------------------------------//

View File

@ -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) \
); );

View File

@ -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);
//------------------------------------------// //------------------------------------------//

View File

@ -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;

View File

@ -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);
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //

View File

@ -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

View File

@ -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

View File

@ -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 *);
//------------------------------------------// //------------------------------------------//

View File

@ -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);
//------------------------------------------// //------------------------------------------//

View File

@ -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
} }

View File

@ -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};

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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();
} }
} }

View File

@ -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));

View File

@ -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) {

View File

@ -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;
} }