feat(userspace): add ring-3 runtime startup and syscall wrappers
This commit is contained in:
1 parent
dc5afa0250
commit
b15dfc048a
4 files changed
+186
No files matched your search
+12
@@ -0,0 +1,12 @@
|
|||||||
|
.section .text
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
xorq %rbp, %rbp
|
||||||
|
call main
|
||||||
|
movq %rax, %rdi
|
||||||
|
movq $0, %rax
|
||||||
|
int $0x80
|
||||||
|
1:
|
||||||
|
jmp 1b
|
||||||
|
|
||||||
|
.section .note.GNU-stack, "", @progbits
|
||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
#include "ulib.h"
|
||||||
|
|
||||||
|
static long syscall3(long number, long a1, long a2, long a3)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
__asm__ volatile(
|
||||||
|
"int $0x80"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(number), "D"(a1), "S"(a2), "d"(a3)
|
||||||
|
: "memory", "rcx", "r11");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long userWrite(int fd, const char* buffer, unsigned long length)
|
||||||
|
{
|
||||||
|
return syscall3(sysWrite, fd, (long)buffer, (long)length);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userRead(int fd, char* buffer, unsigned long length)
|
||||||
|
{
|
||||||
|
return syscall3(sysRead, fd, (long)buffer, (long)length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void userExit(int code)
|
||||||
|
{
|
||||||
|
syscall3(sysExit, code, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userYield(void)
|
||||||
|
{
|
||||||
|
return syscall3(sysYield, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userGetpid(void)
|
||||||
|
{
|
||||||
|
return syscall3(sysGetpid, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* userSbrk(long increment)
|
||||||
|
{
|
||||||
|
return (void*)syscall3(sysSbrk, increment, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void userSleep(unsigned long milliseconds)
|
||||||
|
{
|
||||||
|
syscall3(sysSleep, (long)milliseconds, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userOpen(const char* path, unsigned int flags)
|
||||||
|
{
|
||||||
|
return syscall3(sysOpen, (long)path, (long)flags, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userClose(int fd)
|
||||||
|
{
|
||||||
|
return syscall3(sysClose, fd, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userLseek(int fd, long offset, int whence)
|
||||||
|
{
|
||||||
|
return syscall3(sysLseek, fd, offset, whence);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userStat(const char* path, FbStat* out)
|
||||||
|
{
|
||||||
|
return syscall3(sysStat, (long)path, (long)out, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userGetdents(int fd, FbDirent* out, unsigned long length)
|
||||||
|
{
|
||||||
|
return syscall3(sysGetdents, fd, (long)out, (long)length);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userMkdir(const char* path)
|
||||||
|
{
|
||||||
|
return syscall3(sysMkdir, (long)path, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long userUnlink(const char* path)
|
||||||
|
{
|
||||||
|
return syscall3(sysUnlink, (long)path, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long stringLength(const char* text)
|
||||||
|
{
|
||||||
|
unsigned long length = 0;
|
||||||
|
while (text[length])
|
||||||
|
length++;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(const char* text)
|
||||||
|
{
|
||||||
|
userWrite(1, text, stringLength(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
void printDec(long value)
|
||||||
|
{
|
||||||
|
unsigned long magnitude;
|
||||||
|
if (value < 0) {
|
||||||
|
userWrite(1, "-", 1);
|
||||||
|
magnitude = (unsigned long)(-value);
|
||||||
|
} else {
|
||||||
|
magnitude = (unsigned long)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magnitude == 0) {
|
||||||
|
userWrite(1, "0", 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char reversed[24];
|
||||||
|
int length = 0;
|
||||||
|
while (magnitude > 0) {
|
||||||
|
reversed[length++] = (char)('0' + (magnitude % 10));
|
||||||
|
magnitude /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ordered[24];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
ordered[i] = reversed[length - 1 - i];
|
||||||
|
userWrite(1, ordered, (unsigned long)length);
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef FROSTBYTE_ULIB_H
|
||||||
|
#define FROSTBYTE_ULIB_H
|
||||||
|
|
||||||
|
#include "syscall.h"
|
||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
long userWrite(int fd, const char* buffer, unsigned long length);
|
||||||
|
long userRead(int fd, char* buffer, unsigned long length);
|
||||||
|
void userExit(int code);
|
||||||
|
long userYield(void);
|
||||||
|
long userGetpid(void);
|
||||||
|
void* userSbrk(long increment);
|
||||||
|
void userSleep(unsigned long milliseconds);
|
||||||
|
|
||||||
|
long userOpen(const char* path, unsigned int flags);
|
||||||
|
long userClose(int fd);
|
||||||
|
long userLseek(int fd, long offset, int whence);
|
||||||
|
long userStat(const char* path, FbStat* out);
|
||||||
|
long userGetdents(int fd, FbDirent* out, unsigned long length);
|
||||||
|
long userMkdir(const char* path);
|
||||||
|
long userUnlink(const char* path);
|
||||||
|
|
||||||
|
void print(const char* text);
|
||||||
|
void printDec(long value);
|
||||||
|
unsigned long stringLength(const char* text);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
load PT_LOAD FILEHDR PHDRS FLAGS(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = USER_BASE + SIZEOF_HEADERS;
|
||||||
|
|
||||||
|
.text : { *(.text .text.*) } :load
|
||||||
|
.rodata : { *(.rodata .rodata.*) } :load
|
||||||
|
.data : { *(.data .data.*) } :load
|
||||||
|
.bss : { *(.bss .bss.*) *(COMMON) } :load
|
||||||
|
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.comment)
|
||||||
|
*(.note .note.*)
|
||||||
|
*(.eh_frame)
|
||||||
|
*(.eh_frame_hdr)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user