PMM and liballoc port

This commit is contained in:
2025-12-17 22:42:48 +01:00
parent 13fee12f59
commit f60d8d6861
32 changed files with 1202 additions and 12 deletions

91
kernel/libk/bm.c Normal file
View File

@@ -0,0 +1,91 @@
#include <libk/std.h>
#include <libk/bm.h>
#include <libk/string.h>
void bm_init(struct bm *bm, uint8_t *base, size_t nbits) {
bm->base = base;
bm->nbits = nbits;
memset(bm->base, 0, (nbits + 7) / 8);
}
/*
* Set a bit in a bitmap.
*/
void bm_set(struct bm *bm, size_t k) {
if (k >= bm->nbits)
return;
uint8_t *b = (uint8_t *)((uintptr_t)bm->base + (k / 8));
*b = ((*b) | (1 << (k % 8)));
}
/*
* Clear a bit in a bitmap.
*/
void bm_clear(struct bm *bm, size_t k) {
if (k >= bm->nbits)
return;
uint8_t *b = (uint8_t *)((uintptr_t)bm->base + (k / 8));
*b = ((*b) & ~(1 << (k % 8)));
}
/*
* Test (true/false) a bit in a bitmap.
*/
bool bm_test(struct bm *bm, size_t k) {
if (k >= bm->nbits)
return false;
uint8_t *b = (uint8_t *)((uintptr_t)bm->base + (k / 8));
return (*b) & (1 << (k % 8));
}
/*
* Set a range of bits in a bitmap. if starting bit is out of range, we fail.
*/
bool bm_set_region(struct bm *bm, size_t k, size_t m) {
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
return false;
for (size_t i = k; i < m; i++) {
bool taken = bm_test(bm, i);
if (taken)
return false;
}
for (size_t i = k; i < m; i++)
bm_set(bm, i);
return true;
}
/*
* Clear a range of bits in a bitmap. starting bit must be in range.
*/
void bm_clear_region(struct bm *bm, size_t k, size_t m) {
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
return;
for (size_t i = k; i < m; i++)
bm_clear(bm, i);
}
/*
* Test a range if bits in a bitmap. Return true if at least one bit
* is set, else return false (all bits clear). For convenience, if k or m
* are out of range, act as if the bits are set / bitmap is full - this is
* useful for implementing the physical memory manager algorithm.
*/
bool bm_test_region(struct bm *bm, size_t k, size_t m) {
if ((k >= m) || (k >= bm->nbits) || (k + m >= bm->nbits))
return true;
for (size_t i = k; i < m; i++) {
bool test = bm_test(bm, i);
if (test)
return true;
}
return false;
}