Compare commits

..

3 Commits

6 changed files with 237 additions and 24 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
USER_PROGRAMS := pedicel.raw apex.raw
USER_FILES := wow.txt
USER_PROGRAMS := pedicel.raw apex.raw doom.raw
USER_FILES := wow.txt doom1.wad
BUILDDIR := build
ELFFILE := pepperk
+10 -12
View File
@@ -2,16 +2,14 @@
The following table contains all of the system calls supported by PepperOS, as well as their arguments. The explanation for what every system call does is available as a comment above each function in corresponding files in the `src/syscall` folder.
Name | Number (%rax) | arg0 (%rdi) | arg1 (%rsi) | arg2 (%rdx) |
|---|---|---|---|---|
| sys_read | 0 | unsigned int fd | char* buf | size_t count |
| sys_write | 1 | unsigned int fd | const char* buf | size_t count |
| sys_open | 2 | const char* filename | int flags | |
| sys_close | 3 | unsigned int fd | | |
| sys_lseek | 8 | unsigned int fd | int offset | int whence |
| sys_tell | 9 | unsigned int fd |
| sys_eof | 10 | unsigned int fd |
Name | Number (%rax) | arg0 (%rdi) | arg1 (%rsi) | arg2 (%rdx) | arg3 (%r10) |
|---|---|---|---|---|---|
| sys_read | 0 | unsigned int fd | char* buf | size_t count | |
| sys_write | 1 | unsigned int fd | const char* buf | size_t count | |
| sys_open | 2 | const char* filename | int flags | | |
| sys_close | 3 | unsigned int fd | | | |
| sys_lseek | 8 | unsigned int fd | int offset | int whence | |
| sys_tell | 9 | unsigned int fd | | | |
| sys_eof | 10 | unsigned int fd | | | |
| sys_draw | 11 | const uint8_t* src | int width | int height | int channels |
| sys_exit | 60 | int error_code | | |
| sys_exit | 60 | int error_code | | | |
+3 -3
View File
@@ -18,15 +18,15 @@
extern struct process* current_process;
int sys_read(unsigned int fd, char* buf, size_t count);
int sys_write(unsigned int fd, const char* buf, size_t count);
int sys_open(const char* filename, int flags);
int sys_close(unsigned int fd);
int sys_lseek(unsigned int fd, int offset, int whence);
int sys_tell(unsigned int fd); // needed by doom, therefore TOP PRIORITY
int sys_eof(unsigned int fd); // same
int sys_read(unsigned int fd, char* buf, size_t count);
int sys_write(unsigned int fd, const char* buf, size_t count);
int sys_exit(int error_code);
int sys_draw(const uint8_t* src, int width, int height, int channels);
int sys_exit(int error_code);
/*
* syscall_handler - System call dispatcher
+12 -2
View File
@@ -1,18 +1,28 @@
CC := x86_64-elf-gcc
CC_FLAGS := -ffreestanding -nostdlib -fno-pic -mno-red-zone -Ilibc
DOOM_CC_FLAGS := $(CC_FLAGS) -std=gnu11
LD := x86_64-elf-ld
BUILDDIR := ../build
LIBDIR := libc
all: pedicel apex
all: pedicel apex doom
.PHONY: pedicel
pedicel:
nasm -f bin pedicel.S -o $(BUILDDIR)/pedicel.raw
.PHONY: apex
apex:
$(CC) $(CC_FLAGS) -c apex.c -o $(BUILDDIR)/apex.o
nasm -f elf64 $(LIBDIR)/crt0.S -o $(BUILDDIR)/crt0.o
$(LD) -T $(LIBDIR)/linker.ld $(BUILDDIR)/crt0.o $(BUILDDIR)/apex.o -o $(BUILDDIR)/apex.elf
objcopy -O binary $(BUILDDIR)/apex.elf $(BUILDDIR)/apex.raw
objcopy -O binary $(BUILDDIR)/apex.elf $(BUILDDIR)/apex.raw
.PHONY: doom
doom:
$(CC) $(DOOM_CC_FLAGS) -c doom.c -o $(BUILDDIR)/doom.o
nasm -f elf64 $(LIBDIR)/crt0.S -o $(BUILDDIR)/crt0.o
$(LD) -T $(LIBDIR)/linker.ld $(BUILDDIR)/crt0.o $(BUILDDIR)/doom.o -o $(BUILDDIR)/doom.elf
objcopy -O binary $(BUILDDIR)/doom.elf $(BUILDDIR)/doom.raw
+147
View File
@@ -0,0 +1,147 @@
#define DOOM_IMPLEMENTATION
#include "PureDOOM.h"
#include <syscall.h>
#include <stdint.h>
//We use a separate heap because malloc is not yet available in userspace.
#define DOOM_HEAP_START ((unsigned char*)0x00500000)
#define DOOM_HEAP_SIZE (24 * 1024 * 1024) //24mb
static unsigned char* doom_heap_curr = DOOM_HEAP_START;
static unsigned char* doom_heap_end = DOOM_HEAP_START + DOOM_HEAP_SIZE;
// The following functions are wrappers for system calls made for
// compatibility with puredoom's function signatures
static int doom_cstr_len(const char* str)
{
int len = 0;
while (str && str[len]) len++;
return len;
}
static void doom_print_cb(const char* str)
{
int len = doom_cstr_len(str);
if (len > 0) {
write(1, str, len);
}
}
static void* doom_open_cb(const char* filename, const char* mode)
{
(void)mode; // open doesn't support flags/mode (yet)
int fd = open(filename, 0);
if (fd < 0) return 0;
return (void*)(intptr_t)(fd);
}
static void doom_close_cb(void* handle)
{
int fd = (int)(intptr_t)handle;
if (fd >= 0) {
close(fd);
}
}
static int doom_read_cb(void* handle, void* buf, int count)
{
int fd = (int)(intptr_t)handle;
if (fd < 0) return -1;
return read(fd, (char*)buf, count);
}
static int doom_write_cb(void* handle, const void* buf, int count)
{
int fd = (int)(intptr_t)handle;
if (fd < 0) return -1;
return (int)write(fd, (const char*)buf, count);
}
static int doom_seek_cb(void* handle, int offset, doom_seek_t origin)
{
int fd = (int)(intptr_t)handle;
if (fd < 0) return -1;
return seek(fd, offset, (int)origin);
}
static int doom_tell_cb(void* handle)
{
int fd = (int)(intptr_t)handle;
if (fd < 0) return -1;
return tell(fd);
}
static int doom_eof_cb(void* handle)
{
int fd = (int)(intptr_t)handle;
if (fd < 0) return 1;
return eof(fd);
}
// Bump allocator (bump ptr until we're out of heap memory)
static void* doom_malloc_cb(int size)
{
if (size <= 0) return 0;
uintptr_t curr = (uintptr_t)doom_heap_curr;
// 16-byte align allocated blocks
curr = (curr + 15ULL) & ~15ULL;
if (curr + (uintptr_t)size > (uintptr_t)doom_heap_end) {
return 0;
}
doom_heap_curr = (unsigned char*)(curr + (uintptr_t)size);
return (void*)curr;
}
// No free
static void doom_free_cb(void* ptr)
{
(void)ptr;
}
static void doom_exit_cb(int code)
{
exit(code);
}
// To get path for the WAD file
static char* doom_getenv_cb(const char* var)
{
static char home[] = "/";
static char waddir[] = "/";
if (!var) return 0;
if (doom_strcmp(var, "HOME") == 0) return home;
if (doom_strcmp(var, "DOOMWADDIR") == 0) return waddir;
return 0;
}
int main()
{
char* argv[2] = {"doom", 0};
// Override default implementations
doom_set_print(doom_print_cb);
doom_set_malloc(doom_malloc_cb, doom_free_cb);
doom_set_file_io(doom_open_cb,
doom_close_cb,
doom_read_cb,
doom_write_cb,
doom_seek_cb,
doom_tell_cb,
doom_eof_cb);
doom_set_exit(doom_exit_cb);
doom_set_getenv(doom_getenv_cb);
doom_init(1, argv, 0);
while (true)
{
doom_force_update();
const uint8_t* framebuffer = doom_get_framebuffer(4);
draw(framebuffer, 320, 200, 4);
}
}
+63 -5
View File
@@ -1,21 +1,79 @@
#pragma once
/*
* @author xamidev <xamidev@riseup.net>
* @brief System call wrappers for userspace
* @license GPL-3.0-only
*/
// 3 because 3 arguments to the call, get it??
#pragma once
// TODO: replace all ifndef/define/endif by pragma once..
#include <stddef.h>
#include <stdint.h>
// 3-args syscall
static inline long syscall3(long n, long a, long b, long c) {
long ret;
__asm__ volatile (
"int $0x80"
: "=a"(ret)
: "a"(n), "D"(a), "S"(b), "d"(c)
: "a"(n), "D"(a), "S"(b), "d"(c) // a = rax, D = rdi, S = rsi, d = rdx
: "memory"
);
return ret;
}
static inline void write(int fd, const char* buf, long len) {
syscall3(1, fd, (long)buf, len);
// 4-args syscall
static inline long syscall4(long n, long a, long b, long c, long d) {
long ret;
register long r10 __asm__("r10") = d;
__asm__ volatile (
"int $0x80"
: "=a"(ret)
: "a"(n), "D"(a), "S"(b), "d"(c), "r"(r10)
: "memory"
);
return ret;
}
// Single-arg syscall
static inline long syscall1(long n, long a) {
return syscall3(n, a, 0, 0);
}
static inline int write(int fd, const char* buf, long len) {
return (int)syscall3(1, fd, (long)buf, len);
}
static inline int read(int fd, char* buf, long len) {
return (int)syscall3(0, fd, (long)buf, len);
}
static inline int open(const char* path, int flags) {
return (int)syscall3(2, (long)path, flags, 0);
}
static inline int close(unsigned int fd) {
return (int)syscall3(3, fd, 0, 0);
}
static inline int seek(int fd, int offset, int whence) {
return (int)syscall3(8, fd, offset, whence);
}
static inline int tell(unsigned int fd) {
return (int)syscall1(9, fd);
}
static inline int eof(unsigned int fd) {
return (int)syscall1(10, fd);
}
static inline int draw(const unsigned char* buf, int width, int height, int channels) {
return (int)syscall4(11, (long)buf, width, height, channels);
}
static inline void exit(int code) {