kio++
This commit is contained in:
parent
14fdfdce70
commit
e44d6177a0
2
.buildactions/00_setup.lua
Normal file
2
.buildactions/00_setup.lua
Normal file
@ -0,0 +1,2 @@
|
||||
os.execute("mkdir -p build")
|
||||
os.execute("rm -rf build/*")
|
211
.buildactions/01_velx.lua
Normal file
211
.buildactions/01_velx.lua
Normal file
@ -0,0 +1,211 @@
|
||||
-- VELX builder
|
||||
|
||||
--[[----------------------------------------------------------------------------
|
||||
LZSS - encoder / decoder
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
--]]----------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
local M = {}
|
||||
local string, table = string, table
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local POS_BITS = 12
|
||||
local LEN_BITS = 16 - POS_BITS
|
||||
local POS_SIZE = 1 << POS_BITS
|
||||
local LEN_SIZE = 1 << LEN_BITS
|
||||
local LEN_MIN = 3
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function M.compress(input)
|
||||
local offset, output = 1, {}
|
||||
local window = ''
|
||||
|
||||
local function search()
|
||||
for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
|
||||
local str = string.sub(input, offset, offset + i - 1)
|
||||
local pos = string.find(window, str, 1, true)
|
||||
if pos then
|
||||
return pos, str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while offset <= #input do
|
||||
local flags, buffer = 0, {}
|
||||
|
||||
for i = 0, 7 do
|
||||
if offset <= #input then
|
||||
local pos, str = search()
|
||||
if pos and #str >= LEN_MIN then
|
||||
local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
|
||||
buffer[#buffer + 1] = string.pack('>I2', tmp)
|
||||
else
|
||||
flags = flags | (1 << i)
|
||||
str = string.sub(input, offset, offset)
|
||||
buffer[#buffer + 1] = str
|
||||
end
|
||||
window = string.sub(window .. str, -POS_SIZE)
|
||||
offset = offset + #str
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if #buffer > 0 then
|
||||
output[#output + 1] = string.char(flags)
|
||||
output[#output + 1] = table.concat(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function M.decompress(input)
|
||||
local offset, output = 1, {}
|
||||
local window = ''
|
||||
|
||||
while offset <= #input do
|
||||
local flags = string.byte(input, offset)
|
||||
offset = offset + 1
|
||||
|
||||
for i = 1, 8 do
|
||||
local str = nil
|
||||
if (flags & 1) ~= 0 then
|
||||
if offset <= #input then
|
||||
str = string.sub(input, offset, offset)
|
||||
offset = offset + 1
|
||||
end
|
||||
else
|
||||
if offset + 1 <= #input then
|
||||
local tmp = string.unpack('>I2', input, offset)
|
||||
offset = offset + 2
|
||||
local pos = (tmp >> LEN_BITS) + 1
|
||||
local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
|
||||
str = string.sub(window, pos, pos + len - 1)
|
||||
end
|
||||
end
|
||||
flags = flags >> 1
|
||||
if str then
|
||||
output[#output + 1] = str
|
||||
window = string.sub(window .. str, -POS_SIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output)
|
||||
end
|
||||
|
||||
|
||||
local function struct(tbl)
|
||||
local pat = tbl.endian or "="
|
||||
local args = {}
|
||||
for i=1, #tbl do
|
||||
local a, b = pairs(tbl[i])
|
||||
local k, v = a(b)
|
||||
args[i] = k
|
||||
pat = pat .. v
|
||||
end
|
||||
return setmetatable({}, {__call=function(_, arg)
|
||||
--checkArg(1, arg, "string", "table")
|
||||
if (type(arg) == "string") then
|
||||
local sval = {string.unpack(pat, arg)}
|
||||
local rtn = {}
|
||||
for i=1, #args do
|
||||
rtn[args[i]] = sval[i]
|
||||
end
|
||||
return rtn, sval[#sval]
|
||||
elseif (type(arg) == "table") then
|
||||
local sval = {}
|
||||
for i=1, #args do
|
||||
sval[i] = arg[args[i]]
|
||||
end
|
||||
return string.pack(pat, unpack(sval))
|
||||
end
|
||||
end, __len=function()
|
||||
return string.packsize(pat)
|
||||
end})
|
||||
end
|
||||
|
||||
|
||||
local velx_spec = struct {
|
||||
endian = "<",
|
||||
{magic="c5"},
|
||||
{fver="B"},
|
||||
{compression="B"},
|
||||
{lver="B"},
|
||||
{os="B"},
|
||||
{arctype="c4"},
|
||||
{psize="I3"},
|
||||
{lsize="I3"},
|
||||
{ssize="I3"},
|
||||
{rsize="I4"}
|
||||
}
|
||||
|
||||
local function velx_multistep(path, arcpath, args, steps)
|
||||
local shell_args = ""
|
||||
for k, v in pairs(args) do
|
||||
shell_args = shell_args .. k .. "=\"".. v .."\" "
|
||||
end
|
||||
steps.precomp()
|
||||
local h = io.popen(shell_args.."luacomp "..path, "r")
|
||||
local prog = h:read("*a")
|
||||
h:close()
|
||||
prog = steps.postcomp(prog)
|
||||
steps.prearc()
|
||||
local arc = ""
|
||||
if arcpath then
|
||||
h = io.popen("find "..arcpath.." -depth | tsar -o", "r")
|
||||
arc = h:read("*a")
|
||||
h:close()
|
||||
steps.postarc()
|
||||
end
|
||||
if (not args.noz) then
|
||||
steps.prez()
|
||||
prog = M.compress(prog)
|
||||
steps.postz()
|
||||
end
|
||||
local header = velx_spec({
|
||||
magic = "\27VelX",
|
||||
compression = (args.noz and 0) or 1,
|
||||
lver = 0x53,
|
||||
fver = 1,
|
||||
os = 0x7F,
|
||||
psize = #prog,
|
||||
lsize=0,
|
||||
ssize=0,
|
||||
rsize=#arc,
|
||||
arctype=(arcpath and "tsar") or ""
|
||||
})
|
||||
return header .. prog .. arc
|
||||
end
|
||||
|
||||
local function velx(path, arcpath, args)
|
||||
return velx_multistep(path, arcpath, args, {
|
||||
precomp = function()end,
|
||||
postcomp = function(prog) return prog end,
|
||||
prearc = function()end,
|
||||
postarc = function()end,
|
||||
prez = function()end,
|
||||
postz = function()end,
|
||||
})
|
||||
end
|
50
.buildactions/11_kernel.lua
Normal file
50
.buildactions/11_kernel.lua
Normal file
@ -0,0 +1,50 @@
|
||||
local TSUKI_RELEASE = "0.0.1"
|
||||
local tz = os.date("%z")
|
||||
tz = tz:sub(1, 3)..":"..tz:sub(4)
|
||||
local TSUKI_VERSION = "Lua 5.3 "..os.date("%Y-%m-%dT%H:%M:%S")..tz
|
||||
local TSUKI_TARGET = os.getenv("TSUKI_TARGET") or "OC"
|
||||
|
||||
function actions.kernel(dbg)
|
||||
os.execute("mkdir -p build/kernel")
|
||||
print("Compiling kernel...")
|
||||
local h = io.open("build/kernel/tkrnl.velx", "wb")
|
||||
h:write(velx_multistep("ksrc/init.lua", ".doc", {
|
||||
TSUKI_RELEASE = TSUKI_RELEASE,
|
||||
TSUKI_VERSION = TSUKI_VERSION,
|
||||
TSUKI_TARGET = TSUKI_TARGET,
|
||||
PRINT_DMESG_LEVEL = ((dbg and 0) or 1)
|
||||
}, {
|
||||
precomp = function()
|
||||
print("Compiling kernel...")
|
||||
end,
|
||||
postcomp = function(krnl)
|
||||
os.execute("mkdir .doc")
|
||||
local h = io.open("build/kernel/debug.lua", "w")
|
||||
h:write(krnl)
|
||||
h:close()
|
||||
print("Generating docs and stripping comments...")
|
||||
h = io.popen("lua utils/gendocs.lua .doc 2>.ktmp", "w")
|
||||
h:write(krnl)
|
||||
h:close()
|
||||
h = io.open(".ktmp", "rb")
|
||||
local data = h:read("*a")
|
||||
h:close()
|
||||
os.execute("rm -rf .ktmp")
|
||||
return data
|
||||
end,
|
||||
prearc = function()
|
||||
print("Storing docs...")
|
||||
end,
|
||||
postarc = function()
|
||||
os.execute("rm -rf .doc")
|
||||
end,
|
||||
prez = function()
|
||||
print("Compressing kernel...")
|
||||
end,
|
||||
postz = function()
|
||||
print("Writing kernel out...")
|
||||
end
|
||||
}))
|
||||
end
|
||||
|
||||
actions[#actions+1] = "kernel"
|
7
.buildactions/20_crescent.lua
Normal file
7
.buildactions/20_crescent.lua
Normal file
@ -0,0 +1,7 @@
|
||||
function actions.crescent()
|
||||
os.execute("mkdir -p build/crescent")
|
||||
os.execute("cd extras; lua ../utils/mkvelx.lua crescent/init.lua ../build/crescent/boot.velx")
|
||||
os.execute("cp extras/crescent/bootvelxloader.lua build/crescent/init.lua")
|
||||
end
|
||||
|
||||
actions[#actions+1] = "crescent"
|
7
.buildactions/30_velxboot.lua
Normal file
7
.buildactions/30_velxboot.lua
Normal file
@ -0,0 +1,7 @@
|
||||
function actions.velxboot()
|
||||
os.execute("mkdir -p build/velxboot")
|
||||
os.execute("cd extras; luacomp velxboot/init.lua -O ../build/velxboot/bios.lua")
|
||||
os.execute("cd extras; luacomp velxboot/flashvelxboot.lua -O ../build/velxboot/flashvelxboot.lua")
|
||||
end
|
||||
|
||||
actions[#actions+1] = "velxboot"
|
37
.buildactions/40_coreutils.lua
Normal file
37
.buildactions/40_coreutils.lua
Normal file
@ -0,0 +1,37 @@
|
||||
do
|
||||
--local coreutils = {}
|
||||
--local function add_coreutil(name, outfolder, args)
|
||||
-- args = args or {}
|
||||
-- if not os.execute("[[ -d build/coreutils/"..outfolder.." ]]") then
|
||||
-- os.execute("mkdir -p build/coreutils/"..outfolder)
|
||||
-- end
|
||||
-- actions["coreutil_"..name] = function()
|
||||
-- local data = velx("coreutils/"..name..".lua", nil, args)
|
||||
-- local h = io.open("build/coreutils/"..outfolder.."/"..name..".velx", "w")
|
||||
-- h:write(data)
|
||||
-- h:close()
|
||||
-- end
|
||||
-- coreutils[#coreutils+1] = name
|
||||
--end
|
||||
|
||||
--add_coreutil("init", "sbin")
|
||||
--add_coreutil("shutdown", "sbin")
|
||||
--add_coreutil("sh", "sbin")
|
||||
--add_coreutil("uname", "sbin")
|
||||
|
||||
--function actions.coreutils()
|
||||
-- for i=1, #coreutils do
|
||||
-- actions["coreutil_"..coreutils[i]]()
|
||||
-- end
|
||||
--end
|
||||
local version = "0.1"
|
||||
function actions.coreutils()
|
||||
print("Building coreutils...")
|
||||
os.execute("mkdir -p build/coreutils")
|
||||
local sks = io.open("build/coreutils/sks.velx", "w")
|
||||
sks:write(velx("coreutils/multicall.lua", false, {
|
||||
SKS_COREUTILS_VERSION = version
|
||||
}))
|
||||
end
|
||||
actions[#actions+1] = "coreutils"
|
||||
end
|
5
.buildactions/fe_debug.lua
Normal file
5
.buildactions/fe_debug.lua
Normal file
@ -0,0 +1,5 @@
|
||||
function actions.debug()
|
||||
for i=1, #actions do
|
||||
actions[actions[i]](true)
|
||||
end
|
||||
end
|
5
.buildactions/ff_clean.lua
Normal file
5
.buildactions/ff_clean.lua
Normal file
@ -0,0 +1,5 @@
|
||||
function actions.clean()
|
||||
print("Cleaning up...")
|
||||
--os.execute("rm -rf .docs")
|
||||
--os.execute("rm -rf .ktmp")
|
||||
end
|
235
build.lua
235
build.lua
@ -1,232 +1,21 @@
|
||||
os.execute("mkdir -p build")
|
||||
os.execute("rm -rf build/*")
|
||||
|
||||
--[[----------------------------------------------------------------------------
|
||||
LZSS - encoder / decoder
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
--]]----------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
local M = {}
|
||||
local string, table = string, table
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local POS_BITS = 12
|
||||
local LEN_BITS = 16 - POS_BITS
|
||||
local POS_SIZE = 1 << POS_BITS
|
||||
local LEN_SIZE = 1 << LEN_BITS
|
||||
local LEN_MIN = 3
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function M.compress(input)
|
||||
local offset, output = 1, {}
|
||||
local window = ''
|
||||
|
||||
local function search()
|
||||
for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
|
||||
local str = string.sub(input, offset, offset + i - 1)
|
||||
local pos = string.find(window, str, 1, true)
|
||||
if pos then
|
||||
return pos, str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while offset <= #input do
|
||||
local flags, buffer = 0, {}
|
||||
|
||||
for i = 0, 7 do
|
||||
if offset <= #input then
|
||||
local pos, str = search()
|
||||
if pos and #str >= LEN_MIN then
|
||||
local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
|
||||
buffer[#buffer + 1] = string.pack('>I2', tmp)
|
||||
else
|
||||
flags = flags | (1 << i)
|
||||
str = string.sub(input, offset, offset)
|
||||
buffer[#buffer + 1] = str
|
||||
end
|
||||
window = string.sub(window .. str, -POS_SIZE)
|
||||
offset = offset + #str
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if #buffer > 0 then
|
||||
output[#output + 1] = string.char(flags)
|
||||
output[#output + 1] = table.concat(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function M.decompress(input)
|
||||
local offset, output = 1, {}
|
||||
local window = ''
|
||||
|
||||
while offset <= #input do
|
||||
local flags = string.byte(input, offset)
|
||||
offset = offset + 1
|
||||
|
||||
for i = 1, 8 do
|
||||
local str = nil
|
||||
if (flags & 1) ~= 0 then
|
||||
if offset <= #input then
|
||||
str = string.sub(input, offset, offset)
|
||||
offset = offset + 1
|
||||
end
|
||||
else
|
||||
if offset + 1 <= #input then
|
||||
local tmp = string.unpack('>I2', input, offset)
|
||||
offset = offset + 2
|
||||
local pos = (tmp >> LEN_BITS) + 1
|
||||
local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
|
||||
str = string.sub(window, pos, pos + len - 1)
|
||||
end
|
||||
end
|
||||
flags = flags >> 1
|
||||
if str then
|
||||
output[#output + 1] = str
|
||||
window = string.sub(window .. str, -POS_SIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output)
|
||||
end
|
||||
|
||||
|
||||
local function struct(tbl)
|
||||
local pat = tbl.endian or "="
|
||||
local args = {}
|
||||
for i=1, #tbl do
|
||||
local a, b = pairs(tbl[i])
|
||||
local k, v = a(b)
|
||||
args[i] = k
|
||||
pat = pat .. v
|
||||
end
|
||||
return setmetatable({}, {__call=function(_, arg)
|
||||
--checkArg(1, arg, "string", "table")
|
||||
if (type(arg) == "string") then
|
||||
local sval = {string.unpack(pat, arg)}
|
||||
local rtn = {}
|
||||
for i=1, #args do
|
||||
rtn[args[i]] = sval[i]
|
||||
end
|
||||
return rtn, sval[#sval]
|
||||
elseif (type(arg) == "table") then
|
||||
local sval = {}
|
||||
for i=1, #args do
|
||||
sval[i] = arg[args[i]]
|
||||
end
|
||||
return string.pack(pat, unpack(sval))
|
||||
end
|
||||
end, __len=function()
|
||||
return string.packsize(pat)
|
||||
end})
|
||||
end
|
||||
|
||||
|
||||
local velx_spec = struct {
|
||||
endian = "<",
|
||||
{magic="c5"},
|
||||
{fver="B"},
|
||||
{compression="B"},
|
||||
{lver="B"},
|
||||
{os="B"},
|
||||
{arctype="c4"},
|
||||
{psize="I3"},
|
||||
{lsize="I3"},
|
||||
{ssize="I3"},
|
||||
{rsize="I4"}
|
||||
}
|
||||
local actions = {}
|
||||
|
||||
function actions.kernel()
|
||||
-- This builds Tsuki into a VELX executable.
|
||||
os.execute("mkdir -p build/kernel")
|
||||
print("Compiling kernel...")
|
||||
local h = io.popen("luacomp ksrc/init.lua", "r")
|
||||
local krnl = h:read("*a")
|
||||
h:close()
|
||||
os.execute("luacomp ksrc/init.lua -O build/kernel/debug.lua 2>/dev/null")
|
||||
print("Generating docs and stripping comments...")
|
||||
os.execute("mkdir .docs")
|
||||
h = io.popen("lua utils/gendocs.lua .docs 2>.ktmp", "w")
|
||||
h:write(krnl)
|
||||
h:close()
|
||||
h = io.popen("find .docs -depth | tsar -o", "r")
|
||||
local arc = h:read("*a")
|
||||
h:close()
|
||||
h = io.open(".ktmp", "rb")
|
||||
local data = h:read("*a")
|
||||
h:close()
|
||||
print("Compressing kernel...")
|
||||
data = M.compress(data)
|
||||
print("Writing out tkrnl.velx...")
|
||||
local h = io.open("build/kernel/tkrnl.velx", "wb")
|
||||
local header = velx_spec({
|
||||
magic = "\27VelX",
|
||||
compression = 1,
|
||||
lver = 0x53,
|
||||
fver = 1,
|
||||
os = 0x7F,
|
||||
psize = #data,
|
||||
lsize=0,
|
||||
ssize=0,
|
||||
rsize=#arc,
|
||||
arctype="tsar"
|
||||
})
|
||||
h:write(header)
|
||||
h:write(data)
|
||||
h:write(arc)
|
||||
h:close()
|
||||
end
|
||||
@[[local h = io.popen("ls .buildactions", "r")
|
||||
for line in h:lines() do]]
|
||||
--#include @[{".buildactions/"..line}]
|
||||
@[[end]]
|
||||
|
||||
function actions.crescent()
|
||||
os.execute("mkdir -p build/crescent")
|
||||
os.execute("cd extras; lua ../utils/mkvelx.lua crescent/init.lua ../build/crescent/boot.velx")
|
||||
os.execute("cp extras/crescent/bootvelxloader.lua build/crescent/init.lua")
|
||||
end
|
||||
|
||||
function actions.velxboot()
|
||||
os.execute("mkdir -p build/velxboot")
|
||||
os.execute("cd extras; luacomp velxboot/init.lua -O ../build/velxboot/bios.lua")
|
||||
os.execute("cd extras; luacomp velxboot/flashvelxboot.lua -O ../build/velxboot/flashvelxboot.lua")
|
||||
end
|
||||
|
||||
function actions.clean()
|
||||
print("Cleaning up...")
|
||||
os.execute("rm -rf .docs")
|
||||
os.execute("rm -rf .ktmp")
|
||||
end
|
||||
|
||||
function actions.all()
|
||||
actions.kernel()
|
||||
--[[function actions.debug()
|
||||
actions.kernel(true)
|
||||
actions.crescent()
|
||||
actions.velxboot()
|
||||
actions.clean()
|
||||
end]]
|
||||
|
||||
function actions.all()
|
||||
for i=1, #actions do
|
||||
actions[actions[i]]()
|
||||
end
|
||||
end
|
||||
|
||||
if not arg[1] then
|
||||
|
2
build.sh
Executable file
2
build.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env sh
|
||||
luacomp build.lua 2>/dev/null | lua - "$@"
|
57
coreutils/init.lua
Normal file
57
coreutils/init.lua
Normal file
@ -0,0 +1,57 @@
|
||||
local kargs = ...
|
||||
local kio = kernel.kmode_run("return kio")
|
||||
local tty = kernel.kmode_run("return tty")
|
||||
local exec = kernel.kmode_run("return exec")
|
||||
local thd = require("thread")
|
||||
local fs = require("filesystem")
|
||||
local security = require("security")
|
||||
|
||||
kernel.dmesg(kernel.loglevel.INFO, "ksysinit started")
|
||||
local function run_hooks(hook, args)
|
||||
local hooks = fs.list("/etc/ksysinit/"..hook)
|
||||
for i=1, #hooks do
|
||||
local path = fs.resolve("/etc/ksysinit/"..hook.."/"..hooks[i])
|
||||
local stat = fs.stat(path)
|
||||
if (stat.mode == "file" and stat.uid == 0 and stat.gid == 0 and mode & 2 == 0) then
|
||||
local f, err = loadfile(path)
|
||||
if not f then
|
||||
kernel.dmesg(kernel.loglevel.WARNING, "Failed to load startup hook `"..hooks[i].."': "..err)
|
||||
goto continue
|
||||
end
|
||||
xpcall(function()
|
||||
f(table.unpack(args))
|
||||
end, function(err)
|
||||
kernel.dmesg(kernel.loglevel.ERROR, "Error in startup hook `"..hooks[i].."': "..debug.traceback(err))
|
||||
end)
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
kernel.dmesg(kernel.loglevel.INFO, "running startup hooks")
|
||||
run_hooks("startup", {})
|
||||
|
||||
kernel.dmesg(kernel.loglevel.INFO, "starting ttys")
|
||||
for i=1, tonumber(kargs["tty.count"]) or 1 do
|
||||
local pty = tty.get(i)
|
||||
exec.loadfile("/sbin/login.velx", true, {
|
||||
uid = 0,
|
||||
gid = 0,
|
||||
tty = pty
|
||||
})
|
||||
end
|
||||
|
||||
-- Now we wait for shutdown or other things
|
||||
while true do
|
||||
local siginfo = kernel.sig_pull()
|
||||
if siginfo.type == "shutdown" then
|
||||
run_hooks("shutdown", {})
|
||||
kernel.kmode_run([[computer.shutdown()]])
|
||||
elseif siginfo.type == "reboot" then
|
||||
run_hooks("shutdown", {})
|
||||
kernel.kmode_run([[computer.shutdown(true)]])
|
||||
elseif siginfo.type == "ipc" and siginfo.message[1] == "svcrun" and security.hasperm("svc", siginfo.uid, siginfo.gid) then
|
||||
table.pack(table.unpack(siginfo.message, 4))
|
||||
run_hooks("services/"..siginfo.message[2].."/"..siginfo.message[3], table.pack(table.unpack(siginfo.message, 4)))
|
||||
end
|
||||
end
|
45
coreutils/multicall.lua
Normal file
45
coreutils/multicall.lua
Normal file
@ -0,0 +1,45 @@
|
||||
local calls = {}
|
||||
|
||||
local function version_info()
|
||||
print("SKS Coreutils version $[{SKS_COREUTILS_VERSION}]")
|
||||
end
|
||||
|
||||
@[[function add_util(name)]]
|
||||
calls["@[{name}]"] = function(...)
|
||||
--#include @[{"coreutils/"..name..".lua"}]
|
||||
end
|
||||
@[[end]]
|
||||
|
||||
@[[
|
||||
add_util("init")
|
||||
add_util("reboot")
|
||||
add_util("sh")
|
||||
add_util("shutdown")
|
||||
add_util("svc-ctl")
|
||||
add_util("uname")
|
||||
]]
|
||||
|
||||
calls.sks = function(prog, ...)
|
||||
if not prog then
|
||||
version_info()
|
||||
print("SKS Coreutils multicall binary.\n")
|
||||
print("Calls:")
|
||||
local t = {}
|
||||
for k, v in pairs(calls) do
|
||||
t[#t+1] = k
|
||||
end
|
||||
print(table.concat(t, " "))
|
||||
return 0
|
||||
end
|
||||
return calls[prog](...)
|
||||
end
|
||||
|
||||
setmetatable(calls, {__index=function(_, i)
|
||||
return function()
|
||||
io.stderr:write("call "..i.." not found. run `sks' without args for list of calls.\n")
|
||||
end
|
||||
end})
|
||||
|
||||
local call = os.getenv("_"):match("/(.+)%.[^%.]+")
|
||||
|
||||
return calls[call](...)
|
5
coreutils/reboot.lua
Normal file
5
coreutils/reboot.lua
Normal file
@ -0,0 +1,5 @@
|
||||
if (kernel) then
|
||||
kernel.sig_push {
|
||||
sigtype = "shutdown"
|
||||
}
|
||||
end
|
0
coreutils/sh.lua
Normal file
0
coreutils/sh.lua
Normal file
10
coreutils/shutdown.lua
Normal file
10
coreutils/shutdown.lua
Normal file
@ -0,0 +1,10 @@
|
||||
if (kernel) then
|
||||
if (os.getenv("_"):match("reboot.velx")) then
|
||||
kernel.sig_push {sigtype = "reboot"}
|
||||
else
|
||||
kernel.sig_push {sigtype = "shutdown"}
|
||||
end
|
||||
else
|
||||
io.stderr:write("must be run as root\n")
|
||||
os.exit(-1)
|
||||
end
|
6
coreutils/svc-ctl.lua
Normal file
6
coreutils/svc-ctl.lua
Normal file
@ -0,0 +1,6 @@
|
||||
if (kernel) then
|
||||
--#include "coreutils/svc-ctl/init.lua"
|
||||
else
|
||||
io.stderr:write("must be run as root\n")
|
||||
os.exit(-1)
|
||||
end
|
26
coreutils/svc-ctl/init.lua
Normal file
26
coreutils/svc-ctl/init.lua
Normal file
@ -0,0 +1,26 @@
|
||||
local args = {...}
|
||||
local thread = require("thread")
|
||||
local ipc = require("ipc")
|
||||
local fs = require("filesystem")
|
||||
|
||||
if not args[1] then
|
||||
local svcs = {}
|
||||
for f in fs.list("/etc/ksysinit/services") do
|
||||
svcs[#svcs+1] = f
|
||||
end
|
||||
print(table.concat(svcs, ", "))
|
||||
return 0
|
||||
elseif args[1] and not args[2] then
|
||||
local svcs = {}
|
||||
for f in fs.list("/etc/ksysinit/services/"..args[1]) do
|
||||
svcs[#svcs+1] = f
|
||||
end
|
||||
print(table.concat(svcs, ", "))
|
||||
return 0
|
||||
elseif not fs.exists("/etc/ksysinit/services/"..args[1].."/"..args[2]) then
|
||||
io.stderr:write("hook `"..args[2].."' not found for `"..args[1].."'\n")
|
||||
return 1
|
||||
else
|
||||
local proc = thread.get("/sbin/init")
|
||||
ipc.send(proc, "svcrun", args[1], args[2])
|
||||
end
|
58
coreutils/uname.lua
Normal file
58
coreutils/uname.lua
Normal file
@ -0,0 +1,58 @@
|
||||
local sharg = require("sh_arg")
|
||||
local args = sharg({
|
||||
name = "uname",
|
||||
desc = [[Print certain system information. With no OPTION, same as -s]],
|
||||
options = {
|
||||
{"kernel-name", "s", "print the kernel name"},
|
||||
{"nodename", "n", "print the network node hostname"},
|
||||
{"kernel-release", "r", "print the kernel release"},
|
||||
{"kernel-version", "v", "print the kernel release"},
|
||||
{"machine", "m", "print the machine hardware name"},
|
||||
{"operating-system", "o", "print the operating system"},
|
||||
{"version", false, "output version information and exit"}
|
||||
},
|
||||
}, ...)
|
||||
|
||||
if (args.version) then
|
||||
version_info()
|
||||
return 0
|
||||
end
|
||||
|
||||
if (args.a or args.all) then
|
||||
args.s = true
|
||||
args.r = true
|
||||
args.v = true
|
||||
args.n = true
|
||||
args.m = true
|
||||
args.o = true
|
||||
end
|
||||
|
||||
if table.select("#", ...) == 0 then
|
||||
args.s = true
|
||||
end
|
||||
|
||||
if (args.s) then
|
||||
io.stdout:write(_KINFO.name.." ")
|
||||
end
|
||||
|
||||
if (args.n) then
|
||||
io.stdout:write(os.getenv("HOSTNAME").." ")
|
||||
end
|
||||
|
||||
if (args.r) then
|
||||
io.stdout:write(_KINFO.release.." ")
|
||||
end
|
||||
|
||||
if (args.v) then
|
||||
io.stdout:write(_KINFO.version.." ")
|
||||
end
|
||||
|
||||
if (args.m) then
|
||||
io.stdout:write(_KINFO.machine.." ")
|
||||
end
|
||||
|
||||
if (args.o) then
|
||||
io.stdout:write("SKS/Tsuki ")
|
||||
end
|
||||
|
||||
io.stdout:write("\n")
|
509
debug.lua
509
debug.lua
@ -1,15 +1,140 @@
|
||||
os.execute("mkdir -p build")
|
||||
os.execute("rm -rf build/*")
|
||||
|
||||
function struct(tbl)
|
||||
local actions = {}
|
||||
|
||||
|
||||
|
||||
|
||||
-- VELX builder
|
||||
|
||||
--[[----------------------------------------------------------------------------
|
||||
LZSS - encoder / decoder
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
--]]----------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
local M = {}
|
||||
local string, table = string, table
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local POS_BITS = 12
|
||||
local LEN_BITS = 16 - POS_BITS
|
||||
local POS_SIZE = 1 << POS_BITS
|
||||
local LEN_SIZE = 1 << LEN_BITS
|
||||
local LEN_MIN = 3
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function M.compress(input)
|
||||
local offset, output = 1, {}
|
||||
local window = ''
|
||||
|
||||
local function search()
|
||||
for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
|
||||
local str = string.sub(input, offset, offset + i - 1)
|
||||
local pos = string.find(window, str, 1, true)
|
||||
if pos then
|
||||
return pos, str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while offset <= #input do
|
||||
local flags, buffer = 0, {}
|
||||
|
||||
for i = 0, 7 do
|
||||
if offset <= #input then
|
||||
local pos, str = search()
|
||||
if pos and #str >= LEN_MIN then
|
||||
local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
|
||||
buffer[#buffer + 1] = string.pack('>I2', tmp)
|
||||
else
|
||||
flags = flags | (1 << i)
|
||||
str = string.sub(input, offset, offset)
|
||||
buffer[#buffer + 1] = str
|
||||
end
|
||||
window = string.sub(window .. str, -POS_SIZE)
|
||||
offset = offset + #str
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if #buffer > 0 then
|
||||
output[#output + 1] = string.char(flags)
|
||||
output[#output + 1] = table.concat(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function M.decompress(input)
|
||||
local offset, output = 1, {}
|
||||
local window = ''
|
||||
|
||||
while offset <= #input do
|
||||
local flags = string.byte(input, offset)
|
||||
offset = offset + 1
|
||||
|
||||
for i = 1, 8 do
|
||||
local str = nil
|
||||
if (flags & 1) ~= 0 then
|
||||
if offset <= #input then
|
||||
str = string.sub(input, offset, offset)
|
||||
offset = offset + 1
|
||||
end
|
||||
else
|
||||
if offset + 1 <= #input then
|
||||
local tmp = string.unpack('>I2', input, offset)
|
||||
offset = offset + 2
|
||||
local pos = (tmp >> LEN_BITS) + 1
|
||||
local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
|
||||
str = string.sub(window, pos, pos + len - 1)
|
||||
end
|
||||
end
|
||||
flags = flags >> 1
|
||||
if str then
|
||||
output[#output + 1] = str
|
||||
window = string.sub(window .. str, -POS_SIZE)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(output)
|
||||
end
|
||||
|
||||
|
||||
local function struct(tbl)
|
||||
local pat = tbl.endian or "="
|
||||
local args = {}
|
||||
for i=1, do
|
||||
for i=1, #tbl do
|
||||
local a, b = pairs(tbl[i])
|
||||
local k, v = a(b)
|
||||
args[i] = k
|
||||
pat = pat .. v
|
||||
end
|
||||
return setmetatable({}, {__call=function(_, arg)
|
||||
checkArg(1, arg, "string", "table")
|
||||
--checkArg(1, arg, "string", "table")
|
||||
if (type(arg) == "string") then
|
||||
local sval = {string.unpack(pat, arg)}
|
||||
local rtn = {}
|
||||
@ -29,57 +154,6 @@ function struct(tbl)
|
||||
end})
|
||||
end
|
||||
|
||||
function string.trim(self)
|
||||
return self:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
function string.explode(self, pat)
|
||||
local t, ll
|
||||
t={}
|
||||
ll=0
|
||||
if(#p == 1) then
|
||||
return {p}
|
||||
end
|
||||
while true do
|
||||
l = string.find(self, pat, ll, true) -- find the next d in the string
|
||||
if l ~= nil then -- if "not not" found then..
|
||||
table.insert(t, string.sub(self,ll,l-1)) -- Save it in our array.
|
||||
ll = l + 1 -- save just after where we found it for searching next time.
|
||||
else
|
||||
table.insert(t, string.sub(self,ll)) -- Save what's left in our array.
|
||||
break -- Break at end, as it should be, according to the lua manual.
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
|
||||
---@module security Security
|
||||
local security = {}
|
||||
|
||||
---@func checkacl
|
||||
---@arg permission string "The permission to check."
|
||||
---@return boolean "True if the current process has this permission."
|
||||
function security.checkacl(permission)
|
||||
local perms = acl.get("group", thread.info().egid, {})
|
||||
end
|
||||
|
||||
---@func getmode
|
||||
---@return string "The current security mode."
|
||||
function security.getmode()
|
||||
|
||||
end
|
||||
|
||||
function security.init()
|
||||
klog("security", 1, "Security init started.")
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
local velx = (function()
|
||||
|
||||
|
||||
local velx_spec = struct {
|
||||
endian = "<",
|
||||
@ -88,237 +162,150 @@ local velx_spec = struct {
|
||||
{compression="B"},
|
||||
{lver="B"},
|
||||
{os="B"},
|
||||
{arctype="c4"},
|
||||
{psize="I3"},
|
||||
{lsize="I3"},
|
||||
{ssize="I3"},
|
||||
{rsize="I4"}
|
||||
}
|
||||
|
||||
local velx = {}
|
||||
|
||||
local exec = {}
|
||||
|
||||
function velx.identify(path)
|
||||
local h = io.open(path, "rb")
|
||||
local header = velx_spec(h:read(#velx_spec))
|
||||
local function velx_multistep(path, arcpath, args, steps)
|
||||
local shell_args = ""
|
||||
for k, v in pairs(args) do
|
||||
shell_args = shell_args .. k .. "=".. v .." "
|
||||
end
|
||||
steps.precomp()
|
||||
local h = io.popen(shell_args.."luacomp "..path, "r")
|
||||
local prog = h:read("*a")
|
||||
h:close()
|
||||
return header.magic == "\27VelX"
|
||||
end
|
||||
|
||||
function velx.load(path)
|
||||
|
||||
end
|
||||
|
||||
function velx.verify(path)
|
||||
local h = io.open(path, "rb")
|
||||
local header = velx_spec(h:read(#velx_spec))
|
||||
local code = h:read(header.psize)
|
||||
h:seek("cur", lsize)
|
||||
local sig = h:read(header.ssize)
|
||||
prog = steps.postcomp(prog)
|
||||
steps.prearc()
|
||||
h = io.popen("find .docs -depth | tsar -o", "r")
|
||||
local arc = h:read("*a")
|
||||
h:close()
|
||||
return security.verify(code, sig)
|
||||
steps.postarc()
|
||||
if (not args.noz) then
|
||||
steps.prez()
|
||||
prog = M.compress(prog)
|
||||
steps.postz()
|
||||
end
|
||||
local header = velx_spec({
|
||||
magic = "\27VelX",
|
||||
compression = (args.noz and 0 or) 1,
|
||||
lver = 0x53,
|
||||
fver = 1,
|
||||
os = 0x7F,
|
||||
psize = #prog,
|
||||
lsize=0,
|
||||
ssize=0,
|
||||
rsize=#arc,
|
||||
arctype="tsar"
|
||||
})
|
||||
return header .. prog .. arc
|
||||
end
|
||||
|
||||
function exec:link()
|
||||
self.file:seek("set", #velx_spec+self.header.psize)
|
||||
local linkinfo = self.file:read(self.header.lsize)
|
||||
local linker = {}
|
||||
local pos = 1
|
||||
while true do
|
||||
local size = string.unpack("<H", linkinfo:sub(pos))
|
||||
pos = pos + 2
|
||||
local name = linkinfo:sub(pos, pos+size-1)
|
||||
pos = pos + size
|
||||
size = string.unpack("<H", linkinfo:sub(pos))
|
||||
pos = pos + 2
|
||||
local library = linkinfo:sub(pos, pos+size-1)
|
||||
pos = pos + size
|
||||
if (name == "" or library == "") then
|
||||
break
|
||||
local function velx(path, arcpath, args)
|
||||
return velx_multistep(path, arcpath, args, {
|
||||
precomp = function()end
|
||||
postcomp = function(prog) return prog end
|
||||
prearc = function()end
|
||||
postarc = function()end
|
||||
prez = function()end
|
||||
postz = function()end
|
||||
})
|
||||
end
|
||||
|
||||
local TSUKI_RELEASE = "0.0.1"
|
||||
local tz = os.date("%z")
|
||||
tz = tz:sub(1, 3)..":"..tz:sub(4)
|
||||
local TSUKI_VERSION = "Lua 5.3 "..os.date("%Y-%m-%dT%H:%M:%S")..tz
|
||||
local TSUKI_TARGET = os.getenv("TSUKI_TARGET") or "OC"
|
||||
|
||||
function actions.kernel(dbg)
|
||||
os.execute("mkdir -p build/kernel")
|
||||
print("Compiling kernel...")
|
||||
local h = io.open("build/kernel/tkrnl.velx", "wb")
|
||||
h:write(velx_multistep("ksrc/init.lua", ".docs", {
|
||||
TSUKI_RELEASE = TSUKI_RELEASE,
|
||||
TSUKI_VERSION = TSUKI_VERSION,
|
||||
TSUKI_TARGET = TSUKI_TARGET,
|
||||
PRINT_DMESG_LEVEL = ((dbg and 0) or 1)
|
||||
}, {
|
||||
precomp = function()
|
||||
print("Compiling kernel...")
|
||||
end,
|
||||
postcomp = function(krnl)
|
||||
os.execute("mkdir .docs")
|
||||
local h = io.open("build/kernel/debug.lua")
|
||||
h:write(krnl)
|
||||
h:close()
|
||||
print("Generating docs and stripping comments...")
|
||||
h = io.popen("lua utils/gendocs.lua .docs 2>.ktmp", "w")
|
||||
h:write(krnl)
|
||||
h:close()
|
||||
h = io.open(".ktmp", "rb")
|
||||
local data = h:read("*a")
|
||||
h:close()
|
||||
os.execute("rm -rf .ktmp")
|
||||
return data
|
||||
end,
|
||||
prearc = function()
|
||||
print("Storing docs...")
|
||||
end,
|
||||
postarc = function()
|
||||
os.execute("rm -rf .docs")
|
||||
end,
|
||||
precomp = function()
|
||||
print("Compressing kernel...")
|
||||
end,
|
||||
postcomp = function()
|
||||
print("Writing kernel out...")
|
||||
end
|
||||
linker[#linker+1] = {name, library}
|
||||
end
|
||||
local linkscript = ""
|
||||
for i=1, #linker do
|
||||
linkscript = linkscript .. "local " .. linker[i][1] .. "=require(\"" .. linker[i][2] .. "\")\n"
|
||||
end
|
||||
self.code = linkscript .. self.code
|
||||
return true
|
||||
}))
|
||||
end
|
||||
|
||||
function exec:load()
|
||||
self.file:seek("set", #velx_spec)
|
||||
local code = self.file:read(self.header.psize)
|
||||
if (self.header.compression == 0) then
|
||||
self.code = code
|
||||
elseif (self.header.compression == 1) then
|
||||
self.code = lzss.decompress(self.code)
|
||||
else
|
||||
return nil, "invalid compression method"
|
||||
end
|
||||
return true
|
||||
actions[#actions+1] = "kernel"
|
||||
|
||||
function actions.crescent()
|
||||
os.execute("mkdir -p build/crescent")
|
||||
os.execute("cd extras; lua ../utils/mkvelx.lua crescent/init.lua ../build/crescent/boot.velx")
|
||||
os.execute("cp extras/crescent/bootvelxloader.lua build/crescent/init.lua")
|
||||
end
|
||||
|
||||
function exec:run(args, evar)
|
||||
system.load(self.code, args, system.getglobalenv({_ARCHIVE=self.arc}), system.getevars(evar))
|
||||
actions[#actions+1] = "crescent"
|
||||
|
||||
function actions.velxboot()
|
||||
os.execute("mkdir -p build/velxboot")
|
||||
os.execute("cd extras; luacomp velxboot/init.lua -O ../build/velxboot/bios.lua")
|
||||
os.execute("cd extras; luacomp velxboot/flashvelxboot.lua -O ../build/velxboot/flashvelxboot.lua")
|
||||
end
|
||||
|
||||
end)()
|
||||
actions[#actions+1] = "velxboot"
|
||||
|
||||
local zlua = (function()
|
||||
function actions.clean()
|
||||
print("Cleaning up...")
|
||||
os.execute("rm -rf .docs")
|
||||
os.execute("rm -rf .ktmp")
|
||||
end
|
||||
|
||||
local zlua = {}
|
||||
|
||||
return {}
|
||||
end)
|
||||
--[[function actions.debug()
|
||||
actions.kernel(true)
|
||||
actions.crescent()
|
||||
actions.velxboot()
|
||||
actions.clean()
|
||||
end]]
|
||||
|
||||
-- Executable loading process:
|
||||
-- - Link
|
||||
-- - Load
|
||||
-- - Execute
|
||||
|
||||
if ()
|
||||
|
||||
local fox = {}
|
||||
do
|
||||
|
||||
local struct_inode = struct {
|
||||
endian = "<",
|
||||
{mode="H"},
|
||||
{uid="H"},
|
||||
{fsize="I6"},
|
||||
{atime="I6"},
|
||||
{ctime="I6"},
|
||||
{mtime="I6"},
|
||||
{dtime="I6"},
|
||||
{gid="H"},
|
||||
{sec_count="I4"},
|
||||
{flags="I4"},
|
||||
{osval="I4"},
|
||||
{dbp0="I4"},
|
||||
{dbp1="I4"},
|
||||
{dbp2="I4"},
|
||||
{dbp3="I4"},
|
||||
{dbp4="I4"},
|
||||
{dbp5="I4"},
|
||||
{dbp6="I4"},
|
||||
{dbp7="I4"},
|
||||
{dbp8="I4"},
|
||||
{dbp9="I4"},
|
||||
{dbp10="I4"},
|
||||
{dbp11="I4"},
|
||||
{sibp="I4"},
|
||||
{dibp="I4"},
|
||||
{tibp="I4"},
|
||||
{gen="H"},
|
||||
{acl="I4"},
|
||||
{fragaddr="I4"},
|
||||
{osval2="c10"}
|
||||
}
|
||||
|
||||
local dirent = struct {
|
||||
endian="<",
|
||||
{inode="I4"},
|
||||
{name_size="H"},
|
||||
{etype="B"}
|
||||
}
|
||||
|
||||
local superblock = struct {
|
||||
endian = "<",
|
||||
{sig="H"},
|
||||
{ver_maj="H"},
|
||||
{ver_min="H"},
|
||||
{state="H"},
|
||||
{total_inodes="I4"},
|
||||
{total_blocks="I4"},
|
||||
{reserved_blocks="I4"},
|
||||
{total_unalloc_blocks="I4"},
|
||||
{total_unalloc_inodes="I4"},
|
||||
{total_unalloc_inodes="I4"},
|
||||
}
|
||||
|
||||
local blkstr = {}
|
||||
|
||||
function fox.proxy(blkdev)
|
||||
-- Read the superblock
|
||||
function actions.all()
|
||||
for i=1, #actions do
|
||||
actions[actions[i]]()
|
||||
end
|
||||
end
|
||||
|
||||
local tty = {}
|
||||
do
|
||||
local _tty = {}
|
||||
function _tty:getgpu()
|
||||
return self.gpu.address
|
||||
end
|
||||
|
||||
function _tty:getkb()
|
||||
return self.kb.address
|
||||
end
|
||||
|
||||
function _tty:getscreen()
|
||||
return self.screen.address
|
||||
end
|
||||
if not arg[1] then
|
||||
arg[1] = "all"
|
||||
end
|
||||
|
||||
---@section biosfixes "BIOS fixes"
|
||||
actions[arg[1]]()
|
||||
|
||||
local _biossupport = {}
|
||||
|
||||
|
||||
|
||||
|
||||
---@page zorya_legacy "Zorya 1.x (Zorya Legacy)"
|
||||
---@doc "Zorya 1.x puts a few things in the global space that need to be removed. These include:"
|
||||
---@doc "- The OEFI library"
|
||||
---@doc "- The Zorya library"
|
||||
---@doc ""
|
||||
---@doc "Note: This *should* also apply to any forks of Zorya Legacy."
|
||||
_biossupport["zoryalegacy"] = {
|
||||
quirks = function()
|
||||
|
||||
zorya = nil
|
||||
end,
|
||||
info = function()
|
||||
|
||||
return {
|
||||
name = "Zorya",
|
||||
version = {_ZVER//1, tonumber(tostring(_ZVER):match("%.(%d+)")), _ZPAT, string = _ZVER..".".._ZPAT},
|
||||
oefiver = oefi.getAPIVersion()
|
||||
}
|
||||
end,
|
||||
detect = function()
|
||||
|
||||
return _LOAD == "Zorya"
|
||||
end,
|
||||
name = "zoryalegacy"
|
||||
}
|
||||
|
||||
|
||||
|
||||
---@page zorya_neo "Zorya NEO (Zorya 2.0)"
|
||||
---@doc "There's not much to be done for Zorya NEO as the included Zorya module starts Tsuki with a nice enviroment."
|
||||
_biossupport["zoryaneo"] = {
|
||||
quirks = function()
|
||||
|
||||
|
||||
end,
|
||||
info = function()
|
||||
|
||||
return {
|
||||
name = "Zorya NEO",
|
||||
version = {_ZVER//1, tonumber(tostring(_ZVER):match("%.(%d+)")), _ZPAT, git = _ZGIT, string = _ZVSTR},
|
||||
loader = _ZLOADER
|
||||
}
|
||||
end,
|
||||
detect = function()
|
||||
|
||||
return _BIOS == "Zorya NEO"
|
||||
end,
|
||||
name = "zoryaneo"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-- Mount the rootfs
|
||||
vfs.mount()
|
||||
print("Build complete.")
|
11
ksrc/acl.lua
11
ksrc/acl.lua
@ -2,15 +2,20 @@ local acl = {}
|
||||
do
|
||||
local acl = struct({
|
||||
meta = "B",
|
||||
id = "H",
|
||||
permname = "B"
|
||||
id = "H"
|
||||
})
|
||||
|
||||
local function acl_readstream(stream)
|
||||
local a = acl(stream:read(#acl))
|
||||
local perm = stream:read(a.meta & 0x3f)
|
||||
local
|
||||
end
|
||||
|
||||
function acl.read(stream, dperm, gid, uid)
|
||||
|
||||
end
|
||||
|
||||
function acl.read(stream)
|
||||
function _acl:get_effective_perm(id, group, perm)
|
||||
|
||||
end
|
||||
end
|
9
ksrc/ads.lua
Normal file
9
ksrc/ads.lua
Normal file
@ -0,0 +1,9 @@
|
||||
local ads = {}
|
||||
|
||||
function ads.get(path)
|
||||
|
||||
end
|
||||
|
||||
function ads.list(path)
|
||||
|
||||
end
|
10
ksrc/archives.lua
Normal file
10
ksrc/archives.lua
Normal file
@ -0,0 +1,10 @@
|
||||
local archives = {}
|
||||
archives.tsar = (function()
|
||||
--#include "ksrc/arcs/tsar/init.lua"
|
||||
end)()
|
||||
|
||||
function archive.parse(stream, atype)
|
||||
if archives[atype] then
|
||||
return archives[atype].read(stream)
|
||||
end
|
||||
end
|
@ -16,7 +16,7 @@ end
|
||||
|
||||
local arc = {}
|
||||
|
||||
function arc:handle(path)
|
||||
function arc:read(path)
|
||||
for i=1, #self.tbl do
|
||||
if (self.tbl[i].name == path and self.tbl[i].mode & 32768 > 0) then
|
||||
self.seek(self.tbl[i].pos-self.seek(0))
|
||||
@ -55,12 +55,55 @@ function arc:meta(path)
|
||||
return nil, "file not found"
|
||||
end
|
||||
|
||||
function arc:stream(path)
|
||||
for i=1, #self.tbl do
|
||||
if (self.tbl[i].name == path) then
|
||||
return kio.create_stream({dev=self.dev, start=self.tbl[i].pos, size=self.tbl[i].filesize, pos=1}, {
|
||||
read = function(self, amt)
|
||||
self.dev:seek("set", self.pos+self.start-1)
|
||||
if (self.pos+amt-1 > self.size) then
|
||||
amt = self.size-self.pos
|
||||
end
|
||||
local dat = self.dev:read(amt)
|
||||
self.pos = self.pos + #dat
|
||||
return dat
|
||||
end,
|
||||
seek = function(self, whence, amt)
|
||||
self.pos = kio.calc_seek(whence, amt, self.size, self.pos)
|
||||
return self.pos
|
||||
end,
|
||||
write = function(self)
|
||||
return kio.get_error(kio.errno.UNSUPPORTED_OPERATION)
|
||||
end,
|
||||
close = function(self)
|
||||
|
||||
end
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function arc:trailer()
|
||||
self.dev:seek("set", self.tbl.trailer.pos)
|
||||
return self.dev:read(self.tbl.trailer.filesize)
|
||||
end
|
||||
|
||||
function arc:close()
|
||||
self.close()
|
||||
end
|
||||
|
||||
return {
|
||||
read = function(read, seek, close)
|
||||
read = function(dev)
|
||||
local function read(a)
|
||||
return dev:read(a)
|
||||
end
|
||||
local function seek(a)
|
||||
return dev:seek("cur", a)
|
||||
end
|
||||
local function close()
|
||||
return dev:close()
|
||||
end
|
||||
local start = seek(0)
|
||||
local tbl = {}
|
||||
local lname = ""
|
||||
while lname ~= "TRAILER!!!" do
|
||||
@ -72,8 +115,10 @@ return {
|
||||
lname = et.name
|
||||
if lname ~= "TRAILER!!!" then
|
||||
tbl[#tbl+1] = et
|
||||
else
|
||||
tbl.trailer = et
|
||||
end
|
||||
end
|
||||
return setmetatable({tbl = tbl, read = read, seek = seek, close = close}, {__index=arc})
|
||||
return setmetatable({tbl = tbl, read = read, seek = seek, close = close, dev=dev, start=true}, {__index=arc})
|
||||
end
|
||||
}
|
1
ksrc/bios/unknown/detect.lua
Normal file
1
ksrc/bios/unknown/detect.lua
Normal file
@ -0,0 +1 @@
|
||||
return true
|
2
ksrc/bios/unknown/docs.lua
Normal file
2
ksrc/bios/unknown/docs.lua
Normal file
@ -0,0 +1,2 @@
|
||||
---@page unknown "Unknown"
|
||||
---@doc "This is for if Tsuki doesn't know what BIOS is in use."
|
4
ksrc/bios/unknown/info.lua
Normal file
4
ksrc/bios/unknown/info.lua
Normal file
@ -0,0 +1,4 @@
|
||||
return {
|
||||
name = "Unknown",
|
||||
version = {0, 0, 0, string="0.0.0"}
|
||||
}
|
0
ksrc/bios/unknown/quirks.lua
Normal file
0
ksrc/bios/unknown/quirks.lua
Normal file
@ -1,5 +1,7 @@
|
||||
---@section biosfixes "BIOS fixes"
|
||||
|
||||
@[[do
|
||||
local i=1]]
|
||||
local _biossupport = {}
|
||||
@[[function biosfix(bios)]]
|
||||
--#include @[{"ksrc/bios/"..bios.."/docs.lua"}]
|
||||
@ -13,11 +15,16 @@ _biossupport["@[{bios}]"] = {
|
||||
detect = function()
|
||||
--#include @[{"ksrc/bios/"..bios.."/detect.lua"}]
|
||||
end,
|
||||
name = "@[{bios}]"
|
||||
name = "@[{bios}]",
|
||||
id = @[{i}]
|
||||
}
|
||||
_biossupport[@[{i}]] = "@[{bios}]"
|
||||
@[[i=i+1]]
|
||||
@[[end]]
|
||||
|
||||
@[[biosfix("zoryalegacy")]]
|
||||
@[[biosfix("zoryaneo")]]
|
||||
|
||||
@[[biosfix = nil]]
|
||||
@[[biosfix("unknown")]]
|
||||
@[[biosfix = nil]]
|
||||
@[[end]]
|
@ -0,0 +1,5 @@
|
||||
local eeprom = {}
|
||||
|
||||
function eeprom.proxy(addr)
|
||||
|
||||
end
|
@ -0,0 +1,4 @@
|
||||
--#include "ksrc/blk/eeprom.lua"
|
||||
--#include "ksrc/blk/hdd.lua"
|
||||
--#include "ksrc/blk/partition.lua"
|
||||
--#include "ksrc/blk/promcard.lua"
|
@ -7,7 +7,28 @@ local zlua = (function()
|
||||
--#include "ksrc/execs/zlua/init.lua"
|
||||
end)
|
||||
|
||||
local lua = (function()
|
||||
--#include "ksrc/execs/lua/init.lua"
|
||||
end)
|
||||
|
||||
-- Executable loading process:
|
||||
-- - Link
|
||||
-- - Load
|
||||
-- - Execute
|
||||
-- - Execute
|
||||
|
||||
function exec.loadfile(path, env, runinfo)
|
||||
local stat = vfs.stat(path)
|
||||
if (stat & 0x400 > 0) then
|
||||
runinfo.gid = stat.gid
|
||||
end
|
||||
if (stat & 0x800 > 0) then
|
||||
runinfo.uid = stat.uid
|
||||
end
|
||||
if (velx.identify(path)) then
|
||||
|
||||
elseif (zlua.identify(path)) then
|
||||
|
||||
else -- Load Lua...if we can.
|
||||
|
||||
end
|
||||
end
|
0
ksrc/execs/lua/init.lua
Normal file
0
ksrc/execs/lua/init.lua
Normal file
@ -24,7 +24,11 @@ function velx.identify(path)
|
||||
end
|
||||
|
||||
function velx.load(path)
|
||||
|
||||
local h = io.open(path, "rb")
|
||||
local header = velx_spec(h:read(#velx_spec))
|
||||
local code = h:read(header.psize)
|
||||
h:seek("cur", lsize)
|
||||
local sig = h:read(header.ssize)
|
||||
end
|
||||
|
||||
function velx.verify(path)
|
||||
|
1
ksrc/fs/arcfs/init.lua
Normal file
1
ksrc/fs/arcfs/init.lua
Normal file
@ -0,0 +1 @@
|
||||
local afs = {}
|
21
ksrc/fs/foxfs/ads.lua
Normal file
21
ksrc/fs/foxfs/ads.lua
Normal file
@ -0,0 +1,21 @@
|
||||
function prox:getadses(path)
|
||||
local inode = fox_getnode(self, path)
|
||||
local adsl = fox_readdir(self, inode.ads)
|
||||
return adsl
|
||||
end
|
||||
|
||||
function prox:makeads(path, stream)
|
||||
|
||||
end
|
||||
|
||||
function prox:getads(path, stream)
|
||||
local inode = fox_getnode(self, path)
|
||||
local adsl = fox_readdir(self, inode.ads)
|
||||
for i=1, do
|
||||
if (adsl[i].name == stream) then
|
||||
local node = fox_getinode(self, adsl[i].inode)
|
||||
return {node=node, pos=1, mode=mode, dev=self}
|
||||
end
|
||||
end
|
||||
return nil, "not found"
|
||||
end
|
@ -3,4 +3,12 @@ local dirent = struct {
|
||||
{inode="I4"},
|
||||
{name_size="H"},
|
||||
{etype="B"}
|
||||
}
|
||||
}
|
||||
|
||||
local function fox_readdir(self, inode)
|
||||
|
||||
end
|
||||
|
||||
function prox:list(path)
|
||||
|
||||
end
|
21
ksrc/fs/foxfs/filehand.lua
Normal file
21
ksrc/fs/foxfs/filehand.lua
Normal file
@ -0,0 +1,21 @@
|
||||
function prox:open(path, mode)
|
||||
local node = fox_getnode(self, path)
|
||||
if not node then return nil, "file not found" end
|
||||
return {node=node, pos=1, mode=mode, dev=self}
|
||||
end
|
||||
|
||||
function prox:read(hand, amt)
|
||||
|
||||
end
|
||||
|
||||
function prox:write(hand, data)
|
||||
|
||||
end
|
||||
|
||||
function prox:seek(hand, amt)
|
||||
|
||||
end
|
||||
|
||||
function prox:close(hand)
|
||||
|
||||
end
|
@ -7,11 +7,16 @@ do
|
||||
|
||||
local prox = {}
|
||||
|
||||
function fox.proxy(blkdev)
|
||||
function fox.proxy(dev)
|
||||
-- Read the superblock
|
||||
sb:seek("set", 1025)
|
||||
local sb = superblock(dev:read(#superblock))
|
||||
local prox = {
|
||||
super = sb
|
||||
}
|
||||
end
|
||||
|
||||
local function fox_getinode(prox, inode)
|
||||
prox.dev:size()
|
||||
|
||||
end
|
||||
end
|
@ -27,7 +27,7 @@ local struct_inode = struct {
|
||||
{dibp="I4"},
|
||||
{tibp="I4"},
|
||||
{gen="H"},
|
||||
{acl="I4"},
|
||||
{ads="I4"},
|
||||
{fragaddr="I4"},
|
||||
{osval2="c10"}
|
||||
}
|
@ -1,5 +1,12 @@
|
||||
--#include "ksrc/kstrings.lua"
|
||||
--#include "ksrc/kargs.lua"
|
||||
--#include "ksrc/kio.lua"
|
||||
--#include "ksrc/vfs.lua"
|
||||
--#include "ksrc/struct.lua"
|
||||
--#include "ksrc/string.lua"
|
||||
--#include "ksrc/archives.lua"
|
||||
--#include "ksrc/ads.lua"
|
||||
--#include "ksrc/blkdev.lua"
|
||||
--#include "ksrc/acl.lua"
|
||||
--#include "ksrc/security.lua"
|
||||
--#include "ksrc/exec.lua"
|
||||
@ -7,7 +14,25 @@
|
||||
--#include "ksrc/tty.lua"
|
||||
--#include "ksrc/biosfixes.lua"
|
||||
--#include "ksrc/buffer.lua"
|
||||
--#include "ksrc/kio.lua"
|
||||
--#include "ksrc/threads.lua"
|
||||
--#include "ksrc/net.lua"
|
||||
|
||||
-- Mount the rootfs
|
||||
vfs.mount()
|
||||
kio.dmesg(1, "Starting Tsuki kernel.")
|
||||
kio.init()
|
||||
|
||||
-- Mount the initramfs, if there is one.
|
||||
if (kargs.iramfs or kargs.root == "$") then
|
||||
vfs.mount("/", arcfs.proxy(_ARCHIVE))
|
||||
end
|
||||
|
||||
-- Eventually...
|
||||
do
|
||||
local pty = tty.get(0)
|
||||
kio.dmesg(1, "Passing off to init.")
|
||||
exec.startfile(kargs.init or "/bin/init.velx", true, {
|
||||
uid = 0,
|
||||
gid = 0,
|
||||
tty = pty,
|
||||
args = {kargs}
|
||||
})
|
||||
end
|
0
ksrc/kargs.lua
Normal file
0
ksrc/kargs.lua
Normal file
297
ksrc/kio.lua
297
ksrc/kio.lua
@ -1,8 +1,299 @@
|
||||
---@module kio "Kernel I/O"
|
||||
local kio = {}
|
||||
@[[if not svar.get("PRINT_DMESG_LEVEL") then
|
||||
svar.set("PRINT_DMESG_LEVEL", "1")
|
||||
end]]
|
||||
|
||||
---@module kio "Kernel I/O"
|
||||
kio = {}
|
||||
|
||||
local _stream = {}
|
||||
function _stream:read(amt)
|
||||
local buf = ""
|
||||
local lc = ""
|
||||
if (amt == "*l") then -- Our line ending is \n
|
||||
repeat
|
||||
lc = self.proto.read(self.udat, 1)
|
||||
if (lc ~= "\n") then
|
||||
buf = buf .. (lc or "")
|
||||
end
|
||||
until not lc or lc == "" or lc == "\n"
|
||||
return buf
|
||||
--elseif (amt == "*n") then
|
||||
|
||||
elseif (amt == "*a") then
|
||||
local pos = self:seek("cur", 0)
|
||||
local send = self:seek("end", 0)
|
||||
self:seek("set", pos)
|
||||
amt = send - pos
|
||||
end
|
||||
return self.proto.read(self.udat, amt)
|
||||
end
|
||||
|
||||
function _stream:write(data)
|
||||
return self.proto.write(self.udat, data)
|
||||
end
|
||||
|
||||
function _stream:seek(whence, amt)
|
||||
if not amt then
|
||||
amt = whence or 0
|
||||
whence = "cur"
|
||||
end
|
||||
return self.proto.seek(self.udat, whence, amt)
|
||||
end
|
||||
|
||||
function _stream:eof()
|
||||
local pos = self:seek("cur", 0)
|
||||
local send = self:seek("end", 0)
|
||||
self:seek("set", pos)
|
||||
return pos == send
|
||||
end
|
||||
|
||||
function _stream:close()
|
||||
return self.proto.close(self.udat)
|
||||
end
|
||||
|
||||
function _stream:size()
|
||||
local pos = self:seek("cur", 0)
|
||||
local send = self:seek("end", 0)
|
||||
self:seek("set", pos)
|
||||
return send
|
||||
end
|
||||
|
||||
function kio.create_stream(udat, proto)
|
||||
return setmetatable({udat=udat, proto=proto}, {__index=_stream})
|
||||
end
|
||||
|
||||
@[[local kio_errc = 0
|
||||
function kio_err(name, rtn)]]
|
||||
kio.errno["@[{name}]"] = @[{kio_errc}]
|
||||
kio_errors[@[{kio_errc}]] = "@[{rtn}]"
|
||||
@[[kio_errc = kio_errc + 1
|
||||
end]]
|
||||
|
||||
kio.errno = {}
|
||||
local kio_errors = {}
|
||||
@[[
|
||||
kio_err("FILE_NOT_FOUND", "not found")
|
||||
kio_err("FILE_DIRECTORY", "file is a directory")
|
||||
kio_err("DEV_TIMEOUT", "device timeout")
|
||||
kio_err("IO_ERROR", "generic i/o error")
|
||||
kio_err("UNSUPPORTED_OPERATION", "unsupported operation")
|
||||
kio_err("NOT_ALLOWED", "not allowed")
|
||||
kio_err("TOO_MANY_SYMLINKS", "too many symlinks")
|
||||
kio_err("DEV_FULL", "device is full")
|
||||
kio_err("DEV_READ_ONLY", "device is read only")
|
||||
]]
|
||||
|
||||
kio.geterror = function(e)
|
||||
return nil, kio_errors[e] or "generic error"
|
||||
end
|
||||
|
||||
function kio.invoke(path, method, ...)
|
||||
local dev, rpath = vfs.resolve(path)
|
||||
return dev.dev[method](dev.dev, rpath, ...)
|
||||
end
|
||||
|
||||
function kio.has_ads(path)
|
||||
|
||||
end
|
||||
|
||||
function kio.ads_exists(path, ads)
|
||||
|
||||
end
|
||||
|
||||
function kio.has_acl(path)
|
||||
|
||||
end
|
||||
|
||||
---@func calc_seek
|
||||
---@arg whence string "Like io.seek's whence."
|
||||
---@arg amt integer "The amount to seek."
|
||||
---@arg size integer "The size of the stream."
|
||||
---@arg pos integer "The current position."
|
||||
---@return integer "The new position"
|
||||
---@desc "This function calculates the new position for seeking."
|
||||
function kio.calc_seek(whence, amt, size, pos)
|
||||
if (whence == "cur") then
|
||||
pos = pos + amt
|
||||
elseif (whence == "end") then
|
||||
pos = size + amt
|
||||
elseif (whence == "set") then
|
||||
pos = amt
|
||||
end
|
||||
if pos > size then
|
||||
pos = size
|
||||
elseif pos < 1 then
|
||||
pos = 1
|
||||
end
|
||||
return pos
|
||||
end
|
||||
|
||||
---@func filestream
|
||||
---@arg path string "Path to the file"
|
||||
---@arg mode string "File mode"
|
||||
---@return stream "The stream for the file."
|
||||
---@desc "This creates a stream from a file."
|
||||
function kio.filestream(path, mode)
|
||||
local dev, rpath = vfs.resolve(path)
|
||||
local h = dev:open(rpath, mode)
|
||||
local stat = dev:stat(rpath)
|
||||
return kio.create_stream({dev=dev, hand=h, stat=stat}, {
|
||||
read = function(self, amt)
|
||||
return self.dev:read(self.hand, amt)
|
||||
end,
|
||||
seek = function(self, whence, amt)
|
||||
local pos = self.dev:seek(self.hand, 0)
|
||||
local npos = kio.calc_seek(whence, amt, self.stat.size, pos)
|
||||
return self.dev:seek(self.hand, npos-pos)
|
||||
end,
|
||||
write = function(self, data)
|
||||
return self.dev:write(self.hand, data)
|
||||
end,
|
||||
close = function(self)
|
||||
return self.dev:close(self.hand)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
---@func dir
|
||||
---@arg udat table "The data to pass to to prototype"
|
||||
---@arg proto function "The prototype function for the iterator"
|
||||
---@return function "The iterator."
|
||||
---@desc "Creates a directory iterator."
|
||||
function kio.dir(udat, proto)
|
||||
return function()
|
||||
return proto(udat)
|
||||
end
|
||||
end
|
||||
|
||||
---@func memstream
|
||||
---@arg str string "The string to create a stream of."
|
||||
---@arg write boolean "If the stream should be writable or not."
|
||||
---@return stream "The memory stream."
|
||||
---@desc "Creates a memory stream."
|
||||
---@note "stream:close() returns the string."
|
||||
function kio.memstream(str, write)
|
||||
return kio.create_stream({str=str, pos=1, write=write}, {
|
||||
read = function(self, amt)
|
||||
local dat = self.str:sub(self.pos, self.pos+amt-1)
|
||||
self.pos = self.pos+#dat
|
||||
return dat
|
||||
end,
|
||||
write = function(self, dat)
|
||||
if (write) then
|
||||
local startstr = self.str:sub(1, self.pos-1)
|
||||
local endstr = self.str:sub(self.pos+#dat)
|
||||
self.str = startstr..dat..endstr
|
||||
self.pos = self.pos + #dat
|
||||
end
|
||||
end,
|
||||
seek = function(self, whence, amt)
|
||||
self.pos = kio.calc_seek(whence, amt, #self.str, self.pos)
|
||||
return self.pos
|
||||
end,
|
||||
close = function(self)
|
||||
return self.str
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
kio.loglevel = {
|
||||
DEBUG = 0,
|
||||
INFO = 1,
|
||||
WARNING = 2,
|
||||
ERROR = 3,
|
||||
PANIC = 255
|
||||
}
|
||||
|
||||
kio.levels = {
|
||||
[0] = "DEBUG",
|
||||
"INFO",
|
||||
"WARNING",
|
||||
"ERROR",
|
||||
[255] = "PANIC"
|
||||
}
|
||||
|
||||
---@func dprint
|
||||
---@arg level integer "The log level"
|
||||
---@arg status string "The message."
|
||||
---@desc "This method logs to the kernel log and wherever else is set up to be printed to."
|
||||
function kio.dprint(level, status)
|
||||
local stack = {}
|
||||
local lkexec = {}
|
||||
local i = 0
|
||||
while lkexec do
|
||||
lkexec = debug.getinfo(i)
|
||||
stack[#stack+1] = lkexec
|
||||
end
|
||||
local src = stack[#stack].source:sub(2)
|
||||
local spart = vfs.parts(src)
|
||||
local exec = spart[#spart]:match("^(.+)%.([^%.]+)$")
|
||||
local message = string.format("[%.2f] [%s] [%s] %s", computer.uptime(), levels[level], exec, status)
|
||||
dmesgs[#dmesgs+1] = {ut=computer.uptime,lvl=level,x=exec,st=status}
|
||||
if (level < $[{PRINT_DMESG_LEVEL}]) then
|
||||
sig.push {
|
||||
type = "dprint",
|
||||
msg = message
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
---@func dmesg
|
||||
---@see kio.dprint
|
||||
kio.dmesg = dprint
|
||||
|
||||
---@func panic
|
||||
---@arg msg string "The error message to display."
|
||||
function kio.panic(msg)
|
||||
dmesg(255, "Kernel panic!")
|
||||
end
|
||||
|
||||
---@func create_pipe
|
||||
---@return stream "Pipe in"
|
||||
---@return stream "Pipe out"
|
||||
---@desc "Creates a pipe."
|
||||
function kio.create_pipe()
|
||||
local pipecore = kio.memstream()
|
||||
local pipein = kio.create_stream({
|
||||
dat = pipecore
|
||||
}, {
|
||||
read = function()
|
||||
-- no
|
||||
end,
|
||||
seek = function()
|
||||
-- no
|
||||
end,
|
||||
write = function(self, dat)
|
||||
self.dat:seek("end", 0)
|
||||
self.dat:write(dat)
|
||||
end,
|
||||
close = function()
|
||||
-- *no*
|
||||
end
|
||||
})
|
||||
local pipeout = kio.create_stream({
|
||||
dat = pipecore,
|
||||
pos = 1
|
||||
}, {
|
||||
read = function(self, amt)
|
||||
self.dat:seek("set", self.pos)
|
||||
local dat = self.dat:read()
|
||||
self.pos = self.pos+#dat
|
||||
return dat
|
||||
end,
|
||||
seek = function()end,
|
||||
write = function()end,
|
||||
close = function()end
|
||||
})
|
||||
return pipein, pipeout
|
||||
end
|
||||
|
||||
---@func init
|
||||
---@desc "Only called once. Sets up the kio library."
|
||||
function kio.init()
|
||||
---@func create_buffer
|
||||
---@arg blocking boolean "True if read calls to a buffer that doesn't contain enough data block."
|
||||
---@arg pid integer "This is set to the PID of the process which handles the buffers."
|
||||
---@return table "The buffer for use anywhere."
|
||||
kio.create_buffer = create_buffer
|
||||
kio.create_buffer = create_buffer
|
||||
kio.init = false
|
||||
end
|
6
ksrc/kstrings.lua
Normal file
6
ksrc/kstrings.lua
Normal file
@ -0,0 +1,6 @@
|
||||
_KINFO = {
|
||||
name = "Tsuki",
|
||||
release = "$[{TSUKI_RELEASE}]",
|
||||
version = "$[{TSUKI_VERSION}]",
|
||||
machine = "$[{TSUKI_TARGET}]", -- OC or LuPI2
|
||||
}
|
6
ksrc/net.lua
Normal file
6
ksrc/net.lua
Normal file
@ -0,0 +1,6 @@
|
||||
--#include "ksrc/net/tsukinet/init.lua"
|
||||
|
||||
local net = {}
|
||||
function net.open(netinfo)
|
||||
|
||||
end
|
6
ksrc/stdlib/err.lua
Normal file
6
ksrc/stdlib/err.lua
Normal file
@ -0,0 +1,6 @@
|
||||
_P.pcall = pcall
|
||||
_P.xpcall = xpcall
|
||||
|
||||
_P.error = {}
|
||||
_P.error.geterror = kio.geterror
|
||||
_P.error.errno = kio.errno
|
@ -4,5 +4,7 @@ function _P.load(...)
|
||||
end
|
||||
end
|
||||
|
||||
--#include "ksrc/stdlib/err.lua"
|
||||
--#include "ksrc/stdlib/string.lua"
|
||||
--#include "ksrc/stdlib/thread.lua"
|
||||
--#include "ksrc/stdlib/thread.lua"
|
||||
--#include "ksrc/stdlib/err.lua"
|
0
ksrc/stdlib/io.lua
Normal file
0
ksrc/stdlib/io.lua
Normal file
@ -1,3 +1,5 @@
|
||||
string.newline = "\n"
|
||||
|
||||
function string.trim(self)
|
||||
return self:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
13
ksrc/vfs.lua
Normal file
13
ksrc/vfs.lua
Normal file
@ -0,0 +1,13 @@
|
||||
local vfs = {}
|
||||
|
||||
function vfs.mount(path, proxy)
|
||||
|
||||
end
|
||||
|
||||
function vfs.resolve(path)
|
||||
|
||||
end
|
||||
|
||||
function vfs.umount(pathorproxy)
|
||||
|
||||
end
|
BIN
tkrnl.velx
BIN
tkrnl.velx
Binary file not shown.
@ -157,7 +157,7 @@ for line in io.stdin:lines() do
|
||||
}
|
||||
elseif (rline:match("^%-@return") and cfunc.type == "func") then
|
||||
local args = parse_line(rline:sub(10))
|
||||
cfunc.ret[#cfunc.args+1] = {
|
||||
cfunc.ret[#cfunc.ret+1] = {
|
||||
type = args[1],
|
||||
doc = args[2],
|
||||
}
|
||||
@ -169,7 +169,17 @@ for line in io.stdin:lines() do
|
||||
elseif (rline:match("^%-@see")) then
|
||||
local args = parse_line(rline:sub(7))
|
||||
cfunc.doc[#cfunc.doc+1] = {
|
||||
doc = "See \27_S"..arg[2].."\27_E"
|
||||
doc = "See \27_S"..args[1].."\27_E"
|
||||
}
|
||||
elseif (rline:match("^%-@note")) then
|
||||
local args = parse_line(rline:sub(8))
|
||||
cfunc.doc[#cfunc.doc+1] = {
|
||||
doc = "NOTE: "..args[1]
|
||||
}
|
||||
elseif (rline:match("^%-@desc")) then
|
||||
local args = parse_line(rline:sub(8))
|
||||
cfunc.doc[#cfunc.doc+1] = {
|
||||
doc = args[1]
|
||||
}
|
||||
elseif (rline:match("^%-@vararg")) then
|
||||
cfunc.vararg = true
|
||||
@ -237,7 +247,7 @@ for i=1, #docs do
|
||||
else
|
||||
rettext = "No return."
|
||||
end
|
||||
docc = docc .. fun .. "\n\nArguments:\n"..argtext.."\n\nReturns:\n"..rettext
|
||||
docc = docc .. fun .. "\n\nArguments:\n"..argtext.."\n\nReturns:\n"..rettext.."\n\n"
|
||||
else
|
||||
docc = docc .. docs[i].methods[j].print_name .. "\n\n"
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user