forked from PoliEcho-holding-org/kern
Some unfinished changes + TODO chnages
This commit is contained in:
@@ -1,189 +1,106 @@
|
||||
=== Todo ===
|
||||
TODO
|
||||
====
|
||||
|
||||
Legend:
|
||||
Legend
|
||||
------
|
||||
- [ ] Not done
|
||||
- [x] Done
|
||||
- [_] Was done at some point, but isn't now
|
||||
- [!] Important todo
|
||||
- [?] Optional
|
||||
|
||||
- [ ] Refactoring
|
||||
- [ ] Use UEFI
|
||||
- [ ] Use an existing bootloader
|
||||
- [x] libc - User space
|
||||
- [x] libk - Kernel libc
|
||||
- [x] Kernel rewrite
|
||||
- [ ] Better filesystem
|
||||
- [x] Makefile refactorin' (finally done!!!)
|
||||
Todos
|
||||
-----
|
||||
- [ ] Kernel
|
||||
- [ ] Syscalls
|
||||
- [ ] exit()
|
||||
- [ ] fork()
|
||||
- [ ] read()
|
||||
- [ ] write()
|
||||
- [ ] open()
|
||||
- [ ] close()
|
||||
- [ ] waitpid()
|
||||
- [ ] creat()
|
||||
- [ ] link()
|
||||
- [ ] unlink()
|
||||
- [ ] execve()
|
||||
- [ ] chdir()
|
||||
- [ ] time()
|
||||
- [ ] mknod()
|
||||
- [ ] chmod()
|
||||
- [ ] chown()
|
||||
- [ ] break()
|
||||
- [ ] stat()
|
||||
- [ ] mount()
|
||||
- [ ] umount()
|
||||
- [ ] alarm()
|
||||
- [ ] pause()
|
||||
- [ ] access()
|
||||
- [ ] nice()
|
||||
- [ ] sync()
|
||||
- [ ] kill()
|
||||
- [ ] rename()
|
||||
- [ ] mkdir()
|
||||
- [ ] rmdir()
|
||||
- [ ] dup()
|
||||
- [ ] pipe()
|
||||
- [ ] Memory
|
||||
- [ ] Physical MM
|
||||
- [ ] Virtual MM
|
||||
- [ ] Paging
|
||||
- [ ] Kernel Heap
|
||||
- [ ] Drivers
|
||||
- [x] tty
|
||||
- [x] serial
|
||||
- [ ] Timer
|
||||
- [ ] VFS
|
||||
- [ ] RAMFS
|
||||
- [ ] FAT32
|
||||
- [ ] DevFS
|
||||
- [ ] SysFS
|
||||
- [ ] ProcFS
|
||||
|
||||
- [ ] LIBC
|
||||
- [ ] assert.h
|
||||
- [ ] complex.h (idk why we would need this)
|
||||
- [x] ctype.h
|
||||
- [x] errno.h
|
||||
- [x] fcntl.h
|
||||
- [x] float.h
|
||||
- [x] limits.h
|
||||
- [x] math.h (maybe a separate libm?) TODO: add errno errors in there
|
||||
- [x] setjmp.h (this plagues my mind)
|
||||
- [ ] signal.h (we would need signals first)
|
||||
- [x] stdarg.h
|
||||
- [x] stdbool.h
|
||||
- [x] stddef.h
|
||||
- [x] stdint.h
|
||||
- [x] stdio.h
|
||||
- [x] stdlib.h
|
||||
- [x] string.h
|
||||
- [x] syscall.h
|
||||
- [x] time.h
|
||||
- [ ] unistd.h (do we do POSIX?)
|
||||
- [ ] wchar.h (we would need text support for wide chars ig?)
|
||||
- [ ] wctype.h (same as above)
|
||||
- [ ] sys/
|
||||
- [ ] types.h (syscall types)
|
||||
- [ ] gfx.h (basic graphics lib)
|
||||
- [ ] Bootloader
|
||||
- [ ] MBR
|
||||
- [ ] EFI
|
||||
|
||||
- [x] LIBK
|
||||
- [x] drivers - everything that works with hardware
|
||||
- [x] error - error handling (bigerr is not enough :( )
|
||||
- [x] fs - filesystem
|
||||
- [x] interrupt - handling and registering interupts
|
||||
- [x] memory - memory managing (physical and virtual)
|
||||
- [x] screen - everything that displays on the screen
|
||||
- [x] syscall - system calls
|
||||
- [ ] Libc
|
||||
- [ ] assert.h
|
||||
- [ ] complex.h (idk why we would need this)
|
||||
- [ ] ctype.h
|
||||
- [ ] errno.h
|
||||
- [ ] fcntl.h
|
||||
- [ ] float.h
|
||||
- [ ] limits.h
|
||||
- [ ] math.h
|
||||
- [ ] setjmp.h (this plagues my mind)
|
||||
- [ ] signal.h (we would need signals first)
|
||||
- [ ] stdarg.h
|
||||
- [ ] stdbool.h
|
||||
- [ ] stddef.h
|
||||
- [ ] stdint.h
|
||||
- [ ] stdio.h
|
||||
- [ ] stdlib.h
|
||||
- [ ] string.h
|
||||
- [ ] syscall.h
|
||||
- [ ] time.h
|
||||
- [ ] unistd.h (does POSIX need us?)
|
||||
- [ ] wchar.h (we would need text support for wide chars ig?)
|
||||
- [ ] wctype.h (same as above)
|
||||
|
||||
- [x] Multistage Bootloader
|
||||
- [x] Bootloader reads filesystem to find files
|
||||
- [x] The almighty 'printf()'
|
||||
- [x] Write down where stuff is in memory (in notes.txt)
|
||||
- [ ] Userspace
|
||||
- [ ] sh
|
||||
- [ ] as
|
||||
- [ ] cc
|
||||
- [ ] ld
|
||||
- [ ] editor
|
||||
- [ ] binutils
|
||||
- [ ] coreutils
|
||||
- [ ] minesweeper
|
||||
- [ ] solitaire
|
||||
- [ ] tetris
|
||||
- [ ] doom
|
||||
|
||||
- [ ] "Text" mode (not actually)
|
||||
- [x] Scrolling
|
||||
- [ ] Scroll-back
|
||||
- [x] Color codes (and just multicolor text in general)
|
||||
- [x] Controll sequences!
|
||||
- [x] VESA BIOS Extensions
|
||||
- [x] Better resolution
|
||||
- [x] Graphics mode
|
||||
- [x] Custom font
|
||||
- [_] Larger text size
|
||||
- [ ] Variable text size :)
|
||||
- [x] Make output overflow go to next line
|
||||
- [x] More fonts
|
||||
- [x] Generic screen.h stuff (don't assume 1920x1080 32bpp)
|
||||
- [x] Multi vbe mode support
|
||||
- [x] Setup on boot
|
||||
- [ ] Different font size support
|
||||
|
||||
- [x] Math
|
||||
- [x] Trigonometry
|
||||
- [x] Sine
|
||||
- [x] Cosine
|
||||
- [x] Tangent
|
||||
- [x] Cotangent
|
||||
- [x] Arc (inverse) versions
|
||||
- [x] Hyperbolic versions
|
||||
- [x] Absolute value
|
||||
- [?] isOdd() 🗿
|
||||
- [x] Exponential fn (e^x)
|
||||
- [x] Logarithm
|
||||
- [x] Power
|
||||
- [x] Square Root
|
||||
- [x] Floor
|
||||
- [x] Round
|
||||
- [x] Ceiling
|
||||
- [x] Sign
|
||||
- [x] INFINITY
|
||||
- [x] NAN
|
||||
- [x] E (eulers number)
|
||||
- [x] PI
|
||||
|
||||
- [ ] Filesystem
|
||||
- [x] Utility for filesystem building (not just an assembly file)
|
||||
- [x] Better header for file i/o (disk/filesys.h)
|
||||
- [x] Filetable
|
||||
- [x] A better filesystem using INodes etc.
|
||||
- [x] Files
|
||||
- [x] Larger than one sector (512B)
|
||||
- [x] Any file size (Not multiples of 512B)
|
||||
- [x] Filetypes
|
||||
- [ ] Directories
|
||||
- [x] File tree
|
||||
- [x] Dir Entries
|
||||
- [ ] cd command
|
||||
- [ ] Links??
|
||||
- [ ] Symbolic
|
||||
- [ ] Hard
|
||||
|
||||
- [ ] System Calls
|
||||
- [x] Sleep()
|
||||
- [x] Write()
|
||||
- [x] Read()
|
||||
- [x] Open()
|
||||
- [x] Close()
|
||||
- [x] Malloc()
|
||||
- [x] Free()
|
||||
- [x] Seek()
|
||||
- [ ] Tell()
|
||||
- [ ] Exit()
|
||||
|
||||
- [ ] Shell
|
||||
- [ ] Separate file/program
|
||||
- [ ] ';' separated commands
|
||||
- [ ] I/O Redirection with '<' '>'
|
||||
- [x] Display directory in prompt
|
||||
- [ ] Custom prompts
|
||||
- [ ] Variables
|
||||
- [ ] Enviromental/Global
|
||||
- [ ] Normal
|
||||
- [ ] Commands
|
||||
- [x] echo
|
||||
- [x] clear
|
||||
- [x] help
|
||||
- [x] ls
|
||||
- [x] exit
|
||||
- [ ] touch (make file)
|
||||
- [ ] rm
|
||||
- [ ] mkdir (add dirs first)
|
||||
- [x] reboot
|
||||
- [ ] cd
|
||||
|
||||
- [ ] Standard I/O stuff
|
||||
- [ ] stdin
|
||||
- [x] stdout
|
||||
- [ ] stderr
|
||||
|
||||
- [ ] User (or system) programs
|
||||
- [x] Loading them
|
||||
- [_] Running them
|
||||
- [x] Exit back to kernel/shell
|
||||
- [x] Let them use libs
|
||||
- [x] Proper include files (LibC?)
|
||||
- [x] argc, argv[]
|
||||
|
||||
- [ ] Userspace programs
|
||||
- [ ] Shell
|
||||
- [x] Calculator
|
||||
- [ ] Calendar
|
||||
|
||||
- [ ] Code Editor
|
||||
- [ ] Text editor
|
||||
- [ ] Syntax highlighting
|
||||
- [ ] Saving/Loading
|
||||
- [ ] Hex editor
|
||||
|
||||
- [ ] Assembler/Compiler
|
||||
- [ ] Assembler
|
||||
- [ ] Compiler (probably C)
|
||||
- [ ] Standard lib
|
||||
|
||||
- [ ] Finish all todos
|
||||
- [ ] Refactoring!!!
|
||||
- [ ] Can it run DOOM?
|
||||
- [ ] Games
|
||||
- [ ] Minesweeper
|
||||
- [ ] Solitaire
|
||||
- [ ] Tetris
|
||||
|
||||
- [ ] Write an OS in kern (The FINAL Todo)
|
||||
- [ ] Write an OS in kern.
|
||||
- [ ] Finish all the TODOs
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Magic addresses
|
||||
===============
|
||||
|
||||
This is a list of magic addreses that are used in kern.
|
||||
The goal is to minimize the number of these addreses.
|
||||
|
||||
0x1000 - Memory map location, bootloader.memmap is a pointer to here
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef _BOOTLOADER_H
|
||||
#define _BOOTLOADER_H
|
||||
|
||||
#include <kernel.h>
|
||||
|
||||
// Boot protocols
|
||||
#define BOOT_UNKNOWN 0 // Unknown
|
||||
#define BOOT_MB1 1 // MultiBoot 1
|
||||
#define BOOT_MB2 2 // MultiBoot 2
|
||||
#define BOOT_LIMINE 3 // Limine
|
||||
|
||||
struct boot_memmapEntry {
|
||||
uint64_t base;
|
||||
uint64_t size;
|
||||
uint32_t type;
|
||||
uint32_t attr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Some values may not be provided by the bootloader, in this case
|
||||
* pointers will be NULL and integer values will be 0 if applicable.
|
||||
* Some unprovided values may also be implied. Eg.:
|
||||
* If 'memmap = NULL' then 'memmapLen' doesn't matter.
|
||||
*/
|
||||
struct boot_info {
|
||||
uint32_t memLower;
|
||||
uint32_t memUpper;
|
||||
struct boot_memmapEntry* memmap;
|
||||
size_t memmapLen;
|
||||
};
|
||||
|
||||
/*
|
||||
* This functions arguments depend on the boot protocol provided.
|
||||
* This is the reason for the varargs thing. It runs on of the functions
|
||||
* defined after it.
|
||||
*/
|
||||
int boot_init(int type, ...);
|
||||
|
||||
int boot_init_mb1(void* ptr, uint32_t magic);
|
||||
// TODO:
|
||||
// int boot_init_mb2(...);
|
||||
// int boot_init_limine(...);
|
||||
|
||||
#endif
|
||||
@@ -76,17 +76,15 @@ extern uint32_t __kernel_start, __kernel_end;
|
||||
/*
|
||||
* Logging and errors
|
||||
*/
|
||||
// TODO: Logging with printk()
|
||||
// TODO: Log levels & pr_*() wrappers for printk()
|
||||
#define BUG() (panic("BUG()"))
|
||||
// TODO
|
||||
#define printk(_s) NULL
|
||||
#define pr_dbg(_s) NULL
|
||||
#define pr_wrn(_s) NULL
|
||||
#define pr_err(_s) NULL
|
||||
#define panic(_s) NULL
|
||||
#define BUG() NULL
|
||||
#define WARN() NULL
|
||||
#define BUG_ON(_e) ((_e) ? BUG() : NULL)
|
||||
#define WARN_ON(_e) ((_e) ? WARN() : NULL)
|
||||
#include <serial.h>
|
||||
__noreturn static inline void panic(char* s) {
|
||||
serial_puts(COM1, s);
|
||||
__asm__ volatile("cli");
|
||||
while (1) __asm__ volatile ("hlt");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/* is there a symbol table loaded? */
|
||||
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
|
||||
#define MULTIBOOT_INFO_ELF_SHDR 0x00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
|
||||
|
||||
+10
-1
@@ -1,6 +1,15 @@
|
||||
#ifndef _PMM_H
|
||||
#define _PMM_H
|
||||
|
||||
int pmm_init();
|
||||
#include <multiboot.h>
|
||||
|
||||
#define PMM_BS 4096 // Block Size
|
||||
#define PMM_BPB 8 // Blocks per byte
|
||||
|
||||
int pmm_init(void);
|
||||
void pmm_initRegion(size_t base, size_t len);
|
||||
void pmm_deinitRegion(size_t base, size_t len);
|
||||
void* pmm_alloc(size_t blockCount);
|
||||
void pmm_free(void* ptr, size_t blockCount);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#define COM3 0x3e8
|
||||
#define COM4 0x2e8
|
||||
|
||||
// Buffer for (v)debugf()
|
||||
#define DF_BUF_LEN 2048
|
||||
|
||||
int serial_init(int dev);
|
||||
int serial_txem(int dev);
|
||||
void serial_send(int dev, char data);
|
||||
@@ -16,4 +19,7 @@ char serial_recv(int dev);
|
||||
void serial_write(int dev, char* buf, size_t len);
|
||||
void serial_puts(int dev, char* s);
|
||||
|
||||
int debugf(char* fmt, ...);
|
||||
int vdebugf(char* fmt, va_list args);
|
||||
|
||||
#endif
|
||||
|
||||
+19
-9
@@ -1,31 +1,41 @@
|
||||
OUTPUT_FORMAT("elf32-i386")
|
||||
OUTPUT_ARCH("i386");
|
||||
ENTRY(_start)
|
||||
|
||||
/* Define correct program headers */
|
||||
PHDRS {
|
||||
text PT_LOAD FLAGS((1 << 0) | (1 << 2)); /* Read, Execute */
|
||||
rodata PT_LOAD FLAGS((1 << 0)); /* Read */
|
||||
data PT_LOAD FLAGS((1 << 0) | (1 << 1)); /* Read, Write */
|
||||
}
|
||||
|
||||
/* Define sections */
|
||||
SECTIONS {
|
||||
/* 1MB is a conventional place for kernels */
|
||||
. = 1M;
|
||||
|
||||
/* We need the multiboot header in the first 8192 bytes */
|
||||
__kernel_start = .;
|
||||
.text BLOCK(4K) : ALIGN(4K) {
|
||||
*(.multiboot)
|
||||
*(.text)
|
||||
}
|
||||
} : text
|
||||
|
||||
/* Read-only data */
|
||||
.rodata BLOCK(4K) : ALIGN(4K) {
|
||||
*(.rodata)
|
||||
}
|
||||
} : rodata
|
||||
|
||||
/* Initalized r/w data */
|
||||
.data BLOCK(4K) : ALIGN(4K) {
|
||||
*(.data)
|
||||
}
|
||||
} : data
|
||||
|
||||
/* Uninitialized r/w data and stack */
|
||||
.bss BLOCK(4K) : ALIGN(4K) {
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
} : data
|
||||
__kernel_end = .;
|
||||
|
||||
. = 4M;
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.note*)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <bootloader.h>
|
||||
#include <multiboot.h>
|
||||
#include <kernel.h>
|
||||
|
||||
struct boot_info bootloader = { 0 };
|
||||
|
||||
int boot_init(int type, ...) {
|
||||
va_list args;
|
||||
va_start(args, type);
|
||||
|
||||
switch (type) {
|
||||
case BOOT_UNKNOWN: return 1;
|
||||
case BOOT_MB1: return boot_init_mb1(va_arg(args, void*), va_arg(args, uint32_t));
|
||||
case BOOT_MB2: return 1;
|
||||
case BOOT_LIMINE: return 1;
|
||||
}
|
||||
|
||||
// We got an invalid boot protocol
|
||||
return 1;
|
||||
}
|
||||
|
||||
int boot_init_mb1(void* ptr, uint32_t magic) {
|
||||
multiboot_info_t* mbi = ptr;
|
||||
|
||||
if (magic != 0xBADB002) return 1;
|
||||
|
||||
// Memory info
|
||||
if (mbi->flags & MULTIBOOT_INFO_MEMORY) {
|
||||
bootloader.memLower = mbi->mem_lower;
|
||||
bootloader.memUpper = mbi->mem_upper;
|
||||
}
|
||||
|
||||
// Memory map
|
||||
if (mbi->flags & MULTIBOOT_INFO_MEM_MAP) {
|
||||
uint32_t memmap = mbi->mmap_addr;
|
||||
uint32_t offset = 0;
|
||||
while (offset < mbi->mmap_length) {
|
||||
multiboot_memory_map_t* entry = (multiboot_memory_map_t*)(memmap + offset);
|
||||
offset += entry->size;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+6
-7
@@ -1,19 +1,17 @@
|
||||
#include <bootloader.h>
|
||||
#include <kernel.h>
|
||||
#include <serial.h>
|
||||
#include <pmm.h>
|
||||
#include <tty.h>
|
||||
|
||||
#define _hlt() while (1) __asm__ volatile ("cli; hlt");
|
||||
/* TODO: Commented out stuff */
|
||||
|
||||
__noreturn
|
||||
void kmain(void* ptr, uint32_t magic) {
|
||||
// Init with MultiBoot 1, this populates the global bootloader struct
|
||||
//if (boot_init(BOOT_MB1, ptr, magic) != 0) panic("Unsupporred bootloader.");
|
||||
if (boot_init(BOOT_MB1, ptr, magic) != 0) panic("Unsupporred bootloader.");
|
||||
|
||||
// Serial console for debugging
|
||||
serial_init(COM1);
|
||||
serial_puts(COM1, "\x1b[0H\x1b[Jkern.\n");
|
||||
debugf("\x1b[H\x1b[J\x1b[0mkern. \x1b[35m(serial console)\x1b[0m\n\n");
|
||||
|
||||
// VGA tty thingy
|
||||
tty_init();
|
||||
@@ -29,8 +27,9 @@ void kmain(void* ptr, uint32_t magic) {
|
||||
|
||||
debugf("Basic initialization complete!\n");
|
||||
|
||||
/* TODO: Commented out stuff */
|
||||
|
||||
panic("kmain() reached end.");
|
||||
|
||||
// Temporary loop since panic() does not halt
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
+91
-1
@@ -1,4 +1,94 @@
|
||||
#include <multiboot.h>
|
||||
#include <kernel.h>
|
||||
#include <pmm.h>
|
||||
|
||||
int pmm_init() { return 0; }
|
||||
// Helpers
|
||||
#define SET_BLOCK(_b) memmap[(_b) / 32] |= (1 << ((_b) % 32))
|
||||
#define USET_BLOCK(_b) memmap[(_b) / 32] &= ~(1 << ((_b) % 32))
|
||||
#define TEST_BLOCK(_b) ((memmap[(_b) % 32] & (1 << ((_b) % 32))) ? 1 : 0)
|
||||
|
||||
// Memory manager bitmap
|
||||
uint32_t* memmap = NULL;
|
||||
size_t usedBlocks = 0;
|
||||
size_t maxBlocks = 0;
|
||||
|
||||
// TODO: improve these hardcoded values
|
||||
int pmm_init(void) {
|
||||
memmap = NULL; // Memory map location
|
||||
usedBlocks = 0;
|
||||
maxBlocks = 0; // TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int findFreeBlocks(size_t blockCount) {
|
||||
if (blockCount == 0) return -1;
|
||||
|
||||
uint32_t max = maxBlocks / 32;
|
||||
uint32_t freeCount = 0;
|
||||
for (size_t i = 0; i < max; i++) {
|
||||
// We don't have to check, cause it's all reserved
|
||||
if (memmap[i] == 0xffffffff) continue;
|
||||
|
||||
for (uint8_t j = 0; j < 32; j++) {
|
||||
if (TEST_BLOCK(i * PMM_BPB + j)) freeCount++;
|
||||
else freeCount = 0;
|
||||
|
||||
if (freeCount >= blockCount) return i * PMM_BPB + j;
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find enough free memory :(
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pmm_initRegion(size_t base, size_t len) {
|
||||
uint32_t align = base / PMM_BS;
|
||||
uint32_t blockCount = len / PMM_BS;
|
||||
|
||||
while (blockCount-- > 0) {
|
||||
USET_BLOCK(align);
|
||||
align++;
|
||||
usedBlocks--;
|
||||
}
|
||||
|
||||
SET_BLOCK(0);
|
||||
}
|
||||
|
||||
void pmm_deinitRegion(size_t base, size_t len) {
|
||||
uint32_t align = base / PMM_BS;
|
||||
uint32_t blockCount = len / PMM_BS;
|
||||
|
||||
while (blockCount-- > 0) {
|
||||
align++;
|
||||
SET_BLOCK(align); // We can't increment here, because macros -_(._.)_-
|
||||
usedBlocks++;
|
||||
}
|
||||
|
||||
SET_BLOCK(0);
|
||||
}
|
||||
|
||||
void* pmm_alloc(size_t blockCount) {
|
||||
if ((maxBlocks - usedBlocks) < blockCount) return NULL;
|
||||
|
||||
int startBlock = findFreeBlocks(blockCount);
|
||||
if (startBlock == -1) return NULL;
|
||||
|
||||
for (size_t i = 0; i < blockCount; i++) {
|
||||
SET_BLOCK(startBlock + i);
|
||||
usedBlocks++;
|
||||
}
|
||||
|
||||
return (void*)(startBlock * PMM_BS);
|
||||
}
|
||||
|
||||
void pmm_free(void* ptr, size_t blockCount) {
|
||||
size_t startBlock = (size_t)ptr / PMM_BS;
|
||||
|
||||
for (size_t i = 0; i < blockCount; i++) {
|
||||
USET_BLOCK(startBlock + i);
|
||||
usedBlocks--;
|
||||
}
|
||||
|
||||
SET_BLOCK(0); // Make sure block 0 is always set
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user