mirror of
https://gitlab.os-k.eu/os-k-team/os-k.git
synced 2023-08-25 14:03:10 +02:00
merging BetterTerm changes
This commit is contained in:
commit
ceb08e77dd
7
Makefile
7
Makefile
@ -51,7 +51,7 @@ ifeq ($(mode), debug)
|
||||
CFLAGS += -g
|
||||
endif
|
||||
|
||||
KCC=$(CCNAME) $(COPTIM) $(CWARNS) $(CFLAGS) $(CINCLUDES) -D_OSK_SOURCE -D_KALEID_KERNEL
|
||||
KCC=$(CCNAME) $(COPTIM) $(CWARNS) $(CFLAGS) $(CINCLUDES) -D_OSK_SOURCE -D_KALEID_KERNEL -fstack-protector-all
|
||||
|
||||
# Folders
|
||||
MBRDIR=boot/grub
|
||||
@ -75,7 +75,7 @@ NC='\033[1;37m'
|
||||
## SOURCES INSCRIPTION-------------------------------------------------------- #
|
||||
|
||||
# Lib C sources
|
||||
LibCSources= libc/atoi.c libc/itoa.c \
|
||||
LibCSources = libc/atoi.c libc/itoa.c \
|
||||
libc/mem.c libc/ctype.c \
|
||||
libc/rand.c libc/sprintf.c \
|
||||
libc/status.c libc/string.c \
|
||||
@ -85,7 +85,7 @@ LibCSources= libc/atoi.c libc/itoa.c \
|
||||
KernObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(KernSources))
|
||||
|
||||
# Kernel sources
|
||||
KernSources= libbuf/buf.c libbuf/bput.c \
|
||||
KernSources = libbuf/buf.c libbuf/bput.c \
|
||||
libbuf/bprint.c kernel/cpu/cpuid.c \
|
||||
kernel/cpu/idt.c kernel/init/init.c \
|
||||
kernel/init/table.c kernel/io/cursor.c \
|
||||
@ -93,6 +93,7 @@ KernSources= libbuf/buf.c libbuf/bput.c \
|
||||
kernel/ke/panic.c kernel/mm/map.c \
|
||||
kernel/mm/heap.c kernel/mm/malloc.c \
|
||||
kernel/mm/gdt.c kernel/ps/sched.c \
|
||||
kernel/init/info.c kernel/init/ssp.c \
|
||||
|
||||
LibCObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(LibCSources))
|
||||
|
||||
|
16
ProjectTree
16
ProjectTree
@ -63,7 +63,9 @@
|
||||
│ │ │ │ ├── cpuid.o
|
||||
│ │ │ │ └── idt.o
|
||||
│ │ │ ├── init
|
||||
│ │ │ │ ├── info.o
|
||||
│ │ │ │ ├── init.o
|
||||
│ │ │ │ ├── ssp.o
|
||||
│ │ │ │ └── table.o
|
||||
│ │ │ ├── io
|
||||
│ │ │ │ ├── cursor.o
|
||||
@ -84,16 +86,8 @@
|
||||
│ │ │ └── buf.o
|
||||
│ │ └── libc
|
||||
│ │ ├── atoi.o
|
||||
│ │ ├── atoi.o.1
|
||||
│ │ ├── atoi.o.2
|
||||
│ │ ├── atoi.o.3
|
||||
│ │ ├── atoi.o.4
|
||||
│ │ ├── ctype.o
|
||||
│ │ ├── itoa.o
|
||||
│ │ ├── itoa.o.1
|
||||
│ │ ├── itoa.o.2
|
||||
│ │ ├── itoa.o.3
|
||||
│ │ ├── itoa.o.4
|
||||
│ │ ├── mem.o
|
||||
│ │ ├── rand.o
|
||||
│ │ ├── sprintf.o
|
||||
@ -122,11 +116,11 @@
|
||||
│ │ ├── base.h
|
||||
│ │ ├── boot.h
|
||||
│ │ ├── cpu.h
|
||||
│ │ ├── cursor.h
|
||||
│ │ ├── heap.h
|
||||
│ │ ├── iomisc.h
|
||||
│ │ ├── mboot.h
|
||||
│ │ ├── mm.h
|
||||
│ │ ├── panic.h
|
||||
│ │ ├── proc.h
|
||||
│ │ └── sched.h
|
||||
│ ├── kalbase.h
|
||||
@ -141,7 +135,9 @@
|
||||
│ │ │ ├── cpuid.c
|
||||
│ │ │ └── idt.c
|
||||
│ │ ├── init
|
||||
│ │ │ ├── info.c
|
||||
│ │ │ ├── init.c
|
||||
│ │ │ ├── ssp.c
|
||||
│ │ │ └── table.c
|
||||
│ │ ├── io
|
||||
│ │ │ ├── ata.inc
|
||||
@ -178,4 +174,4 @@
|
||||
├── ProjectTree
|
||||
└── README.md
|
||||
|
||||
37 directories, 116 files
|
||||
37 directories, 112 files
|
||||
|
@ -39,6 +39,10 @@
|
||||
#define NULL 0L
|
||||
#endif
|
||||
|
||||
#ifndef RAND_MAX
|
||||
#define RAND_MAX (1 << 30)
|
||||
#endif
|
||||
|
||||
#ifndef INITOK
|
||||
#define INITOK ((unsigned int)0xCAFEBABE)
|
||||
#endif
|
||||
|
@ -226,22 +226,25 @@ enum
|
||||
_LW = _SH(10), // lower alpha
|
||||
};
|
||||
|
||||
#define DEC_CTYPE_FUNC(name, flag) \
|
||||
#define _DECF(name, flag) \
|
||||
static inline bool name(int __c) \
|
||||
{ return isascii(__c) ? !!(__ctype[__c] & flag) : 0; }
|
||||
|
||||
DEC_CTYPE_FUNC(iscntrl, _CT);
|
||||
DEC_CTYPE_FUNC(isprint, _PR);
|
||||
DEC_CTYPE_FUNC(isgraph, _GR);
|
||||
DEC_CTYPE_FUNC(isdigit, _DG);
|
||||
DEC_CTYPE_FUNC(isspace, _SP);
|
||||
DEC_CTYPE_FUNC(isblank, _BK);
|
||||
DEC_CTYPE_FUNC(ispunct, _PT);
|
||||
DEC_CTYPE_FUNC(isalpha, _AL);
|
||||
DEC_CTYPE_FUNC(isupper, _UP);
|
||||
DEC_CTYPE_FUNC(islower, _LW);
|
||||
DEC_CTYPE_FUNC(isxdigit, _DX);
|
||||
DEC_CTYPE_FUNC(isalnum, (_AL|_DG));
|
||||
_DECF(iscntrl, _CT);
|
||||
_DECF(isprint, _PR);
|
||||
_DECF(isgraph, _GR);
|
||||
_DECF(isdigit, _DG);
|
||||
_DECF(isspace, _SP);
|
||||
_DECF(isblank, _BK);
|
||||
_DECF(ispunct, _PT);
|
||||
_DECF(isalpha, _AL);
|
||||
_DECF(isupper, _UP);
|
||||
_DECF(islower, _LW);
|
||||
_DECF(isxdigit, _DX);
|
||||
_DECF(isalnum, (_AL|_DG));
|
||||
|
||||
#undef _SH
|
||||
#undef _DECF
|
||||
|
||||
//------------------------------------------//
|
||||
|
||||
|
@ -109,4 +109,8 @@ error_t BPutOnBuf(Buffer_t *, uchar);
|
||||
error_t BPrintOnBuf(Buffer_t *, const char *fmt, ...);
|
||||
error_t BPrintOnBufV(Buffer_t *, const char *fmt, va_list);
|
||||
|
||||
error_t bputc(Buffer_t *buf, uchar ch);
|
||||
error_t bprintf(Buffer_t *buf, const char *fmt, ...);
|
||||
error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap);
|
||||
|
||||
#endif
|
||||
|
@ -28,10 +28,6 @@
|
||||
|
||||
#ifdef _KALEID_KERNEL
|
||||
|
||||
#ifndef _KALKERN_PANIC_H
|
||||
#include <kernel/panic.h>
|
||||
#endif
|
||||
|
||||
#ifndef _KALKERN_SCHED_H
|
||||
#include <kernel/sched.h>
|
||||
#endif
|
||||
|
@ -126,10 +126,8 @@ void DebugLog(const char *, ...);
|
||||
|
||||
//------------------------------------------//
|
||||
|
||||
// Needed by basically everyone
|
||||
#ifndef _KALEXTRAS_LOCKS_H
|
||||
#include <extras/locks.h>
|
||||
#endif
|
||||
extern volatile bool KeIsPanicking;
|
||||
noreturn void KeStartPanic(const char *, ...);
|
||||
|
||||
//------------------------------------------//
|
||||
|
||||
|
@ -114,6 +114,13 @@ typedef struct IdtEntry_t
|
||||
uint reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
typedef struct {
|
||||
ushort length;
|
||||
void* base;
|
||||
} __attribute__((packed)) Idtr_t;
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// GNU GPL OS/K //
|
||||
// //
|
||||
// Desc: Kernel panic and crash stuff //
|
||||
// Desc: Cursor-related functions //
|
||||
// //
|
||||
// //
|
||||
// Copyright © 2018-2019 The OS/K Team //
|
||||
@ -26,41 +26,15 @@
|
||||
#include <kernel/base.h>
|
||||
#endif
|
||||
|
||||
#ifndef _KALKERN_PANIC_H
|
||||
#define _KALKERN_PANIC_H
|
||||
#ifndef _KALKERN_CURSOR_H
|
||||
#define _KALKERN_CURSOR_H
|
||||
|
||||
//------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define PANICSTR_SIZE 1024
|
||||
extern volatile bool KeIsPanicking;
|
||||
void IoEnableCursor(void);
|
||||
void IoDisableCursor(void);
|
||||
void IoUpdateCursor(int x, int y);
|
||||
|
||||
//------------------------------------------//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// Disable IRQs
|
||||
//
|
||||
#define KeDisableIRQs() asm volatile ("cli")
|
||||
|
||||
//
|
||||
// Enable IRQs
|
||||
//
|
||||
#define KeEnableIRQs() asm volatile ("sti")
|
||||
|
||||
//
|
||||
// Pause CPU until next interuption
|
||||
// !!! Enables IRQs !!!
|
||||
//
|
||||
#define KePauseCPU() asm volatile ("sti\n\thlt")
|
||||
|
||||
//
|
||||
// Halt the CPU indefinitely
|
||||
//
|
||||
#define KeHaltCPU() do { asm volatile ("hlt"); } while (1)
|
||||
|
||||
//------------------------------------------//
|
||||
|
||||
noreturn void KeStartPanic(const char *, ...);
|
||||
noreturn void KeCrashSystem(void);
|
||||
|
||||
//------------------------------------------//
|
||||
#endif
|
@ -26,8 +26,8 @@
|
||||
#include <kernel/base.h>
|
||||
#endif
|
||||
|
||||
#ifndef _KALKERN_MM_H
|
||||
#define _KALKERN_MM_H
|
||||
#ifndef _KALKERN_HEAP_H
|
||||
#define _KALKERN_HEAP_H
|
||||
|
||||
//------------------------------------------//
|
||||
|
||||
|
@ -29,33 +29,96 @@
|
||||
#ifndef _KALKERN_IOMISC_H
|
||||
#define _KALKERN_IOMISC_H
|
||||
|
||||
//------------------------------------------//
|
||||
// IRQ-related stuff //
|
||||
//------------------------------------------//
|
||||
|
||||
static inline
|
||||
void IoWriteByteOnPort(port_t port, port_t val)
|
||||
{
|
||||
KalAssert(FALSE && ENOSYS);
|
||||
(void)port;
|
||||
(void)val;
|
||||
//
|
||||
// Returns whether IRQs are enabled
|
||||
//
|
||||
static inline bool KeCheckIRQStatus(void) {
|
||||
ulong flags;
|
||||
asm volatile ("pushf\n\tpop %0" : "=g"(flags) );
|
||||
return flags & (1 << 9);
|
||||
}
|
||||
|
||||
static inline
|
||||
uchar IoReadByteFromPort(port_t port)
|
||||
{
|
||||
KalAssert(FALSE && ENOSYS);
|
||||
(void)port;
|
||||
return 0;
|
||||
//
|
||||
// Disables IRQs
|
||||
//
|
||||
#define KeDisableIRQs() asm volatile ("cli")
|
||||
|
||||
//
|
||||
// Enables IRQs
|
||||
//
|
||||
#define KeEnableIRQs() asm volatile ("sti")
|
||||
|
||||
//
|
||||
// Disables IRQs, but saves its previous state
|
||||
//
|
||||
static inline ulong KePauseIRQs(void) {
|
||||
ulong flags;
|
||||
asm volatile ("pushf\n\tcli\n\tpop %0" : "=r"(flags) : : "memory");
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline
|
||||
ushort IoReadWordFromPort(port_t port)
|
||||
{
|
||||
KalAssert(FALSE && ENOSYS);
|
||||
(void)port;
|
||||
return 0;
|
||||
//
|
||||
// Restore IRQ flag to its state before KePauseIRQs
|
||||
//
|
||||
#define KeRestoreIRQs(flags) asm("push %0\n\tpopf" : : "rm"(flags) : "memory","cc")
|
||||
|
||||
//------------------------------------------//
|
||||
// 101 ways to hang the system //
|
||||
//------------------------------------------//
|
||||
|
||||
//
|
||||
// Pauses CPU until next interuption
|
||||
//
|
||||
#define KePauseCPU() asm volatile ("sti\n\thlt")
|
||||
|
||||
//
|
||||
// Halts the CPU indefinitely
|
||||
//
|
||||
#define KeHaltCPU() do { asm volatile ("hlt"); } while (1)
|
||||
|
||||
//
|
||||
// Halts the system, making sure it won't recover
|
||||
//
|
||||
#define KeCrashSystem() do { KeDisableIRQs(); KeHaltCPU(); } while (1)
|
||||
|
||||
//------------------------------------------//
|
||||
// Ports I/O //
|
||||
//------------------------------------------//
|
||||
|
||||
static inline void IoWriteByteOnPort(port_t port, uchar val)
|
||||
{ asm volatile ("outb %1, %0" : : "dN" (port), "a" (val)); }
|
||||
|
||||
static inline uchar IoReadByteFromPort(port_t port) {
|
||||
uchar ret;
|
||||
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline ushort IoReadWordFromPort(port_t port) {
|
||||
ushort ret;
|
||||
asm volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline ushort IoReadDWordFromPort(port_t port) {
|
||||
uint ret;
|
||||
asm volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------//
|
||||
// Misc. I/O //
|
||||
//------------------------------------------//
|
||||
|
||||
//
|
||||
// Wait for completion of some I/O operation
|
||||
// Port 0x80 is used for 'checkpoints' during POST
|
||||
//
|
||||
#define IoWaitCompletion() IoWriteByteOnPort(0x80, 0)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -23,6 +23,10 @@
|
||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _KALKERN_BASE_H
|
||||
#include <kernel/base.h>
|
||||
#endif
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
|
@ -26,6 +26,11 @@
|
||||
#include <kernel/base.h>
|
||||
#endif
|
||||
|
||||
#ifndef _KALKERN_MM_H
|
||||
#define _KALKERN_MM_H
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define MINIMUM_RAM_SIZE 16 // Mio, the minimum RAM size.
|
||||
|
||||
#define AVAILABLE_ZONE 1 // Fully usable RAM zone
|
||||
@ -34,14 +39,14 @@
|
||||
#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;
|
||||
typedef struct GdtEntry_t GdtEntry_t;
|
||||
typedef struct GdtPtr_t GdtPtr_t;
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// The entry structure of the map
|
||||
struct MapEntry_t {
|
||||
void *addr;
|
||||
@ -73,10 +78,9 @@ struct GdtPtr_t
|
||||
{
|
||||
uchar limit; // upper 16 bits
|
||||
ushort base; // address of the first entry
|
||||
}
|
||||
__attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// Initializes the memory map structure
|
||||
@ -109,4 +113,6 @@ void MmInitGdt(void);
|
||||
//
|
||||
extern void MmLoadGdt(GdtPtr_t *GdtPtr);
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#endif
|
||||
|
39
kaleid/kernel/cpu/handlers.asm
Normal file
39
kaleid/kernel/cpu/handlers.asm
Normal file
@ -0,0 +1,39 @@
|
||||
;=----------------------------------------------------------------------------=;
|
||||
; GNU GPL OS/K ;
|
||||
; ;
|
||||
; Desc: ;
|
||||
; ;
|
||||
; ;
|
||||
; Copyright © 2018-2019 The OS/K Team ;
|
||||
; ;
|
||||
; This file is part of OS/K. ;
|
||||
; ;
|
||||
; OS/K is free software: you can redistribute it and/or modify ;
|
||||
; it under the terms of the GNU General Public License as published by ;
|
||||
; the Free Software Foundation, either version 3 of the License, or ;
|
||||
; (at your option) any later version. ;
|
||||
; ;
|
||||
; OS/K is distributed in the hope that it will be useful, ;
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
|
||||
; GNU General Public License for more details. ;
|
||||
; ;
|
||||
; You should have received a copy of the GNU General Public License ;
|
||||
; along with OS/K. If not, see <https://www.gnu.org/licenses/>. ;
|
||||
;=----------------------------------------------------------------------------=;
|
||||
|
||||
;; Divide Error Fault
|
||||
|
||||
;; Debug Exception Fault/trap
|
||||
|
||||
;; NMI Interrupt
|
||||
|
||||
;; Breakpoint Trap
|
||||
|
||||
;; Overflow Trap
|
||||
|
||||
;; Bound Range Exceeded Fault
|
||||
|
||||
;;
|
||||
|
||||
|
@ -22,21 +22,20 @@
|
||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <kernel/base.h>
|
||||
#include <kernel/cpu.h>
|
||||
|
||||
extern void lidt(Idtr_t reg);
|
||||
|
||||
//
|
||||
// Registers the new idt in the idtr register.
|
||||
//
|
||||
static inline void lidt(IdtDescriptor_t idtDesc)
|
||||
|
||||
static inline void loadIdt(void* idtAddr, ushort size)
|
||||
{
|
||||
asm volatile( "lidt %0" : : "m"(idtDesc) );
|
||||
// The IDTR register structure that will be sent
|
||||
Idtr_t IDTR = { size, idtAddr };
|
||||
|
||||
lidt(IDTR);
|
||||
}
|
||||
|
||||
//
|
||||
// Initializes the IDT
|
||||
//
|
||||
static error_t InitIDT(void)
|
||||
{
|
||||
error_t stub;
|
||||
return stub;
|
||||
}
|
||||
|
120
kaleid/kernel/init/info.c
Normal file
120
kaleid/kernel/init/info.c
Normal file
@ -0,0 +1,120 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// GNU GPL OS/K //
|
||||
// //
|
||||
// Desc: Initialization of boot info //
|
||||
// //
|
||||
// //
|
||||
// Copyright © 2018-2019 The OS/K Team //
|
||||
// //
|
||||
// This file is part of OS/K. //
|
||||
// //
|
||||
// OS/K is free software: you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation, either version 3 of the License, or //
|
||||
// any later version. //
|
||||
// //
|
||||
// OS/K is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY//without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <kernel/boot.h>
|
||||
#include <kernel/mboot.h>
|
||||
|
||||
//
|
||||
// BootInfo_t initialization. It is necessary because grub will potentially be
|
||||
// wiped since it is below 1MB.... And we must reorganize all that stuff.
|
||||
//
|
||||
void BtInitBootInfo(multiboot_info_t *mbi)
|
||||
{
|
||||
extern ulong MB_header;
|
||||
extern ulong newKernelEnd;
|
||||
|
||||
// We need the multiboot structure
|
||||
KalAlwaysAssert(mbi);
|
||||
|
||||
//Retrieves the bootloader flags to ensure infos are valid
|
||||
BtLoaderInfo.grubFlags = mbi->flags;
|
||||
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) {
|
||||
BtLoaderInfo.grubName = (char*)(ulong)(mbi->boot_loader_name);
|
||||
BtLoaderInfo.kernelAddr = (void*)&MB_header;
|
||||
BtLoaderInfo.kernelEndAddr = (void*)newKernelEnd;
|
||||
BtLoaderInfo.valid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MODS) {
|
||||
BtLoaderInfo.modulesCount = mbi->mods_count;
|
||||
BtLoaderInfo.modulesAddr = (void*)(ulong)mbi->mods_addr;
|
||||
}
|
||||
//Retrieves the drives informations
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_DRIVE_INFO) {
|
||||
BtBootTab.drives.bufferLength = mbi->drives_length;
|
||||
BtBootTab.drives.bufferAddr = (void*)(ulong)mbi->drives_addr;
|
||||
BtBootTab.drives.bufferValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_BOOTDEV) {
|
||||
BtBootTab.drives.bootDrv = mbi->boot_device;
|
||||
BtBootTab.drives.drvValid = 1;
|
||||
}
|
||||
|
||||
//Retrieves the memory informations
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MEMORY) {
|
||||
BtMemoryInfo.lowMemory = mbi->mem_lower;
|
||||
BtMemoryInfo.upMemory = mbi->mem_upper;
|
||||
BtMemoryInfo.memValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MEM_MAP) {
|
||||
BtMemoryInfo.mapAddr = (void*)(ulong)mbi->mmap_addr;
|
||||
BtMemoryInfo.mapLength = mbi->mmap_length;
|
||||
BtMemoryInfo.mapValid = 1;
|
||||
}
|
||||
|
||||
// Retrieves video mode informations
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_VBE_INFO) {
|
||||
BtVideoInfo.vbeControl = (void*)(ulong)mbi->vbe_control_info;
|
||||
BtVideoInfo.vbeModeInfo = (void*)(ulong)mbi->vbe_mode_info;
|
||||
BtVideoInfo.vbeMode = mbi->vbe_mode;
|
||||
BtVideoInfo.vbeInterfaceSeg = mbi->vbe_interface_seg;
|
||||
BtVideoInfo.vbeInterfaceOff = mbi->vbe_interface_off;
|
||||
BtVideoInfo.vbeInterfaceLen = mbi->vbe_interface_len;
|
||||
BtVideoInfo.vbeValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) {
|
||||
BtVideoInfo.framebufferAddr = (void*)mbi->framebuffer_addr;
|
||||
BtVideoInfo.framebufferPitch = mbi->framebuffer_pitch;
|
||||
BtVideoInfo.framebufferWidth = mbi->framebuffer_width;
|
||||
BtVideoInfo.framebufferHeight= mbi->framebuffer_height;
|
||||
BtVideoInfo.framebufferBpp = mbi->framebuffer_bpp;
|
||||
BtVideoInfo.framebufferType = mbi->framebuffer_type;
|
||||
BtVideoInfo.fbuValid = 1;
|
||||
}
|
||||
|
||||
// Retrieves the firmware infos
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_CONFIG_TABLE) {
|
||||
BtFirmwareInfo.romTable = mbi->config_table;
|
||||
BtFirmwareInfo.romValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_APM_TABLE) {
|
||||
BtFirmwareInfo.apmTable = mbi->apm_table;
|
||||
BtFirmwareInfo.apmValid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void BtDoSanityChecks(uint mbMagic) {
|
||||
uint tmp;
|
||||
|
||||
if (!(mbMagic == MULTIBOOT_BOOTLOADER_MAGIC))
|
||||
KeStartPanic("[Init] Magic number %x is incorrect\n", mbMagic);
|
||||
|
||||
tmp = (BtLoaderInfo.kernelEndAddr
|
||||
- BtLoaderInfo.kernelAddr) / KB;
|
||||
DebugLog("[Init] Kernel successfully loaded at %p with %x magic\n"
|
||||
" and it uses %d Kio\n\n",
|
||||
BtLoaderInfo.kernelAddr,
|
||||
mbMagic,tmp);
|
||||
}
|
||||
|
@ -22,118 +22,28 @@
|
||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <extras/buf.h>
|
||||
#include <kernel/iomisc.h>
|
||||
#include <kernel/cursor.h>
|
||||
#include <kernel/mboot.h>
|
||||
#include <kernel/panic.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/heap.h>
|
||||
#include <kernel/boot.h>
|
||||
#include <kernel/mm.h>
|
||||
|
||||
//
|
||||
// BootInfo_t initialization. It is necessary because grub will potentially be
|
||||
// wiped since it is below 1MB.... And we must reorganize all that stuff.
|
||||
//
|
||||
void BtInitBootInfo(multiboot_info_t *mbi)
|
||||
{
|
||||
extern ulong MB_header;
|
||||
extern ulong newKernelEnd;
|
||||
// info.c
|
||||
extern void BtDoSanityChecks(uint mbMagic);
|
||||
extern void BtInitBootInfo(multiboot_info_t *mbi);
|
||||
|
||||
// We need the multiboot structure
|
||||
KalAlwaysAssert(mbi);
|
||||
|
||||
//Retrieves the bootloader flags to ensure infos are valid
|
||||
BtLoaderInfo.grubFlags = mbi->flags;
|
||||
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) {
|
||||
BtLoaderInfo.grubName = (char*)(ulong)(mbi->boot_loader_name);
|
||||
BtLoaderInfo.kernelAddr = (void*)&MB_header;
|
||||
BtLoaderInfo.kernelEndAddr = (void*)newKernelEnd;
|
||||
BtLoaderInfo.valid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MODS) {
|
||||
BtLoaderInfo.modulesCount = mbi->mods_count;
|
||||
BtLoaderInfo.modulesAddr = (void*)(ulong)mbi->mods_addr;
|
||||
}
|
||||
//Retrieves the drives informations
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_DRIVE_INFO) {
|
||||
BtBootTab.drives.bufferLength = mbi->drives_length;
|
||||
BtBootTab.drives.bufferAddr = (void*)(ulong)mbi->drives_addr;
|
||||
BtBootTab.drives.bufferValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_BOOTDEV) {
|
||||
BtBootTab.drives.bootDrv = mbi->boot_device;
|
||||
BtBootTab.drives.drvValid = 1;
|
||||
}
|
||||
|
||||
//Retrieves the memory informations
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MEMORY) {
|
||||
BtMemoryInfo.lowMemory = mbi->mem_lower;
|
||||
BtMemoryInfo.upMemory = mbi->mem_upper;
|
||||
BtMemoryInfo.memValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MEM_MAP) {
|
||||
BtMemoryInfo.mapAddr = (void*)(ulong)mbi->mmap_addr;
|
||||
BtMemoryInfo.mapLength = mbi->mmap_length;
|
||||
BtMemoryInfo.mapValid = 1;
|
||||
}
|
||||
|
||||
// Retrieves video mode informations
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_VBE_INFO) {
|
||||
BtVideoInfo.vbeControl = (void*)(ulong)mbi->vbe_control_info;
|
||||
BtVideoInfo.vbeModeInfo = (void*)(ulong)mbi->vbe_mode_info;
|
||||
BtVideoInfo.vbeMode = mbi->vbe_mode;
|
||||
BtVideoInfo.vbeInterfaceSeg = mbi->vbe_interface_seg;
|
||||
BtVideoInfo.vbeInterfaceOff = mbi->vbe_interface_off;
|
||||
BtVideoInfo.vbeInterfaceLen = mbi->vbe_interface_len;
|
||||
BtVideoInfo.vbeValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) {
|
||||
BtVideoInfo.framebufferAddr = (void*)mbi->framebuffer_addr;
|
||||
BtVideoInfo.framebufferPitch = mbi->framebuffer_pitch;
|
||||
BtVideoInfo.framebufferWidth = mbi->framebuffer_width;
|
||||
BtVideoInfo.framebufferHeight= mbi->framebuffer_height;
|
||||
BtVideoInfo.framebufferBpp = mbi->framebuffer_bpp;
|
||||
BtVideoInfo.framebufferType = mbi->framebuffer_type;
|
||||
BtVideoInfo.fbuValid = 1;
|
||||
}
|
||||
|
||||
// Retrieves the firmware infos
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_CONFIG_TABLE) {
|
||||
BtFirmwareInfo.romTable = mbi->config_table;
|
||||
BtFirmwareInfo.romValid = 1;
|
||||
}
|
||||
if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_APM_TABLE) {
|
||||
BtFirmwareInfo.apmTable = mbi->apm_table;
|
||||
BtFirmwareInfo.apmValid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void BtInitSanity(uint mbMagic){
|
||||
uint tmp;
|
||||
|
||||
KernLog("%c%c%c OS/K\n \n", 219, 219, 219);
|
||||
|
||||
if (!(mbMagic == MULTIBOOT_BOOTLOADER_MAGIC))
|
||||
KeStartPanic("[Init] Magic number %x is incorrect\n", mbMagic);
|
||||
|
||||
tmp = (BtLoaderInfo.kernelEndAddr
|
||||
- BtLoaderInfo.kernelAddr) / KB;
|
||||
DebugLog("[Init] Kernel successfully loaded at %p with %x magic\n"
|
||||
" and it uses %d Kio\n\n",
|
||||
BtLoaderInfo.kernelAddr,
|
||||
mbMagic,tmp);
|
||||
}
|
||||
|
||||
|
||||
extern void pstest(void);
|
||||
// io/vga.c
|
||||
extern error_t IoInitVGABuffer(void);
|
||||
|
||||
// ps/proc.c test function
|
||||
extern void pstest(void);
|
||||
|
||||
//
|
||||
// Entry point of the Kaleid kernel
|
||||
//
|
||||
noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic)
|
||||
{
|
||||
// We're not ready to deal with interrupts
|
||||
KeDisableIRQs();
|
||||
|
||||
// Initialize the BootInfo_t structure
|
||||
@ -141,9 +51,13 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic)
|
||||
|
||||
// Screen I/O available from this point on
|
||||
IoInitVGABuffer();
|
||||
IoEnableCursor();
|
||||
IoUpdateCursor(0, 0);
|
||||
|
||||
// Sanity checks and hello world
|
||||
BtInitSanity(mbMagic);
|
||||
KernLog("%c%c%c OS/K\n\n", 219, 219, 219); //grrr
|
||||
|
||||
// Sanity checks
|
||||
BtDoSanityChecks(mbMagic);
|
||||
|
||||
// Memory & scheduler
|
||||
MmInitMemoryMap();
|
||||
@ -152,13 +66,9 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic)
|
||||
MmInitHeap();
|
||||
PsInitSched();
|
||||
|
||||
//int i = 0;
|
||||
//while(i < 512) { KernLog("%d\n", i++);}
|
||||
|
||||
MmPrintMemoryMap();
|
||||
|
||||
//KeStartPanic("Test Panic %d", 4);
|
||||
|
||||
// End this machine's suffering
|
||||
BFlushBuf(BStdOut);
|
||||
KeCrashSystem();
|
||||
}
|
||||
|
33
kaleid/kernel/init/ssp.c
Normal file
33
kaleid/kernel/init/ssp.c
Normal file
@ -0,0 +1,33 @@
|
||||
//----------------------------------------------------------------------------//
|
||||
// GNU GPL OS/K //
|
||||
// //
|
||||
// Desc: Stack smashing protection //
|
||||
// //
|
||||
// //
|
||||
// Copyright © 2018-2019 The OS/K Team //
|
||||
// //
|
||||
// This file is part of OS/K. //
|
||||
// //
|
||||
// OS/K is free software: you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation, either version 3 of the License, or //
|
||||
// any later version. //
|
||||
// //
|
||||
// OS/K is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY//without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <kernel/base.h>
|
||||
|
||||
ulong __stack_chk_guard = 0x447c0ffe4dbf9e55;
|
||||
|
||||
noreturn void __stack_chk_fail(void)
|
||||
{
|
||||
KeStartPanic("Stack smashed!");
|
||||
}
|
||||
|
@ -21,3 +21,32 @@
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <kernel/boot.h>
|
||||
#include <kernel/cursor.h>
|
||||
#include <kernel/iomisc.h>
|
||||
|
||||
void IoEnableCursor(void)
|
||||
{
|
||||
IoWriteByteOnPort(0x3D4, 0xA);
|
||||
IoWriteByteOnPort(0x3D5, (IoReadByteFromPort(0x3D5) & 0xC0) | 14);
|
||||
|
||||
IoWriteByteOnPort(0x3D4, 0xB);
|
||||
IoWriteByteOnPort(0x3D5, (IoReadByteFromPort(0x3D5) & 0xE0) | 15);
|
||||
}
|
||||
|
||||
void IoDisableCursor(void)
|
||||
{
|
||||
IoWriteByteOnPort(0x3D4, 0x0A);
|
||||
IoWriteByteOnPort(0x3D5, 0x20);
|
||||
}
|
||||
|
||||
void IoUpdateCursor(int x, int y)
|
||||
{
|
||||
const ushort pos = y * BtVideoInfo.framebufferWidth + x;
|
||||
|
||||
IoWriteByteOnPort(0x3D4, 0x0F);
|
||||
IoWriteByteOnPort(0x3D5, (pos & 0xFF));
|
||||
IoWriteByteOnPort(0x3D4, 0x0E);
|
||||
IoWriteByteOnPort(0x3D5, ((pos >> 8) & 0xFF));
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <extras/buf.h>
|
||||
#include <kernel/boot.h>
|
||||
#include <kernel/cursor.h>
|
||||
|
||||
//----------------------------------------------------------//
|
||||
// Internal functions for VGA terminals //
|
||||
@ -43,17 +44,30 @@
|
||||
error_t bvgaflusher(Buffer_t *buf)
|
||||
{
|
||||
ushort *fbp = BtVideoInfo.framebufferAddr;
|
||||
const uchar color = 0xf;
|
||||
uchar color = 0xf;
|
||||
|
||||
uchar *currentLine = buf->wp - buf->lineLen - buf->lastLF;
|
||||
uchar *ptr = (uchar *)lmax((size_t)buf->buf,
|
||||
(size_t)currentLine
|
||||
- (buf->nLines - 1) * buf->lineLen);
|
||||
uchar *bufStart = (uchar *)lmax((size_t)buf->buf,
|
||||
(size_t)currentLine
|
||||
- (buf->nLines - 1) * buf->lineLen);
|
||||
|
||||
uchar *ptr = bufStart;
|
||||
|
||||
// Writes the buffer's content
|
||||
|
||||
for (; ptr < buf->wp ; ptr++) {
|
||||
*fbp++ = VGA_ComputeEntry(*ptr, color);
|
||||
}
|
||||
|
||||
|
||||
// Update the cursor
|
||||
size_t curX = ((size_t)ptr - (size_t)bufStart) % buf->lineLen;
|
||||
size_t curY = ((size_t)ptr - (size_t)bufStart) / buf->lineLen;
|
||||
|
||||
IoUpdateCursor(curX, curY);
|
||||
|
||||
// Empty the rest of the buffer
|
||||
|
||||
const size_t bufSize = buf->nLines * buf->lineLen;
|
||||
ushort *fbe = BtVideoInfo.framebufferAddr
|
||||
+ (bufSize * sizeof(ushort));
|
||||
@ -63,6 +77,7 @@ error_t bvgaflusher(Buffer_t *buf)
|
||||
while (fbp < fbe) *fbp++ = filler;
|
||||
}
|
||||
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,7 @@
|
||||
|
||||
#include <extras/buf.h>
|
||||
#include <kernel/proc.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/panic.h>
|
||||
#include <kernel/iomisc.h>
|
||||
|
||||
error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap);
|
||||
|
||||
@ -63,7 +62,7 @@ noreturn void KeStartPanic(const char *fmt, ...)
|
||||
}
|
||||
|
||||
if (KeIsPanicking) {
|
||||
vbprintf(BStdOut, "\nDouble panic!", NULL);
|
||||
bprintf(BStdOut, "\nDouble panic!");
|
||||
KeHaltCPU();
|
||||
}
|
||||
|
||||
@ -72,7 +71,7 @@ noreturn void KeStartPanic(const char *fmt, ...)
|
||||
// We don't check vbprintf's output
|
||||
// If it fails, what could we do anyway?
|
||||
|
||||
vbprintf(BStdOut, "\nPanic!\n\n", NULL);
|
||||
bprintf(BStdOut, "\nPANIC\n");
|
||||
|
||||
va_start(ap, fmt);
|
||||
vbprintf(BStdOut, fmt, ap);
|
||||
@ -83,14 +82,3 @@ noreturn void KeStartPanic(const char *fmt, ...)
|
||||
KeHaltCPU();
|
||||
}
|
||||
|
||||
//
|
||||
// Oh well
|
||||
//
|
||||
noreturn void KeCrashSystem(void)
|
||||
{
|
||||
while (1) {
|
||||
KeDisableIRQs();
|
||||
KeHaltCPU();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <kernel/mm.h>
|
||||
#include <kernel/heap.h>
|
||||
#include <extras/locks.h>
|
||||
|
||||
// Least address out of the heap
|
||||
static void *_heap_end;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <extras/list.h>
|
||||
#include <kernel/proc.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/iomisc.h>
|
||||
|
||||
//
|
||||
// For test purpose only
|
||||
@ -81,10 +82,6 @@ void PsUnlockSched(void) {
|
||||
//
|
||||
// The four priority classes of OS/2
|
||||
//
|
||||
/*CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
|
||||
CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
|
||||
CREATE_PER_CPU(ReglPrioProcs, ListHead_t *);
|
||||
CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);*/
|
||||
|
||||
const char *PsPrioClassesNames[] = {
|
||||
"Time-critical class",
|
||||
@ -177,9 +174,6 @@ void PsSchedThisProc(Process_t *proc)
|
||||
//
|
||||
// Selects process to schedule next
|
||||
//
|
||||
// WARNING
|
||||
// Does not call SchedLock()/SchedUnlock()
|
||||
//
|
||||
static Process_t *SelectSchedNext(void)
|
||||
{
|
||||
if (TimeCritProcs->length > 0)
|
||||
@ -293,7 +287,7 @@ leave:
|
||||
PsUnlockSched();
|
||||
|
||||
if (PsCurProc != NULL && PsCurProc != previous) {
|
||||
// XXX context switch
|
||||
// dispatch & context switch
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,12 +383,12 @@ void pstest(void)
|
||||
KernLog("\nRegular: ");
|
||||
PrintList(ReglPrioProcs);
|
||||
|
||||
KernLog("\nIdle:");
|
||||
KernLog("\nIdle: ");
|
||||
PrintList(IdlePrioProcs);
|
||||
|
||||
int tick = 0;
|
||||
|
||||
while (tick < 24) {
|
||||
while (tick < 14) {
|
||||
//if (tick%25==0)ClearTerm(StdOut);
|
||||
if (tick > 0 && tick != 50 && tick % 10 == 0) {
|
||||
KernLog("Blocking current process\n");
|
||||
@ -409,7 +403,7 @@ void pstest(void)
|
||||
KernLog("Tick %d - Running: ", tick);
|
||||
|
||||
if (PsCurProc == NULL) {
|
||||
KernLog("IDLE");
|
||||
KernLog("IDLE\n");
|
||||
}
|
||||
|
||||
else {
|
||||
@ -419,7 +413,7 @@ void pstest(void)
|
||||
PsSchedOnTick();
|
||||
|
||||
if (tick == 50) // already done
|
||||
KernLog("Re-scheduling process 0");
|
||||
KernLog("Re-scheduling process 0\n");
|
||||
|
||||
tick++;
|
||||
}
|
||||
|
@ -25,9 +25,6 @@
|
||||
#include <extras/buf.h>
|
||||
#include <extras/locks.h>
|
||||
|
||||
error_t bputc(Buffer_t *buf, uchar ch);
|
||||
error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap);
|
||||
|
||||
//
|
||||
// Prints formatted string on buf according to fmt
|
||||
//
|
||||
@ -56,6 +53,18 @@ error_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap)
|
||||
return rc;
|
||||
}
|
||||
|
||||
error_t bprintf(Buffer_t *buf, const char *fmt, ...)
|
||||
{
|
||||
error_t rc;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
rc = vbprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
//
|
||||
// Prints 0 for octal, 0x for hexadecimal, 0b for binary
|
||||
//
|
||||
@ -285,13 +294,21 @@ error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap)
|
||||
if (width < 12) width = 12;
|
||||
}
|
||||
|
||||
// Unknown/unsupported modifier
|
||||
// Note: a '\0' after length field falls here
|
||||
else {
|
||||
// End of string too soon
|
||||
else if (type == '\0') {
|
||||
bputc(buf, '%');
|
||||
rc = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
// Unknown/unsupported modifier
|
||||
else {
|
||||
bputc(buf, '%');
|
||||
bputc(buf, '?');
|
||||
rc = bputc(buf, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Numerical conversions
|
||||
//
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include <extras/buf.h>
|
||||
#include <extras/locks.h>
|
||||
|
||||
error_t bputc(Buffer_t *buf, uchar ch);
|
||||
|
||||
//
|
||||
// Writes a character on a buffer
|
||||
//
|
||||
|
@ -24,9 +24,6 @@
|
||||
|
||||
#include <kalbase.h>
|
||||
|
||||
// XXX Move to header
|
||||
#define RAND_MAX (1 << 30)
|
||||
|
||||
//
|
||||
// Seed value
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user