Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory Management #8

Merged
merged 7 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ LDFLAGS:=$(LDFLAGS)
LIBS:=$(LIBS) -nostdlib -lk -lgcc

ARCHDIR=arch/$(HOSTARCH)
MMUDIR=mmu

include $(ARCHDIR)/make.config
include ${MMUDIR}/make.config

CFLAGS:=$(CFLAGS) $(KERNEL_ARCH_CFLAGS)
CPPFLAGS:=$(CPPFLAGS) $(KERNEL_ARCH_CPPFLAGS)
Expand All @@ -29,14 +31,16 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)

KERNEL_OBJS=\
$(KERNEL_ARCH_OBJS) \
kernel/kernel.o
kernel/kernel.o \
${MMU_OBJS}

OBJS=\
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \
${MMU_OBJS} \

LINK_LIST=\
$(LDFLAGS) \
Expand Down
13 changes: 12 additions & 1 deletion kernel/arch/i386/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ SECTIONS
*(.bss)
}

end = .;
. = ALIGN(4096);
.page_directory : {
__page_directory = .;
. += 4096;
}
.page_tables : {
__page_tables_start = .;
. += 4096 * 4;
}

/* The compiler may produce other sections, put them in the proper place in
in this file, if you'd like to include them in the final kernel. */
}
}
38 changes: 33 additions & 5 deletions kernel/include/arch/i386/x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,40 @@ struct idtdesc {
#define INTGATE 0x8E
#define TRAPGATE 0xEF

#define DESC_NULL 0x0000
#define DESC_KERNEL_CODE 0x0008
#define DESC_KERNEL_DATA 0x0010
#define DESC_USER_CODE 0x0018
#define DESC_USER_DATA 0x0020
#define NUM_PAGE_TABLES 4

#define KERN_PDIR 0x00001000
#define KERN_STACK 0x0009FFF0
#define KERN_BASE 0x00100000
#define KERN_PG_HEAP 0x00800000
#define KERN_PG_HEAP_LIM 0x10000000
#define KERN_HEAP 0x20000000
#define KERN_HEAP_LIM 0x70000000

extern char end;
#define KERN_PG_1 0x400000
#define KERN_PG_1_LIM 0x800000


#define USER_OFFSET 0x40000000
#define USER_STACK 0xE0000000

#define VADDR_PD_OFFSET(addr) ((addr) & 0xFFC00000) >> 22
#define VADDR_PT_OFFSET(addr) ((addr) & 0x003FF000) >> 12
#define VADDR_PG_OFFSET(addr) (addr) & 0x00000FFF
#define PAGE(addr) (addr) >> 12

#define PAGING_FLAG 0x80000000 /* CR0 - bit 31 */
#define PSE_FLAG 0x00000010 /* CR4 - bit 4 */

#define PG_PRESENT 0x00000001 /* page directory / table */
#define PG_WRITE 0x00000002
#define PG_USER 0x00000004
#define PG_4MB 0x00000080

#define PAGESIZE 4096
#define RAM_MAXSIZE 0x100000000
#define RAM_MAXPAGE 0x100000

void create_gdt_descriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags, struct gdtdesc *);

Expand Down
Empty file added kernel/include/ds/kfifo.h
Empty file.
54 changes: 54 additions & 0 deletions kernel/include/ds/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef DS_LIST_H
#define DS_LIST_H

struct list_head {
struct list_head *next, *prev;
};

#define LIST_HEAD_INIT(name) { &{name}, &{name} }

#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)

static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}

static inline void list_add(struct list_head *newItem, struct list_head *list)
{
newItem->prev = list;
newItem->next = list->next;
list->next->prev = newItem;
list->next = newItem;
}

static inline void list_del(struct list_head *list)
{
list->next->prev = list->prev;
list->prev->next = list->next;
list->next = 0;
list->prev = 0;
}

static inline int is_list_empty(const struct list_head *list)
{
return list->next == list;
}

#define list_entry(ptr, type, member) \
(type*) ((char*) ptr - (char*) &((type*)0)->member)

