diff options
author | Alex Auvolat <alex@adnab.me> | 2017-04-21 16:57:00 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2017-04-21 16:57:00 +0200 |
commit | f8334e283c5eb0efeb4bb8a134041e18388d5f01 (patch) | |
tree | 508bc475133262afee1d4a1d9fe7af3f576e2ee9 /src/sysbin | |
parent | ec08d0410730a16836eb40f5e46082b3bbaf45f6 (diff) | |
download | kogata-f8334e283c5eb0efeb4bb8a134041e18388d5f01.tar.gz kogata-f8334e283c5eb0efeb4bb8a134041e18388d5f01.zip |
Lua init
Diffstat (limited to 'src/sysbin')
-rw-r--r-- | src/sysbin/init/main.c | 164 | ||||
-rw-r--r-- | src/sysbin/lx/lxinit.c | 1 | ||||
-rw-r--r-- | src/sysbin/lx/lxioctllib.c | 62 | ||||
-rw-r--r-- | src/sysbin/lx/lxlib.c | 41 | ||||
-rw-r--r-- | src/sysbin/lx/lxlib.h | 10 | ||||
-rw-r--r-- | src/sysbin/lx/lxsyslib.c | 43 | ||||
-rw-r--r-- | src/sysbin/lx/main.c | 38 |
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; } |