summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2021-11-26 16:23:32 -0500
committerJon Santmyer <jon@jonsantmyer.com>2021-11-26 16:23:32 -0500
commit8a929b4f450616790f6d43a3078a8c6925264aa2 (patch)
tree842638c2d7ff1b81d06440d0b35d5dcff52cc1b1
parentcfd5c05a4d13519c3d21390ccd7798838f4bf1b5 (diff)
downloadmodit-slim-8a929b4f450616790f6d43a3078a8c6925264aa2.tar.gz
modit-slim-8a929b4f450616790f6d43a3078a8c6925264aa2.tar.bz2
modit-slim-8a929b4f450616790f6d43a3078a8c6925264aa2.zip
add arg processing to ld; padding for printf; shell vfs
-rw-r--r--app/init/ird.c82
-rw-r--r--app/init/ird.h56
-rw-r--r--app/init/main.c2
-rw-r--r--app/init/scheduler.c17
-rw-r--r--app/init/scheduler.h2
-rw-r--r--app/ld/main.c100
-rw-r--r--app/vfs/Makefile12
-rw-r--r--app/vfs/main.c7
m---------kernel0
-rw-r--r--lib/c/stdio/puts.c7
-rw-r--r--lib/c/stdio/vsnprintf.c26
-rw-r--r--root/include/vfs/vfs.h41
12 files changed, 300 insertions, 52 deletions
diff --git a/app/init/ird.c b/app/init/ird.c
index f2f2a30..2de9ca2 100644
--- a/app/init/ird.c
+++ b/app/init/ird.c
@@ -1,29 +1,105 @@
#include "ird.h"
+#include "scheduler.h"
#include <sys/mem.h>
+#include <sys/cid.h>
#include <modit/syscall.h>
#include <modit/task.h>
#include <stdio.h>
DEFN_SYSCALL(initrd, SYSCALL_INITRD_GET)
-struct initrd_file *initrd_head = NULL;
+struct initrd_file *initrd_files = NULL;
+size_t initrd_filesz = 0;
static uintptr_t tar_start;
static uintptr_t tar_end;
+static size_t
+tar_fromoctal(char *s)
+{
+ size_t num = 0;
+ for(; *s; s++) {
+ num *= 8;
+ num += (*s) - '0';
+ }
+
+ return num;
+}
+
+static void
+tar_parse(uintptr_t addr)
+{
+ size_t blocks = 0;
+ size_t filei = 0;
+ struct tar_header *block = (struct tar_header*)addr;
+
+ while(block->name[0] != 0) {
+ size_t filesz = tar_fromoctal(block->size);
+ size_t fileblocks = (filesz + (TAR_BLOCKSIZE - 1)) / TAR_BLOCKSIZE;
+
+ blocks += fileblocks + 1;
+ initrd_filesz++;
+ block = (struct tar_header*)(addr + (blocks * TAR_BLOCKSIZE));
+ }
+
+ initrd_files = malloc(sizeof(struct initrd_file) * initrd_filesz);
+ block = (struct tar_header*)addr;
+ blocks = 0;
+ while(block->name[0] != 0) {
+ size_t filesz = tar_fromoctal(block->size);
+ size_t fileblocks = (filesz + (TAR_BLOCKSIZE - 1)) / TAR_BLOCKSIZE;
+
+ initrd_files[filei].name = block->name;
+ initrd_files[filei].size = filesz;
+ initrd_files[filei].data = (char*)((uintptr_t)block + TAR_BLOCKSIZE);
+
+ printf("FILE %-16s SIZE %8i bytes\n", block->name, filesz);
+
+ blocks += fileblocks + 1;
+ filei++;
+ block = (struct tar_header*)(addr + (blocks * TAR_BLOCKSIZE));
+ }
+}
+
+struct initrd_file*
+ird_get(const char *name)
+{
+ for(size_t i = 0; i < initrd_filesz; i++) {
+ if(!strcmp(name, initrd_files[i].name)) return &initrd_files[i];
+ }
+ return NULL;
+}
+
+static void
+ird_spawn(const char *prg)
+{
+ struct initrd_file *ldfile = ird_get("bin/ld");
+ struct initrd_file *prgfile = ird_get(prg);
+}
+
void
ird_setup(void)
{
uintptr_t irdp = 0;
size_t irds = 0;
-
struct syscall_initrd_data data = { .phys = &irdp, .len = &irds };
+
+ //Detach ird server from init
+ cid_t icid = fork_ghost();
+ if(icid != 0) {
+ scheduler_addctx(root, icid, 0);
+ return;
+ }
+
_syscall_initrd(&data);
tar_end = MODIT_USER_STACK - 0x1000000;
- tar_start = tar_end - irds;
+ tar_start = tar_end - (((irds / 0x1000) + 1) * 0x1000);
for(uintptr_t i = 0; i < irds; i += 0x1000) {
mmap(irdp + i, tar_start + i);
}
+
+ tar_parse(tar_start);
+ ird_spawn("bin/vfs");
}
diff --git a/app/init/ird.h b/app/init/ird.h
index aaa072c..9d0e3b9 100644
--- a/app/init/ird.h
+++ b/app/init/ird.h
@@ -1,7 +1,61 @@
#ifndef INIT_IRD_H
#define INIT_IRD_H 1
-#include "modit/initrd.h"
+#include <stdint.h>
+#include <stddef.h>
+
+#define TAR_LINK_NORMAL '0'
+#define TAR_LINK_HARD '1'
+#define TAR_LINK_SYMB '2'
+
+#define USTAR_TYPE_NORMAL '0'
+#define USTAR_TYPE_HARD '1'
+#define USTAR_TYPE_SYMB '2'
+#define USTAR_TYPE_CHR '3'
+#define USTAR_TYPE_BLK '4'
+#define USTAR_TYPE_DIR '5'
+#define USTAR_TYPE_FIFO '6'
+#define USTAR_TYPE_CONTIG '7'
+
+#define TAR_BLOCKSIZE 512
+
+struct tar_header {
+ char name[100];
+ char mode[8];
+ char oid[8];
+ char gid[8];
+ char size[12];
+ char lmt[12];
+ char checksum[8];
+ char link;
+ char linkname[100];
+};
+
+struct ustar_header {
+ char name[100];
+ char mode[8];
+ char oid[8];
+ char gid[8];
+ char size[12];
+ char lmt[12];
+ char checksum[8];
+ char type;
+ char linkname[100];
+ char ustar[6];
+ char ustarver[2];
+ char oun[32];
+ char ogn[32];
+ char devmajor[8];
+ char devminor[8];
+ char prefix[155];
+};
+
+struct initrd_file {
+ const char *name;
+ char *data;
+ size_t size;
+ char flags;
+};
void ird_setup(void);
diff --git a/app/init/main.c b/app/init/main.c
index a091a5a..348557c 100644
--- a/app/init/main.c
+++ b/app/init/main.c
@@ -13,8 +13,8 @@ main(int argc, char **argv)
{
(void)argc;
(void)argv;
- rpcsrv_setup();
scheduler_setup();
+ rpcsrv_setup();
ird_setup();
rpc_handle(false);
diff --git a/app/init/scheduler.c b/app/init/scheduler.c
index 90eae64..2486194 100644
--- a/app/init/scheduler.c
+++ b/app/init/scheduler.c
@@ -55,6 +55,7 @@ scheduler_addctx(pid_t pid, cid_t id, uint8_t p)
new->next = parent->contexts;
new->cid = id;
new->priority = p;
+ new->scheduled = true;
struct clnode *node = malloc(sizeof(struct clnode));
node->ctx = new;
@@ -103,14 +104,14 @@ scheduler_loop(void)
settimer(20);
swapto(1);
while(1) {
- for(struct clnode *node = list_tail; node; node = node->next) {
- struct context *ctx = node->ctx;
- if(!ctx->scheduled) continue;
- list_current = node;
-
- settimer(PROC_QUANTUM(ctx->priority));
- swapto(ctx->cid);
- }
+ if(list_current == NULL) list_current = list_tail;
+ struct context *ctx = list_current->ctx;
+ list_current = list_current->next;
+
+ if(!ctx->scheduled) continue;
+
+ settimer(PROC_QUANTUM(ctx->priority));
+ swapto(ctx->cid);
//Sort by priority
}
}
diff --git a/app/init/scheduler.h b/app/init/scheduler.h
index 559fb56..7726251 100644
--- a/app/init/scheduler.h
+++ b/app/init/scheduler.h
@@ -1,7 +1,7 @@
#ifndef INIT_SCHEDULER_H
#define INIT_SCHEDULER_H 1
-#define PROC_PRIORITY_MUL 10
+#define PROC_PRIORITY_MUL 5
#define PROC_QUANTUM(l) ((l + 1) * PROC_PRIORITY_MUL)
#include <stdbool.h>
diff --git a/app/ld/main.c b/app/ld/main.c
index 8613a0c..dd00df4 100644
--- a/app/ld/main.c
+++ b/app/ld/main.c
@@ -4,10 +4,10 @@
#include <stddef.h>
static struct stkpack {
- char **argv;
- char **envp;
- char data[];
-} *stack_data;
+ char *argv;
+ char *envp;
+ char *program;
+} stack_data;
DEFN_SYSCALL(print, SYSCALL_PRINT)
void prints(const char *s)
@@ -45,33 +45,66 @@ memset(void *restrict dest, char b, size_t n)
}
int
+strlen(const char *s) {
+ size_t l = 0;
+ while(s[l]) l++;
+ return l;
+}
+
+int
strcmp(char *a, char *b) {
size_t i = 0;
while(a[i] == b[i] && a[i] != 0) i++;
return a[i] - b[i];
}
+#define PUSH(s, v, l) \
+ s -= l; \
+ memcpy((void*)s, (void*)v, l)
+
+#define PUSHV(s, v) \
+ s -= 8; \
+ *((uintptr_t*)s) = (uintptr_t)v
+
void
elf_run(uintptr_t entry)
{
- size_t argc = 0;
- //if(stack_data->argv != NULL)
- // while(stack_data->argv[argc++] != 0);
-
- asm volatile("movq %0, %%rdi; \
- movq %1, %%rsi; \
- movq %2, %%rdx; \
- jmp %3"::
- "r"(stack_data->argv),
- "r"(argc),
- "r"(stack_data->envp),
- "r"(entry): "rdi", "rsi", "rdx");
+ //We need room to place the new program's stack.
+ //Because the program data is already used, we can recycle it
+ uintptr_t nstack = (uintptr_t)stack_data.program;
+
+ //Place argv
+ uintptr_t argvl = nstack;
+ int argc;
+ for(const char *arg = stack_data.argv; *arg; arg += strlen(arg)) {
+ PUSHV(nstack, arg);
+ argc++;
+ }
+
+ //Place envp
+ uintptr_t envpl = nstack;
+ for(const char *env = stack_data.envp; *env; env += strlen(env)) {
+ PUSHV(nstack, env);
+ }
+
+ //Place argc, [argv], [envp], entry
+ PUSHV(nstack, argvl);
+ PUSHV(nstack, argc );
+ PUSHV(nstack, envpl);
+ PUSHV(nstack, entry);
+
+ asm volatile("\
+ mov %0, %%rsp; \
+ popq %%rax; \
+ popq %%rdx; \
+ popq %%rdi; \
+ popq %%rsi; \
+ jmp %%rax;":: "r"(nstack));
}
void
-elf_parse_exec()
+elf_parse_exec(struct elf64_header *header)
{
- struct elf64_header *header = (struct elf64_header*)stack_data->data;
struct elf64_program_header *phdrs = (struct elf64_program_header*)((uintptr_t)header + header->e_phoff);
for(size_t i = 0; i < header->e_phnum; i++) {
@@ -80,30 +113,43 @@ elf_parse_exec()
alloc(phdr->p_vaddr, phdr->p_memsz);
memset((void*)(phdr->p_vaddr), 0, phdr->p_memsz);
- memcpy((void*)(phdr->p_vaddr), (void*)((uintptr_t)stack_data->data + phdr->p_offset), phdr->p_filesz);
+ memcpy((void*)(phdr->p_vaddr), (void*)((uintptr_t)header + phdr->p_offset), phdr->p_filesz);
}
elf_run(header->e_entry);
}
int
-elf_parse(void)
+elf_parse(struct elf64_header *header)
{
- struct elf64_header *header = (struct elf64_header*)stack_data->data;
-
if(header->e_type == ELF_ET_EXEC) {
- elf_parse_exec();
+ elf_parse_exec(header);
}
prints("Unable to execute unknown ELF type\n");
return -1;
}
int
-main(struct stkpack *data)
+main(char *data)
{
- stack_data = data;
+ char *argv = data;
+ char *envp = data;
+ char *program = data;
+
+ //Loop through NULL-terminated args list
+ for(; *envp; envp += strlen(envp)) prints(envp);
+ envp++;
+
+ //Loop through NULL-terminated envp list
+ program = envp;
+ for(; *program; program += strlen(program)) prints(program);
+ program++;
+
+ stack_data.argv = argv;
+ stack_data.envp = envp;
+ stack_data.program = program;
- struct elf64_header *header = (struct elf64_header*)stack_data->data;
+ struct elf64_header *header = (struct elf64_header*)stack_data.program;
if(!ELF_HEADER_CHECK(header)) {
prints("Passed file is not ELF\n");
@@ -125,5 +171,5 @@ main(struct stkpack *data)
return -4;
}
- return elf_parse();
+ return elf_parse(header);
}
diff --git a/app/vfs/Makefile b/app/vfs/Makefile
new file mode 100644
index 0000000..a172a09
--- /dev/null
+++ b/app/vfs/Makefile
@@ -0,0 +1,12 @@
+CFILES := $(wildcard *.c)
+CFILES += $(wildcard *.s)
+
+CC ?= gcc
+
+WARNS := -Wall -Wextra -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict -Wnull-dereference -Wdouble-promotion -Wshadow -Wcast-align
+CFLAGS := $(WARNS) -static
+OUT := vfs
+
+.PHONY: all
+all: $(CFILES)
+ $(CC) $(CFLAGS) $(CFILES) -o $(IRDDIR)/bin/$(OUT)
diff --git a/app/vfs/main.c b/app/vfs/main.c
new file mode 100644
index 0000000..ab05a67
--- /dev/null
+++ b/app/vfs/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ printf("Hello, World!\n");
+}
diff --git a/kernel b/kernel
-Subproject 6f895bf2b6609a9b98bf8b74a6f7d140f3ed588
+Subproject c070667252e6db6bde6cb6b1d96a0c5bbb52b43
diff --git a/lib/c/stdio/puts.c b/lib/c/stdio/puts.c
new file mode 100644
index 0000000..55a3472
--- /dev/null
+++ b/lib/c/stdio/puts.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int
+puts(const char *s)
+{
+ return prints(s);
+}
diff --git a/lib/c/stdio/vsnprintf.c b/lib/c/stdio/vsnprintf.c
index b5c6a15..edc437b 100644
--- a/lib/c/stdio/vsnprintf.c
+++ b/lib/c/stdio/vsnprintf.c
@@ -7,7 +7,7 @@ static int
__vsnprintf_itoa(char *term, intmax_t val, int base)
{
int size = 0;
- intmax_t dec = 1;
+ uintmax_t dec = 1;
bool neg = false;
if(val < 0) {
val = 0 - val;
@@ -48,14 +48,15 @@ vsnprintf(
}
c++;
//Flags
- bool alternate = false, zero = false, leftadj = false, spaced = false, sign = false;
+ bool alternate = false, zero = false, leftadj = false, sign = false;
+ char padchr = ' ';
while(strchr("#0- +", *c) != NULL) {
switch(*c) {
case '#': alternate = true; break;
- case '0': zero = true; break;
+ case '0': padchr = '0'; zero = true; break;
case '-': leftadj = true; break;
- case ' ': spaced = true; break;
+ case ' ': padchr = ' '; zero = false; break;
case '+': sign = true; break;
}
c++;
@@ -96,13 +97,13 @@ vsnprintf(
intmax_t val = va_arg(ap, intmax_t);
int pwidth = __vsnprintf_itoa(NULL, val, base);
int bufwidth = pwidth > minwidth ? pwidth : minwidth; //Make sure intstr will fit in buffer
+ int leftdist = leftadj == false ? bufwidth - 1 : (zero ? bufwidth - 1 : pwidth - 1); //Horrible left-align shenanigans
if(val < 0 || sign) bufwidth++; //Make room for sign
char buffer[bufwidth];
- if(zero) memset(buffer, '0', bufwidth);
- if(spaced) memset(buffer, ' ', bufwidth);
+ memset(buffer, padchr, bufwidth);
if(val < 0 || sign) //Set sign at top of buffer
buffer[0] = val > 0 ? '+' : '-';
- __vsnprintf_itoa(&buffer[bufwidth - 1], val, base); //Write intstr to buffer starting at end
+ __vsnprintf_itoa(&buffer[leftdist], val, base); //Write intstr to buffer starting at end
if(upper) strupp(buffer);
wrsize += __vsnprintf_copytill(&str[wrsize], buffer, bufwidth, size); //Copy until reaching either bufwidth or size
size -= bufwidth;
@@ -110,10 +111,13 @@ vsnprintf(
case 's': {
const char *val = va_arg(ap, const char*);
int vallen = strlen(val) - 1;
- char buffer[vallen];
- memcpy(buffer, val, vallen);
- wrsize += __vsnprintf_copytill(&str[wrsize], buffer, vallen, size);
- size -= vallen;
+ int bufwidth = vallen > minwidth ? vallen : minwidth;
+ int leftdist = leftadj ? 0 : bufwidth - vallen;
+ char buffer[bufwidth];
+ memset(buffer, padchr, bufwidth);
+ memcpy(buffer + (leftdist), val, vallen);
+ wrsize += __vsnprintf_copytill(&str[wrsize], buffer, bufwidth, size);
+ size -= bufwidth;
} break;
}
}
diff --git a/root/include/vfs/vfs.h b/root/include/vfs/vfs.h
new file mode 100644
index 0000000..7bb0b18
--- /dev/null
+++ b/root/include/vfs/vfs.h
@@ -0,0 +1,41 @@
+#ifndef VFS_VFS_H
+#define VFS_VFS_H 1
+
+#include <sys/cid.h>
+#include <rpc/rpc.h>
+
+#define VFS_FILE_TYPE_FILE 0
+#define VFS_FILE_TYPE_DIR 1
+#define VFS_FILE_TYPE_BLK 2
+
+#define VFS_RPC_OPEN_ARGS "s"
+#define VFS_RPC_OPEN_RET 'i'
+
+#define VFS_RPC_CLOSE_ARGS "i"
+#define VFS_RPC_CLOSE_RET 'i'
+
+#define VFS_RPC_READ_ARGS "vi"
+#define VFS_RPC_READ_RET 'i'
+
+#define VFS_RPC_WRITE_ARGS "vi"
+#define VFS_RPC_WRITE_RET 'i'
+
+typedef struct vfs_file
+{
+ struct vfs_file *next;
+ struct vfs_file *children;
+
+ const char *name;
+ char type;
+ char flags;
+ cid_t driver;
+
+ RPCFUNC *open;
+ RPCFUNC *close;
+ RPCFUNC *read;
+ RPCFUNC *write;
+
+ int dvri;
+} vfs_file_t;
+
+#endif