Finally a working paging and heap, missing copyright headers added
This commit is contained in:
parent
1b6689a4de
commit
e732850791
@ -7,7 +7,7 @@ Welcome to rockOS project, a hobby OS that aims to run rogue and nethack.
|
|||||||
- PIC initialization
|
- PIC initialization
|
||||||
- PIT timer
|
- PIT timer
|
||||||
- Keyboard driver
|
- Keyboard driver
|
||||||
- a thing that is supposed to be paging
|
- Paging and Kheap
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -40,6 +40,8 @@ you can run qemu.sh to compile and open the OS on QEMU or iso.sh to just generat
|
|||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
- osdev.org community for huge documentation on OS Development
|
- osdev.org community for huge documentation on OS Development
|
||||||
- musl for libc implementation
|
- musl for libc implementation
|
||||||
|
- James Molloy for his paging and kheap tutorial
|
||||||
|
- Free Software Foundation for multiboot specification
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
@ -30,6 +30,8 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)
|
|||||||
KERNEL_OBJS=\
|
KERNEL_OBJS=\
|
||||||
$(KERNEL_ARCH_OBJS) \
|
$(KERNEL_ARCH_OBJS) \
|
||||||
rockos/kernel.o \
|
rockos/kernel.o \
|
||||||
|
rockos/data_struct/sorted_array.o \
|
||||||
|
rockos/kheap.o \
|
||||||
rockos/paging.o \
|
rockos/paging.o \
|
||||||
rockos/keyboard.o \
|
rockos/keyboard.o \
|
||||||
rockos/timer.o \
|
rockos/timer.o \
|
||||||
|
@ -37,6 +37,7 @@ void gdt_set_descriptor(uint8_t vector, uint32_t base, uint32_t limit, uint8_t a
|
|||||||
}
|
}
|
||||||
|
|
||||||
void gdt_init(void) {
|
void gdt_init(void) {
|
||||||
|
printf("Beginning gdt initialization.\n");
|
||||||
gdt_set_descriptor(0, 0, 0, 0, 0); // 0x0000 Null Descriptor
|
gdt_set_descriptor(0, 0, 0, 0, 0); // 0x0000 Null Descriptor
|
||||||
gdt_set_descriptor(1, 0, 0xFFFFF, 0x9A, 0xC); // 0x0008 Kernel Mode Code Segment
|
gdt_set_descriptor(1, 0, 0xFFFFF, 0x9A, 0xC); // 0x0008 Kernel Mode Code Segment
|
||||||
gdt_set_descriptor(2, 0, 0xFFFFF, 0x92, 0xC); // 0x0010 Kernel Mode Data Segment
|
gdt_set_descriptor(2, 0, 0xFFFFF, 0x92, 0xC); // 0x0010 Kernel Mode Data Segment
|
||||||
|
@ -96,6 +96,7 @@ void idt_set_descriptor(uint8_t vector, void (*isr)(void*), uint8_t flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void idt_init(void) {
|
void idt_init(void) {
|
||||||
|
printf("Beginning IDT initialization.\n");
|
||||||
idtptr.base = (uintptr_t)&idt[0];
|
idtptr.base = (uintptr_t)&idt[0];
|
||||||
idtptr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
idtptr.limit = (uint16_t)sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
||||||
|
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* TTY section header of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* VGA section header of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef ARCH_I386_VGA_H
|
#ifndef ARCH_I386_VGA_H
|
||||||
#define ARCH_I386_VGA_H
|
#define ARCH_I386_VGA_H
|
||||||
|
|
||||||
|
42
kernel/include/rockos/data_struct/sorted_array.h
Normal file
42
kernel/include/rockos/data_struct/sorted_array.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Sorted array data structure header of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ROCKOS_ORDERED_ARRAY_H
|
||||||
|
#define _ROCKOS_ORDERED_ARRAY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef char (*LessThan)(void*, void*);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void** data;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t max_size;
|
||||||
|
LessThan less_than;
|
||||||
|
} SortedArray;
|
||||||
|
|
||||||
|
char less_than(void*, void*);
|
||||||
|
|
||||||
|
SortedArray SortedArrayCreate(uint32_t, LessThan);
|
||||||
|
SortedArray SortedArrayPlace(void*, uint32_t, LessThan);
|
||||||
|
void SortedArrayDestroy(SortedArray*);
|
||||||
|
void SortedArrayInsert(void*, SortedArray*);
|
||||||
|
void* SortedArraySearch(uint32_t, SortedArray*);
|
||||||
|
void SortedArrayDelete(uint32_t, SortedArray*);
|
||||||
|
|
||||||
|
#endif
|
58
kernel/include/rockos/kheap.h
Executable file
58
kernel/include/rockos/kheap.h
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* KHeap section header of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ROCKOS_KHEAP_H
|
||||||
|
#define _ROCKOS_KHEAP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <rockos/data_struct/sorted_array.h>
|
||||||
|
|
||||||
|
#define KHEAP_START 0xC0000000
|
||||||
|
#define KHEAP_INITIAL_SIZE 0x100000
|
||||||
|
#define HEAP_INDEX_SIZE 0x20000
|
||||||
|
#define HEAP_MAGIC 0x06163474
|
||||||
|
#define HEAP_MIN_SIZE 0x70000
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t magic;
|
||||||
|
uint8_t hole;
|
||||||
|
uint32_t size;
|
||||||
|
} Header;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t magic;
|
||||||
|
Header* header;
|
||||||
|
} Footer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SortedArray index;
|
||||||
|
uint32_t addr_start;
|
||||||
|
uint32_t addr_end;
|
||||||
|
uint32_t addr_max;
|
||||||
|
uint8_t supervisor;
|
||||||
|
uint8_t readonly;
|
||||||
|
} Heap;
|
||||||
|
|
||||||
|
Heap* HeapCreate(uint32_t, uint32_t, uint32_t, uint8_t, uint8_t);
|
||||||
|
void* alloc(uint32_t, uint8_t, Heap*);
|
||||||
|
void free(void*, Heap*);
|
||||||
|
uint32_t kmalloc_int(uint32_t, uint8_t, uint32_t*);
|
||||||
|
uint32_t kmalloc(uint32_t);
|
||||||
|
void kfree(void*);
|
||||||
|
|
||||||
|
#endif
|
36
kernel/include/rockos/paging.h
Normal file → Executable file
36
kernel/include/rockos/paging.h
Normal file → Executable file
@ -16,15 +16,39 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifndef _ROCKOS_PAGING_H
|
#ifndef _ROCKOS_PAGING_H
|
||||||
#define _ROCKOS_PAGING_H
|
#define _ROCKOS_PAGING_H
|
||||||
|
|
||||||
#define PAGE_ENTRIES 1024
|
#include <stdint.h>
|
||||||
#define PAGE_SIZE 4096
|
|
||||||
|
|
||||||
void alloc_pages(uint32_t*, size_t);
|
typedef struct {
|
||||||
|
uint32_t present: 1;
|
||||||
|
uint32_t rw: 1;
|
||||||
|
uint32_t user: 1;
|
||||||
|
uint32_t accessed: 1;
|
||||||
|
uint32_t dirty: 1;
|
||||||
|
uint32_t unused: 7;
|
||||||
|
uint32_t frame: 20;
|
||||||
|
} Page;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Page pages[1024];
|
||||||
|
} PageTable;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PageTable* tables[1024];
|
||||||
|
uint32_t tablesPhys[1024];
|
||||||
|
uint32_t physAddr;
|
||||||
|
} PageDirectory;
|
||||||
|
|
||||||
|
void paging_init();
|
||||||
|
void paging_switch_dir(PageDirectory*);
|
||||||
|
Page* PageGet(uint32_t, int32_t, PageDirectory*);
|
||||||
|
void FrameSet(uint32_t);
|
||||||
|
void FrameClear(uint32_t);
|
||||||
|
uint32_t FrameTest(uint32_t);
|
||||||
|
uint32_t FrameFirst();
|
||||||
|
void FrameFree(Page*);
|
||||||
|
void FrameAlloc(Page*, char, char);
|
||||||
|
|
||||||
#endif
|
#endif
|
31
kernel/include/rockos/rockos.h
Normal file
31
kernel/include/rockos/rockos.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Header of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static inline void panic(char* str) {
|
||||||
|
printf("%s\n", str);
|
||||||
|
asm("cli;hlt");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void assert(uint32_t val) {
|
||||||
|
if(!val) {
|
||||||
|
panic("ASSERTION FAILED!");
|
||||||
|
}
|
||||||
|
}
|
87
kernel/rockos/data_struct/sorted_array.c
Executable file
87
kernel/rockos/data_struct/sorted_array.c
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* Sorted array data structure of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rockos/data_struct/sorted_array.h>
|
||||||
|
#include <rockos/rockos.h>
|
||||||
|
#include <rockos/kheap.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char less_than(void* a, void* b) {
|
||||||
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
SortedArray SortedArrayCreate(uint32_t size, LessThan less) {
|
||||||
|
SortedArray myArray = {
|
||||||
|
.data = (void*)kmalloc(size * sizeof(void*)),
|
||||||
|
.size = 0,
|
||||||
|
.max_size = size,
|
||||||
|
.less_than = less,
|
||||||
|
};
|
||||||
|
memset(myArray.data, 0, size * sizeof(void*));
|
||||||
|
return myArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
SortedArray SortedArrayPlace(void* address, uint32_t size, LessThan less) {
|
||||||
|
SortedArray myArray = {
|
||||||
|
.data = (void**)address,
|
||||||
|
.size = 0,
|
||||||
|
.max_size = size,
|
||||||
|
.less_than = less,
|
||||||
|
};
|
||||||
|
memset(myArray.data, 0, size * sizeof(void*));
|
||||||
|
return myArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortedArrayDestroy(SortedArray* myArray) {
|
||||||
|
kfree(myArray->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortedArrayInsert(void* element, SortedArray* myArray) {
|
||||||
|
assert((uint32_t)myArray->less_than);
|
||||||
|
uint32_t iter = 0;
|
||||||
|
while(iter < myArray->size && myArray->less_than(myArray->data[iter], element)) {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
if(myArray->size == iter) {
|
||||||
|
myArray->data[myArray->size++] = element;
|
||||||
|
} else {
|
||||||
|
void* temp = myArray->data[iter];
|
||||||
|
myArray->data[iter] = element;
|
||||||
|
while(iter < myArray->size) {
|
||||||
|
++iter;
|
||||||
|
void* temp2 = myArray->data[iter];
|
||||||
|
myArray->data[iter] = temp;
|
||||||
|
temp = temp2;
|
||||||
|
}
|
||||||
|
myArray->size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* SortedArraySearch(uint32_t index, SortedArray* myArray) {
|
||||||
|
assert(index < myArray->size);
|
||||||
|
return myArray->data[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortedArrayDelete(uint32_t index, SortedArray* myArray) {
|
||||||
|
assert(index < myArray->size);
|
||||||
|
while (index < myArray->size) {
|
||||||
|
myArray->data[index] = myArray->data[index + 1];
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
myArray->size--;
|
||||||
|
}
|
@ -1,23 +1,37 @@
|
|||||||
#include <stdio.h>
|
/**
|
||||||
|
* Entry point of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <rockos/tty.h>
|
#include <rockos/tty.h>
|
||||||
#include <rockos/keyboard.h>
|
#include <rockos/keyboard.h>
|
||||||
#include <rockos/pic.h>
|
#include <rockos/pic.h>
|
||||||
#include <rockos/hal.h>
|
#include <rockos/hal.h>
|
||||||
#include <rockos/timer.h>
|
#include <rockos/timer.h>
|
||||||
#include <rockos/paging.h>
|
#include <rockos/paging.h>
|
||||||
|
#include <rockos/kheap.h>
|
||||||
#include <rockos/multiboot.h>
|
#include <rockos/multiboot.h>
|
||||||
|
#include <rockos/rockos.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
extern char _rockos_start, _rockos_end;
|
extern char _rockos_start, _rockos_end;
|
||||||
|
|
||||||
static multiboot_info_t* multiboot_info;
|
static multiboot_info_t* multiboot_info;
|
||||||
|
|
||||||
void panic(char* str) {
|
|
||||||
printf("%s\n", str);
|
|
||||||
asm("cli;hlt");
|
|
||||||
}
|
|
||||||
|
|
||||||
void bootloader_init(multiboot_info_t* mbd, unsigned int magic) {
|
void bootloader_init(multiboot_info_t* mbd, unsigned int magic) {
|
||||||
/* Make sure the magic number matches for memory mapping*/
|
/* Make sure the magic number matches for memory mapping*/
|
||||||
if(magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
if(magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||||
@ -65,13 +79,15 @@ void kernel_main() {
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t* pages;
|
|
||||||
alloc_pages(pages, 1);
|
uint32_t a = kmalloc(8);
|
||||||
printf("Page Start: %#08X\n", *pages);
|
uint32_t b = kmalloc(8);
|
||||||
alloc_pages(*pages, 8192);
|
uint32_t c = kmalloc(8);
|
||||||
for(int i = 0; i < 8192; ++i){
|
printf("A: %#08X B: %#08X C: %#08X\n",a,b,c);
|
||||||
//printf("Page Start: %#08X\n", (uint32_t)(*pages + i));
|
kfree(c);
|
||||||
}
|
kfree(b);
|
||||||
|
uint32_t d = kmalloc(8);
|
||||||
|
printf("D: %#08X\n", d);
|
||||||
|
|
||||||
unsigned char key;
|
unsigned char key;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Keyboard driver of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <rockos/keyboard.h>
|
#include <rockos/keyboard.h>
|
||||||
#include <rockos/pic.h>
|
#include <rockos/pic.h>
|
||||||
#include <rockos/timer.h>
|
#include <rockos/timer.h>
|
||||||
|
292
kernel/rockos/kheap.c
Executable file
292
kernel/rockos/kheap.c
Executable file
@ -0,0 +1,292 @@
|
|||||||
|
/**
|
||||||
|
* KHeap section of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rockos/kheap.h>
|
||||||
|
#include <rockos/paging.h>
|
||||||
|
#include <rockos/rockos.h>
|
||||||
|
#include <rockos/data_struct/sorted_array.h>
|
||||||
|
|
||||||
|
extern char _rockos_end;
|
||||||
|
uint32_t start_addr = (uint32_t)&_rockos_end;
|
||||||
|
extern PageDirectory* kernel_dir;
|
||||||
|
Heap* kheap = 0;
|
||||||
|
|
||||||
|
static int32_t smallest_hole(uint32_t size, uint8_t aligned, Heap* heap) {
|
||||||
|
uint32_t i = 0;
|
||||||
|
while(i < heap->index.size) {
|
||||||
|
Header* header = (Header*)SortedArraySearch(i, &heap->index);
|
||||||
|
if(aligned) {
|
||||||
|
uint32_t location = (uint32_t)header;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
if((location + sizeof(Header) & ~0xFFF) != 0) {
|
||||||
|
offset = 0x1000 - (location + sizeof(Header)) % 0x1000;
|
||||||
|
}
|
||||||
|
uint32_t hole_size = (uint32_t)header->size - offset;
|
||||||
|
if(hole_size >= (uint32_t)size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (header->size >= size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(i == heap->index.size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void expand(uint32_t size, Heap* heap) {
|
||||||
|
assert(size > heap->addr_end - heap->addr_start);
|
||||||
|
if((size & ~0xFFF) != 0) {
|
||||||
|
size &= ~0xFFF;
|
||||||
|
size += 0x1000;
|
||||||
|
}
|
||||||
|
assert(heap->addr_start + size <= heap->addr_max);
|
||||||
|
uint32_t size_old = heap->addr_end - heap->addr_start;
|
||||||
|
for(uint32_t i = size_old; i < size; i+= 0x1000) {
|
||||||
|
FrameAlloc( PageGet(heap->addr_start + i, 1, kernel_dir), heap->supervisor, heap->readonly );
|
||||||
|
}
|
||||||
|
heap->addr_end = heap->addr_start + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t shrink(uint32_t size, Heap* heap) {
|
||||||
|
assert(size < heap->addr_end - heap->addr_start);
|
||||||
|
if(size & 0x1000) {
|
||||||
|
size &= 0x1000;
|
||||||
|
size += 0x1000;
|
||||||
|
}
|
||||||
|
if(size < HEAP_MIN_SIZE) {
|
||||||
|
size = HEAP_MIN_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size_old = heap->addr_end - heap->addr_start;
|
||||||
|
for(uint32_t i = size_old - 0x1000; size < i; i -= 0x1000) {
|
||||||
|
FrameFree(PageGet(heap->addr_start + i, 0, kernel_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
heap->addr_end = heap->addr_start + size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* alloc(uint32_t size, uint8_t aligned, Heap* heap) {
|
||||||
|
uint32_t size_new = size + sizeof(Header) + sizeof(Footer);
|
||||||
|
int32_t iter = smallest_hole(size_new, aligned, heap);
|
||||||
|
if(iter == -1) {
|
||||||
|
uint32_t len_old = heap->addr_end - heap->addr_start;
|
||||||
|
uint32_t end_old_addr = heap->addr_end;
|
||||||
|
expand(len_old + size_new, heap);
|
||||||
|
uint32_t len_new = heap->addr_end - heap->addr_start;
|
||||||
|
iter = 0;
|
||||||
|
uint32_t idx = -1;
|
||||||
|
uint32_t val = 0;
|
||||||
|
while((uint32_t)iter < heap->index.size) {
|
||||||
|
uint32_t temp = (uint32_t)SortedArraySearch(iter, &heap->index);
|
||||||
|
if (temp > val) {
|
||||||
|
val = temp;
|
||||||
|
idx = iter;
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(idx == -1) {
|
||||||
|
Header* header = (Header*)end_old_addr;
|
||||||
|
header->magic = HEAP_MAGIC;
|
||||||
|
header->size = len_new - len_old;
|
||||||
|
header->hole = 1;
|
||||||
|
Footer* footer = (Footer*)(end_old_addr + header->size - sizeof(Footer));
|
||||||
|
footer->magic = HEAP_MAGIC;
|
||||||
|
footer->header = header;
|
||||||
|
SortedArrayInsert((void*)header, &heap->index);
|
||||||
|
} else {
|
||||||
|
Header* header = SortedArraySearch(idx, &heap->index);
|
||||||
|
header->size += len_new - len_old;
|
||||||
|
Footer* footer = (Footer*)((uint32_t)header + header->size - sizeof(Footer));
|
||||||
|
footer->magic = HEAP_MAGIC;
|
||||||
|
footer->header = header;
|
||||||
|
}
|
||||||
|
return alloc(size, aligned, heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Header* hole_header_old = (Header*)SortedArraySearch(iter, &heap->index);
|
||||||
|
uint32_t hole_pos_old = (uint32_t)hole_header_old;
|
||||||
|
uint32_t hole_size_old = hole_header_old->size;
|
||||||
|
|
||||||
|
if(hole_size_old - size_new < sizeof(Header) + sizeof(Footer)) {
|
||||||
|
size += hole_size_old - size_new;
|
||||||
|
size_new = hole_size_old;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(aligned && (hole_pos_old & ~0xFFF)) {
|
||||||
|
uint32_t location_new = hole_pos_old + 0x1000 - (hole_pos_old & 0xFFF) - sizeof(Header);
|
||||||
|
Header* hole_header = (Header*) hole_pos_old;
|
||||||
|
hole_header->size = 0x1000 - (hole_pos_old & 0xFFF) - sizeof(Header);
|
||||||
|
hole_header->magic = HEAP_MAGIC;
|
||||||
|
hole_header->hole = 1;
|
||||||
|
Footer* hole_footer = (Footer*)((uint32_t)location_new - sizeof(Footer));
|
||||||
|
hole_footer->magic = HEAP_MAGIC;
|
||||||
|
hole_footer->header = hole_header;
|
||||||
|
hole_pos_old = location_new;
|
||||||
|
hole_size_old -= hole_header->size;
|
||||||
|
} else {
|
||||||
|
SortedArrayDelete(iter, &heap->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Header* block_header = (Header*)hole_pos_old;
|
||||||
|
block_header->magic = HEAP_MAGIC;
|
||||||
|
block_header->hole = 0;
|
||||||
|
block_header->size = size_new;
|
||||||
|
Footer* block_footer = (Footer*)(hole_pos_old + sizeof(Header) + size);
|
||||||
|
block_footer->magic = HEAP_MAGIC;
|
||||||
|
block_footer->header = block_header;
|
||||||
|
|
||||||
|
if(hole_size_old - size_new) {
|
||||||
|
Header* hole_header = (Header*)(hole_pos_old + sizeof(Header) + size + sizeof(Footer));
|
||||||
|
hole_header->magic = HEAP_MAGIC;
|
||||||
|
hole_header->hole = 1;
|
||||||
|
hole_header->size = hole_size_old - size_new;
|
||||||
|
Footer* hole_footer = (Footer*)((uint32_t)hole_header + hole_size_old - size_new - sizeof(Footer));
|
||||||
|
if ((uint32_t)hole_footer < heap->addr_end) {
|
||||||
|
hole_footer->magic = HEAP_MAGIC;
|
||||||
|
hole_footer->header = hole_header;
|
||||||
|
}
|
||||||
|
SortedArrayInsert((void*)hole_header, &heap->index);
|
||||||
|
}
|
||||||
|
return (void*)((uint32_t)block_header + sizeof(Header));
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void* pointer, Heap* heap) {
|
||||||
|
if(pointer == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Header* header = (Header*)((uint32_t)pointer - sizeof(Header));
|
||||||
|
Footer* footer = (Footer*)((uint32_t)header + header->size - sizeof(Footer));
|
||||||
|
|
||||||
|
assert(header->magic == HEAP_MAGIC);
|
||||||
|
assert(footer->magic == HEAP_MAGIC);
|
||||||
|
|
||||||
|
header->hole = 1;
|
||||||
|
char add = 1;
|
||||||
|
|
||||||
|
Footer* temp_footer = (Footer*)((uint32_t)header - sizeof(Footer));
|
||||||
|
if(temp_footer->magic == HEAP_MAGIC && temp_footer->header->hole) {
|
||||||
|
uint32_t cache_size = header->size;
|
||||||
|
header = temp_footer->header;
|
||||||
|
footer->header = header;
|
||||||
|
header->size += cache_size;
|
||||||
|
add = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Header* temp_header = (Header*)((uint32_t)footer + sizeof(footer));
|
||||||
|
if(temp_header->magic == HEAP_MAGIC && temp_header->hole) {
|
||||||
|
header->size += temp_header->size;
|
||||||
|
temp_footer = (Footer*)((uint32_t)temp_header + temp_header->size - sizeof(Footer));
|
||||||
|
footer = temp_footer;
|
||||||
|
uint32_t iter = 0;
|
||||||
|
while((iter < heap->index.size) && (SortedArraySearch(iter, &heap->index) != (void*)temp_header)) {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
assert(iter < heap->index.size);
|
||||||
|
SortedArrayDelete(iter, &heap->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((uint32_t)footer + sizeof(Footer) == heap->addr_end) {
|
||||||
|
uint32_t len_old = heap->addr_end - heap->addr_start;
|
||||||
|
uint32_t len_new = shrink((uint32_t)header - heap->addr_start, heap);
|
||||||
|
if(header->size - (len_old - len_new) > 0) {
|
||||||
|
header->size -= len_old - len_new;
|
||||||
|
footer = (Footer*)((uint32_t)header + header->size - sizeof(Footer));
|
||||||
|
footer->magic = HEAP_MAGIC;
|
||||||
|
footer->header = header;
|
||||||
|
} else {
|
||||||
|
uint32_t iter = 0;
|
||||||
|
while((iter < heap->index.size) && (SortedArraySearch(iter, &heap->index) != (void*)temp_header)) {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
if(iter < heap->index.size) {
|
||||||
|
SortedArrayDelete(iter, &heap->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(add) {
|
||||||
|
SortedArrayInsert((void*)header, &heap->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t kmalloc_int(uint32_t size, uint8_t aligned, uint32_t* phys_addr) {
|
||||||
|
if(kheap) {
|
||||||
|
void* addr = alloc(size, aligned, kheap);
|
||||||
|
if (phys_addr) {
|
||||||
|
Page* page = PageGet((uint32_t)addr, 0, kernel_dir);
|
||||||
|
*phys_addr = (page->frame * 0x1000) + ((uint32_t)addr & 0xFFF);
|
||||||
|
}
|
||||||
|
return (uint32_t)addr;
|
||||||
|
}
|
||||||
|
if(aligned && (start_addr & 0xFFF)) {
|
||||||
|
start_addr &= ~0xFFF;
|
||||||
|
start_addr += 0x1000;
|
||||||
|
}
|
||||||
|
if(phys_addr) {
|
||||||
|
*phys_addr = start_addr;
|
||||||
|
}
|
||||||
|
uint32_t temp = start_addr;
|
||||||
|
start_addr += size;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t kmalloc(uint32_t size) {
|
||||||
|
return kmalloc_int(size, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kfree(void* pointer) {
|
||||||
|
free(pointer, kheap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char HeaderLessThan(void* a, void* b) {
|
||||||
|
return ((Header*)a)->size < ((Header*)b)->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Heap* HeapCreate(uint32_t start, uint32_t end, uint32_t max, uint8_t supervisor, uint8_t readonly) {
|
||||||
|
Heap* heap = (Heap*)kmalloc(sizeof(Heap));
|
||||||
|
|
||||||
|
assert(start % 0x1000 == 0);
|
||||||
|
assert(end % 0x1000 == 0);
|
||||||
|
|
||||||
|
heap->index = SortedArrayPlace((void*)start, HEAP_INDEX_SIZE, &HeaderLessThan);
|
||||||
|
start += sizeof(void*) * HEAP_INDEX_SIZE;
|
||||||
|
|
||||||
|
if(start & ~0xFFF) {
|
||||||
|
start &= ~0xFFF;
|
||||||
|
start += 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
heap->addr_start = start;
|
||||||
|
heap->addr_end = end;
|
||||||
|
heap->addr_max = max;
|
||||||
|
heap->supervisor = supervisor;
|
||||||
|
heap->readonly = readonly;
|
||||||
|
|
||||||
|
Header* hole = (Header*)start;
|
||||||
|
hole->size = end - start;
|
||||||
|
hole->magic = HEAP_MAGIC;
|
||||||
|
hole->hole = 1;
|
||||||
|
SortedArrayInsert((void*)hole, &heap->index);
|
||||||
|
|
||||||
|
return heap;
|
||||||
|
}
|
192
kernel/rockos/paging.c
Normal file → Executable file
192
kernel/rockos/paging.c
Normal file → Executable file
@ -1,76 +1,142 @@
|
|||||||
|
/**
|
||||||
|
* Paging section of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <rockos/paging.h>
|
#include <rockos/paging.h>
|
||||||
#include <stdint.h>
|
#include <rockos/kheap.h>
|
||||||
#include <stddef.h>
|
#include <rockos/rockos.h>
|
||||||
#include <stdio.h>
|
#include <string.h>
|
||||||
|
|
||||||
void load_page_dir(uint32_t* page_dir) {
|
#define INDEX_FROM_BIT(x) (x/(8*4))
|
||||||
asm volatile (
|
#define OFFSET_FROM_BIT(x) (x%(8*4))
|
||||||
"mov %%eax, %%cr3"
|
|
||||||
:
|
PageDirectory* kernel_dir = 0;
|
||||||
: "a"(page_dir)
|
PageDirectory* current_dir = 0;
|
||||||
: "memory"
|
|
||||||
);
|
uint32_t* frames;
|
||||||
|
uint32_t nframes;
|
||||||
|
|
||||||
|
extern uint32_t start_addr;
|
||||||
|
extern Heap* kheap;
|
||||||
|
|
||||||
|
void FrameSet(uint32_t frame_addr) {
|
||||||
|
uint32_t frame = frame_addr / 0x1000;
|
||||||
|
frames[INDEX_FROM_BIT(frame)] |= (1 << OFFSET_FROM_BIT(frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_paging() {
|
void FrameClear(uint32_t frame_addr) {
|
||||||
asm volatile (
|
uint32_t frame = frame_addr / 0x1000;
|
||||||
"mov %cr0, %eax\n"
|
frames[INDEX_FROM_BIT(frame)] &= ~(1 << OFFSET_FROM_BIT(frame));
|
||||||
"or $0x80000000, %eax\n"
|
|
||||||
"mov %eax, %cr0"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char _rockos_end;
|
uint32_t FrameTest(uint32_t frame_addr) {
|
||||||
static uint32_t* page_dir __attribute__((packed));
|
uint32_t frame = frame_addr / 0x1000;
|
||||||
|
return (frames[INDEX_FROM_BIT(frame)] & (1 << OFFSET_FROM_BIT(frame)));
|
||||||
void paging_init() {
|
|
||||||
page_dir = (uint32_t*)(((uint32_t)&_rockos_end & ~0xFFF) + 0x1000);
|
|
||||||
for(int i = 0; i < PAGE_ENTRIES; i++) {
|
|
||||||
// Supervisor: only kernel-mode can access
|
|
||||||
// Write Enabled: Can be both read and written to
|
|
||||||
// Not Present: Page table not present
|
|
||||||
*(page_dir + i) = 0x00000002;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t* firstPageTable __attribute__((packed)) = (uint32_t*)(((uint32_t)page_dir & ~0xFFF) + 0x1000);
|
|
||||||
for(unsigned int i = 0; i < PAGE_ENTRIES; i++) {
|
|
||||||
// As the address is page aligned, it will leave 12 bits zeroed,
|
|
||||||
// which are used by the attributes.
|
|
||||||
firstPageTable[i] = (i*0x1000) | 0x003; // attr: supervisor, r/w, present, 9th bit set
|
|
||||||
}
|
|
||||||
|
|
||||||
page_dir[0] = (uint32_t)firstPageTable | 0x003; //attr: supervisor, r/w, present
|
|
||||||
load_page_dir(page_dir);
|
|
||||||
enable_paging();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void alloc_pages(uint32_t* pages, size_t size) {
|
uint32_t FrameFirst() {
|
||||||
for(size_t i = 0; i < size;) {
|
for(uint32_t i = 0; i < INDEX_FROM_BIT(nframes); ++i) {
|
||||||
for(size_t j = 0; j < PAGE_ENTRIES && i < size; ++j) {
|
if(frames[i] != 0xFFFFFFFF) {
|
||||||
printf("oklahoma %#08X\n", page_dir[j]);
|
for(uint32_t j = 0; j < 32; ++j) {
|
||||||
if((page_dir[j] & 3) == 3) {
|
uint32_t test = 1 << j;
|
||||||
uint32_t* pageTable __attribute__((packed)) = page_dir[j] & ~0xFFF;
|
if(!(frames[i]&test)) {
|
||||||
for(int k = 0; k < PAGE_ENTRIES && i < size; ++k) {
|
return i*4*8 + j;
|
||||||
if((pageTable[k] & 3) == 3 && (pageTable[k] & 0x100) != 0x100) {
|
|
||||||
pageTable[k] |= 0x100;
|
|
||||||
pages[i] = ((uint32_t)pageTable & ~0xFFF) | (pageTable[k] >> 12);
|
|
||||||
printf("connecticut %#08X\n", pages[i]);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
printf("aa %#08X\n", (page_dir[j-1] & ~0xFFF) + 0x4000);
|
|
||||||
uint32_t* newPageTable __attribute__((packed)) = (page_dir[j-1] & ~0xFFF) + 0x4000;
|
|
||||||
printf("alabama %#08X, %#08X\n", newPageTable[0], (page_dir[j-1] & ~0xFFF) + 0x4000);
|
|
||||||
for(unsigned int l = 0; l < PAGE_ENTRIES; l++) {
|
|
||||||
// As the address is page aligned, it will leave 12 bits zeroed,
|
|
||||||
// which are used by the attributes.
|
|
||||||
newPageTable[l] = (l*0x1000) | 0x003; // attr: supervisor, r/w, present, 9th bit set
|
|
||||||
}
|
|
||||||
page_dir[j] = (uint32_t)newPageTable | 0x003;
|
|
||||||
printf("NewPageTable: %#08X\n", page_dir[j]);
|
|
||||||
--j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameAlloc(Page* page, char kernel, char writeable) {
|
||||||
|
if (page->frame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t i = FrameFirst();
|
||||||
|
if(i == (uint32_t)-1) {
|
||||||
|
panic("NO FREE FRAMES LEFT!");
|
||||||
|
}
|
||||||
|
FrameSet(i * 0x1000);
|
||||||
|
page->present = 1;
|
||||||
|
page->rw = writeable;
|
||||||
|
page->user = !kernel;
|
||||||
|
page->frame = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameFree(Page* page) {
|
||||||
|
uint32_t frame;
|
||||||
|
if(!(frame = page->frame)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FrameClear(frame);
|
||||||
|
page->frame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Page* PageGet(uint32_t addr, int32_t make, PageDirectory* dir) {
|
||||||
|
addr /= 0x1000;
|
||||||
|
uint32_t table_i = addr / 1024;
|
||||||
|
if(dir->tables[table_i]) {
|
||||||
|
return &dir->tables[table_i]->pages[addr%1024];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(make) {
|
||||||
|
uint32_t temp;
|
||||||
|
dir->tables[table_i] = (PageTable*)kmalloc_int(sizeof(PageTable), 1, &temp);
|
||||||
|
memset(dir->tables[table_i], 0, 0x1000);
|
||||||
|
dir->tablesPhys[table_i] = temp | 0x7;
|
||||||
|
return &dir->tables[table_i]->pages[addr%1024];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paging_switch_dir(PageDirectory* dir) {
|
||||||
|
current_dir = dir;
|
||||||
|
asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhys));
|
||||||
|
uint32_t cr0;
|
||||||
|
asm volatile("mov %%cr0, %0": "=r"(cr0));
|
||||||
|
cr0 |= 0x80000000;
|
||||||
|
asm volatile("mov %0, %%cr0":: "r"(cr0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void paging_init() {
|
||||||
|
printf("Initializing paging.\n");
|
||||||
|
uint32_t page_end_mem = 0x1000000;
|
||||||
|
nframes = page_end_mem / 0x1000;
|
||||||
|
|
||||||
|
frames = (uint32_t*)kmalloc(INDEX_FROM_BIT(nframes));
|
||||||
|
memset(frames, 0, INDEX_FROM_BIT(nframes));
|
||||||
|
|
||||||
|
kernel_dir = (PageDirectory*)kmalloc_int(sizeof(PageDirectory), 1, 0);
|
||||||
|
memset(kernel_dir, 0, sizeof(PageDirectory));
|
||||||
|
current_dir = kernel_dir;
|
||||||
|
|
||||||
|
for(uint32_t i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000) {
|
||||||
|
PageGet(i, 1, kernel_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < start_addr + 0x1000; i += 0x1000) {
|
||||||
|
FrameAlloc(PageGet(i, 1, kernel_dir), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000) {
|
||||||
|
FrameAlloc(PageGet(i, 1, kernel_dir), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
paging_switch_dir(kernel_dir);
|
||||||
|
kheap = HeapCreate(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0);
|
||||||
}
|
}
|
@ -1,3 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* PIT section of rockOS
|
||||||
|
* Copyright (C) 2022 Furkan Mudanyali
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <rockos/timer.h>
|
#include <rockos/timer.h>
|
||||||
#include <rockos/hal.h>
|
#include <rockos/hal.h>
|
||||||
#include <rockos/pic.h>
|
#include <rockos/pic.h>
|
||||||
|
Reference in New Issue
Block a user