mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-21 18:32:20 +00:00
looping kalloc can allocate all of memory (sometimes) :3
This commit is contained in:
parent
c8c8d009f6
commit
1d794d87f4
8 changed files with 147 additions and 105 deletions
55
Makefile
55
Makefile
|
@ -1,62 +1,59 @@
|
||||||
SRC_DIR=src
|
KERNEL=kernel.bin
|
||||||
INCLUDE_DIR=include
|
ISO=os_image.iso
|
||||||
BUILD_DIR=build
|
|
||||||
|
|
||||||
K_BIN_NAME=kernel.bin
|
|
||||||
ISO_NAME=os_image.iso
|
|
||||||
|
|
||||||
|
ARCH=amd64
|
||||||
CC=cc
|
CC=cc
|
||||||
LD=ld
|
LD=ld
|
||||||
AS=nasm
|
AS=nasm
|
||||||
|
|
||||||
CFLAGS+=-std=c2x -ffreestanding -fno-stack-protector -g -Wall -Wextra -pedantic -lgcc -isystem $(INCLUDE_DIR)
|
CFLAGS += -std=c2x -ffreestanding -fno-stack-protector -g -Wall -Wextra -pedantic -lgcc -isystem include
|
||||||
CFLAGS+=-DPAGE_SIZE=4096
|
CFLAGS += -DPAGE_SIZE=4096
|
||||||
|
|
||||||
LDFLAGS+=-nmagic
|
LDFLAGS += -nmagic -nostdlib
|
||||||
|
|
||||||
C_SRC=$(shell find $(SRC_DIR) -type f -name "*.c")
|
H_SRC = $(shell find src include -type f -name "*.h")
|
||||||
C_OBJ=$(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SRC))
|
|
||||||
|
|
||||||
H_SRC=$(shell find $(SRC_DIR) -type f -name "*.h")
|
C_SRC = $(shell find src -type f -name "*.c")
|
||||||
H_INCLUDE=$(shell find $(INCLUDE_DIR) -type f -name "*.h")
|
C_OBJ = $(patsubst %.c,build/%.o,$(C_SRC))
|
||||||
|
|
||||||
A_SRC=$(shell find $(SRC_DIR) -type f -name "*.S")
|
A_SRC = $(shell find src -type f -name "*.S" -not -path "src/arch/*")
|
||||||
A_OBJ=$(patsubst %.S,$(BUILD_DIR)/%.S.o,$(A_SRC))
|
A_SRC += $(shell find src/arch/$(ARCH) -type f -name "*.S")
|
||||||
|
A_OBJ = $(patsubst %.S,build/%.S.o,$(A_SRC))
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(BUILD_DIR)/$(ISO_NAME)
|
all: build/$(ISO)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@printf "\033[31m RM \033[0m%s\n" $(BUILD_DIR)
|
@printf "\033[31m RM \033[0m%s\n" build
|
||||||
@rm -rf $(BUILD_DIR)/*
|
@rm -rf build/*
|
||||||
|
|
||||||
$(A_OBJ): $(BUILD_DIR)/%.S.o : %.S
|
$(A_OBJ): build/%.S.o : %.S
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
@printf "\033[33m AS \033[0m%s\n" $<
|
@printf "\033[33m AS \033[0m%s\n" $<
|
||||||
@nasm $< -f elf64 -o $@
|
@nasm $< -f elf64 -o $@
|
||||||
|
|
||||||
$(C_OBJ): $(BUILD_DIR)/%.o : %.c
|
$(C_OBJ): build/%.o : %.c
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
@printf "\033[34m CC \033[0m%s\n" $<
|
@printf "\033[34m CC \033[0m%s\n" $<
|
||||||
@$(CC) -c $(CFLAGS) -o $@ $<
|
@$(CC) -c $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILD_DIR)/$(K_BIN_NAME): arch/amd64/linker.ld $(A_OBJ) $(C_OBJ) $(H_SRC) $(H_INCLUDE)
|
build/$(KERNEL): arch/$(ARCH)/linker.ld $(A_OBJ) $(C_OBJ) $(H_SRC)
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
@printf "\033[32m LD \033[0m%s\n" $@
|
@printf "\033[32m LD \033[0m%s\n" $@
|
||||||
@$(LD) $(LDFLAGS) --no-warn-rwx-segments -T arch/amd64/linker.ld -o $(BUILD_DIR)/$(K_BIN_NAME) $(A_OBJ) $(C_OBJ)
|
@$(LD) $(LDFLAGS) --no-warn-rwx-segments -T arch/$(ARCH)/linker.ld -o build/$(KERNEL) $(A_OBJ) $(C_OBJ)
|
||||||
|
|
||||||
$(BUILD_DIR)/$(ISO_NAME): $(BUILD_DIR)/$(K_BIN_NAME) grub.cfg
|
build/$(ISO): build/$(KERNEL) grub.cfg
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
@mkdir -p $(BUILD_DIR)/iso/boot/grub
|
@mkdir -p build/iso/boot/grub
|
||||||
@cp grub.cfg $(BUILD_DIR)/iso/boot/grub
|
@cp grub.cfg build/iso/boot/grub
|
||||||
@cp $(BUILD_DIR)/$(K_BIN_NAME) $(BUILD_DIR)/iso/boot
|
@cp build/$(KERNEL) build/iso/boot
|
||||||
@printf "\033[35m ISO \033[0m%s\n" $(BUILD_DIR)/$(ISO_NAME)
|
@printf "\033[35m ISO \033[0m%s\n" build/$(ISO)
|
||||||
@grub-mkrescue -o $(BUILD_DIR)/$(ISO_NAME) $(BUILD_DIR)/iso 2> /dev/null
|
@grub-mkrescue -o build/$(ISO) build/iso 2> /dev/null
|
||||||
|
|
||||||
run: all
|
run: all
|
||||||
@qemu-system-x86_64 \
|
@qemu-system-x86_64 \
|
||||||
-cdrom $(BUILD_DIR)/$(ISO_NAME) \
|
-cdrom build/$(ISO) \
|
||||||
-serial stdio \
|
-serial stdio \
|
||||||
-display gtk,show-menubar=off,zoom-to-fit=on \
|
-display gtk,show-menubar=off,zoom-to-fit=on \
|
||||||
-m 1G \
|
-m 1G \
|
||||||
|
|
|
@ -31,6 +31,7 @@ SECTIONS {
|
||||||
|
|
||||||
.bss BLOCK(4K) : ALIGN(4K)
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
{
|
{
|
||||||
|
*(COMMON)
|
||||||
*(.bss)
|
*(.bss)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ static void load_pd(void *phys) {
|
||||||
return;
|
return;
|
||||||
pt->address = (uint64_t)phys >> 12;
|
pt->address = (uint64_t)phys >> 12;
|
||||||
pt->flags = F_PRESENT | F_WRITEABLE;
|
pt->flags = F_PRESENT | F_WRITEABLE;
|
||||||
invlpg(pdpt_mapped);
|
invlpg(pd_mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_pt(void *phys) {
|
static void load_pt(void *phys) {
|
||||||
|
@ -456,10 +456,14 @@ static int map_pages(
|
||||||
|
|
||||||
page->address = (uint64_t)phys >> 12;
|
page->address = (uint64_t)phys >> 12;
|
||||||
page->flags = F_PRESENT | flags;
|
page->flags = F_PRESENT | flags;
|
||||||
invlpg(virt);
|
|
||||||
|
if (flags & F_GLOBAL)
|
||||||
|
invlpg(virt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__asm volatile("mov %cr3, %rax; mov %rax, %cr3;");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
void kmain(struct boot_info *info) {
|
void kmain(struct boot_info *info) {
|
||||||
memory_init(&info->map);
|
memory_init(&info->map);
|
||||||
//acpi_init(info->acpi_table);
|
|
||||||
//fb_init(1024, 768);
|
//fb_init(1024, 768);
|
||||||
|
//acpi_init(info->acpi_table);
|
||||||
|
|
||||||
kprintf("enterd kmain\n");
|
kprintf("enterd kmain\n");
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ void kmain(struct boot_info *info) {
|
||||||
*(char *)(0xB8000 + 0x146) = 'i';
|
*(char *)(0xB8000 + 0x146) = 'i';
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
//kprintf("ret: 0x%p\n", kalloc(1024));
|
__asm__("hlt;");
|
||||||
// loop so we dont halt
|
// loop so we dont halt
|
||||||
// this allows interrupts to fire
|
// this allows interrupts to fire
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ void *memmove(void *dest, const void *src, unsigned long n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *restrict dest, int c, unsigned long n) {
|
void *memset(void *restrict dest, int c, unsigned long n) {
|
||||||
|
|
||||||
unsigned char *d = dest;
|
unsigned char *d = dest;
|
||||||
for (; n; n--) *d++ = c;
|
for (; n; n--) *d++ = c;
|
||||||
return dest;
|
return dest;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include "serial.h"
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
|
@ -52,6 +51,7 @@ void *kalloc_new(size_t size) {
|
||||||
node = 0;
|
node = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(addr, 0, pages * PAGE_SIZE);
|
||||||
struct page_header *header = addr;
|
struct page_header *header = addr;
|
||||||
header->magic = 0xBEEFCAFE;
|
header->magic = 0xBEEFCAFE;
|
||||||
header->used = size;
|
header->used = size;
|
||||||
|
@ -66,6 +66,8 @@ void *kalloc_new(size_t size) {
|
||||||
|
|
||||||
if (end_header != NULL) {
|
if (end_header != NULL) {
|
||||||
end_header->next = header;
|
end_header->next = header;
|
||||||
|
} else {
|
||||||
|
end_header = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
|
@ -146,7 +148,12 @@ void *krealloc(void *src, size_t dst_len) {
|
||||||
return NULL; // allocation failed
|
return NULL; // allocation failed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dst_len < src_len)
|
||||||
|
src_len = dst_len;
|
||||||
|
|
||||||
memcpy(dst, src, src_len);
|
memcpy(dst, src, src_len);
|
||||||
|
kfree(src);
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +166,7 @@ void kfree(void *ptr) {
|
||||||
|
|
||||||
header = get_header(ptr);
|
header = get_header(ptr);
|
||||||
|
|
||||||
if (header == NULL || header->used == 0) {
|
if (header == NULL) {
|
||||||
panic("attempted to kfree invalid pointer");
|
panic("attempted to kfree invalid pointer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include "serial.h"
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
|
@ -15,8 +14,6 @@ extern char kernel_end;
|
||||||
// between memory_start and kernel_start will be the bitmap
|
// between memory_start and kernel_start will be the bitmap
|
||||||
static uintptr_t memory_start = 0;
|
static uintptr_t memory_start = 0;
|
||||||
|
|
||||||
typedef unsigned char page[4096];
|
|
||||||
|
|
||||||
struct memory_area {
|
struct memory_area {
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
uintptr_t addr;
|
uintptr_t addr;
|
||||||
|
@ -26,9 +23,8 @@ static uint64_t *bitmap;
|
||||||
static uint64_t total_memory;
|
static uint64_t total_memory;
|
||||||
static uint64_t free_memory;
|
static uint64_t free_memory;
|
||||||
static uint64_t page_count;
|
static uint64_t page_count;
|
||||||
static uint64_t page_free_start;
|
|
||||||
static uint64_t segment_count;
|
static uint64_t segment_count;
|
||||||
static struct memory_area *page_start;
|
struct memory_area *page_start;
|
||||||
|
|
||||||
static int n_pages(const struct memory_area *m) {
|
static int n_pages(const struct memory_area *m) {
|
||||||
return m->len / PAGE_SIZE;
|
return m->len / PAGE_SIZE;
|
||||||
|
@ -37,7 +33,7 @@ static int n_pages(const struct memory_area *m) {
|
||||||
static void *page_at(int i) {
|
static void *page_at(int i) {
|
||||||
int cur_page = 0;
|
int cur_page = 0;
|
||||||
for (uint64_t idx = 0; idx < segment_count; idx++) {
|
for (uint64_t idx = 0; idx < segment_count; idx++) {
|
||||||
struct memory_area *m = &page_start[idx];
|
const struct memory_area *m = page_start;
|
||||||
int pages = n_pages(m);
|
int pages = n_pages(m);
|
||||||
if (i - cur_page < pages) {
|
if (i - cur_page < pages) {
|
||||||
return (void *) (m->addr + (PAGE_SIZE * (i - cur_page)));
|
return (void *) (m->addr + (PAGE_SIZE * (i - cur_page)));
|
||||||
|
@ -47,10 +43,11 @@ static void *page_at(int i) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long page_idx(page p) {
|
static long page_idx(void *page) {
|
||||||
uintptr_t addr = (uintptr_t) p;
|
uintptr_t addr = (uintptr_t) page;
|
||||||
int cur_page = 0;
|
int cur_page = 0;
|
||||||
for (struct memory_area *m = page_start; m != NULL; m++) {
|
for (uint64_t idx = 0; idx < segment_count; idx++) {
|
||||||
|
const struct memory_area *m = page_start;
|
||||||
if ((uintptr_t) m + m->len > addr) {
|
if ((uintptr_t) m + m->len > addr) {
|
||||||
return cur_page + ((addr - m->addr) / PAGE_SIZE);
|
return cur_page + ((addr - m->addr) / PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -82,15 +79,9 @@ void *alloc_phys_pages(int pages) {
|
||||||
|
|
||||||
int n_contiguous = 0;
|
int n_contiguous = 0;
|
||||||
int free_region_start = 0;
|
int free_region_start = 0;
|
||||||
bool first = true;
|
for (uint64_t i = 0; i < page_count; i++) {
|
||||||
for (uint64_t i = page_free_start; i < page_count; i++) {
|
|
||||||
bool free = !bitmap_get(i);
|
bool free = !bitmap_get(i);
|
||||||
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
page_free_start = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (free) {
|
if (free) {
|
||||||
if (n_contiguous == 0) free_region_start = i;
|
if (n_contiguous == 0) free_region_start = i;
|
||||||
n_contiguous++;
|
n_contiguous++;
|
||||||
|
@ -113,8 +104,6 @@ void free_phys_pages(void *ptr, int pages) {
|
||||||
long idx = page_idx(ptr);
|
long idx = page_idx(ptr);
|
||||||
if (idx == -1) return;
|
if (idx == -1) return;
|
||||||
|
|
||||||
if ((unsigned) idx < page_free_start) page_free_start = idx;
|
|
||||||
|
|
||||||
for (int i = 0; i < pages; i++)
|
for (int i = 0; i < pages; i++)
|
||||||
bitmap_set(idx + pages, false);
|
bitmap_set(idx + pages, false);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +154,6 @@ void memory_init(struct memory_map *map) {
|
||||||
total_memory = 0;
|
total_memory = 0;
|
||||||
free_memory = 0;
|
free_memory = 0;
|
||||||
page_count = 0;
|
page_count = 0;
|
||||||
page_free_start = 0;
|
|
||||||
page_start = NULL;
|
page_start = NULL;
|
||||||
|
|
||||||
segment_count = 0;
|
segment_count = 0;
|
||||||
|
@ -181,21 +169,21 @@ void memory_init(struct memory_map *map) {
|
||||||
segment_count++;
|
segment_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
long bitmap_pages = page_count / 64 / PAGE_SIZE + 1;
|
long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1;
|
||||||
free_memory = page_count * PAGE_SIZE;
|
|
||||||
|
|
||||||
//HACK: terrible hack bad bad bad bad
|
|
||||||
long bitmap_size = bitmap_pages * PAGE_SIZE;
|
long bitmap_size = bitmap_pages * PAGE_SIZE;
|
||||||
bitmap = (uint64_t *) page_align(kaddr(kernel_end));
|
bitmap = (uint64_t *) page_align(kaddr(kernel_end));
|
||||||
|
|
||||||
long page_area_size = segment_count * sizeof(struct memory_area);
|
long page_area_size = segment_count * sizeof(struct memory_area);
|
||||||
char *page_area_addr = (char *)bitmap + bitmap_size;
|
char *page_area_addr = (char *)bitmap + bitmap_size;
|
||||||
|
page_area_addr = (char *) page_align((uintptr_t) page_area_addr);
|
||||||
|
|
||||||
|
memory_start = page_align((uintptr_t)page_area_addr + page_area_size);
|
||||||
|
|
||||||
bitmap = mmap(bitmap, bitmap_size);
|
bitmap = mmap(bitmap, bitmap_size);
|
||||||
memset(bitmap, 0, bitmap_size);
|
memset(bitmap, 0, bitmap_size);
|
||||||
|
|
||||||
memory_start = page_align(kaddr(kernel_end) + bitmap_size + page_area_size);
|
|
||||||
|
|
||||||
page_area_addr = mmap(page_area_addr, page_area_size);
|
page_area_addr = mmap(page_area_addr, page_area_size);
|
||||||
|
memset(page_area_addr, 0, page_area_size);
|
||||||
|
|
||||||
page_start = (struct memory_area *) page_area_addr;
|
page_start = (struct memory_area *) page_area_addr;
|
||||||
|
|
||||||
struct memory_area *area = page_start;
|
struct memory_area *area = page_start;
|
||||||
|
|
|
@ -35,6 +35,32 @@ static struct addr_node *get_node_idx(int idx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_node_ptrs(
|
||||||
|
struct addr_node *old,
|
||||||
|
struct addr_node *new,
|
||||||
|
int old_len,
|
||||||
|
int new_len
|
||||||
|
) {
|
||||||
|
if (old == NULL)
|
||||||
|
return;
|
||||||
|
int idx = 0;
|
||||||
|
for (int i = 0; i < old_len; i++) {
|
||||||
|
struct addr_node *o = &old[i];
|
||||||
|
if (o && !o->is_used)
|
||||||
|
continue;
|
||||||
|
struct addr_node *n = &new[idx++];
|
||||||
|
*n = *o;
|
||||||
|
if (n->prev != NULL)
|
||||||
|
n->prev->next = n;
|
||||||
|
if (n->next != NULL)
|
||||||
|
n->next->prev = n;
|
||||||
|
}
|
||||||
|
for (int i = idx; i < new_len; i++) {
|
||||||
|
struct addr_node *n = &new[idx++];
|
||||||
|
n->is_used = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct addr_node *get_node(void) {
|
static struct addr_node *get_node(void) {
|
||||||
size_t count = BSS_NODES + alloc_node_count;
|
size_t count = BSS_NODES + alloc_node_count;
|
||||||
|
|
||||||
|
@ -43,10 +69,13 @@ static struct addr_node *get_node(void) {
|
||||||
int new_alloc = alloc_node_count * 2;
|
int new_alloc = alloc_node_count * 2;
|
||||||
if (new_alloc < 8)
|
if (new_alloc < 8)
|
||||||
new_alloc = 8;
|
new_alloc = 8;
|
||||||
int allocated = new_alloc - alloc_node_count;
|
struct addr_node *new_nodes;
|
||||||
int old = new_alloc - allocated;
|
new_nodes = kalloc(sizeof(struct addr_node) * new_alloc);
|
||||||
alloc_nodes = krealloc(alloc_nodes, sizeof(struct addr_node) * new_alloc);
|
if (new_nodes == NULL)
|
||||||
memset(alloc_nodes + old, 0, sizeof(struct addr_node) + allocated);;
|
panic("virt addr alloc nodes is null");
|
||||||
|
update_node_ptrs(alloc_nodes, new_nodes, alloc_node_count, new_alloc);
|
||||||
|
kfree(alloc_nodes);
|
||||||
|
alloc_nodes = new_nodes;
|
||||||
alloc_node_count = new_alloc;
|
alloc_node_count = new_alloc;
|
||||||
is_allocating = false;
|
is_allocating = false;
|
||||||
count = BSS_NODES + alloc_node_count;
|
count = BSS_NODES + alloc_node_count;
|
||||||
|
@ -83,45 +112,15 @@ void virtaddr_init(void) {
|
||||||
start_node = &bootstrap_nodes[0];
|
start_node = &bootstrap_nodes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void *virtaddr_alloc(int n_pages) {
|
|
||||||
|
|
||||||
if (n_pages < 1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
long n_length = n_pages * PAGE_SIZE;
|
|
||||||
struct addr_node *node = start_node;
|
|
||||||
|
|
||||||
for (; node != NULL ; node = node->next) {
|
|
||||||
|
|
||||||
if (node->is_alloc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
long length = node->end - node->start;
|
|
||||||
if (length >= n_length) {
|
|
||||||
struct addr_node *new = get_node();
|
|
||||||
if (node->prev != NULL) {
|
|
||||||
node->prev->next = new;
|
|
||||||
}
|
|
||||||
new->next = node;
|
|
||||||
node->prev = new;
|
|
||||||
new->start = node->start;
|
|
||||||
new->end = new->start + n_length;
|
|
||||||
node->start = new->end;
|
|
||||||
new->is_alloc = true;
|
|
||||||
new->is_used = true;
|
|
||||||
new->next = node;
|
|
||||||
return (void *) new->start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void merge_back(struct addr_node *node) {
|
static void merge_back(struct addr_node *node) {
|
||||||
while (node->prev && !node->is_alloc) {
|
while(node->prev) {
|
||||||
|
if (node->is_alloc != node->prev->is_alloc)
|
||||||
|
break;
|
||||||
struct addr_node *temp = node->prev;
|
struct addr_node *temp = node->prev;
|
||||||
node->start = node->prev->start;
|
node->start = temp->start;
|
||||||
node->prev = node->prev->prev;
|
node->prev = temp->prev;
|
||||||
|
if (temp->prev)
|
||||||
|
temp->prev->next = node;
|
||||||
free_node(temp);
|
free_node(temp);
|
||||||
}
|
}
|
||||||
if (node->prev == NULL) {
|
if (node->prev == NULL) {
|
||||||
|
@ -130,14 +129,61 @@ static void merge_back(struct addr_node *node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void merge_forward(struct addr_node *node) {
|
static void merge_forward(struct addr_node *node) {
|
||||||
|
<<<<<<< HEAD
|
||||||
while (node->next && !node->is_alloc) {
|
while (node->next && !node->is_alloc) {
|
||||||
|
=======
|
||||||
|
while(node->next) {
|
||||||
|
if (node->is_alloc != node->next->is_alloc)
|
||||||
|
break;
|
||||||
|
>>>>>>> ea2de5a (looping kalloc can allocate all of memory (sometimes) :3)
|
||||||
struct addr_node *temp = node->next;
|
struct addr_node *temp = node->next;
|
||||||
node->end = node->next->end;
|
node->end = temp->end;
|
||||||
node->next = node->next->next;
|
node->next = temp->next;
|
||||||
|
if (temp->next)
|
||||||
|
temp->next->prev = node;
|
||||||
free_node(temp);
|
free_node(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *virtaddr_alloc(int n_pages) {
|
||||||
|
if (n_pages < 1)
|
||||||
|
return NULL;
|
||||||
|
long n_length = n_pages * PAGE_SIZE;
|
||||||
|
struct addr_node *node = start_node;
|
||||||
|
|
||||||
|
for (; node != NULL ; node = node->next) {
|
||||||
|
long length = node->end - node->start;
|
||||||
|
if (node->is_alloc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (length >= n_length) {
|
||||||
|
struct addr_node *new = get_node();
|
||||||
|
if (node->prev != NULL) {
|
||||||
|
node->prev->next = new;
|
||||||
|
} else {
|
||||||
|
start_node = new;
|
||||||
|
}
|
||||||
|
new->next = node;
|
||||||
|
new->prev = node->prev;
|
||||||
|
node->prev = new;
|
||||||
|
new->start = node->start;
|
||||||
|
new->end = new->start + n_length;
|
||||||
|
node->start = new->end;
|
||||||
|
new->is_alloc = true;
|
||||||
|
new->is_used = true;
|
||||||
|
new->next = node;
|
||||||
|
return (void*)new->start;
|
||||||
|
//void *mem = (void *) new->start;
|
||||||
|
//merge_back(new);
|
||||||
|
//merge_forward(new);
|
||||||
|
//return mem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
long virtaddr_free(void *virtaddr) {
|
long virtaddr_free(void *virtaddr) {
|
||||||
|
|
||||||
uintptr_t virt = (uintptr_t) virtaddr;
|
uintptr_t virt = (uintptr_t) virtaddr;
|
||||||
|
|
Loading…
Reference in a new issue