summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/files.c2
-rw-r--r--src/kernel/files.h4
-rw-r--r--src/kernel/link.ld15
-rw-r--r--src/kernel/main.c194
-rw-r--r--src/kernel/mem.c21
-rw-r--r--src/kernel/mem.h19
-rw-r--r--src/kernel/misc.c46
-rw-r--r--src/kernel/misc.h27
-rw-r--r--src/kernel/proc.c9
-rw-r--r--src/kernel/proc.h4
-rw-r--r--src/kernel/stub.asm76
-rw-r--r--src/kernel/vga.c37
-rw-r--r--src/kernel/vga.h2
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);