aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2025-01-28 04:53:10 -0500
committerRaghuram Subramani <raghus2247@gmail.com>2025-01-28 09:13:21 -0500
commitc307bc6ad3b058027162c3db0b22f65f98665648 (patch)
treec57da2d99d14bc2c05d830526cf9b8f34508bdd0
parent690d5f698a14554901d6f661f23695a4dca09a7c (diff)
kmalloc: Initial (extremely buggy) implementation from liballoc
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/include/libk/kmalloc.h47
-rw-r--r--kernel/include/libk/stdio.h1
-rw-r--r--kernel/kernel/kernel.c20
-rw-r--r--kernel/libk/kmalloc.c580
-rw-r--r--kernel/libk/printk.c14
-rw-r--r--kernel/mm/virtual_mm/virtual_mm.c44
7 files changed, 670 insertions, 37 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 059600d..fb997be 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -18,6 +18,7 @@ set(SRC
libk/printf.c
libk/printk.c
libk/strlen.c
+ libk/kmalloc.c
mm/memory_map.c
mm/physical_mm/memory_map.c
diff --git a/kernel/include/libk/kmalloc.h b/kernel/include/libk/kmalloc.h
new file mode 100644
index 0000000..f760ee1
--- /dev/null
+++ b/kernel/include/libk/kmalloc.h
@@ -0,0 +1,47 @@
+/*
+ * bubbl
+ * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __libk_kmalloc_h
+#define __libk_kmalloc_h
+
+#include <stddef.h>
+
+void *kmalloc(size_t);
+void *krealloc(void *, size_t);
+void *kcalloc(size_t, size_t);
+void kfree(void *);
+
+/** This is a boundary tag which is prepended to the
+ * page or section of a page which we have allocated. It is
+ * used to identify valid memory blocks that the
+ * application is trying to free.
+ */
+struct boundary_tag {
+ unsigned int magic; //< It's a kind of ...
+ unsigned int size; //< Requested size.
+ unsigned int real_size; //< Actual size.
+ int index; //< Location in the page table.
+
+ struct boundary_tag *split_left; //< Linked-list info for broken pages.
+ struct boundary_tag *split_right; //< The same.
+
+ struct boundary_tag *next; //< Linked list info.
+ struct boundary_tag *prev; //< Linked list info.
+};
+
+#endif
diff --git a/kernel/include/libk/stdio.h b/kernel/include/libk/stdio.h
index 2f33980..f944fe4 100644
--- a/kernel/include/libk/stdio.h
+++ b/kernel/include/libk/stdio.h
@@ -37,5 +37,6 @@ int vsprintf(char *str, const char *fmt, va_list ap);
int vsnprintf(char *str, size_t len, const char *fmt, va_list ap);
void printk(const char *from, const char *msg, ...);
+void printk_raw(const char *msg, ...);
#endif
diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c
index 8754aa2..4579a5d 100644
--- a/kernel/kernel/kernel.c
+++ b/kernel/kernel/kernel.c
@@ -18,18 +18,16 @@
#include <boot/gdt.h>
+#include <drivers/serial.h>
+#include <drivers/vga_text_buffer.h>
+#include <kernel/halt.h>
+#include <libk/kmalloc.h>
+#include <libk/stdio.h>
#include <mm/memory_map.h>
#include <mm/multiboot.h>
#include <mm/physical_mm.h>
#include <mm/virtual_mm.h>
-#include <kernel/halt.h>
-
-#include <libk/stdio.h>
-
-#include <drivers/serial.h>
-#include <drivers/vga_text_buffer.h>
-
void
kernel_main(uint32_t magic, multiboot_info_t *multiboot_info)
{
@@ -46,8 +44,12 @@ kernel_main(uint32_t magic, multiboot_info_t *multiboot_info)
physical_mm_init();
virtual_mm_initialize();
- void *starting_address = virtual_mm_alloc_pages(1);
- virtual_mm_free_pages(starting_address, 2);
+ int *a;
+ for (int i = 0; i < 3; i++) {
+ a = kmalloc(1);
+ printk("debug", "%d: Kmalloc allocated: 0x%x", i, a);
+ *a = 79;
+ }
printk("\nKernel", "Started.");
diff --git a/kernel/libk/kmalloc.c b/kernel/libk/kmalloc.c
new file mode 100644
index 0000000..69e77ba
--- /dev/null
+++ b/kernel/libk/kmalloc.c
@@ -0,0 +1,580 @@
+/*
+
+ * bubbl
+ * Copyright (C) 2025 Raghuram Subramani <raghus2247@gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <kernel/spinlock.h>
+#include <libk/kmalloc.h>
+#include <libk/stdio.h>
+#include <mm/virtual_mm.h>
+#include <stdatomic.h>
+#include <stdint.h>
+
+static atomic_flag s_liballoc_lock;
+
+#define liballoc_alloc virtual_mm_alloc_pages
+#define liballoc_free virtual_mm_free_pages
+
+#define printf printk_raw
+
+int
+liballoc_lock(void)
+{
+ spinlock_acquire(&s_liballoc_lock);
+ return 0;
+}
+
+int
+liballoc_unlock(void)
+{
+ spinlock_release(&s_liballoc_lock);
+ return 0;
+}
+
+/** Durand's Ridiculously Amazing Super Duper Memory functions. */
+
+#define DEBUG
+
+#define LIBALLOC_MAGIC 0xc001c0de
+#define MAXCOMPLETE 5
+#define MAXEXP 32
+#define MINEXP 8
+
+#define MODE_BEST 0
+#define MODE_INSTANT 1
+
+#define MODE MODE_BEST
+
+struct boundary_tag *l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
+int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks
+
+#ifdef DEBUG
+unsigned int l_allocated = 0; //< The real amount of memory allocated.
+unsigned int l_inuse = 0; //< The amount of memory in use (kmalloc'ed).
+#endif
+
+static int l_initialized = 0; //< Flag to indicate initialization.
+static int l_pageSize = 4096; //< Individual page size
+static unsigned int l_pageCount = 16; //< Minimum number of pages to allocate.
+
+// *********** HELPER FUNCTIONS *******************************
+
+/** Returns the exponent required to manage 'size' amount of memory.
+ *
+ * Returns n where 2^n <= size < 2^(n+1)
+ */
+static inline unsigned int
+getexp(unsigned int size)
+{
+ if (size < (1 << MINEXP)) {
+#ifdef DEBUG
+ printf("getexp returns -1 for %i less than MINEXP\n", size);
+#endif
+ return -1; // Smaller than the quantum.
+ }
+
+ int shift = MINEXP;
+
+ while (shift < MAXEXP) {
+ if (((unsigned int) 1 << shift) > size)
+ break;
+ shift += 1;
+ }
+
+#ifdef DEBUG
+ printf("getexp returns %i (%i bytes) for %i size\n",
+ shift - 1,
+ (1 << (shift - 1)),
+ size);
+#endif
+
+ return shift - 1;
+}
+
+static void *
+liballoc_memset(void *s, int c, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ ((char *) s)[i] = c;
+
+ return s;
+}
+
+static void *
+liballoc_memcpy(void *s1, const void *s2, size_t n)
+{
+ char *cdest;
+ char *csrc;
+ unsigned int *ldest = (unsigned int *) s1;
+ unsigned int *lsrc = (unsigned int *) s2;
+
+ while (n >= sizeof(unsigned int)) {
+ *ldest++ = *lsrc++;
+ n -= sizeof(unsigned int);
+ }
+
+ cdest = (char *) ldest;
+ csrc = (char *) lsrc;
+
+ while (n > 0) {
+ *cdest++ = *csrc++;
+ n -= 1;
+ }
+
+ return s1;
+}
+
+#ifdef DEBUG
+static void
+dump_array(void)
+{
+ int i = 0;
+ struct boundary_tag *tag = NULL;
+
+ printf("------ Free pages array ---------\n");
+ printf("System memory allocated: %i\n", l_allocated);
+ printf("Memory in used (kmalloc'ed): %i\n", l_inuse);
+
+ for (i = 0; i < MAXEXP; i++) {
+ printf("%.2i(%i): ", i, l_completePages[i]);
+
+ tag = l_freePages[i];
+ while (tag != NULL) {
+ if (tag->split_left != NULL)
+ printf("*");
+ printf("%i", tag->real_size);
+ if (tag->split_right != NULL)
+ printf("*");
+
+ printf(" ");
+ tag = tag->next;
+ }
+ printf("\n");
+ }
+
+ printf("'*' denotes a split to the left/right of a tag\n");
+}
+#endif
+
+static inline void
+insert_tag(struct boundary_tag *tag, int index)
+{
+ int realIndex;
+
+ if (index < 0) {
+ realIndex = getexp(tag->real_size - sizeof(struct boundary_tag));
+ if (realIndex < MINEXP)
+ realIndex = MINEXP;
+ } else
+ realIndex = index;
+
+ tag->index = realIndex;
+
+ if (l_freePages[realIndex] != NULL) {
+ l_freePages[realIndex]->prev = tag;
+ tag->next = l_freePages[realIndex];
+ }
+
+ l_freePages[realIndex] = tag;
+}
+
+static inline void
+remove_tag(struct boundary_tag *tag)
+{
+ if (l_freePages[tag->index] == tag)
+ l_freePages[tag->index] = tag->next;
+
+ if (tag->prev != NULL)
+ tag->prev->next = tag->next;
+ if (tag->next != NULL)
+ tag->next->prev = tag->prev;
+
+ tag->next = NULL;
+ tag->prev = NULL;
+ tag->index = -1;
+}
+
+static inline struct boundary_tag *
+melt_left(struct boundary_tag *tag)
+{
+ struct boundary_tag *left = tag->split_left;
+
+ left->real_size += tag->real_size;
+ left->split_right = tag->split_right;
+
+ if (tag->split_right != NULL)
+ tag->split_right->split_left = left;
+
+ return left;
+}
+
+static inline struct boundary_tag *
+absorb_right(struct boundary_tag *tag)
+{
+ struct boundary_tag *right = tag->split_right;
+
+ remove_tag(right); // Remove right from free pages.
+
+ tag->real_size += right->real_size;
+
+ tag->split_right = right->split_right;
+ if (right->split_right != NULL)
+ right->split_right->split_left = tag;
+
+ return tag;
+}
+
+static inline struct boundary_tag *
+split_tag(struct boundary_tag *tag)
+{
+ unsigned int remainder
+ = tag->real_size - sizeof(struct boundary_tag) - tag->size;
+
+ struct boundary_tag *new_tag
+ = (struct boundary_tag *) ((unsigned int) tag
+ + sizeof(struct boundary_tag) + tag->size);
+
+ new_tag->magic = LIBALLOC_MAGIC;
+ new_tag->real_size = remainder;
+
+ new_tag->next = NULL;
+ new_tag->prev = NULL;
+
+ new_tag->split_left = tag;
+ new_tag->split_right = tag->split_right;
+
+ if (new_tag->split_right != NULL)
+ new_tag->split_right->split_left = new_tag;
+ tag->split_right = new_tag;
+
+ tag->real_size -= new_tag->real_size;
+
+ insert_tag(new_tag, -1);
+
+ return new_tag;
+}
+
+// ***************************************************************
+
+static struct boundary_tag *
+allocate_new_tag(unsigned int size)
+{
+ unsigned int pages;
+ unsigned int usage;
+ struct boundary_tag *tag;
+
+ // This is how much space is required.
+ usage = size + sizeof(struct boundary_tag);
+
+ // Perfect amount of space
+ pages = usage / l_pageSize;
+ if ((usage % l_pageSize) != 0)
+ pages += 1;
+
+ // Make sure it's >= the minimum size.
+ if (pages < l_pageCount)
+ pages = l_pageCount;
+
+ tag = (struct boundary_tag *) liballoc_alloc(pages);
+
+ if (tag == NULL)
+ return NULL; // uh oh, we ran out of memory.
+
+ tag->magic = LIBALLOC_MAGIC;
+ tag->size = size;
+ tag->real_size = pages * l_pageSize;
+ tag->index = -1;
+
+ tag->next = NULL;
+ tag->prev = NULL;
+ tag->split_left = NULL;
+ tag->split_right = NULL;
+
+#ifdef DEBUG
+ printf("Resource allocated %x of %i pages (%i bytes) for %i size.\n",
+ tag,
+ pages,
+ pages * l_pageSize,
+ size);
+
+ l_allocated += pages * l_pageSize;
+
+ printf("Total memory usage = %i KB\n", (int) ((l_allocated / (1024))));
+#endif
+
+ return tag;
+}
+
+void *
+kmalloc(size_t size)
+{
+ int index;
+ void *ptr;
+ struct boundary_tag *tag = NULL;
+
+ liballoc_lock();
+
+ if (l_initialized == 0) {
+#ifdef DEBUG
+ printf("%s\n", "liballoc initializing.");
+#endif
+ for (index = 0; index < MAXEXP; index++) {
+ l_freePages[index] = NULL;
+ l_completePages[index] = 0;
+ }
+ l_initialized = 1;
+ }
+
+ index = getexp(size) + MODE;
+ if (index < MINEXP)
+ index = MINEXP;
+
+ // Find one big enough.
+ tag = l_freePages[index]; // Start at the front of the list.
+ while (tag != NULL) {
+ // If there's enough space in this tag.
+ if ((tag->real_size - sizeof(struct boundary_tag))
+ >= (size + sizeof(struct boundary_tag))) {
+#ifdef DEBUG
+ printf("Tag search found %i >= %i\n",
+ (tag->real_size - sizeof(struct boundary_tag)),
+ (size + sizeof(struct boundary_tag)));
+#endif
+ break;
+ }
+
+ tag = tag->next;
+ }
+
+ // No page found. Make one.
+ if (tag == NULL) {
+ if ((tag = allocate_new_tag(size)) == NULL) {
+ liballoc_unlock();
+ return NULL;
+ }
+
+ index = getexp(tag->real_size - sizeof(struct boundary_tag));
+ } else {
+ remove_tag(tag);
+
+ if ((tag->split_left == NULL) && (tag->split_right == NULL))
+ l_completePages[index] -= 1;
+ }
+
+ // We have a free page. Remove it from the free pages list.
+
+ tag->size = size;
+
+ // Removed... see if we can re-use the excess space.
+
+#ifdef DEBUG
+ printf("Found tag with %i bytes available (requested %i bytes, leaving %i), "
+ "which has exponent: %i (%i bytes)\n",
+ tag->real_size - sizeof(struct boundary_tag),
+ size,
+ tag->real_size - size - sizeof(struct boundary_tag),
+ index,
+ 1 << index);
+#endif
+
+ unsigned int remainder
+ = tag->real_size - size
+ - sizeof(struct boundary_tag) * 2; // Support a new tag + remainder
+
+ if (((int) (remainder)
+ > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/) {
+ int childIndex = getexp(remainder);
+
+ if (childIndex >= 0) {
+#ifdef DEBUG
+ printf("Seems to be splittable: %i >= 2^%i .. %i\n",
+ remainder,
+ childIndex,
+ (1 << childIndex));
+#endif
+
+ struct boundary_tag *new_tag = split_tag(tag);
+ (void) new_tag;
+
+#ifdef DEBUG
+ printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n",
+ tag->real_size,
+ new_tag->real_size,
+ new_tag->index);
+#endif
+ }
+ }
+
+ ptr = (void *) ((unsigned int) tag + sizeof(struct boundary_tag));
+
+#ifdef DEBUG
+ l_inuse += size;
+ printf("kmalloc: %x, %i, %i\n",
+ ptr,
+ (int) l_inuse / 1024,
+ (int) l_allocated / 1024);
+ dump_array();
+#endif
+
+ liballoc_unlock();
+ return ptr;
+}
+
+void
+kfree(void *ptr)
+{
+ int index;
+ struct boundary_tag *tag;
+
+ if (ptr == NULL)
+ return;
+
+ liballoc_lock();
+
+ tag = (struct boundary_tag *) ((unsigned int) ptr
+ - sizeof(struct boundary_tag));
+
+ if (tag->magic != LIBALLOC_MAGIC) {
+ liballoc_unlock(); // release the lock
+ return;
+ }
+
+#ifdef DEBUG
+ l_inuse -= tag->size;
+ printf("free: %x, %i, %i\n",
+ ptr,
+ (int) l_inuse / 1024,
+ (int) l_allocated / 1024);
+#endif
+
+ // MELT LEFT...
+ while ((tag->split_left != NULL) && (tag->split_left->index >= 0)) {
+#ifdef DEBUG
+ printf("Melting tag left into available memory. Left was %i, becomes %i "
+ "(%i)\n",
+ tag->split_left->real_size,
+ tag->split_left->real_size + tag->real_size,
+ tag->split_left->real_size);
+#endif
+ tag = melt_left(tag);
+ remove_tag(tag);
+ }
+
+ // MELT RIGHT...
+ while ((tag->split_right != NULL) && (tag->split_right->index >= 0)) {
+#ifdef DEBUG
+ printf("Melting tag right into available memory. This was was %i, becomes "
+ "%i (%i)\n",
+ tag->real_size,
+ tag->split_right->real_size + tag->real_size,
+ tag->split_right->real_size);
+#endif
+ tag = absorb_right(tag);
+ }
+
+ // Where is it going back to?
+ index = getexp(tag->real_size - sizeof(struct boundary_tag));
+ if (index < MINEXP)
+ index = MINEXP;
+
+ // A whole, empty block?
+ if ((tag->split_left == NULL) && (tag->split_right == NULL)) {
+
+ if (l_completePages[index] == MAXCOMPLETE) {
+ // Too many standing by to keep. Free this one.
+ unsigned int pages = tag->real_size / l_pageSize;
+
+ if ((tag->real_size % l_pageSize) != 0)
+ pages += 1;
+ if (pages < l_pageCount)
+ pages = l_pageCount;
+
+ liballoc_free(tag, pages);
+
+#ifdef DEBUG
+ l_allocated -= pages * l_pageSize;
+ printf("Resource freeing %x of %i pages\n", tag, pages);
+ dump_array();
+#endif
+
+ liballoc_unlock();
+ return;
+ }
+
+ l_completePages[index] += 1; // Increase the count of complete pages.
+ }
+
+ // ..........
+
+ insert_tag(tag, index);
+#ifdef DEBUG
+ printf("Returning tag with %i bytes (requested %i bytes), which has "
+ "exponent: %i\n",
+ tag->real_size,
+ tag->size,
+ index);
+ dump_array();
+#endif
+
+ liballoc_unlock();
+}
+
+void *
+kcalloc(size_t nobj, size_t size)
+{
+ int real_size;
+ void *p;
+
+ real_size = nobj * size;
+
+ p = kmalloc(real_size);
+
+ liballoc_memset(p, 0, real_size);
+
+ return p;
+}
+
+void *
+krealloc(void *p, size_t size)
+{
+ void *ptr;
+ struct boundary_tag *tag;
+ size_t real_size;
+
+ if (size == 0) {
+ kfree(p);
+ return NULL;
+ }
+ if (p == NULL)
+ return kmalloc(size);
+
+ liballoc_lock(); // lockit
+ tag = (struct boundary_tag *) ((unsigned int) p
+ - sizeof(struct boundary_tag));
+ real_size = tag->size;
+ liballoc_unlock();
+
+ if (real_size > size)
+ real_size = size;
+
+ ptr = kmalloc(size);
+ liballoc_memcpy(ptr, p, real_size);
+ kfree(p);
+
+ return ptr;
+}
diff --git a/kernel/libk/printk.c b/kernel/libk/printk.c
index ee84fa4..f97fa1c 100644
--- a/kernel/libk/printk.c
+++ b/kernel/libk/printk.c
@@ -38,3 +38,17 @@ printk(const char *from, const char *msg, ...)
serial_write_string(str);
serial_write_string("\033[0m\n");
}
+
+void
+printk_raw(const char *msg, ...)
+{
+ /* TODO: Dynamic Memory Allocation */
+ char str[256];
+
+ va_list ap;
+ va_start(ap, msg);
+ vsnprintf(str, sizeof(str), msg, ap);
+ va_end(ap);
+
+ serial_write_string(str);
+}
diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c
index 4039597..4acf7c7 100644
--- a/kernel/mm/virtual_mm/virtual_mm.c
+++ b/kernel/mm/virtual_mm/virtual_mm.c
@@ -86,26 +86,31 @@ virtual_mm_initialize(void)
virtual_mm_enable_paging();
}
-void
-virtual_mm_map_page(void *physical_address, void *virtual_address)
+ALWAYS_INLINE uint32_t *
+get_or_make_table(uint32_t *pd_entry)
{
- uint32_t *pd_entry = &current_page_directory[GET_PD_INDEX(virtual_address)];
-
- uint32_t *table = 0;
- /* If the pd_entry isn't present, allocate a block for it, zero the table,
- * and set the pd_entry's frame to the table's address. */
+ uint32_t *table;
if (!PDE_IS_PRESENT(pd_entry)) {
table = physical_mm_allocate_block();
if (!table)
ASSERT_NOT_REACHED();
for (uint32_t i = 0; i < 1024; i++)
- table[i] = 0;
+ table[i] = 0x0;
*pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1);
} else
table = (uint32_t *) PDE_GET_TABLE(pd_entry);
+ return table;
+}
+
+void
+virtual_mm_map_page(void *physical_address, void *virtual_address)
+{
+ uint32_t *pd_entry = &current_page_directory[GET_PD_INDEX(virtual_address)];
+ uint32_t *table = get_or_make_table(pd_entry);
+
uint32_t *pt_entry = &table[GET_PT_INDEX(virtual_address)];
if (PTE_IS_PRESENT(pt_entry)) {
printk("debug", "Mapping previously mapped memory: 0x%x", pt_entry);
@@ -129,28 +134,10 @@ virtual_mm_unmap_page(void *virtual_address)
table = (uint32_t *) PDE_GET_TABLE(pd_entry);
uint32_t *pt_entry = &table[GET_PT_INDEX(virtual_address)];
+ printk("debug", "Freeing: 0x%x", pt_entry);
*pt_entry = 0;
}
-ALWAYS_INLINE uint32_t *
-get_or_make_table(uint32_t *pd_entry)
-{
- uint32_t *table;
- if (!PDE_IS_PRESENT(pd_entry)) {
- table = physical_mm_allocate_block();
- if (!table)
- ASSERT_NOT_REACHED();
-
- for (uint32_t i = 0; i < 1024; i++)
- table[i] = 0x0;
-
- *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1);
- } else
- table = (uint32_t *) PDE_GET_TABLE(pd_entry);
-
- return table;
-}
-
uint32_t
virtual_mm_find_free_virtual_addresses(uint32_t n)
{
@@ -173,7 +160,8 @@ virtual_mm_find_free_virtual_addresses(uint32_t n)
pt_index++) {
/* If we overflow, switch to the consecutive page directory entry */
if (pt_index == PAGE_TABLE_SIZE) {
- if (++pd_index == PAGE_DIRECTORY_SIZE)
+ pd_index++;
+ if (pd_index == PAGE_DIRECTORY_SIZE)
return 0; /* Ran out of pd_entries */
pd_entry = &current_page_directory[pd_index];