aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-10 20:12:10 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-10 20:12:10 +0100
commit6d9cd139c42a48f5ddf8f8e284f56873de73fd31 (patch)
tree7b4ca008eb6375c0d5ba9eb1456674ee996fb5d6
parent4ab8b6206b1ba36cbf4db4a416e04304bbd7ebc0 (diff)
downloadkogata-6d9cd139c42a48f5ddf8f8e284f56873de73fd31.tar.gz
kogata-6d9cd139c42a48f5ddf8f8e284f56873de73fd31.zip
Things are happenning ; lots of bugs.
-rw-r--r--Makefile4
-rw-r--r--README.md3
-rwxr-xr-xmake_cdrom.sh20
-rw-r--r--src/apps/init/main.c55
-rw-r--r--src/common/include/proto/proc.h7
-rw-r--r--src/kernel/core/idt.c2
-rw-r--r--src/kernel/fs/iso9660.c16
-rw-r--r--src/kernel/user/process.c21
-rw-r--r--src/lib/libkogata/debug.c4
-rw-r--r--src/lib/libkogata/syscall.c2
-rw-r--r--src/sysbin/giosrv/Makefile12
-rw-r--r--src/sysbin/giosrv/main.c28
-rw-r--r--src/sysbin/init/Makefile (renamed from src/apps/init/Makefile)2
-rw-r--r--src/sysbin/init/main.c211
-rw-r--r--src/sysbin/linker.ld (renamed from src/apps/linker.ld)0
-rw-r--r--src/sysbin/login/Makefile12
-rw-r--r--src/sysbin/login/main.c19
17 files changed, 336 insertions, 82 deletions
diff --git a/Makefile b/Makefile
index 5a087fb..fc9a1c9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,6 @@
-DIRS = src/common/libkogata src/common/libc src/common/libalgo src/kernel src/lib/libkogata src/apps/init
+DIRS = src/common/libkogata src/common/libc src/common/libalgo \
+ src/kernel src/lib/libkogata \
+ src/sysbin/init src/sysbin/giosrv src/sysbin/login
all:
for dir in $(DIRS); do \
diff --git a/README.md b/README.md
index df36132..742cc37 100644
--- a/README.md
+++ b/README.md
@@ -104,7 +104,8 @@ running the tests):
src/common/ code shared between kernel and userspace libs
src/common/include/proto datastructures & constants used for system calls
src/lib/ code for userspace libraries
- src/apps/ userspace binaries
+ src/lib/include/proto definition of IPC protocols used in the system
+ src/sysbin/ userspace system binaries
src/tests/ test suite
## Roadmap
diff --git a/make_cdrom.sh b/make_cdrom.sh
index d67b3ec..b539273 100755
--- a/make_cdrom.sh
+++ b/make_cdrom.sh
@@ -8,23 +8,29 @@ fi
# Copy system files to CDROM
-cp src/kernel/kernel.bin cdrom; strip cdrom/kernel.bin
-cp src/apps/init/init.bin cdrom; strip cdrom/init.bin
+cp src/kernel/kernel.bin cdrom/boot; strip cdrom/boot/kernel.bin
+cp src/sysbin/init/init.bin cdrom/boot; strip cdrom/boot/init.bin
+
+mkdir -p cdrom/sys/bin
+cp src/sysbin/giosrv/giosrv.bin cdrom/sys/bin
+cp src/sysbin/login/login.bin cdrom/sys/bin
+
+for BIN in cdrom/sys/bin/*.bin; do strip $BIN; done
cp README.md cdrom
# Setup config files
+mkdir -p cdrom/config/default
+
+echo "root:/sys" > cdrom/config/default/sysdir
+
cat > cdrom/boot/grub/menu.lst <<EOF
timeout 10
default 0
title kogata OS
-kernel /kernel.bin root=io:/disk/atapi0 root_opts=l init=root:/init.bin
-
-title kogata OS without root
-kernel /kernel.bin init=io:/mod/init.bin
-module /init.bin
+kernel /boot/kernel.bin root=io:/disk/atapi0 root_opts=l init=root:/boot/init.bin config=default
EOF
# Generate CDROm image
diff --git a/src/apps/init/main.c b/src/apps/init/main.c
deleted file mode 100644
index b351615..0000000
--- a/src/apps/init/main.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <string.h>
-
-#include <malloc.h>
-
-#include <syscall.h>
-#include <debug.h>
-#include <user_region.h>
-
-int main(int argc, char **argv) {
- dbg_print("Hello, world! from user process.\n");
-
- {
- fd_t f = open("io:/", FM_READDIR);
- dbg_printf("openned io:/ as %d\n", f);
- dirent_t x;
- size_t ent_no = 0;
- while (readdir(f, ent_no++, &x)) {
- dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size);
- if (x.st.type == FT_REGULAR) {
- char buf[256];
- strcpy(buf, "io:/");
- strcpy(buf+4, x.name);
- dbg_printf("trying to open %s...\n", buf);
- fd_t ff = open(buf, FM_READ);
- if (ff != 0) {
- dbg_printf("ok, open as %d\n", ff);
- char* cont = malloc(x.st.size + 1);
- dbg_print_region_info();
- read(ff, 0, x.st.size, cont);
- cont[x.st.size] = 0;
- dbg_printf("> '%s'\n", cont);
- close(ff);
- } else {
- dbg_printf("Could not open '%s'\n", buf);
- }
- }
- }
- close(f);
- }
-
- {
- fd_t f = open("root:/", FM_READDIR);
- dbg_printf("openned root:/ as %d\n", f);
- dirent_t x;
- size_t ent_no = 0;
- while (readdir(f, ent_no++, &x)) {
- dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size);
- }
- close(f);
- }
-
- return 0;
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/common/include/proto/proc.h b/src/common/include/proto/proc.h
index 29b5b91..fafb2fd 100644
--- a/src/common/include/proto/proc.h
+++ b/src/common/include/proto/proc.h
@@ -7,9 +7,10 @@ typedef int pid_t;
#define PS_LOADING 1
#define PS_RUNNING 2
-#define PS_FINISHED 3
-#define PS_FAILURE 4 // exception or segfault or stuff
-#define PS_KILLED 5
+#define PS_EXITING 3
+#define PS_FINISHED 4
+#define PS_FAILURE 5 // exception or segfault or stuff
+#define PS_KILLED 6
#define FAIL_EXCEPTION 1 // unhandled processor exception
#define FAIL_ZEROPTR 2 // segfault at < 4k
diff --git a/src/kernel/core/idt.c b/src/kernel/core/idt.c
index eef3ca6..b94695f 100644
--- a/src/kernel/core/idt.c
+++ b/src/kernel/core/idt.c
@@ -122,7 +122,7 @@ void idt_irq_handler(registers_t *regs) {
if (regs->err_code == 0) {
irq0_handler(regs, st);
} else {
- dbg_printf("IRQ%d\n", regs->err_code);
+ dbg_printf("irq%d.", regs->err_code);
if (irq_handlers[regs->err_code] != 0) {
irq_handlers[regs->err_code](regs);
diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c
index 4c1bdd2..4de6f2b 100644
--- a/src/kernel/fs/iso9660.c
+++ b/src/kernel/fs/iso9660.c
@@ -186,8 +186,6 @@ bool iso9660_dir_walk(fs_node_t *n, const char* search_for, struct fs_node *node
size_t filename_len = strlen(search_for);
- dbg_printf("Looking up %s...\n", search_for);
-
size_t dr_len = 0;
for (size_t pos = 0; pos < node->dr.size.lsb; pos += dr_len) {
union {
@@ -206,11 +204,13 @@ bool iso9660_dir_walk(fs_node_t *n, const char* search_for, struct fs_node *node
if (node->fs->use_lowercase) convert_dr_to_lowercase(dr);
char* name = dr->name;
- size_t len = dr->name_len - 2;
+ size_t len = dr->name_len;
+ if (!(dr->flags & ISO9660_DR_FLAG_DIR)) len -= 2;
+
+ if (!(dr->flags & ISO9660_DR_FLAG_DIR) && name[len] != ';') continue;
+ if (name[len-1] == '.') len--; // file with no extension
- if (name[len] != ';') continue;
if (len != filename_len) continue;
-
if (strncmp(name, search_for, len) == 0) {
// Found it !
iso9660_node_t *n = (iso9660_node_t*)malloc(sizeof(iso9660_node_t));
@@ -309,9 +309,11 @@ bool iso9660_dir_readdir(fs_handle_t *h, size_t ent_no, dirent_t *d) {
if (node->fs->use_lowercase) convert_dr_to_lowercase(dr);
char* name = dr->name;
- size_t len = dr->name_len - 2;
+ size_t len = dr->name_len;
+ if (!(dr->flags & ISO9660_DR_FLAG_DIR)) len -= 2;
- if (name[len] != ';') continue;
+ if (!(dr->flags & ISO9660_DR_FLAG_DIR) && name[len] != ';') continue;
+ if (name[len-1] == '.') len--; // file with no extension
if (idx == ent_no) {
// Found the node we are interested in
diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c
index 18b4255..63b568a 100644
--- a/src/kernel/user/process.c
+++ b/src/kernel/user/process.c
@@ -161,13 +161,26 @@ void current_process_exit(int status, int exit_code) {
free(d);
}
+ process_t *p = current_process();
+
+ mutex_lock(&p->lock);
+ if (p->status == PS_EXITING) {
+ mutex_unlock(&p->lock);
+ exit();
+ }
+
+ p->status = PS_EXITING;
+
exit_data_t *d = (exit_data_t*)malloc(sizeof(exit_data_t));
- d->proc = current_process();;
+ d->proc = p;
d->status = status;
d->exit_code = exit_code;
- worker_push(process_exit_v, d);
+ while (!worker_push(process_exit_v, d)) yield();
+
+ mutex_unlock(&p->lock);
+
exit();
}
@@ -184,7 +197,7 @@ void process_exit(process_t *p, int status, int exit_code) {
mutex_lock(&p->lock);
- ASSERT(p->status == PS_RUNNING || p->status == PS_LOADING);
+ ASSERT(p->status == PS_RUNNING || p->status == PS_LOADING || p->status == PS_EXITING);
p->status = status;
p->exit_code = exit_code;
@@ -450,6 +463,8 @@ int proc_add_fd(process_t *p, fs_handle_t *f) {
}
bool proc_add_fd_as(process_t *p, fs_handle_t *f, int fd) {
+ if (fd <= 0) return false;
+
if (hashtbl_find(p->files, (void*)fd) != 0) return false;
if (fd >= p->next_fd) p->next_fd = fd + 1;
diff --git a/src/lib/libkogata/debug.c b/src/lib/libkogata/debug.c
index a8b9414..ac3e0e2 100644
--- a/src/lib/libkogata/debug.c
+++ b/src/lib/libkogata/debug.c
@@ -5,13 +5,13 @@
#include <syscall.h>
void panic(const char* msg, const char* file, int line) {
- dbg_printf("Panic '%s', at %s:%d\n", msg, file, line);
+ dbg_printf("PANIC in user process\n %s\n at %s:%d\n", msg, file, line);
exit(-1);
while(true);
}
void panic_assert(const char* assert, const char* file, int line) {
- dbg_printf("Assert failed '%s', at %s:%d\n", assert, file, line);
+ dbg_printf("ASSERT FAILED in user process\n %s\n at %s:%d\n", assert, file, line);
exit(-1);
while(true);
}
diff --git a/src/lib/libkogata/syscall.c b/src/lib/libkogata/syscall.c
index 67f95fd..bf0b35e 100644
--- a/src/lib/libkogata/syscall.c
+++ b/src/lib/libkogata/syscall.c
@@ -182,7 +182,7 @@ bool bind_make_fs(pid_t pid, const char* name, const char* driver, fd_t source,
return call(SC_BIND_MAKE_FS, (uint32_t)&args, 0, 0, 0, 0);
}
bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd) {
- return call(SC_BIND_FD, new_fd, fd, 0, 0, 0);
+ return call(SC_BIND_FD, pid, new_fd, fd, 0, 0);
}
bool proc_exec(pid_t pid, const char* file) {
return call(SC_PROC_EXEC, pid, (uint32_t)file, strlen(file), 0, 0);
diff --git a/src/sysbin/giosrv/Makefile b/src/sysbin/giosrv/Makefile
new file mode 100644
index 0000000..102bf4c
--- /dev/null
+++ b/src/sysbin/giosrv/Makefile
@@ -0,0 +1,12 @@
+
+OBJ = main.o
+
+LIB = ../../lib/libkogata/libkogata.lib ../../common/libc/libc.lib
+
+CFLAGS = -I ./include -I ../../common/include -I ../../lib/include
+
+LDFLAGS = -T ../linker.ld -Xlinker -Map=giosrv.map
+
+OUT = giosrv.bin
+
+include ../../rules.make
diff --git a/src/sysbin/giosrv/main.c b/src/sysbin/giosrv/main.c
new file mode 100644
index 0000000..ab30664
--- /dev/null
+++ b/src/sysbin/giosrv/main.c
@@ -0,0 +1,28 @@
+#include <string.h>
+
+#include <malloc.h>
+
+#include <syscall.h>
+#include <debug.h>
+#include <user_region.h>
+
+#include <proto/fb.h>
+
+int main(int argc, char **argv) {
+ dbg_print("[giosrv] Starting up.\n");
+
+ fd_t fbdev = open("io:/display/vesa", FM_READ | FM_WRITE | FM_MMAP);
+ if (fbdev == 0) PANIC("Could not open fbdev");
+
+ framebuffer_info_t i;
+ int r = ioctl(fbdev, IOCTL_FB_GET_INFO, &i);
+ dbg_printf("[giosrv] ioctl -> %d\n", r);
+ ASSERT(r == 1);
+ dbg_printf("[giosrv] Running on FB %dx%d\n", i.width, i.height);
+
+ while(true); // nothing to do
+
+ return 0;
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/apps/init/Makefile b/src/sysbin/init/Makefile
index c54bbfb..53a1f45 100644
--- a/src/apps/init/Makefile
+++ b/src/sysbin/init/Makefile
@@ -1,7 +1,7 @@
OBJ = main.o
-LIB = ../../lib/libkogata/libkogata.lib ../../common/libc/libc.lib
+LIB = ../../lib/libkogata/libkogata.lib ../../common/libc/libc.lib ../../common/libalgo/libalgo.lib
CFLAGS = -I ./include -I ../../common/include -I ../../lib/include
diff --git a/src/sysbin/init/main.c b/src/sysbin/init/main.c
new file mode 100644
index 0000000..a2c607d
--- /dev/null
+++ b/src/sysbin/init/main.c
@@ -0,0 +1,211 @@
+#include <string.h>
+#include <printf.h>
+
+#include <malloc.h>
+
+#include <syscall.h>
+#include <debug.h>
+#include <user_region.h>
+
+#include <btree.h>
+
+pid_t giosrv_pid = 0, login_pid = 0;
+fd_pair_t root_gip_chan;
+
+btree_t *parse_cmdline(const char* x) {
+ btree_t *ret = create_btree(str_key_cmp_fun, free_key_val);
+ ASSERT(ret != 0);
+
+ x = strchr(x, ' ');
+ if (x == 0) return ret;
+
+ while ((*x) != 0) {
+ while (*x == ' ') x++;
+
+ char* eq = strchr(x, '=');
+ char* sep = strchr(x, ' ');
+ if (sep == 0) {
+ if (eq == 0) {
+ btree_add(ret, strdup(x), strdup(x));
+ } else {
+ btree_add(ret, strndup(x, eq - x), strdup(eq + 1));
+ }
+ break;
+ } else {
+ if (eq == 0 || eq > sep) {
+ btree_add(ret, strndup(x, sep - x), strndup(x, sep - x));
+ } else {
+ btree_add(ret, strndup(x, eq - x), strndup(eq + 1, sep - eq - 1));
+ }
+ x = sep + 1;
+ }
+ }
+
+ void iter(void* a, void* b) {
+ dbg_printf(" '%s' -> '%s'\n", a, b);
+ }
+ btree_iter(ret, iter);
+
+ return ret;
+}
+
+btree_t* read_cmdline() {
+ char cmdline_buf[256];
+
+ fd_t f = open("io:/cmdline", FM_READ);
+ if (f == 0) return 0;
+
+ size_t len = read(f, 0, 255, cmdline_buf);
+ cmdline_buf[len] = 0;
+
+ close(f);
+
+ return parse_cmdline(cmdline_buf);
+}
+
+void setup_sys() {
+ fd_t sysdir_cfg = open("config:/sysdir", FM_READ);
+ if (sysdir_cfg == 0) PANIC("[init] Could not read config:/sysdir");
+
+ char buf[256];
+ size_t l = read(sysdir_cfg, 0, 255, buf);
+ buf[l] = 0;
+ close(sysdir_cfg);
+
+ char* eol = strchr(buf, '\n');
+ if (eol) *eol = 0;
+
+ dbg_printf("[init] Using system directory %s\n", buf);
+ bool ok;
+
+ char* sep = strchr(buf, ':');
+ if (sep == 0) {
+ ok = fs_subfs("sys", "root", buf, FM_READ | FM_MMAP);
+ } else {
+ *sep = 0;
+ ok = fs_subfs("sys", buf, sep +1, FM_READ | FM_MMAP);
+ }
+
+ if (!ok) PANIC("[init] Could not bind root:/sys to sys:/");
+}
+
+void launch_giosrv() {
+ if (giosrv_pid != 0) return;
+
+ giosrv_pid = new_proc();
+ if (giosrv_pid == 0) {
+ PANIC("[init] Could not create process for giosrv");
+ }
+
+ dbg_printf("[init] Setting up giosrv, pid: %d\n", giosrv_pid);
+
+ bool ok;
+
+ ok = bind_fs(giosrv_pid, "io", "io");
+ if (!ok) PANIC("[init] Could not bind io:/ to giosrv");
+
+ ok = bind_fs(giosrv_pid, "sys", "sys");
+ if (!ok) PANIC("[init] Could not bind sys:/ to giosrv");
+
+ ok = bind_fs(giosrv_pid, "config", "config");
+ if (!ok) PANIC("[init] Could not bind config:/ to giosrv");
+
+ ok = bind_fd(giosrv_pid, 1, root_gip_chan.a);
+ if (!ok) PANIC("[init] Could not bind root GIP channel FD to giosrv");
+
+ ok = proc_exec(giosrv_pid, "sys:/bin/giosrv.bin");
+ if (!ok) PANIC("[init] Could not run giosrv.bin");
+
+ dbg_printf("[init] giosrv started.\n");
+}
+
+void launch_login() {
+ if (login_pid != 0) return;
+
+ login_pid = new_proc();
+ if (login_pid == 0) {
+ PANIC("[init] Could not create process for login");
+ }
+
+ dbg_printf("[init] Setting up login, pid: %d\n", login_pid);
+
+ bool ok;
+
+ ok = bind_fs(login_pid, "root", "root");
+ if (!ok) PANIC("[init] Could not bind root:/ to login");
+
+ ok = bind_fs(login_pid, "sys", "sys");
+ if (!ok) PANIC("[init] Could not bind sys:/ to login");
+
+ ok = bind_fs(login_pid, "config", "config");
+ if (!ok) PANIC("[init] Could not bind config:/ to login");
+
+ ok = bind_fd(login_pid, 1, root_gip_chan.a);
+ if (!ok) PANIC("[init] Could not bind root GIP channel FD to login");
+
+ ok = proc_exec(login_pid, "sys:/bin/login.bin");
+ if (!ok) PANIC("[init] Could not run login.bin");
+
+ dbg_printf("[init] login started.\n");
+}
+
+int main(int argc, char **argv) {
+ dbg_print("[init] Starting up!\n");
+
+ // Read kernel cmdline
+ btree_t *cmdline = read_cmdline();
+ if (cmdline == 0) PANIC("[init] Could not parse cmdline");
+
+ // Later : setup config: and read config file
+ if (btree_find(cmdline, "config") == 0) {
+ PANIC("[init] No config=xxx option specified on command line");
+ } else {
+ char* config = (char*)btree_find(cmdline, "config");
+ dbg_printf("[init] Loading system configuration: %s\n", config);
+ ASSERT(strlen(config) < 30);
+
+ char buf[50];
+ snprintf(buf, 50, "/config/%s", config);
+ bool ok = fs_subfs("config", "root", buf, FM_READ | FM_WRITE | FM_MMAP);
+ if (!ok) PANIC("[init] Could not setup config:");
+ }
+
+ // Setup sys: partition
+ setup_sys();
+
+ // Setup GIP channel for communication between giosrv and login
+ root_gip_chan = make_channel(false);
+ if (root_gip_chan.a == 0 || root_gip_chan.b == 0) {
+ PANIC("[init] Could not create root GIP channel.");
+ }
+
+ // Launch giosrv && login
+ launch_giosrv();
+ launch_login();
+
+ // Make sure no one dies
+ while(true) {
+ proc_status_t s;
+ proc_wait(0, false, &s);
+ if (s.pid != 0) {
+ if (s.pid == giosrv_pid) {
+ giosrv_pid = 0;
+
+ dbg_printf("[init] giosrv died, restarting.\n");
+ launch_giosrv();
+ } else if (s.pid == login_pid) {
+ login_pid = 0;
+
+ dbg_printf("[init] login died, restarting.\n");
+ launch_login();
+ } else {
+ ASSERT(false);
+ }
+ }
+ usleep(1000000);
+ }
+
+ return 0;
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/apps/linker.ld b/src/sysbin/linker.ld
index 50bebbe..50bebbe 100644
--- a/src/apps/linker.ld
+++ b/src/sysbin/linker.ld
diff --git a/src/sysbin/login/Makefile b/src/sysbin/login/Makefile
new file mode 100644
index 0000000..01be4e1
--- /dev/null
+++ b/src/sysbin/login/Makefile
@@ -0,0 +1,12 @@
+
+OBJ = main.o
+
+LIB = ../../lib/libkogata/libkogata.lib ../../common/libc/libc.lib
+
+CFLAGS = -I ./include -I ../../common/include -I ../../lib/include
+
+LDFLAGS = -T ../linker.ld -Xlinker -Map=login.map
+
+OUT = login.bin
+
+include ../../rules.make
diff --git a/src/sysbin/login/main.c b/src/sysbin/login/main.c
new file mode 100644
index 0000000..f92b18c
--- /dev/null
+++ b/src/sysbin/login/main.c
@@ -0,0 +1,19 @@
+#include <string.h>
+
+#include <malloc.h>
+
+#include <syscall.h>
+#include <debug.h>
+#include <user_region.h>
+
+int main(int argc, char **argv) {
+ dbg_print("[login] Starting up.\n");
+
+ usleep(10000000); // pretend we are doing something
+
+ // and now pretend we have exited due to some kind of failure
+
+ return 0;
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/