summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/ints.txt19
-rw-r--r--fs-skel/sys/startup.rc1
-rw-r--r--makefile117
-rw-r--r--qemu-debug.gdb2
-rw-r--r--src/kernel/elf-link.ld2
-rw-r--r--src/kernel/idt.c40
-rw-r--r--src/kernel/isrs.asm2
-rw-r--r--src/kernel/log.c2
-rw-r--r--src/kernel/main.c23
-rw-r--r--src/kernel/task.c3
-rw-r--r--src/user/hello/hello.c2
-rw-r--r--src/user/include/knob/format.h1
-rw-r--r--src/user/include/pland/syscall.h27
-rw-r--r--src/user/init/init.c (renamed from src/user/init/main.c)2
-rw-r--r--src/user/knob/format.c18
-rw-r--r--src/user/meminfo/meminfo.c19
16 files changed, 187 insertions, 93 deletions
diff --git a/doc/ints.txt b/doc/ints.txt
index 2a97049..cd91f60 100644
--- a/doc/ints.txt
+++ b/doc/ints.txt
@@ -11,6 +11,7 @@ args in ebx, ecx, edx, esi, edi
result in eax
note: do not assume eax is unmodified if there is no value to be returned
modifies ecx, edx
+see table 1
file system calls have units of bytes unless otherwise specified
functions returning handles or pointers use 0 to indicate error
@@ -20,6 +21,8 @@ see keys.txt for the return type of the "get key" system call
invalid system call numbers change eax to -1, and have no other effect.
+table 1:
+
function | eax | eax out | ebx | ecx | edx | esi | edi
---------------|-----|---------------|---------------|-------------|-------|--------|-----
open file | 0x0 | handle | drive number | path | | |
@@ -29,4 +32,18 @@ invalid system call numbers change eax to -1, and have no other effect.
start task | 0x4 | success | drive number | path | | |
log string | 0x5 | | sz string | | | |
get key | 0x6 | keycode | | | | |
- allocate ram | 0x7 | start pointer | pages | | | | \ No newline at end of file
+ allocate ram | 0x7 | start pointer | pages | | | |
+ memory info | 0x8 | see table 2 | see table 2 | | | |
+
+
+table 2:
+all values are in units of pages
+eax -1 indicates unrecognized ebx
+
+ ebx | eax out
+-----|--------------------------
+ 0x0 | kernel dynamic area size
+ 0x1 | kernel dynamic area left
+ 0x2 | total userspace size
+ 0x3 | total userspace left
+ 0x4 | this process memory left \ No newline at end of file
diff --git a/fs-skel/sys/startup.rc b/fs-skel/sys/startup.rc
index 7d0f8f8..c13d593 100644
--- a/fs-skel/sys/startup.rc
+++ b/fs-skel/sys/startup.rc
@@ -1 +1,2 @@
+BIN/MEMINFO.ELF
BIN/HELLO.ELF \ No newline at end of file
diff --git a/makefile b/makefile
index 07e10f2..8ddce57 100644
--- a/makefile
+++ b/makefile
@@ -1,5 +1,13 @@
-disk: kernel boot skel init hello
- mkdir -p obj out
+kgccargs = -Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=malloc -m32 -Og -ffreestanding -fno-asynchronous-unwind-tables
+ugccargs = ${kgccargs} -Isrc/user/include
+nasmargs = -f elf32
+partlink = -r -m elf_i386
+
+out/disk.vdi: out/disk.img
+ VBoxManage convertfromraw out/disk.img out/disk.vdi --uuid a61929ed-3bf2-45ff-b98a-44f87c616dba
+
+out/disk.img: out/kernel.bin out/boot.bin out/fs
+ mkdir -p obj
/sbin/mkfs.fat -C -f 1 -F 16 -n "PORTLAND OS" -R 65 -s 1 -S 512 obj/shadow.img 8192
echo -n -e '\xeb\x3c' > obj/jmp.bin
dd if=obj/jmp.bin of=obj/shadow.img obs=2 conv=notrunc
@@ -8,78 +16,59 @@ disk: kernel boot skel init hello
mv obj/shadow.img out/disk.img
mcopy -i out/disk.img -s out/fs/* ::/
-vdi-file: disk
- VBoxManage convertfromraw out/disk.img out/disk.vdi --uuid a61929ed-3bf2-45ff-b98a-44f87c616dba
-
-debug: disk
+debug: out/disk.img
gdb -x qemu-debug.gdb
clean:
rm -r obj out || true
-skel:
- mkdir -p out/fs
+out/fs: obj/hello.elf obj/init.elf obj/meminfo.elf
+ mkdir -p out/fs/bin
cp -r fs-skel/* out/fs/
+ objcopy -S obj/hello.elf out/fs/bin/hello.elf
+ objcopy -S obj/init.elf out/fs/bin/init.elf
+ objcopy -S obj/meminfo.elf out/fs/bin/meminfo.elf
+
+obj/kernel/%.ko: src/kernel/%.c
+ mkdir -p $(shell dirname $@)
+ gcc ${kgccargs} -c $< -o $@
+
+obj/kernel/%.kao: src/kernel/%.asm
+ mkdir -p $(shell dirname $@)
+ nasm ${nasmargs} $< -o $@
+
+out/kernel.bin: obj/kernel/drive.ko obj/kernel/fat.ko obj/kernel/ide.ko \
+ obj/kernel/idt.ko obj/kernel/log.ko obj/kernel/main.ko \
+ obj/kernel/main2.ko obj/kernel/pmap.ko obj/kernel/paging.ko \
+ obj/kernel/panic.ko obj/kernel/pci.ko obj/kernel/elf.ko \
+ obj/kernel/serial.ko obj/kernel/task.ko obj/kernel/util.ko \
+ obj/kernel/vga.ko obj/kernel/isrs.kao
+ mkdir -p out
+ ld -T src/kernel/elf-link.ld obj/kernel/* -o obj/kernel.elf
+ objcopy -O binary obj/kernel.elf out/kernel.bin
-kgccargs = -Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=malloc -m32 -Og -ffreestanding -fno-asynchronous-unwind-tables
-ugccargs = ${kgccargs} -Isrc/user/include
-nasmargs = -f elf32
-partlink = -r -m elf_i386
-
-init: knob
- mkdir -p obj/init out/fs/bin
-
- gcc ${ugccargs} -c src/user/init/main.c -o obj/init/main.o
-
- ld -T src/user/elf.ld obj/init/main.o obj/knob.o -o obj/init.elf
- objcopy -S obj/init.elf out/fs/bin/init.elf
-
-hello: knob
- mkdir -p obj/hello out/fs/bin
-
- gcc ${ugccargs} -c src/user/hello/hello.c -o obj/hello/hello.o
-
- ld -T src/user/elf.ld obj/hello/hello.o obj/knob.o -o obj/hello.elf
- objcopy -S obj/hello.elf out/fs/bin/hello.elf
-
-knob:
- mkdir -p obj/knob
+out/boot.bin: src/boot.asm
+ mkdir -p out
+ nasm src/boot.asm -o out/boot.bin
- gcc ${ugccargs} -c src/user/knob/env.c -o obj/knob/env.o
- gcc ${ugccargs} -c src/user/knob/file.c -o obj/knob/file.o
- gcc ${ugccargs} -c src/user/knob/format.c -o obj/knob/format.o
- gcc ${ugccargs} -c src/user/knob/heap.c -o obj/knob/heap.o
- gcc ${ugccargs} -c src/user/knob/quit.c -o obj/knob/quit.o
- gcc ${ugccargs} -c src/user/knob/user.c -o obj/knob/user.o
- gcc ${ugccargs} -c src/user/knob/task.c -o obj/knob/task.o
- nasm ${nasmargs} src/user/knob/entry.asm -o obj/knob/entry.o
+obj/%.o: src/user/%.c
+ mkdir -p $(shell dirname $@)
+ gcc ${ugccargs} -c $< -o $@
- ld ${partlink} obj/knob/*.o -o obj/knob.o
+obj/%.ao: src/user/%.asm
+ mkdir -p $(shell dirname $@)
+ nasm ${nasmargs} $< -o $@
-kernel:
- mkdir -p obj/kernel out
+obj/knob.so: obj/knob/env.o obj/knob/file.o obj/knob/format.o \
+ obj/knob/heap.o obj/knob/quit.o obj/knob/user.o \
+ obj/knob/task.o obj/knob/entry.ao
+ ld ${partlink} obj/knob/* -o obj/knob.so
- gcc ${kgccargs} -c src/kernel/drive.c -o obj/kernel/drive.o
- gcc ${kgccargs} -c src/kernel/fat.c -o obj/kernel/fat.o
- gcc ${kgccargs} -c src/kernel/ide.c -o obj/kernel/ide.o
- gcc ${kgccargs} -c src/kernel/idt.c -o obj/kernel/idt.o
- gcc ${kgccargs} -c src/kernel/log.c -o obj/kernel/log.o
- gcc ${kgccargs} -c src/kernel/main.c -o obj/kernel/main.o
- gcc ${kgccargs} -c src/kernel/main2.c -o obj/kernel/main2.o
- gcc ${kgccargs} -c src/kernel/pmap.c -o obj/kernel/pmap.o
- gcc ${kgccargs} -c src/kernel/paging.c -o obj/kernel/paging.o
- gcc ${kgccargs} -c src/kernel/panic.c -o obj/kernel/panic.o
- gcc ${kgccargs} -c src/kernel/pci.c -o obj/kernel/pci.o
- gcc ${kgccargs} -c src/kernel/elf.c -o obj/kernel/elf.o
- gcc ${kgccargs} -c src/kernel/serial.c -o obj/kernel/serial.o
- gcc ${kgccargs} -c src/kernel/task.c -o obj/kernel/task.o
- gcc ${kgccargs} -c src/kernel/util.c -o obj/kernel/util.o
- gcc ${kgccargs} -c src/kernel/vga.c -o obj/kernel/vga.o
- nasm ${nasmargs} src/kernel/isrs.asm -o obj/kernel/isrs.o
+obj/hello.elf: obj/hello/hello.o obj/knob.so
+ ld -T src/user/elf.ld obj/hello/* obj/knob.so -o obj/hello.elf
- ld -T src/kernel/elf-link.ld obj/kernel/*.o -o obj/kernel.elf
- objcopy -O binary obj/kernel.elf out/kernel.bin
+obj/init.elf: obj/init/init.o obj/knob.so
+ ld -T src/user/elf.ld obj/init/* obj/knob.so -o obj/init.elf
-boot:
- mkdir -p out
- nasm src/boot.asm -o out/boot.bin
+obj/meminfo.elf: obj/meminfo/meminfo.o obj/knob.so
+ ld -T src/user/elf.ld obj/meminfo/* obj/knob.so -o obj/meminfo.elf \ No newline at end of file
diff --git a/qemu-debug.gdb b/qemu-debug.gdb
index 3fedd2e..2bb5c40 100644
--- a/qemu-debug.gdb
+++ b/qemu-debug.gdb
@@ -1,8 +1,8 @@
target remote | qemu-system-i386 -m 512 -S -gdb stdio out/disk.img
add-symbol-file obj/kernel.elf
-add-symbol-file obj/init.elf
set disassembly-flavor intel
layout reg
break main
break panic
+break _before_start_task
cont
diff --git a/src/kernel/elf-link.ld b/src/kernel/elf-link.ld
index 10abac0..84d3f92 100644
--- a/src/kernel/elf-link.ld
+++ b/src/kernel/elf-link.ld
@@ -4,7 +4,7 @@ OUTPUT_ARCH(i386)
SECTIONS {
. = 0x00030000;
.text : {
- */main.o(.text)
+ */main.ko(.text)
*(.text)
}
.rodata : {
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
index 31d597f..3d23797 100644
--- a/src/kernel/idt.c
+++ b/src/kernel/idt.c
@@ -6,6 +6,7 @@
#include "panic.h"
#include "task.h"
#include "paging.h"
+#include "pmap.h"
enum {
IDT_PRESENT = 0x80,
@@ -73,6 +74,32 @@ static void *sc_allocate_ram(uint32_t pages) {
return pd_user_allocate_anywhere_writable(active_task->page_directory, pages);
}
+enum mi_arg {
+ MI_KERNEL_MAX,
+ MI_KERNEL_LEFT,
+ MI_USER_MAX,
+ MI_USER_LEFT,
+ MI_TASK_LEFT
+};
+
+__attribute__ ((pure))
+static uint32_t sc_memory_info(enum mi_arg arg) {
+ switch (arg) {
+ case MI_KERNEL_MAX:
+ return max_kernel_pages;
+ case MI_KERNEL_LEFT:
+ return kernel_pages_left;
+ case MI_USER_MAX:
+ return max_user_pages;
+ case MI_USER_LEFT:
+ return user_pages_left;
+ case MI_TASK_LEFT:
+ panic("TODO: this process memory left");
+ default:
+ return -1;
+ }
+}
+
void const *syscall_table[] = {
&sc_open_file,
&sc_close_file,
@@ -81,14 +108,17 @@ void const *syscall_table[] = {
&sc_start_task,
&sc_log_string,
&sc_get_key,
- &sc_allocate_ram
+ &sc_allocate_ram,
+ &sc_memory_info
};
-extern void syscall_isr;
-extern void quit_isr;
-extern void yield_isr;
+typedef void isr_t;
+
+extern isr_t syscall_isr;
+extern isr_t quit_isr;
+extern isr_t yield_isr;
-static void register_int(uint8_t n, void *isr, uint8_t dpl) {
+static void register_int(uint8_t n, isr_t *isr, uint8_t dpl) {
idt[n].addr_low = (uint32_t)isr & 0xffff;
idt[n].addr_high = (uint32_t)isr >> 16;
idt[n].cs = 0x10;
diff --git a/src/kernel/isrs.asm b/src/kernel/isrs.asm
index 1fd6fcb..82c17fe 100644
--- a/src/kernel/isrs.asm
+++ b/src/kernel/isrs.asm
@@ -11,7 +11,7 @@ extern active_task
extern delete_task
extern advance_active_task
-n_syscalls equ 8
+n_syscalls equ 0x9
section .text
syscall_isr:
diff --git a/src/kernel/log.c b/src/kernel/log.c
index 39fc1ba..b5a96cb 100644
--- a/src/kernel/log.c
+++ b/src/kernel/log.c
@@ -12,6 +12,8 @@ static const uint8_t log_mode_colors[] = {
void set_log_mode(enum log_mode mode) {
vga_set_color(log_mode_colors[mode]);
+ vga_printch('\n');
+ vga_printch('\n');
}
void logch(char ch) {
diff --git a/src/kernel/main.c b/src/kernel/main.c
index 2f63d71..d99b595 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -124,30 +124,25 @@ void main() {
logch('\n');
}
- if (!try_elf_run(drives, "BIN/INIT.ELF"))
- panic("Failed to load init program.");
-
if (BOOT_INFO->support_flags & BIS_PAE)
- logsz("Processor supports PAE (but Portland OS does not yet).\n\n");
+ logsz("Processor supports PAE (but Portland OS does not yet).\n");
else
- logsz("Processor does not support PAE.\n\n");
+ logsz("Processor does not support PAE.\n");
- u32_dec(kernel_pages_left * 4, nbuf);
- logsz(nbuf);
- logsz("k / ");
+ logsz("Kernel dynamic area size: ");
u32_dec(max_kernel_pages * 4, nbuf);
logsz(nbuf);
- logsz("k kernel heap free.\n");
- u32_dec(user_pages_left * 4, nbuf);
- logsz(nbuf);
- logsz("k / ");
+ logsz("k\nUserspace area size: ");
u32_dec(max_user_pages * 4, nbuf);
logsz(nbuf);
- logsz("k user memory free.\n");
+ logsz("k\n\n");
+
+ if (!try_elf_run(drives, "BIN/INIT.ELF"))
+ panic("Failed to load init program.");
init_idt();
+ logsz("Switching to init task.\n");
set_log_mode(LOG_USER);
- logch('\n');
_start_user_mode();
} \ No newline at end of file
diff --git a/src/kernel/task.c b/src/kernel/task.c
index 80818a7..2a1f4c4 100644
--- a/src/kernel/task.c
+++ b/src/kernel/task.c
@@ -79,9 +79,8 @@ void advance_active_task() {
if (++active_task == tasks + MAX_TASKS)
active_task = tasks;
if (active_task == prev_task) {
- logch('\n');
set_log_mode(LOG_SYSTEM);
- logsz("\nNo active tasks, halting.");
+ logsz("No active tasks, halting.");
while (1)
asm ("hlt");
}
diff --git a/src/user/hello/hello.c b/src/user/hello/hello.c
index 65e23f0..00d33b5 100644
--- a/src/user/hello/hello.c
+++ b/src/user/hello/hello.c
@@ -1,5 +1,5 @@
#include <knob/user.h>
void main() {
- tell_user_sz("\nHello, world!\nThis is a userspace program that has been started by init.");
+ tell_user_sz("Hello, world!\n");
} \ No newline at end of file
diff --git a/src/user/include/knob/format.h b/src/user/include/knob/format.h
index 16d3d83..6c4aa5d 100644
--- a/src/user/include/knob/format.h
+++ b/src/user/include/knob/format.h
@@ -5,5 +5,6 @@
#include <stdint.h>
bool try_sntoi(const char *s, uint32_t n, uint32_t *out);
+void itosz(uint32_t i, char *out);
#endif \ No newline at end of file
diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h
index 5858d16..298fc51 100644
--- a/src/user/include/pland/syscall.h
+++ b/src/user/include/pland/syscall.h
@@ -7,6 +7,8 @@
typedef uint32_t _file_handle_t;
typedef uint32_t _task_handle_t;
typedef uint32_t _drive_number_t;
+typedef uint32_t _pages_t;
+
typedef enum {
_KEY_BACKSPACE = '\b',
_KEY_RETURN = '\n',
@@ -40,7 +42,8 @@ enum _scn {
_SCN_START_TASK,
_SCN_LOG_STRING,
_SCN_GET_KEY,
- _SCN_ALLOCATE_RAM
+ _SCN_ALLOCATE_RAM,
+ _SCN_MEMORY_INFO
};
static inline uint32_t _sc0(enum _scn eax) {
@@ -133,8 +136,28 @@ static inline _key_code_t _get_key() {
return _sc0(_SCN_GET_KEY);
}
-static inline void *_allocate_ram(uint32_t pages) {
+static inline void *_allocate_ram(_pages_t pages) {
return (void *)_sc1(_SCN_ALLOCATE_RAM, pages);
}
+static inline _pages_t _kernel_dynamic_area_size() {
+ return _sc1(_SCN_MEMORY_INFO, 0x0);
+}
+
+static inline _pages_t _kernel_dynamic_area_left() {
+ return _sc1(_SCN_MEMORY_INFO, 0x1);
+}
+
+static inline _pages_t _total_userspace_size() {
+ return _sc1(_SCN_MEMORY_INFO, 0x2);
+}
+
+static inline _pages_t _total_userspace_left() {
+ return _sc1(_SCN_MEMORY_INFO, 0x3);
+}
+
+static inline _pages_t _this_process_memory_left() {
+ return _sc1(_SCN_MEMORY_INFO, 0x4);
+}
+
#endif \ No newline at end of file
diff --git a/src/user/init/main.c b/src/user/init/init.c
index c301a78..b8536be 100644
--- a/src/user/init/main.c
+++ b/src/user/init/init.c
@@ -5,7 +5,7 @@
void main() {
struct file *f = open_file("SYS/STARTUP.RC");
if (!f) {
- tell_user_sz("\nCould not open SYS/STARTUP.RC");
+ tell_user_sz("Could not open SYS/STARTUP.RC\n");
return;
}
diff --git a/src/user/knob/format.c b/src/user/knob/format.c
index f55e857..087f6fd 100644
--- a/src/user/knob/format.c
+++ b/src/user/knob/format.c
@@ -10,4 +10,22 @@ bool try_sntoi(const char *s, uint32_t n, uint32_t *out) {
}
*out = calc;
return true;
+}
+
+void itosz(uint32_t i, char *out) {
+ if (!i) {
+ *(uint16_t *)out = (uint16_t)'0';
+ return;
+ }
+ bool zero = false;
+ for (uint32_t m = 1000000000; m; m /= 10) {
+ uint8_t d = (i / m) % 10;
+ if (zero)
+ *(out++) = d + '0';
+ else if (d) {
+ zero = true;
+ *(out++) = d + '0';
+ }
+ }
+ *out = '\0';
} \ No newline at end of file
diff --git a/src/user/meminfo/meminfo.c b/src/user/meminfo/meminfo.c
new file mode 100644
index 0000000..dd1d371
--- /dev/null
+++ b/src/user/meminfo/meminfo.c
@@ -0,0 +1,19 @@
+#include <pland/syscall.h>
+#include <knob/user.h>
+#include <knob/format.h>
+
+void main() {
+ char nbuf[11];
+
+ tell_user_sz("Kernel dynamic memory remaining: ");
+
+ itosz(_kernel_dynamic_area_left() * 4, nbuf);
+ tell_user_sz(nbuf);
+ tell_user_sz("k\n");
+
+ tell_user_sz("Userspace memory remaining: ");
+
+ itosz(_total_userspace_left() * 4, nbuf);
+ tell_user_sz(nbuf);
+ tell_user_sz("k\n");
+} \ No newline at end of file