From 84739c5c81b82bd36619fde7010f011cf25c4a87 Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Sun, 28 Apr 2024 19:47:20 +0530 Subject: [PATCH 1/7] Added list.h --- kernel/Makefile | 3 ++ kernel/include/mmu/alloc.h | 9 ++++++ kernel/include/mmu/list.h | 54 +++++++++++++++++++++++++++++++++ kernel/include/mmu/page_table.h | 0 kernel/mmu/make.config | 2 ++ kernel/mmu/page_table.c | 0 6 files changed, 68 insertions(+) create mode 100644 kernel/include/mmu/alloc.h create mode 100644 kernel/include/mmu/list.h create mode 100644 kernel/include/mmu/page_table.h create mode 100644 kernel/mmu/make.config create mode 100644 kernel/mmu/page_table.c diff --git a/kernel/Makefile b/kernel/Makefile index 2711f7c..3617c2b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -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) @@ -37,6 +39,7 @@ $(ARCHDIR)/crtbegin.o \ $(KERNEL_OBJS) \ $(ARCHDIR)/crtend.o \ $(ARCHDIR)/crtn.o \ +${MMU_OBJS} \ LINK_LIST=\ $(LDFLAGS) \ diff --git a/kernel/include/mmu/alloc.h b/kernel/include/mmu/alloc.h new file mode 100644 index 0000000..a6d0ed8 --- /dev/null +++ b/kernel/include/mmu/alloc.h @@ -0,0 +1,9 @@ +#ifdef ALLOC_H +#define ALLOC_H + +extern "C" { + void *kmalloc(unsigned long); + void kfree(void *); +} + +#endif diff --git a/kernel/include/mmu/list.h b/kernel/include/mmu/list.h new file mode 100644 index 0000000..ac380ea --- /dev/null +++ b/kernel/include/mmu/list.h @@ -0,0 +1,54 @@ +#ifndef LIST_H +#define 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; + } +76tfx + 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) hj b78 + + #define list_first_entry(head, type, member) \ + list_entry((head)->ptr, 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 diff --git a/kernel/include/mmu/page_table.h b/kernel/include/mmu/page_table.h new file mode 100644 index 0000000..e69de29 diff --git a/kernel/mmu/make.config b/kernel/mmu/make.config new file mode 100644 index 0000000..c7d7da2 --- /dev/null +++ b/kernel/mmu/make.config @@ -0,0 +1,2 @@ +MMU_OBJS=\ +${MMUDIR}/page_table.o \ diff --git a/kernel/mmu/page_table.c b/kernel/mmu/page_table.c new file mode 100644 index 0000000..e69de29 From fe5ff8a9e0a2ac736657d0207d7a070cbf88b93d Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Wed, 1 May 2024 13:35:10 +0530 Subject: [PATCH 2/7] Restructe and added vmm.h --- kernel/include/ds/kfifo.h | 0 kernel/include/{mmu => ds}/list.h | 0 kernel/include/mmu/vmm.h | 72 +++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 kernel/include/ds/kfifo.h rename kernel/include/{mmu => ds}/list.h (100%) create mode 100644 kernel/include/mmu/vmm.h diff --git a/kernel/include/ds/kfifo.h b/kernel/include/ds/kfifo.h new file mode 100644 index 0000000..e69de29 diff --git a/kernel/include/mmu/list.h b/kernel/include/ds/list.h similarity index 100% rename from kernel/include/mmu/list.h rename to kernel/include/ds/list.h diff --git a/kernel/include/mmu/vmm.h b/kernel/include/mmu/vmm.h new file mode 100644 index 0000000..369e0ec --- /dev/null +++ b/kernel/include/mmu/vmm.h @@ -0,0 +1,72 @@ +#ifndef VMM_H +#ifdef VMM_H + +#include +#include +#include +#include + +extern "C" { + +struct page { + char *v_addr; + char *p_addr; + list_head list; +}; + +struct page_directory { + page *base; + list_head pt; +}; + +struct vm_area { + char *vm_start; + char *vm_end; + list_head list; +}; + +typedef page_directory proc_memory; + +extern char *kern_heap; + +extern 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*, char*); + +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 { + unsigned long size:31; + unsigned long used:1; +} __attribute__ ((packed)); + +} + +#endif + From 8e2c8d7f13a77682a7f0c4afb66bd262e80cb3da Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Wed, 1 May 2024 22:49:49 +0530 Subject: [PATCH 3/7] Added vmm --- kernel/mmu/make.config | 2 +- kernel/mmu/vmm.c | 186 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 kernel/mmu/vmm.c diff --git a/kernel/mmu/make.config b/kernel/mmu/make.config index c7d7da2..c96445c 100644 --- a/kernel/mmu/make.config +++ b/kernel/mmu/make.config @@ -1,2 +1,2 @@ MMU_OBJS=\ -${MMUDIR}/page_table.o \ +${MMUDIR}/vmm.o \ diff --git a/kernel/mmu/vmm.c b/kernel/mmu/vmm.c new file mode 100644 index 0000000..d5676af --- /dev/null +++ b/kernel/mmu/vmm.c @@ -0,0 +1,186 @@ +#include +#include + +extern "C" { + + char *kern_heap; + list_head kern_free_vm; + uint32_t *pd0 = (uint32_t *) KERN_PDIR; + char *pg0 = (char*) 0; + char *pg1 = (char*) KERN_PG_!; + char *pg1_end = (char*) KERN_PG_!_LIM; + uint8_t mem_bitmap[RAM_MAXPAGE /8]; + + uint32_t kmalloc_used = 0; + + char* get_page_frame(void) + { + int byte, bit; + int page = -1; + + for(byte = 0; byte < RAM_SIZE / 8; byte++) + { + if(mem_bitmap[byte] != 0xFF) + { + for(bit = 0; bit < 8; bit++) + { + if(!(mem_bitmap[byte] & (1 << bit))) { + page = 8 * byte + bit; + set_page_frame_used(page); + return (char*) (page * PAGESIZE); + } + } + } + } + return (char*) -1; + } + + page* get_page_from_heap(void) + { + page *pg; + vm_area *area; + char *v_addr, *p_addr; + + p_addr = get_page_frame(); + if((int)(p_addr) < 0) { + printf("PANIC: get_page_from_heap(); no page frame available. Can't work!\n"); + } + + if(list_empty(&kern_free_vm)) { + printf("PANIC: get_page_from_heap(): no memory left in page heap. System can't work\n"); + } + + area = list_first_entry(&kern_free_vm, vm_area, list); + v_addr = area->vm_start; + + area->vm_start += PAGESIZE; + + if(area->vm_start == area->vm_end) { + list_del(&area->list); + kfree(area); + } + + pd0_add_page(v_addr, p_addr, 0); + + pg = (page*) kmalloc(sizeof(page)); + pg->v_addr = v_addr; + pg->p_addr = p_addr; + pg->list.next = 0; + pg->list.prev = 0; + + return pg; + } + + int release_page_from_heap(char *v_addr) + { + struct vm_area *next_area, *prev_area, *new_area; + char *p_addr; + + p_addr = get_p_addr(v_addr); + if(p_addr) { + release_page_frame(p_addr); + } else { + printf("WARNING: release_page_from_heap(): no page frame associated with v_addr: %d\n", v_addr); + return 1; + } + + pd_remove_page(v_addr); + + list_for_each_entry(next_area, &kern_free_vm, list) { + if(next_area->vm_start > v_addr) + break; + } + + prev_area = list_entry(next_area->list.prev, struct vm_area, list); + + if(prev_area->vm_end == v_addr) { + prev_area->vm_end += PAGESIZE; + if(prev_area->vm_end == next_area->vm_start) { + prev_area = next_area->vm_end; + list_del(&next_area->list); + kfree(next_area); + } + } else if(next_area->vm_start == v_addr + PAGESIZE) { + next_area->vm_start = v_addr; + } else if (next_area->vm_start > v_addr + PAGESIZE) { + new_area = (struct vm_area*) kmalloc(sizeof(struct vm_area)); + new_area->vm_start = v_addr; + new_area->vm_end = v_addr + PAGESIZE; + list_add(&new_area->list, &prev_area->list); + } else { + printf("\nPANIC: release_page_from_heap(): COrrupted list"); + asm("hlt"); + } + + return 0; + } + + void memory_init(uint32_t high_mem) + { + int pg, pg_limit; + unsigned long i; + struct vm_area *p, *pm; + + pg_limit = (high_mem * 1024) / PAGESIZE; + + for(pg = 0; pg < pg_limit/8; pg++) + mem_bitmap[pg] = 0; + + for(pg = pg_limit/8; pg < RAM_MAXPAGE /8; pg++) + mem_bitmap[pg] = 0xFF; + + for(pg = PAGE(0x0); pg < (int)(PAGE((uint32_t) pg1_end)); pg++) + { + set_page_frame_used(pg); + } + + pd[0] = ((uint32_t) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB)); + pd[1] = ((uint32_t) pg1 | (PG_PRESENT | PG_WRITE | PG_4MB)); + + for(i = 2; i < 1023; i++) + { + pd0[i] = ((uint32_t) pg1 + PAGESIZE*i (PG_PRESENT | PG_WRITE)); + } + + pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE)); + + asm(" mov %0, %%eax \n \ + mov %%eax, %%cr3 \n \ + mov %%cr4, %%eax \n \ + or %3, %%eax \n \ + mov %%eax, %%cr4 \n \ + mov %%cr0, %%eax \n \ + or %1, %%eax \n \ + mov %%eax, %%cr0":: "m"(pd0), "1"(PAGING_FLAG), "i"(PSE_FLAG)); + + kern_heap = (char*) KERN_HEAP; + ksbrk(1); + + p = (struct vm_area*) kmalloc(sizeof(struct vm_area)); + p->vm_start = (char*) KERN_PG_HEAP; + p->vm_end = (char*) KERN_PG_HEAP_LIM; + INIT_LIST_HEAD(&kern_free_vm); + list_add(&p->list, &kern_free_vm); + + return; + } + + struct page_directory *pd_create(void) + { + struct page_directory *pd; + uint32_t *pdir; + int i; + + pd = (struct page_directory *) kmalloc(sizeof(struct page_directory)); + pd->base = get_page_from_heap(); + + pdir = (uint32_t) pd->base->v_addr; + for(i = 0; i < 256; i++) + pdir[i] = pd0[i]; + + pdir[1023] = ((uint32_t) pd->base->p_addr | (PG_PRESENT | PG_WRITE)); + + INIT_LIST_HEAD(&pd->pt); + return pd; + } +} From 36f128b57c8724718762b848646413475a596ada Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Tue, 7 May 2024 05:48:21 +0530 Subject: [PATCH 4/7] Fix some issues --- kernel/include/arch/i386/x86.h | 34 +++++++++++++++++---- kernel/include/ds/list.h | 10 +++---- kernel/include/mmu/alloc.h | 3 +- kernel/include/mmu/vmm.h | 19 +++++------- kernel/kernel/kernel.c | 3 ++ kernel/mmu/alloc.c | 55 ++++++++++++++++++++++++++++++++++ kernel/mmu/make.config | 1 + kernel/mmu/vmm.c | 55 +++++++++++++++++++++------------- 8 files changed, 137 insertions(+), 43 deletions(-) create mode 100644 kernel/mmu/alloc.c diff --git a/kernel/include/arch/i386/x86.h b/kernel/include/arch/i386/x86.h index 952562b..4a8673a 100644 --- a/kernel/include/arch/i386/x86.h +++ b/kernel/include/arch/i386/x86.h @@ -44,13 +44,37 @@ 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 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 0x10000000 +#define KERN_HEAP_LIM 0x40000000 + + +#define KERN_PG_1 0x400000 +#define KERN_PG_1_LIM 0x800000 + +#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 *); void init_gdt(void); diff --git a/kernel/include/ds/list.h b/kernel/include/ds/list.h index ac380ea..9c46a13 100644 --- a/kernel/include/ds/list.h +++ b/kernel/include/ds/list.h @@ -15,7 +15,7 @@ list->next = list; list->prev = list; } -76tfx + static inline void list_add(struct list_head *newItem, struct list_head *list) { newItem->prev = list; @@ -38,17 +38,17 @@ } #define list_entry(ptr, type, member) \ - (type*) ((char*) ptr - (char*) &((type*)0)->member) hj b78 + (type*) ((char*) ptr - (char*) &((type*)0)->member) #define list_first_entry(head, type, member) \ - list_entry((head)->ptr, 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) + 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) \ + p = list_entry(p->member.next, typeof(*p), member) #endif diff --git a/kernel/include/mmu/alloc.h b/kernel/include/mmu/alloc.h index a6d0ed8..73e6ab6 100644 --- a/kernel/include/mmu/alloc.h +++ b/kernel/include/mmu/alloc.h @@ -2,7 +2,8 @@ #define ALLOC_H extern "C" { - void *kmalloc(unsigned long); + int kbsrk(uint32_t) + void *kmalloc(uint32_t); void kfree(void *); } diff --git a/kernel/include/mmu/vmm.h b/kernel/include/mmu/vmm.h index 369e0ec..e21ce68 100644 --- a/kernel/include/mmu/vmm.h +++ b/kernel/include/mmu/vmm.h @@ -1,35 +1,34 @@ #ifndef VMM_H -#ifdef VMM_H +#define VMM_H + #include #include #include #include -extern "C" { - struct page { char *v_addr; char *p_addr; - list_head list; + struct list_head list; }; struct page_directory { - page *base; - list_head pt; + struct page *base; + struct list_head pt; }; struct vm_area { char *vm_start; char *vm_end; - list_head list; + struct list_head list; }; -typedef page_directory proc_memory; +typedef struct page_directory proc_memory; extern char *kern_heap; -extern list_head kern_free_vm; +extern struct list_head kern_free_vm; extern uint32_t *pd0; @@ -66,7 +65,5 @@ struct kmalloc_header { unsigned long used:1; } __attribute__ ((packed)); -} #endif - diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index 4b98f3e..43b009e 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -1,6 +1,7 @@ #include #include #include +#include void divide_by_zero(void); @@ -11,6 +12,8 @@ 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"); + char* test = kmalloc(20); + printf("Memory Address %d\n", test); divide_by_zero(); printf("DONE"); } diff --git a/kernel/mmu/alloc.c b/kernel/mmu/alloc.c new file mode 100644 index 0000000..507dc40 --- /dev/null +++ b/kernel/mmu/alloc.c @@ -0,0 +1,55 @@ +#include +#include + +extern "C" { + void *kmalloc(uint32_t size) + { + if(size <= 0) + { + return 0; + } + + + uint32_t realsize = sizeof(struct kmalloc_header) + size; + if(realsize < KMALLOC_MINSIZE) + { + realsize = KMALLOCSIZE; + } + + chunk = (struct *kmalloc_header) KERN_HEAP; + while(chunk->used || chunk->size < realsize) + { + printf("chunk: %d, %d\n", chunk->used, chunk->size); + chunk = (struct *KMALLOC_HEADER) ((char*)chunk + chunk->size); + if(chunk == (struct *KMALLOC_HEADER) kern_heap) + { + if((int)ksbrk(realsize/PAGESIZE) < 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)((chunk*) chunk + realsize) + other->size = chunk-size - realsize; + other->used = 0; + chunk->size = realsize; + chunk->used = 1; + } + + kmalloc_used += realsize; + + return (char *) chunk + sizeof(struct kmalloc_header); + } +} diff --git a/kernel/mmu/make.config b/kernel/mmu/make.config index c96445c..c45bd0d 100644 --- a/kernel/mmu/make.config +++ b/kernel/mmu/make.config @@ -1,2 +1,3 @@ MMU_OBJS=\ ${MMUDIR}/vmm.o \ +${MMUDIR}/alloc.o \ diff --git a/kernel/mmu/vmm.c b/kernel/mmu/vmm.c index d5676af..057b02b 100644 --- a/kernel/mmu/vmm.c +++ b/kernel/mmu/vmm.c @@ -1,14 +1,13 @@ -#include +#include #include - -extern "C" { - +#include +#include char *kern_heap; - list_head kern_free_vm; + struct list_head kern_free_vm; uint32_t *pd0 = (uint32_t *) KERN_PDIR; char *pg0 = (char*) 0; - char *pg1 = (char*) KERN_PG_!; - char *pg1_end = (char*) KERN_PG_!_LIM; + char *pg1 = (char*) KERN_PG_1; + char *pg1_end = (char*) KERN_PG_1_LIM; uint8_t mem_bitmap[RAM_MAXPAGE /8]; uint32_t kmalloc_used = 0; @@ -18,7 +17,7 @@ extern "C" { int byte, bit; int page = -1; - for(byte = 0; byte < RAM_SIZE / 8; byte++) + for(byte = 0; byte < RAM_MAXSIZE / 8; byte++) { if(mem_bitmap[byte] != 0xFF) { @@ -35,10 +34,10 @@ extern "C" { return (char*) -1; } - page* get_page_from_heap(void) + struct page* get_page_from_heap(void) { - page *pg; - vm_area *area; + struct page *pg; + struct vm_area *area; char *v_addr, *p_addr; p_addr = get_page_frame(); @@ -46,11 +45,11 @@ extern "C" { printf("PANIC: get_page_from_heap(); no page frame available. Can't work!\n"); } - if(list_empty(&kern_free_vm)) { + if(is_list_empty(&kern_free_vm)) { printf("PANIC: get_page_from_heap(): no memory left in page heap. System can't work\n"); } - area = list_first_entry(&kern_free_vm, vm_area, list); + area = list_first_entry(&kern_free_vm, struct m_area, list); v_addr = area->vm_start; area->vm_start += PAGESIZE; @@ -62,7 +61,7 @@ extern "C" { pd0_add_page(v_addr, p_addr, 0); - pg = (page*) kmalloc(sizeof(page)); + pg = (struct page*) kmalloc(sizeof(struct page)); pg->v_addr = v_addr; pg->p_addr = p_addr; pg->list.next = 0; @@ -118,8 +117,8 @@ extern "C" { void memory_init(uint32_t high_mem) { int pg, pg_limit; - unsigned long i; - struct vm_area *p, *pm; + uint32_t i; + struct vm_area *p, *pd; pg_limit = (high_mem * 1024) / PAGESIZE; @@ -129,7 +128,7 @@ extern "C" { for(pg = pg_limit/8; pg < RAM_MAXPAGE /8; pg++) mem_bitmap[pg] = 0xFF; - for(pg = PAGE(0x0); pg < (int)(PAGE((uint32_t) pg1_end)); pg++) + /*for(pg = PAGE(0x0); pg < (uint32_t)(PAGE((uint32_t) pg1_end)); pg++) { set_page_frame_used(pg); } @@ -142,7 +141,7 @@ extern "C" { pd0[i] = ((uint32_t) pg1 + PAGESIZE*i (PG_PRESENT | PG_WRITE)); } - pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE)); + pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE));*/ asm(" mov %0, %%eax \n \ mov %%eax, %%cr3 \n \ @@ -165,11 +164,11 @@ extern "C" { return; } - struct page_directory *pd_create(void) + /*struct page_directory *pd_create(void) { struct page_directory *pd; uint32_t *pdir; - int i; + uint32_t i; pd = (struct page_directory *) kmalloc(sizeof(struct page_directory)); pd->base = get_page_from_heap(); @@ -183,4 +182,18 @@ extern "C" { INIT_LIST_HEAD(&pd->pt); return pd; } -} + + struct page_directory *pd_copy(struct page_directory * pdFather) + { + struct page_directory *pd; + uint32_t *pdir; + int ; + + pd = (struct page_directory *) kmalloc(sizeof(struct page_directory)); + pd->base = get_page_from_heap(); + + pdir = (uint32_t *) pd->base->v_addr; + + + }*/ + From 59ac8ff3e2017fc5b70101074c6bff20aeca9d26 Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Thu, 9 May 2024 17:53:09 +0530 Subject: [PATCH 5/7] Fix some bugs --- kernel/include/ds/list.h | 4 ++-- kernel/include/mmu/alloc.h | 14 +++++++------- kernel/include/mmu/vmm.h | 6 ++---- kernel/kernel/kernel.c | 7 ++++--- kernel/mmu/alloc.c | 21 ++++++++++----------- kernel/mmu/vmm.c | 25 +++++++++++++------------ 6 files changed, 38 insertions(+), 39 deletions(-) diff --git a/kernel/include/ds/list.h b/kernel/include/ds/list.h index 9c46a13..6570bf0 100644 --- a/kernel/include/ds/list.h +++ b/kernel/include/ds/list.h @@ -1,5 +1,5 @@ -#ifndef LIST_H -#define LIST_H +#ifndef DS_LIST_H +#define DS_LIST_H struct list_head { struct list_head *next, *prev; diff --git a/kernel/include/mmu/alloc.h b/kernel/include/mmu/alloc.h index 73e6ab6..173efe0 100644 --- a/kernel/include/mmu/alloc.h +++ b/kernel/include/mmu/alloc.h @@ -1,10 +1,10 @@ -#ifdef ALLOC_H -#define ALLOC_H +#ifndef MMU_ALLOC_H +#define MMU_ALLOC_H + +#include +void *ksbrk(uint32_t); +void *kmalloc(uint32_t); +void kfree(void *); -extern "C" { - int kbsrk(uint32_t) - void *kmalloc(uint32_t); - void kfree(void *); -} #endif diff --git a/kernel/include/mmu/vmm.h b/kernel/include/mmu/vmm.h index e21ce68..fee3f0f 100644 --- a/kernel/include/mmu/vmm.h +++ b/kernel/include/mmu/vmm.h @@ -1,12 +1,10 @@ -#ifndef VMM_H -#define VMM_H +#ifndef MMU_VMM_H +#define MMU_VMM_H #include #include #include -#include - struct page { char *v_addr; char *p_addr; diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index 43b009e..b76cb66 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -1,8 +1,8 @@ #include #include -#include +//#include +#include #include - void divide_by_zero(void); void kernel_main(void) { @@ -12,7 +12,8 @@ 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"); - char* test = kmalloc(20); + memory_init(2048); + char* test = (char*) kmalloc(20); printf("Memory Address %d\n", test); divide_by_zero(); printf("DONE"); diff --git a/kernel/mmu/alloc.c b/kernel/mmu/alloc.c index 507dc40..b3717ce 100644 --- a/kernel/mmu/alloc.c +++ b/kernel/mmu/alloc.c @@ -1,7 +1,6 @@ -#include +#include #include - -extern "C" { +#include void *kmalloc(uint32_t size) { if(size <= 0) @@ -13,15 +12,15 @@ extern "C" { uint32_t realsize = sizeof(struct kmalloc_header) + size; if(realsize < KMALLOC_MINSIZE) { - realsize = KMALLOCSIZE; + realsize = KMALLOC_MINSIZE; } - chunk = (struct *kmalloc_header) KERN_HEAP; + struct kmalloc_header *chunk = (struct kmalloc_header*) KERN_HEAP; while(chunk->used || chunk->size < realsize) { printf("chunk: %d, %d\n", chunk->used, chunk->size); - chunk = (struct *KMALLOC_HEADER) ((char*)chunk + chunk->size); - if(chunk == (struct *KMALLOC_HEADER) kern_heap) + chunk = (struct kmalloc_header*) ((char*)chunk + chunk->size); + if(chunk == (struct kmalloc_header*) kern_heap) { if((int)ksbrk(realsize/PAGESIZE) < 0) { @@ -29,7 +28,7 @@ extern "C" { asm("hlt"); return 0; } - } else if(chunk > (struct *KMALLOC_HEADER) kern_heap) + } else if(chunk > (struct kmalloc_header*) kern_heap) { printf("Got address %d while heap limit is %d", chunk, kern_heap); asm("hlt"); @@ -41,8 +40,8 @@ extern "C" { { chunk->used = 1; } else { - other = (struct *kmalloc_header)((chunk*) chunk + realsize) - other->size = chunk-size - realsize; + struct kmalloc_header* other = (struct kmalloc_header*)((char*) chunk+ realsize); + other->size = (uint32_t) (chunk-size - realsize); other->used = 0; chunk->size = realsize; chunk->used = 1; @@ -52,4 +51,4 @@ extern "C" { return (char *) chunk + sizeof(struct kmalloc_header); } -} + diff --git a/kernel/mmu/vmm.c b/kernel/mmu/vmm.c index 057b02b..a6a28d9 100644 --- a/kernel/mmu/vmm.c +++ b/kernel/mmu/vmm.c @@ -1,7 +1,4 @@ #include -#include -#include -#include char *kern_heap; struct list_head kern_free_vm; uint32_t *pd0 = (uint32_t *) KERN_PDIR; @@ -49,7 +46,7 @@ printf("PANIC: get_page_from_heap(): no memory left in page heap. System can't work\n"); } - area = list_first_entry(&kern_free_vm, struct m_area, list); + area = list_first_entry(&kern_free_vm, struct vm_area, list); v_addr = area->vm_start; area->vm_start += PAGESIZE; @@ -70,7 +67,7 @@ return pg; } - int release_page_from_heap(char *v_addr) +/* int release_page_from_heap(char *v_addr) { struct vm_area *next_area, *prev_area, *new_area; char *p_addr; @@ -86,8 +83,9 @@ pd_remove_page(v_addr); list_for_each_entry(next_area, &kern_free_vm, list) { - if(next_area->vm_start > v_addr) + if(next_area->vm_start > v_addr){ break; + } } prev_area = list_entry(next_area->list.prev, struct vm_area, list); @@ -113,7 +111,7 @@ return 0; } - +*/ void memory_init(uint32_t high_mem) { int pg, pg_limit; @@ -122,11 +120,13 @@ pg_limit = (high_mem * 1024) / PAGESIZE; - for(pg = 0; pg < pg_limit/8; pg++) + for(pg = 0; pg < pg_limit/8; pg++){ mem_bitmap[pg] = 0; + } - for(pg = pg_limit/8; pg < RAM_MAXPAGE /8; pg++) + for(pg = pg_limit/8; pg < RAM_MAXPAGE /8; pg++){ mem_bitmap[pg] = 0xFF; + } /*for(pg = PAGE(0x0); pg < (uint32_t)(PAGE((uint32_t) pg1_end)); pg++) { @@ -143,14 +143,15 @@ pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE));*/ - asm(" mov %0, %%eax \n \ + asm volatile(" mov %0, %%eax \n \ mov %%eax, %%cr3 \n \ mov %%cr4, %%eax \n \ - or %3, %%eax \n \ + or %2, %%eax \n \ mov %%eax, %%cr4 \n \ mov %%cr0, %%eax \n \ or %1, %%eax \n \ - mov %%eax, %%cr0":: "m"(pd0), "1"(PAGING_FLAG), "i"(PSE_FLAG)); + mov %%eax, %%cr0":: "m"(pd0), "i"(PAGING_FLAG), "i"(PSE_FLAG)); + kern_heap = (char*) KERN_HEAP; ksbrk(1); From 5ccc3241b9e7865a9cf52d718c950fd1f1af23b6 Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Wed, 15 May 2024 13:22:46 +0530 Subject: [PATCH 6/7] MMu working but have some memroy bugs --- kernel/Makefile | 3 ++- kernel/include/arch/i386/x86.h | 4 ++-- kernel/include/mmu/vmm.h | 6 +++--- kernel/kernel/kernel.c | 3 ++- kernel/mmu/alloc.c | 18 +++++++++++++++-- kernel/mmu/cr.asm | 28 +++++++++++++++++++++++++ kernel/mmu/make.config | 2 ++ kernel/mmu/vmm.c | 37 ++++++++++++++++++++++++++-------- 8 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 kernel/mmu/cr.asm diff --git a/kernel/Makefile b/kernel/Makefile index 3617c2b..4750bdb 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -31,7 +31,8 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS) KERNEL_OBJS=\ $(KERNEL_ARCH_OBJS) \ -kernel/kernel.o +kernel/kernel.o \ +${MMU_OBJS} OBJS=\ $(ARCHDIR)/crti.o \ diff --git a/kernel/include/arch/i386/x86.h b/kernel/include/arch/i386/x86.h index 4a8673a..d68cecf 100644 --- a/kernel/include/arch/i386/x86.h +++ b/kernel/include/arch/i386/x86.h @@ -51,8 +51,8 @@ struct idtdesc { #define KERN_BASE 0x00100000 #define KERN_PG_HEAP 0x00800000 #define KERN_PG_HEAP_LIM 0x10000000 -#define KERN_HEAP 0x10000000 -#define KERN_HEAP_LIM 0x40000000 +#define KERN_HEAP 0x20000000 +#define KERN_HEAP_LIM 0x70000000 #define KERN_PG_1 0x400000 diff --git a/kernel/include/mmu/vmm.h b/kernel/include/mmu/vmm.h index fee3f0f..f69f3c2 100644 --- a/kernel/include/mmu/vmm.h +++ b/kernel/include/mmu/vmm.h @@ -34,7 +34,7 @@ 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 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)) @@ -59,8 +59,8 @@ char* get_p_addr(char*); #define KMALLOC_MINSIZE 16 struct kmalloc_header { - unsigned long size:31; - unsigned long used:1; + uint32_t size:31; + uint32_t used:1; } __attribute__ ((packed)); diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index b76cb66..663d126 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -13,8 +13,9 @@ void kernel_main(void) { printf("Terminal initialization compelete\n"); printf("Tesing formating, %c \t%d %s\n", 'Q', 1234, "Hello world from format"); memory_init(2048); + /* char* test = (char*) kmalloc(20); - printf("Memory Address %d\n", test); + printf("Memory Address %d\n", test);*/ divide_by_zero(); printf("DONE"); } diff --git a/kernel/mmu/alloc.c b/kernel/mmu/alloc.c index b3717ce..76d86df 100644 --- a/kernel/mmu/alloc.c +++ b/kernel/mmu/alloc.c @@ -1,6 +1,18 @@ #include #include #include +void kfree(void *v_addr) +{ + printf("KFREEEEEEEE\n"); + +} +void *ksbrk(uint32_t n) +{ + //printf("BREakkkkkk\n"); + + struct kmalloc_header* chunk = (struct kmalloc_header *) kern_heap; + return chunk; +} void *kmalloc(uint32_t size) { if(size <= 0) @@ -18,9 +30,10 @@ struct kmalloc_header *chunk = (struct kmalloc_header*) KERN_HEAP; while(chunk->used || chunk->size < realsize) { - printf("chunk: %d, %d\n", chunk->used, chunk->size); + //printf("chunk: %d, %d\n", chunk->used, chunk->size); chunk = (struct kmalloc_header*) ((char*)chunk + chunk->size); - if(chunk == (struct kmalloc_header*) kern_heap) + printf("C: %d, S: %d, U: %d, h: %d", chunk, chunk->used, chunk->size, kern_heap); + if(chunk == (struct kmalloc_header*) KERN_HEAP) { if((int)ksbrk(realsize/PAGESIZE) < 0) { @@ -51,4 +64,5 @@ return (char *) chunk + sizeof(struct kmalloc_header); } + diff --git a/kernel/mmu/cr.asm b/kernel/mmu/cr.asm new file mode 100644 index 0000000..f433147 --- /dev/null +++ b/kernel/mmu/cr.asm @@ -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 diff --git a/kernel/mmu/make.config b/kernel/mmu/make.config index c45bd0d..7268870 100644 --- a/kernel/mmu/make.config +++ b/kernel/mmu/make.config @@ -1,3 +1,5 @@ MMU_OBJS=\ +${MMUDIR}/cr.o \ ${MMUDIR}/vmm.o \ ${MMUDIR}/alloc.o \ + diff --git a/kernel/mmu/vmm.c b/kernel/mmu/vmm.c index a6a28d9..5b41ee1 100644 --- a/kernel/mmu/vmm.c +++ b/kernel/mmu/vmm.c @@ -1,4 +1,5 @@ #include +#include char *kern_heap; struct list_head kern_free_vm; uint32_t *pd0 = (uint32_t *) KERN_PDIR; @@ -56,7 +57,7 @@ kfree(area); } - pd0_add_page(v_addr, p_addr, 0); +// pd0_add_page(v_addr, p_addr, 0); pg = (struct page*) kmalloc(sizeof(struct page)); pg->v_addr = v_addr; @@ -112,10 +113,12 @@ return 0; } */ +extern void write_cr3(uint32_t *); +extern void write_cr0(uint32_t ); +extern uint32_t read_cr0(void); void memory_init(uint32_t high_mem) { int pg, pg_limit; - uint32_t i; struct vm_area *p, *pd; pg_limit = (high_mem * 1024) / PAGESIZE; @@ -132,8 +135,8 @@ { set_page_frame_used(pg); } - - pd[0] = ((uint32_t) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB)); +*/ + /* pd[0] = ((uint32_t) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB)); pd[1] = ((uint32_t) pg1 | (PG_PRESENT | PG_WRITE | PG_4MB)); for(i = 2; i < 1023; i++) @@ -142,23 +145,41 @@ } pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE));*/ + uint32_t *page_dir = (uint32_t *) 0x9C000; + uint32_t *page_table = (uint32_t *) 0x9D000; + uint32_t address = 0; + uint32_t i; + for(i = 0; i < 1024; i++) + { + page_table[i] = address | 3; + address = address + 4096; + }; - asm volatile(" mov %0, %%eax \n \ + page_dir[0] = page_table; + page_dir[1] = page_dir[0] | 3; + for(i = 1; i < 1024; i++) + { + page_dir[i] = 0 | 3; + }; + /*asm volatile(" mov %0, %%eax \n \ mov %%eax, %%cr3 \n \ mov %%cr4, %%eax \n \ or %2, %%eax \n \ mov %%eax, %%cr4 \n \ mov %%cr0, %%eax \n \ or %1, %%eax \n \ - mov %%eax, %%cr0":: "m"(pd0), "i"(PAGING_FLAG), "i"(PSE_FLAG)); - + mov %%eax, %%cr0":: "m"(pd0), "i"(PAGING_FLAG), "i"(PSE_FLAG));*/ + write_cr3(page_dir); + write_cr0(read_cr0() | 0x000000000); + //asm("hlt"); kern_heap = (char*) KERN_HEAP; - ksbrk(1); + // ksbrk(1); p = (struct vm_area*) kmalloc(sizeof(struct vm_area)); p->vm_start = (char*) KERN_PG_HEAP; p->vm_end = (char*) KERN_PG_HEAP_LIM; + printf("FOUND FREE MEM: %d %d", p->vm_start, p->vm_end); INIT_LIST_HEAD(&kern_free_vm); list_add(&p->list, &kern_free_vm); From 607548d6d7f3c4b101543589d97d1aecb5782552 Mon Sep 17 00:00:00 2001 From: Riyan Dhiman Date: Fri, 17 May 2024 16:58:01 +0530 Subject: [PATCH 7/7] mmu working fine now yeaaa --- kernel/arch/i386/linker.ld | 13 +++++- kernel/include/arch/i386/x86.h | 8 +++- kernel/include/mmu/alloc.h | 2 +- kernel/include/mmu/vmm.h | 2 +- kernel/kernel/kernel.c | 6 +-- kernel/mmu/alloc.c | 48 +++++++++++++++---- kernel/mmu/vmm.c | 84 +++++++++++++++++++--------------- 7 files changed, 108 insertions(+), 55 deletions(-) diff --git a/kernel/arch/i386/linker.ld b/kernel/arch/i386/linker.ld index 7823cfc..0f27dd4 100644 --- a/kernel/arch/i386/linker.ld +++ b/kernel/arch/i386/linker.ld @@ -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. */ -} \ No newline at end of file +} diff --git a/kernel/include/arch/i386/x86.h b/kernel/include/arch/i386/x86.h index d68cecf..f8c88e3 100644 --- a/kernel/include/arch/i386/x86.h +++ b/kernel/include/arch/i386/x86.h @@ -44,7 +44,7 @@ struct idtdesc { #define INTGATE 0x8E #define TRAPGATE 0xEF - +#define NUM_PAGE_TABLES 4 #define KERN_PDIR 0x00001000 #define KERN_STACK 0x0009FFF0 @@ -54,10 +54,14 @@ struct idtdesc { #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 diff --git a/kernel/include/mmu/alloc.h b/kernel/include/mmu/alloc.h index 173efe0..325f351 100644 --- a/kernel/include/mmu/alloc.h +++ b/kernel/include/mmu/alloc.h @@ -2,7 +2,7 @@ #define MMU_ALLOC_H #include -void *ksbrk(uint32_t); +void *ksbrk(uint16_t); void *kmalloc(uint32_t); void kfree(void *); diff --git a/kernel/include/mmu/vmm.h b/kernel/include/mmu/vmm.h index f69f3c2..370f305 100644 --- a/kernel/include/mmu/vmm.h +++ b/kernel/include/mmu/vmm.h @@ -49,7 +49,7 @@ 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*, char*); +int pd0_add_page(char*, char*, int); int pd_ad_page(char*, char*, int, struct page_directory *); int pd_remove_page(char*); diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index 663d126..a2151dd 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -12,10 +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(2048); - /* + memory_init(20); + char* test = (char*) kmalloc(20); - printf("Memory Address %d\n", test);*/ + printf("Memory Address %d\n", test); divide_by_zero(); printf("DONE"); } diff --git a/kernel/mmu/alloc.c b/kernel/mmu/alloc.c index 76d86df..7819981 100644 --- a/kernel/mmu/alloc.c +++ b/kernel/mmu/alloc.c @@ -6,11 +6,35 @@ void kfree(void *v_addr) printf("KFREEEEEEEE\n"); } -void *ksbrk(uint32_t n) +void *ksbrk(uint16_t n) { - //printf("BREakkkkkk\n"); + printf("BREakkkkkk\n"); - struct kmalloc_header* chunk = (struct kmalloc_header *) kern_heap; + 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) @@ -27,15 +51,21 @@ void *ksbrk(uint32_t n) realsize = KMALLOC_MINSIZE; } - struct kmalloc_header *chunk = (struct kmalloc_header*) KERN_HEAP; + printf("Size required: %d\n", realsize); + struct kmalloc_header *chunk, *other; + chunk = (struct kmalloc_header*) &end; while(chunk->used || chunk->size < realsize) { - //printf("chunk: %d, %d\n", chunk->used, chunk->size); + 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); - printf("C: %d, S: %d, U: %d, h: %d", chunk, chunk->used, chunk->size, kern_heap); - if(chunk == (struct kmalloc_header*) KERN_HEAP) + if(chunk == (struct kmalloc_header*) kern_heap) { - if((int)ksbrk(realsize/PAGESIZE) < 0) + chunk = (ksbrk((realsize/PAGESIZE)+1)); + if((int)chunk < 0) { printf("No memory left %d, heap: %d", chunk, kern_heap); asm("hlt"); @@ -53,7 +83,7 @@ void *ksbrk(uint32_t n) { chunk->used = 1; } else { - struct kmalloc_header* other = (struct kmalloc_header*)((char*) chunk+ realsize); + other = (struct kmalloc_header*)((char*) chunk+ realsize); other->size = (uint32_t) (chunk-size - realsize); other->used = 0; chunk->size = realsize; diff --git a/kernel/mmu/vmm.c b/kernel/mmu/vmm.c index 5b41ee1..335c61f 100644 --- a/kernel/mmu/vmm.c +++ b/kernel/mmu/vmm.c @@ -1,13 +1,17 @@ #include #include + extern uint32_t __page_directory; + extern uint32_t __page_tables_start; char *kern_heap; struct list_head kern_free_vm; - uint32_t *pd0 = (uint32_t *) KERN_PDIR; - char *pg0 = (char*) 0; + uint32_t *pd0 = (uint32_t *) ( &__page_directory); + char *pg0 = ((uint32_t *)&__page_tables_start); char *pg1 = (char*) KERN_PG_1; char *pg1_end = (char*) KERN_PG_1_LIM; uint8_t mem_bitmap[RAM_MAXPAGE /8]; + + uint32_t kmalloc_used = 0; char* get_page_frame(void) @@ -119,8 +123,8 @@ extern uint32_t read_cr0(void); void memory_init(uint32_t high_mem) { int pg, pg_limit; - struct vm_area *p, *pd; - + struct vm_area *p, *pm; + uint32_t i; pg_limit = (high_mem * 1024) / PAGESIZE; for(pg = 0; pg < pg_limit/8; pg++){ @@ -130,51 +134,32 @@ extern uint32_t read_cr0(void); for(pg = pg_limit/8; pg < RAM_MAXPAGE /8; pg++){ mem_bitmap[pg] = 0xFF; } - - /*for(pg = PAGE(0x0); pg < (uint32_t)(PAGE((uint32_t) pg1_end)); pg++) +/* + for(pg = PAGE(0x0); pg < (uint32_t)(PAGE((uint32_t) pg1_end)); pg++) { set_page_frame_used(pg); } -*/ - /* pd[0] = ((uint32_t) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB)); - pd[1] = ((uint32_t) pg1 | (PG_PRESENT | PG_WRITE | PG_4MB)); + + pd0[0] = ((uint32_t) pg0 | (PG_PRESENT | PG_WRITE | PG_4MB)); + pd0[1] = ((uint32_t) pg1 | (PG_PRESENT | PG_WRITE | PG_4MB)); for(i = 2; i < 1023; i++) { - pd0[i] = ((uint32_t) pg1 + PAGESIZE*i (PG_PRESENT | PG_WRITE)); + pd0[i] = ((uint32_t) pg1 + PAGESIZE*i | (PG_PRESENT | PG_WRITE)); } - pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE));*/ - uint32_t *page_dir = (uint32_t *) 0x9C000; - uint32_t *page_table = (uint32_t *) 0x9D000; - uint32_t address = 0; - uint32_t i; - for(i = 0; i < 1024; i++) - { - page_table[i] = address | 3; - address = address + 4096; - }; - - page_dir[0] = page_table; - page_dir[1] = page_dir[0] | 3; - for(i = 1; i < 1024; i++) - { - page_dir[i] = 0 | 3; - }; - /*asm volatile(" mov %0, %%eax \n \ - mov %%eax, %%cr3 \n \ - mov %%cr4, %%eax \n \ - or %2, %%eax \n \ - mov %%eax, %%cr4 \n \ - mov %%cr0, %%eax \n \ - or %1, %%eax \n \ - mov %%eax, %%cr0":: "m"(pd0), "i"(PAGING_FLAG), "i"(PSE_FLAG));*/ - write_cr3(page_dir); + pd0[1023] = ((uint32_t) pd0 | (PG_PRESENT | PG_WRITE)); + */ + for (int i = 0; i < 1024; i++) { + pg0[i] = (i * 0x1000) | 3; // Present, read/write + } + pd0[0] = ((uint32_t) pg0) | 3; + write_cr3(pd0); write_cr0(read_cr0() | 0x000000000); //asm("hlt"); - kern_heap = (char*) KERN_HEAP; - // ksbrk(1); + kern_heap = &end; + ksbrk(1); p = (struct vm_area*) kmalloc(sizeof(struct vm_area)); p->vm_start = (char*) KERN_PG_HEAP; @@ -218,4 +203,27 @@ extern uint32_t read_cr0(void); }*/ +int pd0_add_page(char *v_addr, char *p_addr, int flags) + { + uint32_t *pde; + uint32_t *pte; + + if (v_addr > (char *) USER_OFFSET) { + printf("ERROR: pd0_add_page(): %d is not in kernel space !\n", v_addr); + return 0; + } + /* On verifie que la table de page est bien presente */ + pde = (uint32_t *) (0xFFFFF000 | (((uint32_t) v_addr & 0xFFC00000) >> 20)); + if ((*pde & PG_PRESENT) == 0) { + //error + printf("\nERROR: %d\n", *pde); + // return 0; + } + + /* Modification de l'entree dans la table de page */ + pte = (uint32_t *) (0xFFC00000 | (((uint32_t) v_addr & 0xFFFFF000) >> 10)); + *pte = ((uint32_t) p_addr) | (PG_PRESENT | PG_WRITE | flags); + set_page_frame_used(p_addr); + return 0; + }