minor changes, redoing makefile, meminfo program
This commit is contained in:
parent
73bb0e4864
commit
b8284137d4
16 changed files with 192 additions and 98 deletions
19
doc/ints.txt
19
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 | | | |
|
||||
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
|
|
@ -1 +1,2 @@
|
|||
BIN/MEMINFO.ELF
|
||||
BIN/HELLO.ELF
|
117
makefile
117
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
|
||||
|
||||
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
|
||||
obj/kernel/%.ko: src/kernel/%.c
|
||||
mkdir -p $(shell dirname $@)
|
||||
gcc ${kgccargs} -c $< -o $@
|
||||
|
||||
init: knob
|
||||
mkdir -p obj/init out/fs/bin
|
||||
obj/kernel/%.kao: src/kernel/%.asm
|
||||
mkdir -p $(shell dirname $@)
|
||||
nasm ${nasmargs} $< -o $@
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
ld ${partlink} obj/knob/*.o -o obj/knob.o
|
||||
|
||||
kernel:
|
||||
mkdir -p obj/kernel out
|
||||
|
||||
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
|
||||
|
||||
ld -T src/kernel/elf-link.ld obj/kernel/*.o -o obj/kernel.elf
|
||||
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
|
||||
|
||||
boot:
|
||||
out/boot.bin: src/boot.asm
|
||||
mkdir -p out
|
||||
nasm src/boot.asm -o out/boot.bin
|
||||
|
||||
obj/%.o: src/user/%.c
|
||||
mkdir -p $(shell dirname $@)
|
||||
gcc ${ugccargs} -c $< -o $@
|
||||
|
||||
obj/%.ao: src/user/%.asm
|
||||
mkdir -p $(shell dirname $@)
|
||||
nasm ${nasmargs} $< -o $@
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
|
@ -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
|
||||
|
|
|
@ -4,7 +4,7 @@ OUTPUT_ARCH(i386)
|
|||
SECTIONS {
|
||||
. = 0x00030000;
|
||||
.text : {
|
||||
*/main.o(.text)
|
||||
*/main.ko(.text)
|
||||
*(.text)
|
||||
}
|
||||
.rodata : {
|
||||
|
|
|
@ -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;
|
||||
|
||||
static void register_int(uint8_t n, void *isr, uint8_t dpl) {
|
||||
extern isr_t syscall_isr;
|
||||
extern isr_t quit_isr;
|
||||
extern isr_t yield_isr;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -124,30 +124,25 @@ void main() {
|
|||
logch('\n');
|
||||
}
|
||||
|
||||
if (BOOT_INFO->support_flags & BIS_PAE)
|
||||
logsz("Processor supports PAE (but Portland OS does not yet).\n");
|
||||
else
|
||||
logsz("Processor does not support PAE.\n");
|
||||
|
||||
logsz("Kernel dynamic area size: ");
|
||||
u32_dec(max_kernel_pages * 4, nbuf);
|
||||
logsz(nbuf);
|
||||
logsz("k\nUserspace area size: ");
|
||||
u32_dec(max_user_pages * 4, nbuf);
|
||||
logsz(nbuf);
|
||||
logsz("k\n\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");
|
||||
else
|
||||
logsz("Processor does not support PAE.\n\n");
|
||||
|
||||
u32_dec(kernel_pages_left * 4, nbuf);
|
||||
logsz(nbuf);
|
||||
logsz("k / ");
|
||||
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 / ");
|
||||
u32_dec(max_user_pages * 4, nbuf);
|
||||
logsz(nbuf);
|
||||
logsz("k user memory free.\n");
|
||||
|
||||
init_idt();
|
||||
|
||||
logsz("Switching to init task.\n");
|
||||
set_log_mode(LOG_USER);
|
||||
logch('\n');
|
||||
_start_user_mode();
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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';
|
||||
}
|
19
src/user/meminfo/meminfo.c
Normal file
19
src/user/meminfo/meminfo.c
Normal file
|
@ -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");
|
||||
}
|
Reference in a new issue