diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/files.c | 2 | ||||
-rw-r--r-- | src/kernel/files.h | 4 | ||||
-rw-r--r-- | src/kernel/link.ld | 15 | ||||
-rw-r--r-- | src/kernel/main.c | 194 | ||||
-rw-r--r-- | src/kernel/mem.c | 21 | ||||
-rw-r--r-- | src/kernel/mem.h | 19 | ||||
-rw-r--r-- | src/kernel/misc.c | 46 | ||||
-rw-r--r-- | src/kernel/misc.h | 27 | ||||
-rw-r--r-- | src/kernel/proc.c | 9 | ||||
-rw-r--r-- | src/kernel/proc.h | 4 | ||||
-rw-r--r-- | src/kernel/stub.asm | 76 | ||||
-rw-r--r-- | src/kernel/vga.c | 37 | ||||
-rw-r--r-- | src/kernel/vga.h | 2 |
13 files changed, 319 insertions, 137 deletions
diff --git a/src/kernel/files.c b/src/kernel/files.c index c17edd4..b42638a 100644 --- a/src/kernel/files.c +++ b/src/kernel/files.c @@ -24,7 +24,7 @@ uint16_t open_file(uint8_t *name) { } void close_file(uint16_t handle) { - FILE_HANDLES[handle].first_sector = 0; + file_table[handle].first_sector = 0; } void read_file(uint16_t handle, uint32_t length, void *buffer) { diff --git a/src/kernel/files.h b/src/kernel/files.h index 31ad21f..38e59f1 100644 --- a/src/kernel/files.h +++ b/src/kernel/files.h @@ -22,14 +22,14 @@ OF THIS SOFTWARE. #ifndef FILES_H #define FILES_H -struct file_handle_info { +struct file_info { uint16_t first_sector; uint16_t current_sector; uint8_t *io_buffer; uint32_t position; }; -#define FILE_HANDLES ((struct file_handle_info *)*(uint32_t *)0x0000050c) +struct file_info *file_table; uint16_t open_file(uint8_t *name); void close_file(uint16_t handle); void read_file(uint16_t handle, uint32_t length, void *buffer); diff --git a/src/kernel/link.ld b/src/kernel/link.ld index aeb8974..7d160f2 100644 --- a/src/kernel/link.ld +++ b/src/kernel/link.ld @@ -1,13 +1,8 @@ -MEMORY { - kload : ORIGIN = 0x01000000, LENGTH = 0x01000000 -} - SECTIONS { . = 0x01000000; - .text : { - _start = .; - *(.text) - } >kload - .rodata : { *(.rodata) } >kload - .data : { *(.data) *(.bss) } >kload + .mb_header : ALIGN(8) { *(.mb_header) } + .text : ALIGN(512) { *(.text) } + .rodata : ALIGN(512) { *(.rodata) } + .data : ALIGN(512) { *(.data) } + .bss : ALIGN(512) { *(.bss) } }
\ No newline at end of file diff --git a/src/kernel/main.c b/src/kernel/main.c index 9ad9d1c..74fd8bf 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -21,33 +21,177 @@ OF THIS SOFTWARE. #include "files.h" #include "mem.h" #include "proc.h" -#include "misc.h" - -void _start(void) { - *(uint16_t *)0x0000200e = 0x0000; - - *(uint32_t *)0x0000050c = (uint32_t)allocate_pages(16 * sizeof(struct file_handle_info), 2); - for (struct file_handle_info *i = FILE_HANDLES, *l = FILE_HANDLES + 65536; i < l; ++i) - i->first_sector = 0; - - *(uint32_t *)0x00000510 = (uint32_t)allocate_pages(16 * sizeof(struct proc_info), 2); - for (struct proc_info *i = PROCS, *l = PROCS + 65536; i < l; ++i) - i->memory_start = 0; - - uint16_t pages_free = 0, pages_total = 0; - for (uint16_t *i = MMAP; i < MMAP + 0x1000; ++i) - switch (*i) { - case 1: - continue; - case 0: - ++pages_free; +#include <stdbool.h> + +extern uint32_t info_pointer; + +enum tag_type { + BOOT_COMMAND = 1, + LOADER_NAME = 2, + BOOT_MODULES = 3, + MEMORY_INFO = 4, + BOOT_DEVICE = 5, + MEMORY_MAP = 6, + VBE_INFO = 7, + FBUF_INFO = 8, + ELF_SYMBOLS = 9, + APM_TABLE = 10, + EFI_I386_TABLE = 11, + EFI_AMD64_TABLE = 12, + SMBIOS_TABLE = 13, + RSDP_ACPI1 = 14, + RSDP_ACPI2 = 15, + NETWORK_INFO = 16, + EFI_MEMORY_MAP = 17, + EFI_SERVICES = 18, + EFI_I386_HANDLE = 19, + EFI_AMD64_HANDLE = 20, + IMAGE_BASE_ADDR = 21 +}; + +struct tag_start { + uint32_t type; + uint32_t size; + uint8_t rest; +} __attribute__ ((__packed__)); + +struct boot_device_tag { + uint32_t bios_device; + uint32_t partition; + uint32_t subpartition; +} __attribute__ ((__packed__)); + +enum mem_type { + AVAILABLE = 1, + ACPI = 3, + PRESERVE = 4, + DEFECTIVE = 5 +}; + +struct boot_device_tag boot_device; +bool have_boot_device = false; +bool have_mmap = false; + +enum error_codes { + NO_BOOT_DEVICE = 0, + NO_MMAP = 1, + INSUFF_MEMORY = 2 +}; + +uint32_t main(void) { + uint32_t info_size = *(uint32_t *)info_pointer; + struct tag_start *tag_pointer = (struct tag_start *)(info_pointer + 2); + + while (tag_pointer->type) { + switch (tag_pointer->type) { + + case BOOT_DEVICE: + boot_device = *(struct boot_device_tag *)&tag_pointer->rest; + have_boot_device = true; + put_sz("Boot device: 0x"); + put_32_hex(boot_device.bios_device); + if (boot_device.partition != 0xffffffff) { + put_sz(", 0x"); + put_32_hex(boot_device.partition); + if (boot_device.subpartition != 0xffffffff) { + put_sz(", 0x"); + put_32_hex(boot_device.subpartition); + } + } + put_char('\n'); + break; + + case MEMORY_MAP: + mmap_start = (struct mmap_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; + 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); + 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) { + case AVAILABLE: + put_sz(": usable\n"); + next->whose = FREE; + usable += next->length; + break; + case ACPI: + put_sz(": ACPI info\n"); + next->whose = HARDWARE; + break; + case PRESERVE: + put_sz(": hardware use\n"); + next->whose = HARDWARE; + break; + case DEFECTIVE: + put_sz(": defective\n"); + next->whose = HARDWARE; + break; + default: + put_sz(": unrecognized type, assuming hardware use\n"); + next->whose = HARDWARE; + break; + } + } + next = next->next = (struct mmap_entry *)((uint32_t)next + size); + } + + put_sz("Total usable memory: 0x"); + put_32_hex(usable); + put_char('\n'); + + bool clean; + do { + clean = true; + for (struct mmap_entry *current = mmap_start; current; current = current->next) + for (struct mmap_entry *against = mmap_start; against; against = against->next) + if ((current->base + current->length == against->base) && + (current->whose == against->whose)) { + current->length += against->length; + if (against == mmap_start) + mmap_start = against->next; + else { + for (current = mmap_start; current->next != against; current = current->next) + ; + current->next = against->next; + } + clean = false; + } + } while (clean); + + have_mmap = true; + break; + default: - ++pages_total; + put_sz("Ignoring multiboot tag 0x"); + put_32_hex(tag_pointer->type); + put_char('\n'); + } - put_16(pages_free); - put_sz(" of "); - put_16(pages_total); - put_sz(" pages free.\n"); + tag_pointer = (struct tag_start *)((uint8_t *)tag_pointer + tag_pointer->size); + }; + + if (!have_boot_device) + return NO_BOOT_DEVICE; + if (!have_mmap) + return NO_MMAP; + + if (!((proc_table = allocate_block(sizeof(struct proc_info) * 65536, KERNEL)) && + (file_table = allocate_block(sizeof(struct file_info) * 65536, KERNEL)))) + return INSUFF_MEMORY; + ; put_sz("Welcome to Portland version 0.0.8!\n"); while (1) diff --git a/src/kernel/mem.c b/src/kernel/mem.c index 509c768..6544108 100644 --- a/src/kernel/mem.c +++ b/src/kernel/mem.c @@ -19,23 +19,10 @@ OF THIS SOFTWARE. #include "mem.h" -void *allocate_pages(uint16_t n_pages, uint16_t proc_n) { - for (uint16_t *i = MMAP, *l = MMAP + 0x1000 - proc_n; ++i; i <= l) - outer_for: - if (!*i) { - for (uint16_t j = 1; j < n_pages; ++j) - if (i[j]) { - i += j + 1; - goto outer_for; - } - for (uint16_t j = 0; j < n_pages; ++j) - i[j] = proc_n; - return (void *)((i - MMAP) * 0x1000); - } - return (void *)0; +void *allocate_block(uint32_t size, uint16_t proc_n) { + //TODO } -void deallocate_pages(void *from, uint16_t n_pages) { - for (uint16_t *mb = MMAP + (uint32_t)from / 0x1000, *l = mb + n_pages; mb < l; ++mb) - *mb = 0; +void deallocate_block(void *start) { + //TODO }
\ No newline at end of file diff --git a/src/kernel/mem.h b/src/kernel/mem.h index 2bfb3bf..1eb27bd 100644 --- a/src/kernel/mem.h +++ b/src/kernel/mem.h @@ -22,8 +22,21 @@ OF THIS SOFTWARE. #ifndef MEM_H #define MEM_H -#define MMAP ((uint16_t *)0x00002000) -void *allocate_pages(uint16_t n_pages, uint16_t proc_n); -void deallocate_pages(void *from, uint16_t n_pages); +enum special_mmap_codes { + FREE = 0, + HARDWARE = 1, + KERNEL = 2 +}; + +struct mmap_entry { + uint64_t base; + uint64_t length; + uint32_t whose; + struct mmap_entry *next; +} __attribute__ ((__packed__)); + +struct mmap_entry *mmap_start; +void *allocate_block(uint32_t size, uint16_t proc_n); +void deallocate_block(void *start); #endif
\ No newline at end of file diff --git a/src/kernel/misc.c b/src/kernel/misc.c deleted file mode 100644 index d002345..0000000 --- a/src/kernel/misc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2019 Benji Dial - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS -ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -OF THIS SOFTWARE. -*/ - -#include "misc.h" -#include "vga.h" -#include <stdbool.h> - -void put_16(uint16_t n) { - bool s = false; - if (n / 10000) { - put_char((uint8_t)'0' + n / 10000); - s = true; - } - n %= 10000; - if (n / 1000 || s) { - put_char((uint8_t)'0' + n / 1000); - s = true; - } - n %= 1000; - if (n / 100 || s) { - put_char((uint8_t)'0' + n / 100); - s = true; - } - n %= 100; - if (n / 10 || s) { - put_char((uint8_t)'0' + n / 10); - s = true; - } - put_char((uint8_t)'0' + n % 10); -}
\ No newline at end of file diff --git a/src/kernel/misc.h b/src/kernel/misc.h deleted file mode 100644 index d333f26..0000000 --- a/src/kernel/misc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2019 Benji Dial - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS -ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -OF THIS SOFTWARE. -*/ - -#include <stdint.h> - -#ifndef MISC_H -#define MISC_H - -void put_16(uint16_t n); - -#endif
\ No newline at end of file diff --git a/src/kernel/proc.c b/src/kernel/proc.c index a0fb863..84075d7 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -25,9 +25,10 @@ uint16_t new_proc(uint8_t *file) { uint16_t handle = open_file(file); if (handle) for (uint16_t id = 3; id; ++id) - if (!PROCS[id].memory_start) { + if (!proc_table[id].memory_start) { uint32_t size = get_size(id); - void *mem = PROCS[id].memory_start = allocate_pages(PROCS[id].n_pages = (size - 1) / 4096 + 1, id); + void *mem; + proc_table[id].memory_end = size + (proc_table[id].memory_start = allocate_block(size, id)); read_file(handle, size, mem); close_file(handle); //Process file header and make new process @@ -38,6 +39,6 @@ uint16_t new_proc(uint8_t *file) { } void end_proc(uint16_t id) { - deallocate_pages(PROCS[id].memory_start, PROCS[id].n_pages); - PROCS[id].memory_start = 0; + deallocate_block(proc_table[id].memory_start); + proc_table[id].memory_start = 0; }
\ No newline at end of file diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 893b84e..261ae6b 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -24,10 +24,10 @@ OF THIS SOFTWARE. struct proc_info { void *memory_start; - uint16_t n_pages; + void *memory_end; }; -#define PROCS ((struct proc_info *)*(uint32_t *)0x00000510) +struct proc_info *proc_table; uint16_t new_proc(uint8_t *file); void end_proc(uint16_t id); diff --git a/src/kernel/stub.asm b/src/kernel/stub.asm new file mode 100644 index 0000000..2c097d3 --- /dev/null +++ b/src/kernel/stub.asm @@ -0,0 +1,76 @@ +;Copyright 2019 Benji Dial + +;Permission to use, copy, modify, and/or distribute this +;software for any purpose with or without fee is hereby +;granted, provided that the above copyright notice and this +;permission notice appear in all copies. + +;THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS +;ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +;EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +;INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +;RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +;ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +;ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +;OF THIS SOFTWARE. + +extern main + +section .mb_header +dd 0xe852_50d6;magic +dd 0x0000_0000;architecture - i386 +dd mb_end - $$;length +dd 0x17adaf2a - mb_end + $$;check + +;tags +dw 0x0001;info request +dw 0x0000;flags +dd mb_end - $$ - 16 +dd 5;boot device +dd 6;memory map + +mb_end: + +section .text +bits 32 +_start: + mov dword [info_pointer], ebx + mov esp, stack + call main + mov edx, eax + + mov eax, 0x20f0_20f0 + mov ebx, 0x000b_8000 + mov ecx, 0x000b_8fa0 +clear_screen_loop: + mov dword [ebx], eax + add ebx, 4 + test ebx, ecx + jne clear_screen_loop + + mov dword [0x000b_8000], 0xf072_f045 + mov dword [0x000b_8004], 0xf06f_f072 + mov dword [0x000b_8008], 0xf020_f072 + + mov ebx, 0x000b_8022 +error_number_loop: + mov al, dl + and al, 0x07 + or al, 0x30 + mov byte [ebx], al + sub ebx, 2 + shr edx, 3 + test ebx, 0x000b_800a + jne error_number_loop + + cli +halt: + hlt + jmp halt + +section .bss +global info_pointer +info_pointer resd 1 +resb 0x1000 - $ + $$ +stack:
\ No newline at end of file diff --git a/src/kernel/vga.c b/src/kernel/vga.c index 046dda7..e3e2516 100644 --- a/src/kernel/vga.c +++ b/src/kernel/vga.c @@ -18,6 +18,7 @@ OF THIS SOFTWARE. */ #include "vga.h" +#include <stdbool.h> uint16_t cursor_pos = 0; uint8_t color = 0xf0; @@ -62,6 +63,42 @@ void put_sz(uint8_t *sz) { put_char(*(sz++)); } +void put_16(uint16_t n) { + bool s = false; + if (n / 10000) { + put_char((uint8_t)'0' + n / 10000); + s = true; + } + n %= 10000; + if (n / 1000 || s) { + put_char((uint8_t)'0' + n / 1000); + s = true; + } + n %= 1000; + if (n / 100 || s) { + put_char((uint8_t)'0' + n / 100); + s = true; + } + n %= 100; + if (n / 10 || s) { + put_char((uint8_t)'0' + n / 10); + s = true; + } + put_char((uint8_t)'0' + n % 10); +} + +void put_32_hex(uint32_t n) { + for (uint8_t i = 0; i < 4; ++i) { + put_char(n / 0xf0000000 + (n < 0xa0000000 ? (uint8_t)'0' : (uint8_t)'a' - 1)); + n <<= 4; + } + put_char('_'); + for (uint8_t i = 0; i < 4; ++i) { + put_char(n / 0xf0000000 + (n < 0xa0000000 ? (uint8_t)'0' : (uint8_t)'a' - 1)); + n <<= 4; + } +} + void move_cursor(uint8_t col, uint8_t row) { cursor_pos = (col + row * cols) * 2; } diff --git a/src/kernel/vga.h b/src/kernel/vga.h index 74a5d04..2214f27 100644 --- a/src/kernel/vga.h +++ b/src/kernel/vga.h @@ -25,6 +25,8 @@ OF THIS SOFTWARE. #define VGA_BUFFER ((uint8_t *)0x000b8000) void put_char(uint8_t ch); void put_sz(uint8_t *s); +void put_16(uint16_t n); +void put_32_hex(uint32_t n); void move_cursor(uint8_t col, uint8_t row); void set_color(uint8_t c); |