diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/grub.cfg | 3 | ||||
-rw-r--r-- | src/kernel/main.c | 59 | ||||
-rw-r--r-- | src/kernel/mem.c | 48 | ||||
-rw-r--r-- | src/kernel/mem.h | 8 |
4 files changed, 85 insertions, 33 deletions
diff --git a/src/grub.cfg b/src/grub.cfg new file mode 100644 index 0000000..ccc1e7c --- /dev/null +++ b/src/grub.cfg @@ -0,0 +1,3 @@ +menuentry "portland" { + multiboot2 /boot/kernel.elf +}
\ No newline at end of file diff --git a/src/kernel/main.c b/src/kernel/main.c index 74fd8bf..29c0a4d 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -68,6 +68,12 @@ enum mem_type { DEFECTIVE = 5 }; +struct mmap_tag_entry { + uint64_t base; + uint64_t length; + uint32_t type; +} __attribute__ ((__packed__)); + struct boot_device_tag boot_device; bool have_boot_device = false; bool have_mmap = false; @@ -102,50 +108,49 @@ uint32_t main(void) { break; case MEMORY_MAP: - mmap_start = (struct mmap_entry *)((uint32_t)&tag_pointer->rest + 8); + { + struct mmap_tag_entry *tag = (struct mmap_tag_entry *)((uint32_t)&tag_pointer->rest + 8); uint32_t size = *(uint32_t *)&tag_pointer->rest; - struct mmap_entry *next = mmap_start; - struct mmap_entry **fill_last = &mmap_start; + struct mmap_entry *entry = (struct mmap_entry *)tag; + struct mmap_entry **last_next = &mmap_start; uint32_t usable = 0; - while (next) { - if (!(next->base & 0xffffffff00000000)) { - *fill_last = next; - fill_last = &next->next; - if ((next->base + next->length - 1) & 0xffffffff00000000) - next->length = 1 + ~(next->base); + while (tag) { + if (!(tag->base & 0xffffffff00000000)) { + entry->base = (uint32_t)tag->base; + entry->length = (tag->base + tag->length - 1) & 0xffffffff00000000 ? + 1 + ~(uint32_t)tag->base : (uint32_t)tag->length; put_sz("Memory: 0x"); - put_32_hex((uint32_t)(next->base >> 32)); - put_char('_'); - put_32_hex((uint32_t)next->base); - put_sz(" - "); - put_32_hex((uint32_t)(next->length >> 32)); - put_char('_'); - put_32_hex((uint32_t)next->length); - switch (next->whose) { + put_32_hex(entry->base); + put_sz(" - 0x"); + put_32_hex(entry->base + entry->length - 1); + switch (tag->type) { case AVAILABLE: put_sz(": usable\n"); - next->whose = FREE; - usable += next->length; + entry->whose = FREE; + usable += entry->length; break; case ACPI: put_sz(": ACPI info\n"); - next->whose = HARDWARE; + entry->whose = HARDWARE; break; case PRESERVE: put_sz(": hardware use\n"); - next->whose = HARDWARE; + entry->whose = HARDWARE; break; case DEFECTIVE: put_sz(": defective\n"); - next->whose = HARDWARE; + entry->whose = HARDWARE; break; default: put_sz(": unrecognized type, assuming hardware use\n"); - next->whose = HARDWARE; + entry->whose = HARDWARE; break; } + *last_next = entry; + last_next = &entry->next; + ++entry; } - next = next->next = (struct mmap_entry *)((uint32_t)next + size); + tag = (struct mmap_tag_entry *)((uint32_t)tag + size); } put_sz("Total usable memory: 0x"); @@ -173,14 +178,14 @@ uint32_t main(void) { have_mmap = true; break; - + } default: put_sz("Ignoring multiboot tag 0x"); put_32_hex(tag_pointer->type); put_char('\n'); } - tag_pointer = (struct tag_start *)((uint8_t *)tag_pointer + tag_pointer->size); + tag_pointer = (struct tag_start *)((uint32_t)tag_pointer + tag_pointer->size); }; if (!have_boot_device) @@ -193,7 +198,7 @@ uint32_t main(void) { return INSUFF_MEMORY; ; - put_sz("Welcome to Portland version 0.0.8!\n"); + put_sz("Welcome to Portland version 0.0.9!\n"); while (1) put_sz("|\b/\b-\b\\\b"); } diff --git a/src/kernel/mem.c b/src/kernel/mem.c index 6544108..636c23e 100644 --- a/src/kernel/mem.c +++ b/src/kernel/mem.c @@ -20,9 +20,53 @@ OF THIS SOFTWARE. #include "mem.h" void *allocate_block(uint32_t size, uint16_t proc_n) { - //TODO + struct mmap_entry *i = mmap_start; + while (i->whose || (i->length < size)) + if (i->next) + i = i->next; + else + return (void *)0; + if (i->length == size) { + i->whose = proc_n; + return (void *)i->base; + } + uint32_t remaining = i->length - size; + i->whose = proc_n; + i->length = size; + struct mmap_entry *new; + //TODO: ALLOCATE NEW + new->base = i->base + size; + new->length = remaining; + new->whose = FREE; + new->next = i->next; + i->next = new; + return (void *)i->base; } void deallocate_block(void *start) { - //TODO + struct mmap_entry *find = mmap_start; + while (find->base != (uint32_t)start) + if (find->next) + find = find->next; + else + return; + find->whose = FREE; + + for (struct mmap_entry *find_after = mmap_start; find_after; find_after = find_after->next) + if (find_after->base == find->base + find->length) { + if (!find_after->whose) { + find->length += find_after->length; + find->next = find_after->next; + } + break; + } + + for (struct mmap_entry *find_before = mmap_start; find_before; find_before = find_before->next) + if (find->base == find_before->base + find_before->length) { + if (!find_before->whose) { + find_before->length += find->length; + find_before->next = find->next; + } + break; + } }
\ No newline at end of file diff --git a/src/kernel/mem.h b/src/kernel/mem.h index 1eb27bd..106db90 100644 --- a/src/kernel/mem.h +++ b/src/kernel/mem.h @@ -29,11 +29,11 @@ enum special_mmap_codes { }; struct mmap_entry { - uint64_t base; - uint64_t length; - uint32_t whose; + uint32_t base; + uint32_t length; + uint16_t whose; struct mmap_entry *next; -} __attribute__ ((__packed__)); +}; struct mmap_entry *mmap_start; void *allocate_block(uint32_t size, uint16_t proc_n); |