aboutsummaryrefslogtreecommitdiff
path: root/src/sysbin
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2017-04-21 16:57:00 +0200
committerAlex Auvolat <alex@adnab.me>2017-04-21 16:57:00 +0200
commitf8334e283c5eb0efeb4bb8a134041e18388d5f01 (patch)
tree508bc475133262afee1d4a1d9fe7af3f576e2ee9 /src/sysbin
parentec08d0410730a16836eb40f5e46082b3bbaf45f6 (diff)
downloadkogata-f8334e283c5eb0efeb4bb8a134041e18388d5f01.tar.gz
kogata-f8334e283c5eb0efeb4bb8a134041e18388d5f01.zip
Lua init
Diffstat (limited to 'src/sysbin')
-rw-r--r--src/sysbin/init/main.c164
-rw-r--r--src/sysbin/lx/lxinit.c1
-rw-r--r--src/sysbin/lx/lxioctllib.c62
-rw-r--r--src/sysbin/lx/lxlib.c41
-rw-r--r--src/sysbin/lx/lxlib.h10
-rw-r--r--src/sysbin/lx/lxsyslib.c43
-rw-r--r--src/sysbin/lx/main.c38
7 files changed, 278 insertions, 81 deletions
diff --git a/src/sysbin/init/main.c b/src/sysbin/init/main.c
index ce09f37..e923ab3 100644
--- a/src/sysbin/init/main.c
+++ b/src/sysbin/init/main.c
@@ -9,8 +9,8 @@
#include <kogata/btree.h>
-pid_t giosrv_pid = 0, login_pid = 0;
-fd_pair_t root_gip_chan;
+bool loop_exec = true;
+pid_t giosrv_pid = 0, login_pid = 0, lx_init_pid = 0;
void _parse_cmdline_iter(void* a, void* b) {
dbg_printf(" '%s' -> '%s'\n", a, b);
@@ -90,7 +90,7 @@ void setup_sys() {
if (!ok) PANIC("[init] Could not bind root:/sys to sys:/");
}
-void launch_giosrv() {
+void launch_giosrv(fd_pair_t *root_gip_chan) {
if (giosrv_pid != 0) return;
giosrv_pid = sc_new_proc();
@@ -111,7 +111,7 @@ void launch_giosrv() {
ok = sc_bind_fs(giosrv_pid, "config", "config");
if (!ok) PANIC("[init] Could not bind config:/ to giosrv");
- ok = sc_bind_fd(giosrv_pid, STD_FD_GIOSRV, root_gip_chan.a);
+ ok = sc_bind_fd(giosrv_pid, STD_FD_GIOSRV, root_gip_chan->a);
if (!ok) PANIC("[init] Could not bind root GIP channel FD to giosrv");
ok = sc_proc_exec(giosrv_pid, "sys:/bin/giosrv.bin");
@@ -120,7 +120,7 @@ void launch_giosrv() {
dbg_printf("[init] giosrv started.\n");
}
-void launch_login() {
+void launch_login(fd_pair_t *root_gip_chan) {
if (login_pid != 0) return;
login_pid = sc_new_proc();
@@ -141,7 +141,7 @@ void launch_login() {
ok = sc_bind_fs(login_pid, "config", "config");
if (!ok) PANIC("[init] Could not bind config:/ to login");
- ok = sc_bind_fd(login_pid, STD_FD_GIP, root_gip_chan.b);
+ ok = sc_bind_fd(login_pid, STD_FD_GIP, root_gip_chan->b);
if (!ok) PANIC("[init] Could not bind root GIP channel FD to login");
ok = sc_proc_exec(login_pid, "sys:/bin/login.bin");
@@ -150,30 +150,99 @@ void launch_login() {
dbg_printf("[init] login started.\n");
}
-int main(int argc, char **argv) {
- dbg_print("[init] Starting up!\n");
+void launch_lx_init(const char* lx_init_app, fd_pair_t *io_chan) {
+ if (lx_init_pid != 0) return;
- // Read kernel cmdline
- btree_t *cmdline = read_cmdline();
- if (cmdline == 0) PANIC("[init] Could not parse cmdline");
+ lx_init_pid = sc_new_proc();
+ if (lx_init_pid == 0) {
+ PANIC("[init] Could not create process for lx_init");
+ }
- // setup config:
- 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);
+ dbg_printf("[init] Setting up lx_init, pid: %d\n", lx_init_pid);
- char buf[50];
- snprintf(buf, 50, "/config/%s", config);
- bool ok = sc_fs_subfs("config", "root", buf, FM_READ | FM_WRITE | FM_MMAP | FM_READDIR);
- if (!ok) PANIC("[init] Could not setup config:");
+ bool ok;
+
+ ok = sc_bind_fs(lx_init_pid, "io", "io");
+ if (!ok) PANIC("[init] Could not bind io:/ to lx_init");
+
+ ok = sc_bind_fs(lx_init_pid, "root", "root");
+ if (!ok) PANIC("[init] Could not bind root:/ to lx_init");
+
+ ok = sc_bind_fs(lx_init_pid, "sys", "sys");
+ if (!ok) PANIC("[init] Could not bind sys:/ to lx_init");
+
+ ok = sc_bind_fs(lx_init_pid, "config", "config");
+ if (!ok) PANIC("[init] Could not bind config:/ to lx_init");
+
+ char app_path[256];
+ snprintf(app_path, 256, "/app/%s", lx_init_app);
+
+ ok = sc_bind_subfs(lx_init_pid, "app", "sys", app_path, FM_ALL_MODES);
+ if (!ok) PANIC("[init] Could not bind app:/ to lx_init");
+
+ ok = sc_bind_fd(lx_init_pid, STD_FD_STDOUT, io_chan->b);
+ if (!ok) PANIC("[init] Could not bind stdout channel to lx_init");
+
+ ok = sc_bind_fd(lx_init_pid, STD_FD_STDERR, io_chan->b);
+ if (!ok) PANIC("[init] Could not bind stderr channel to lx_init");
+
+ ok = sc_proc_exec(lx_init_pid, "sys:/bin/lx.bin");
+ if (!ok) PANIC("[init] Could not run lx.bin");
+
+ dbg_printf("[init] lx_init started\n");
+}
+
+void dump_all(fd_t fd) {
+ char buf[256];
+ while(true){
+ int n = sc_read(fd, 0, 255, buf);
+ if (n > 0) {
+ buf[n] = 0;
+ sc_dbg_print(buf);
+ } else {
+ break;
+ }
}
+}
- // Setup sys:
- setup_sys();
+int run_lua(const char* lx_init_app) {
+ // Setup a channel for stdout/stderr printing
+ fd_pair_t io_chan;
+ io_chan = sc_make_channel(false);
+ if (io_chan.a == 0 || io_chan.b == 0) {
+ PANIC("[init] Could not create Lua emergency I/O channel.");
+ }
+
+ launch_lx_init(lx_init_app, &io_chan);
+
+ while(true) {
+ dump_all(io_chan.a);
+
+ proc_status_t s;
+ sc_proc_wait(0, false, &s);
+ if (s.pid != 0) {
+ if (s.pid == lx_init_pid) {
+ if (!loop_exec) {
+ dump_all(io_chan.a);
+ PANIC("[init] lx_init died!\n");
+ }
+
+ lx_init_pid = 0;
+
+ dbg_printf("[init] lx_init_app died, restarting.\n");
+ launch_lx_init(lx_init_app, &io_chan);
+ } else {
+ ASSERT(false);
+ }
+ }
+
+ sc_usleep(100000);
+ }
+}
+int run_no_lua() {
+ fd_pair_t root_gip_chan;
+
// Setup GIP channel for communication between giosrv and login
root_gip_chan = sc_make_channel(false);
if (root_gip_chan.a == 0 || root_gip_chan.b == 0) {
@@ -181,8 +250,8 @@ int main(int argc, char **argv) {
}
// Launch giosrv && login
- launch_giosrv();
- launch_login();
+ launch_giosrv(&root_gip_chan);
+ launch_login(&root_gip_chan);
// Make sure no one dies
while(true) {
@@ -190,21 +259,60 @@ int main(int argc, char **argv) {
sc_proc_wait(0, false, &s);
if (s.pid != 0) {
if (s.pid == giosrv_pid) {
+ if (!loop_exec) PANIC("[init] giosrv died!\n");
+
giosrv_pid = 0;
dbg_printf("[init] giosrv died, restarting.\n");
- launch_giosrv();
+ launch_giosrv(&root_gip_chan);
} else if (s.pid == login_pid) {
+ if (!loop_exec) PANIC("[init] login died!\n");
+
login_pid = 0;
dbg_printf("[init] login died, restarting.\n");
- launch_login();
+ launch_login(&root_gip_chan);
} else {
ASSERT(false);
}
}
sc_usleep(1000000);
}
+}
+
+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");
+
+ // setup config:
+ 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 = sc_fs_subfs("config", "root", buf, FM_READ | FM_WRITE | FM_MMAP | FM_READDIR);
+ if (!ok) PANIC("[init] Could not setup config:");
+ }
+
+ // Setup sys:
+ setup_sys();
+
+ if (btree_find(cmdline, "loop_exec") &&
+ strcmp(btree_find(cmdline, "loop_exec"), "true"))
+ loop_exec = false;
+
+ if (btree_find(cmdline, "lx_init_app")) {
+ run_lua(btree_find(cmdline, "lx_init_app"));
+ } else {
+ run_no_lua();
+ }
return 0;
}
diff --git a/src/sysbin/lx/lxinit.c b/src/sysbin/lx/lxinit.c
index c185b45..b727ccd 100644
--- a/src/sysbin/lx/lxinit.c
+++ b/src/sysbin/lx/lxinit.c
@@ -35,6 +35,7 @@
static const luaL_Reg loadedlibs[] = {
{LX_SYSLIBNAME, lx_open_sys},
{LX_MSGLIBNAME, lx_open_msg},
+ {LX_IOCTLLIBNAME, lx_open_ioctl},
{NULL, NULL}
};
diff --git a/src/sysbin/lx/lxioctllib.c b/src/sysbin/lx/lxioctllib.c
new file mode 100644
index 0000000..4b9be91
--- /dev/null
+++ b/src/sysbin/lx/lxioctllib.c
@@ -0,0 +1,62 @@
+/*
+** Lua eXtended ioctl library
+*/
+
+#define lxioctllib_c
+#define LUA_LIB
+
+#include <lua/lprefix.h>
+
+
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <lua/lua.h>
+
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+
+#include <kogata/syscall.h>
+#include <kogata/gip.h>
+
+#include "lxlib.h"
+
+
+static int ioctl_fb_get_info(lua_State *L) {
+ int fd = luaL_checkinteger(L, 1);
+
+ fb_info_t mode;
+ int r = sc_ioctl(fd, IOCTL_FB_GET_INFO, &mode);
+ if (r == 1) {
+ lua_createtable(L, 0, 5);
+ setintfield(L, "width", mode.width);
+ setintfield(L, "height", mode.height);
+ setintfield(L, "pitch", mode.pitch);
+ setintfield(L, "bpp", mode.bpp);
+ setintfield(L, "memory_model", mode.memory_model);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+
+/* }====================================================== */
+
+static const luaL_Reg ioctllib[] = {
+ {"fb_get_info", ioctl_fb_get_info},
+ {NULL, NULL}
+};
+
+
+LUAMOD_API int lx_open_ioctl (lua_State *L) {
+ luaL_newlib(L, ioctllib);
+ return 1;
+}
+
+
+/* vim: set sts=2 ts=2 sw=2 tw=0 et :*/
diff --git a/src/sysbin/lx/lxlib.c b/src/sysbin/lx/lxlib.c
new file mode 100644
index 0000000..9f6843b
--- /dev/null
+++ b/src/sysbin/lx/lxlib.c
@@ -0,0 +1,41 @@
+/*
+** Lua eXtended library helpers
+*/
+
+#define lxsyslib_c
+#define LUA_LIB
+
+#include <lua/lprefix.h>
+
+
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <lua/lua.h>
+
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+
+#include "lxlib.h"
+
+
+bool lx_checkboolean(lua_State *L, int arg) {
+ if (!lua_isboolean(L, arg)) {
+ luaL_argerror(L, arg, "expected boolean");
+ }
+ return lua_toboolean(L, arg);
+}
+
+
+void setintfield (lua_State *L, const char *key, int value) {
+ lua_pushinteger(L, value);
+ lua_setfield(L, -2, key);
+}
+
+void setstrfield (lua_State *L, const char *key, const char* value) {
+ lua_pushstring(L, value);
+ lua_setfield(L, -2, key);
+}
diff --git a/src/sysbin/lx/lxlib.h b/src/sysbin/lx/lxlib.h
index 199c78d..260db97 100644
--- a/src/sysbin/lx/lxlib.h
+++ b/src/sysbin/lx/lxlib.h
@@ -6,12 +6,18 @@
#include <lua/lua.h>
-#define LX_SYSLIBNAME "lx.sys"
-LUAMOD_API int (lx_open_sys) (lua_State *L);
+// Helper for libraries
+bool lx_checkboolean(lua_State *L, int arg);
+void setintfield (lua_State *L, const char *key, int value);
+void setstrfield (lua_State *L, const char *key, const char* value);
+
#define LX_SYSLIBNAME "lx.sys"
LUAMOD_API int (lx_open_sys) (lua_State *L);
+#define LX_IOCTLLIBNAME "lx.ioctl"
+LUAMOD_API int (lx_open_ioctl) (lua_State *L);
+
#define LX_MSGLIBNAME "lx.msg"
LUAMOD_API int (luaopen_cmsgpack) (lua_State *L);
#define lx_open_msg luaopen_cmsgpack
diff --git a/src/sysbin/lx/lxsyslib.c b/src/sysbin/lx/lxsyslib.c
index 52c6978..72c9882 100644
--- a/src/sysbin/lx/lxsyslib.c
+++ b/src/sysbin/lx/lxsyslib.c
@@ -22,25 +22,6 @@
#include "lxlib.h"
-bool lx_checkboolean(lua_State *L, int arg) {
- if (!lua_isboolean(L, arg)) {
- luaL_argerror(L, arg, "expected boolean");
- }
- return lua_toboolean(L, arg);
-}
-
-
-static void setintfield (lua_State *L, const char *key, int value) {
- lua_pushinteger(L, value);
- lua_setfield(L, -2, key);
-}
-
-static void setstrfield (lua_State *L, const char *key, const char* value) {
- lua_pushstring(L, value);
- lua_setfield(L, -2, key);
-}
-
-
static int sys_dbg_print(lua_State *L) {
const char *str = luaL_checkstring(L, 1);
sc_dbg_print(str);
@@ -68,6 +49,7 @@ static int sys_usleep(lua_State *L) {
Missing syscalls :
- sys_new_thread, exit_thread -> into specific threading library
- mmap, mmap_file, mchmap, munmap -> into specific memory-related library ??
+ - ioctl, fctl -> into ioctl library
*/
static int sys_create(lua_State *L) {
@@ -180,25 +162,10 @@ static int sys_stat_open(lua_State *L) {
return 1;
}
-static int sys_ioctl(lua_State *L) {
- // TODO
- return 0;
-}
-
-static int sys_fctl(lua_State *L) {
- // TODO
- return 0;
-}
-
static int sys_select(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
int nfds = luaL_len(L, 1);
- int timeout;
- if (lua_isinteger(L, 2)) {
- timeout = luaL_checkinteger(L, 2);
- } else {
- timeout = 0;
- }
+ int timeout = luaL_checkinteger(L, 2);
sel_fd_t *fds = (sel_fd_t*)malloc(nfds*sizeof(sel_fd_t));
if (fds == NULL)
@@ -398,6 +365,7 @@ static int sys_proc_wait(lua_State *L) {
return 1;
}
+/* }====================================================== */
static const luaL_Reg syslib[] = {
{"dbg_print", sys_dbg_print},
@@ -414,8 +382,6 @@ static const luaL_Reg syslib[] = {
{"write", sys_write},
{"readdir", sys_readdir},
{"stat_open", sys_stat_open},
- {"ioctl", sys_ioctl},
- {"fctl", sys_fctl},
{"select", sys_select},
{"make_channel",sys_make_channel},
{"make_shm", sys_make_shm},
@@ -438,9 +404,6 @@ static const luaL_Reg syslib[] = {
{NULL, NULL}
};
-/* }====================================================== */
-
-
LUAMOD_API int lx_open_sys (lua_State *L) {
luaL_newlib(L, syslib);
diff --git a/src/sysbin/lx/main.c b/src/sysbin/lx/main.c
index b7e08d9..573e1bb 100644
--- a/src/sysbin/lx/main.c
+++ b/src/sysbin/lx/main.c
@@ -346,12 +346,26 @@ int handle_luainit (lua_State *L) {
}
-/*
-** Main body of stand-alone interpreter (to be called in protected mode).
-** Reads the options and handles them all.
-*/
+bool find_lua_main(lua_State *L) {
+ lua_getglobal(L, "package");
+ if (lua_getfield(L, -1, "searchers") != LUA_TTABLE)
+ luaL_error(L, "'package.searchers' must be a table");
+ lua_remove(L, -2);
+ for (int i = 1; ; i++) {
+ if (lua_rawgeti(L, -1, i) == LUA_TNIL) { /* no more searchers? */
+ lua_pop(L, 2); // pop nil & searchers table
+ return false;
+ }
+ lua_pushstring(L, "main");
+ lua_call(L, 1, 2); /* call it */
+ if (lua_isfunction(L, -2)) /* did it find a loader? */
+ return true; /* module loader found */
+ else
+ lua_pop(L, 2); /* remove both returns */
+ }
+}
+
int pmain (lua_State *L) {
- int status;
luaL_checkversion(L); /* check that interpreter has correct version */
print_version();
@@ -362,18 +376,20 @@ int pmain (lua_State *L) {
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
return 0; /* error running LUA_INIT */
- lua_getglobal(L, "require");
- lua_pushstring(L, "main");
- status = docall(L, 1, 1); /* call 'require("main")' */
- if (status != LUA_OK) {
+ if (find_lua_main(L)) {
+ // call loader
+ lua_pushstring(L, "main");
+ lua_insert(L, -2);
+ lua_call(L, 2, 1);
+ } else {
// no main, launch a REPL
if (lua_stdin_is_tty()) { /* running in interactive mode? */
doREPL(L); /* do read-eval-print loop */
} else {
- dofile(L, NULL); /* executes stdin as a file */
+ dofile(L, NULL); /* executes stdin as a file */
}
+ lua_pushboolean(L, 1); /* signal no errors */
}
- lua_pushboolean(L, 1); /* signal no errors */
return 1;
}