diff --git a/README.md b/README.md index c8fc2fe..b32c372 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Then you can run those commands: 2. Type `make run` to start it in QEMU or `make bochs` to start it with bochs(only for debug purposes). Otherwise you can download an already compiled ISO file -[here](https://github.com/ice-bit/iceOS/raw/master/imgs/iceOS.iso)(md5sum: `ab3d5b8307015461b44e62d0c2d42806`) +[here](https://github.com/ice-bit/iceOS/raw/master/imgs/iceOS.iso)(md5sum: `342691301699a73102fa6a57abea6989`) ## Features iceOS already have/will have the following features: @@ -44,6 +44,8 @@ iceOS already have/will have the following features: - [x] Interrupts implementation; - [x] PIC & PIT implementation; - [x] PS/2 driver; +- [x] Heap implementation; +- [ ] Virtual File System - [x] Support for x86 architecture; - [x] GRUB as bootloader; @@ -54,6 +56,7 @@ This project is made with different kind of resources and different kind of know - [Operating System Concepts - Silberschatz (2016)](https://www.amazon.it/Sistemi-operativi-Concetti-ed-esempi/dp/8865183713/ref=pd_lpo_sbs_14_img_1?_encoding=UTF8&psc=1&refRID=4A5T2C7KKH7RA0K1T7RV) - [The Art Of Electronics - Horowitz (2015)](https://www.amazon.it/gp/product/0521809266/ref=ppx_od_dt_b_asin_title_s00?ie=UTF8&psc=1) - [OSDev wiki](https://wiki.osdev.org/Main_Page) +- [JamesM's kernel development tutorials](http://www.jamesmolloy.co.uk/tutorial_html/1.-Environment%20setup.html) - [The Little Book About OS Development](https://littleosbook.github.io/) - [I actually started this project due to skiftOS](https://github.com/skiftOS/skift) ## License diff --git a/imgs/iceOS.iso b/imgs/iceOS.iso index eafcb2b..8b6e845 100644 Binary files a/imgs/iceOS.iso and b/imgs/iceOS.iso differ diff --git a/imgs/qemu_screenshot.png b/imgs/qemu_screenshot.png index 10f8455..8c1ed85 100644 Binary files a/imgs/qemu_screenshot.png and b/imgs/qemu_screenshot.png differ diff --git a/kernel/kernel_main.c b/kernel/kernel_main.c index 332c3ef..5b09a48 100644 --- a/kernel/kernel_main.c +++ b/kernel/kernel_main.c @@ -15,6 +15,7 @@ #include "shell/shell.h" #include "libc/stdio.h" #include "libc/multiboot.h" +#include "libc/assert.h" #include @@ -38,23 +39,23 @@ void kernel_main() { printf_color("\n[INFO]", LIGHT_CYAN, BLACK); printf_color(" - Loaded PS/2 driver", WHITE, BLACK); - init_paging(); + init_paging(); // Initialize paging printf_color("\n[INFO]", LIGHT_CYAN, BLACK); printf_color(" - Loaded Paging", WHITE, BLACK); - - /* printf_color("\n[TEST]", LIGHT_BROWN, BLACK); // Testing heap - printf_color(" - Allocating heap blocks..\n", LIGHT_BROWN, BLACK); - - uint32_t x = kmalloc(8), y = kmalloc(16), z = kmalloc(32); - printf("x: %x, y: %x, z: %x", x, y, z); - printf_color("\n[TEST]", LIGHT_BROWN, BLACK); // Testing heap - printf_color(" - Freeing heap blocks..\n", LIGHT_BROWN, BLACK); - kfree((void*)x), kfree((void*)y), kfree((void*)z); + printf_color(" - Testing heap..\n", LIGHT_BROWN, BLACK); - printf_color("\n[STATUS]", LIGHT_GREEN, BLACK); - printf_color(" - Heap worked successfullt!", WHITE, BLACK); */ + uint32_t x = kmalloc(32), y = kmalloc(32); + printf("x: %x, y: %x", x, y); + kfree((void*)y); + uint32_t z = kmalloc(8); + printf(", z: %x\n", z); // If z is equal to y, heap's anti-fragmentation algorithm works + ASSERT(z == y); + kfree((void*)z), kfree((void*)x); + + printf_color("[STATUS]", LIGHT_GREEN, BLACK); + printf_color(" - Heap works!", WHITE, BLACK); iceos_ascii_logo(); init_prompt(); // Initialize frame buffer diff --git a/kernel/mem/kheap.c b/kernel/mem/kheap.c index 607716e..15d1a8b 100644 --- a/kernel/mem/kheap.c +++ b/kernel/mem/kheap.c @@ -1,7 +1,6 @@ #include "kheap.h" #include "paging.h" - -// TODO: add assert +#include "../libc/assert.h" extern uint32_t end; uint32_t placement_addr = (uint32_t)&end; @@ -50,13 +49,18 @@ uint32_t kmalloc(uint32_t sz) { } static void expand(uint32_t new_size, heap_t *heap) { + // First check if new size is greater than older one + ASSERT(new_size > heap->end_address - heap->start_address); + // Get nearest page boundary if((new_size&0xFFFFF000) != 0) { new_size &= 0xFFFFF000; new_size += 0x1000; } + // Check if new size is not greater than maximum size + ASSERT(heap->start_address+new_size <= heap->max_address); - uint32_t old_size = heap->end_adddress - heap->start_address; + uint32_t old_size = heap->end_address - heap->start_address; uint32_t it = old_size; while(it < new_size) { @@ -64,10 +68,12 @@ static void expand(uint32_t new_size, heap_t *heap) { (heap->supervisor) ? 1 : 0, (heap->readonly) ? 0 : 1); it += 0x1000; // Page size } - heap->end_adddress = heap->start_address+new_size; + heap->end_address = heap->start_address+new_size; } static uint32_t contract(uint32_t new_size, heap_t *heap) { + ASSERT(new_size < heap->end_address-heap->start_address); + if(new_size&0x1000) { new_size &= 0x1000; new_size += 0x1000; @@ -76,14 +82,14 @@ static uint32_t contract(uint32_t new_size, heap_t *heap) { if(new_size < HEAP_MIN_SIZE) new_size = HEAP_MIN_SIZE; - uint32_t old_size = heap->end_adddress - heap->start_address; + uint32_t old_size = heap->end_address - heap->start_address; uint32_t it = old_size - 0x1000; while(new_size < it) { - free_frame(get_page(heap->start_address+it,0, kernel_directory)); + free_frame(get_page(heap->start_address+it, 0, kernel_directory)); it -= 0x1000; } - heap->end_adddress = heap->start_address + new_size; + heap->end_address = heap->start_address + new_size; return new_size; } @@ -94,10 +100,10 @@ static uint32_t find_smallest_hole(uint32_t size, uint8_t page_align, heap_t *he while(it < heap->index.size) { header_t *head = (header_t*)lookup_ordered_array(it, &heap->index); if(page_align > 0) { - // IF page must be aligned + // page must be aligned? uint32_t location = (uint32_t)head; uint32_t offset = 0; - if((((location+sizeof(header_t)) & 0xFFFFF000) != 0)) + if(((location+sizeof(header_t)) & 0xFFFFF000) != 0) offset = 0x1000 - (location+sizeof(header_t))%0x1000; uint32_t hole_size = (uint32_t)head->size - offset; // Check if we can fit this page in that hole @@ -122,8 +128,11 @@ static uint8_t header_t_less_than(void *a, void *b) { heap_t *create_heap(uint32_t start, uint32_t end_addr, uint32_t max, uint8_t supervisor, uint8_t readonly) { heap_t *heap = (heap_t*)kmalloc(sizeof(heap_t)); + ASSERT(start%0x1000 == 0); + ASSERT(end_addr%0x1000 == 0); + // Initialize the index - heap->index = place_ordered_array((void*)start, HEAP_MIN_SIZE, &header_t_less_than); + heap->index = place_ordered_array((void*)start, HEAP_INDEX_SIZE, &header_t_less_than); // Shift start address to the right start += sizeof(type_t) * HEAP_INDEX_SIZE; @@ -134,7 +143,7 @@ heap_t *create_heap(uint32_t start, uint32_t end_addr, uint32_t max, uint8_t sup } // Store vars into heap heap->start_address = start; - heap->end_adddress = end_addr; + heap->end_address = end_addr; heap->max_address = max; heap->supervisor = supervisor; heap->readonly = readonly; @@ -154,12 +163,12 @@ void *alloc(uint32_t size, uint8_t page_align, heap_t *heap) { uint32_t it = find_smallest_hole(new_size, page_align, heap); if((int32_t)it == -1) { - uint32_t old_len = heap->end_adddress - heap->start_address; - uint32_t old_end_addr = heap->end_adddress; + uint32_t old_len = heap->end_address - heap->start_address; + uint32_t old_end_addr = heap->end_address; // Allocate more space expand(old_len+new_size, heap); - uint32_t new_len = heap->end_adddress - heap->start_address; + uint32_t new_len = heap->end_address - heap->start_address; it = 0; uint32_t idx = -1; uint32_t value = 0x0; @@ -237,7 +246,7 @@ void *alloc(uint32_t size, uint8_t page_align, heap_t *heap) { hole_head->is_hole = 1; hole_head->size = origin_hole_s - new_size; footer_t *hole_foot = (footer_t*)((uint32_t)hole_head + origin_hole_s - new_size - sizeof(footer_t)); - if((uint32_t)hole_foot < heap->end_adddress) { + if((uint32_t)hole_foot < heap->end_address) { hole_foot->magic = HEAP_MAGIC; hole_foot->header = hole_head; } @@ -258,7 +267,8 @@ void free(void *p, heap_t *heap) { header_t *head = (header_t*)((uint32_t)p - sizeof(header_t)); footer_t *foot = (footer_t*)((uint32_t)head + head->size - sizeof(footer_t)); - // TODO: assert + ASSERT(head->magic == HEAP_MAGIC); + ASSERT(foot->magic == HEAP_MAGIC); head->is_hole = 1; // Make this a hole int8_t add_to_free_hole = 1; // Add this header to free holes @@ -284,15 +294,16 @@ void free(void *p, heap_t *heap) { while((it < heap->index.size) && (lookup_ordered_array(it, &heap->index) != (void*)test_head)) it++; - // TODO: ASSERTION // Check if we actually found something + ASSERT(it < heap->index.size); + // Remove that item remove_ordered_array(it, &heap->index); } // If footer is located at the end, we can contract the heap - if((uint32_t)foot+sizeof(footer_t) == heap->end_adddress) { - uint32_t old_len = heap->end_adddress-heap->start_address; + if((uint32_t)foot+sizeof(footer_t) == heap->end_address) { + uint32_t old_len = heap->end_address-heap->start_address; uint32_t new_len = contract((uint32_t)head - heap->start_address, heap); // Check dimensions after resizing if(head->size - (old_len-new_len) > 0) { diff --git a/kernel/mem/kheap.h b/kernel/mem/kheap.h index 90dfd5d..a423c90 100644 --- a/kernel/mem/kheap.h +++ b/kernel/mem/kheap.h @@ -49,7 +49,7 @@ typedef struct { typedef struct { ordered_array_t index; uint32_t start_address; // Begin of allocated space - uint32_t end_adddress; // End of allocated space + uint32_t end_address; // End of allocated space uint32_t max_address; // Maximum size heap can be expanded to uint8_t supervisor; uint8_t readonly; diff --git a/kernel/shell/shell.c b/kernel/shell/shell.c index 8cd7af7..9351ec5 100644 --- a/kernel/shell/shell.c +++ b/kernel/shell/shell.c @@ -119,20 +119,11 @@ void processCommand(uint8_t *cmd) { } void iceos_ascii_logo() { -printf_color( - "\n\n" - " MMMMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " MMMMMMMMMMMM...?MMM.. MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " MMMMMMMMM ........M .MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " MMMMMMMM...........M .MMMMMMMM..MMO ........MMM....MM..MMMMM\n" - " MMMMM ..............M..MMMMMMM..M...........M.....,.M.. MMMM\n" - " MMMM................MM,.. .MMM....MMMM......M..MMMM..M,..MMM\n" - " MMM ................... MMMMMM....MMMM......M..MMMM..MMN..MM\n" - " M ......................,MMMMM..M.. ........M.......M... .~M\n" - " ........................MMMMM..MMM.........MMM...MMM....MMMM\n" - " .........................MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " M .....................DMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" - " MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n", + printf_color("\n\n" + "##############################################\n#", + LIGHT_BLUE, BLACK); + printf_color(" iceOS - developed by Marco Cetica (c) 2019 ", LIGHT_MAGENTA, BLACK); - printf_color(" (c) Marco Cetica 2019\n", LIGHT_GREEN, BLACK); - } \ No newline at end of file + printf_color("#\n##############################################\n", + LIGHT_BLUE, BLACK); +} \ No newline at end of file