#define list_first_entry(head, type, member) \
list_entry((head)->next, type, member)
#define list_for_each(p, head) \
for(p = (head)->next; p != (head); p = p->next)
#define list_for_each_safe(p, n, head) \
for(p = (head)->next; n = p->next; p != (head); p = n; n = n->next)
#define list_for_each_entry(p, head, member) \
for(p = list_entry((head)->next, typeof(*p), member); \
&p->member != (head); \
p = list_entry(p->member.next, typeof(*p), member)

#endif
10 changes: 10 additions & 0 deletions kernel/include/mmu/alloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef MMU_ALLOC_H
#define MMU_ALLOC_H

#include<stdint.h>
void *ksbrk(uint16_t);
void *kmalloc(uint32_t);
void kfree(void *);


#endif
Empty file added kernel/include/mmu/page_table.h
Empty file.
67 changes: 67 additions & 0 deletions kernel/include/mmu/vmm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef MMU_VMM_H
#define MMU_VMM_H


#include<mmu/alloc.h>
#include<ds/list.h>
#include<arch/i386/x86.h>
struct page {
char *v_addr;
char *p_addr;
struct list_head list;
};

struct page_directory {
struct page *base;
struct list_head pt;
};

struct vm_area {
char *vm_start;
char *vm_end;
struct list_head list;
};

typedef struct page_directory proc_memory;

extern char *kern_heap;

extern struct list_head kern_free_vm;

extern uint32_t *pd0;

extern uint8_t mem_bitmap[];

extern uint32_t kmalloc_used;

#define set_page_frame_used(page) mem_bitmap[(uint32_t)page/8] |= (1 << (((uint32_t) page)%8))

#define release_page_frame(p_addr) mem_bitmap[((uint32_t)p_addr/PAGESIZE)/8] &= ~(1 <<(((uint32_t) p_addr/PAGESIZE)%8))

char *get_page_frame(void);

struct page *get_page_from_heap(void);
int release_page_from_heap(char *);

void memory_init(uint32_t high_mem);

struct page_directory *pd_create(void);
int pd_destroy(struct page_directory *);
struct page_directory *pd_copy(struct page_directory *pdFather);

int pd0_add_page(char*, char*, int);

int pd_ad_page(char*, char*, int, struct page_directory *);
int pd_remove_page(char*);

char* get_p_addr(char*);

#define KMALLOC_MINSIZE 16

struct kmalloc_header {
uint32_t size:31;
uint32_t used:1;
} __attribute__ ((packed));


#endif
9 changes: 7 additions & 2 deletions kernel/kernel/kernel.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include<stdio.h>
#include<kernel/tty.h>
#include<arch/i386/x86.h>

//#include<arch/i386/x86.h>
#include<mmu/vmm.h>
#include<mmu/alloc.h>
void divide_by_zero(void);

void kernel_main(void) {
Expand All @@ -11,6 +12,10 @@ void kernel_main(void) {
// isrs_install();
printf("Terminal initialization compelete\n");
printf("Tesing formating, %c \t%d %s\n", 'Q', 1234, "Hello world from format");
memory_init(20);

char* test = (char*) kmalloc(20);
printf("Memory Address %d\n", test);
divide_by_zero();
printf("DONE");
}
Expand Down
98 changes: 98 additions & 0 deletions kernel/mmu/alloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include<mmu/vmm.h>
#include<stdio.h>
#include<stdint.h>
void kfree(void *v_addr)
{
printf("KFREEEEEEEE\n");

}
void *ksbrk(uint16_t n)
{
printf("BREakkkkkk\n");

struct kmalloc_header* chunk;
char *p_addr;
uint32_t i;
printf("KSBRK: N: %d\n", n);

if((kern_heap + (n*PAGESIZE)) > (char*) KERN_HEAP_LIM) {
printf("PANIC ksbrk(): no memory left\n");
return (char *) -1;
}

chunk = (struct kmalloc_header *) kern_heap;

for(i = 0; i < n; i++) {
p_addr = get_page_frame();
printf("P ADDR: %d\n", p_addr);
if((uint32_t)(p_addr) < 0) {
printf("PANIC ksbrk(): no page left\n");
return (char*) -1;
}
pd0_add_page(kern_heap, p_addr, 0);
kern_heap += PAGESIZE;
}

chunk->size = PAGESIZE*n;
chunk->used = 0;
return chunk;
}
void *kmalloc(uint32_t size)
{
if(size <= 0)
{
return 0;
}


uint32_t realsize = sizeof(struct kmalloc_header) + size;
if(realsize < KMALLOC_MINSIZE)
{
realsize = KMALLOC_MINSIZE;
}

printf("Size required: %d\n", realsize);
struct kmalloc_header *chunk, *other;
chunk = (struct kmalloc_header*) &end;
while(chunk->used || chunk->size < realsize)
{
if(chunk->size == 0) {
printf("PANIC: kmalloc(): corrupted chunk on %d with null size (heap %d). System halt", chunk, kern_heap);
asm("hlt");
return 0;
}
chunk = (struct kmalloc_header*) ((char*)chunk + chunk->size);
if(chunk == (struct kmalloc_header*) kern_heap)
{
chunk = (ksbrk((realsize/PAGESIZE)+1));
if((int)chunk < 0)
{
printf("No memory left %d, heap: %d", chunk, kern_heap);
asm("hlt");
return 0;
}
} else if(chunk > (struct kmalloc_header*) kern_heap)
{
printf("Got address %d while heap limit is %d", chunk, kern_heap);
asm("hlt");
return 0;
}
}

if(chunk->size - realsize < KMALLOC_MINSIZE)
{
chunk->used = 1;
} else {
other = (struct kmalloc_header*)((char*) chunk+ realsize);
other->size = (uint32_t) (chunk-size - realsize);
other->used = 0;
chunk->size = realsize;
chunk->used = 1;
}

kmalloc_used += realsize;

return (char *) chunk + sizeof(struct kmalloc_header);
}


28 changes: 28 additions & 0 deletions kernel/mmu/cr.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

global read_cr0
read_cr0:
mov eax, cr0
retn

global write_cr0
write_cr0:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr0, eax
pop ebp
retn

global read_cr3
read_cr3:
mov eax, cr3
retn

global write_cr3
write_cr3:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov cr3, eax
pop ebp
retn
5 changes: 5 additions & 0 deletions kernel/mmu/make.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
MMU_OBJS=\
${MMUDIR}/cr.o \
${MMUDIR}/vmm.o \
${MMUDIR}/alloc.o \

Empty file added kernel/mmu/page_table.c
Empty file.
Loading
Loading