12 Commits
117 changed files with 922 additions and 3005 deletions
+338 -115
View File
@@ -1,121 +1,344 @@
local cp,c=component,computer;local b_addr=c.getBootAddress();local b_fs=cp.proxy(b_addr)
local gpu=cp.list("gpu")() and cp.proxy(cp.list("gpu")())
local e_rom=cp.list("eeprom")() and cp.proxy(cp.list("eeprom")())
local screens={}
for addr in cp.list("screen") do
if gpu then
gpu.bind(addr)
local w,h=gpu.maxResolution()
gpu.setResolution(w,h)
gpu.fill(1,1,w,h," ")
cp.proxy(addr).turnOn()
screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
end
--:Minify:--
local args={...}
local bootdrive=args[1]
local gpu=components:getFirst("gpu")
local screenTextBuffer=nil
local cursorX,cursorY=0,0
local screenSizeX,screenSizeY=128,25
if gpu then
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY)
for t,v in components:list() do
if t == "screen" then
gpu:assignBuffer(screenTextBuffer, v)
end
end
end
local function scroll(scr) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(t)
if not gpu then return end
for s=1, #screens do
local scr=screens[s]
gpu.bind(scr.addr)
for i=1,#t do
local char=t:sub(i,i)
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;gpu.set(scr.cx,scr.cy," ") end
else gpu.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr);scr.cy=scr.cy-1 end
end
end
local function write(text)
cursorX, cursorY = screenTextBuffer:pasteText(cursorX, cursorY, "SCROLL_SPILL_CLEAR", text)
cursorY = cursorY + 1
cursorX = 0
if cursorY >= screenSizeY then
cursorY = screenSizeY-1
screenTextBuffer:newline()
end
end
local function throw(err)
if gpu then
gpu.setBackground(0x0000AA);
gpu.setForeground(0xFFFFFF);
for i=1, #screens do
gpu.fill(1,1,screens[i].w,screens[i].h," ");
screens[i].cx,screens[i].cy=1,1;
end
write("CRITICAL KERNEL ERROR:\n"..tostring(err))
end
while true do c.pullSignal() end
local function displaySuperBadError(err)
gpu:freeAllBuffers()
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY)
for t,v in components:list() do
if t == "screen" then
gpu:assignBuffer(screenTextBuffer, v)
end
end
term.setBackgroundColor(0x1)
term.setTextColor(0x4)
term.clear()
term.setCursorPos(1, 1)
term.write("A critical error occurred while loading the system:")
term.setCursorPos(1, 3)
write(err)
while true do end
end
local ok,err=xpcall(function()
local apis={}
local _l={coroutine=1,debug=1,_VERSION=1,assert=1,collectgarbage=1,error=1,getmetatable=1,ipairs=1,load=1,math=1,next=1,pairs=1,pcall=1,rawequal=1,rawget=1,rawlen=1,rawset=1,select=1,setmetatable=1,string=1,table=1,tonumber=1,tostring=1,type=1,xpcall=1,_G=1}
for k,v in pairs(_G) do if not _l[k] then apis[k]=v;_G[k]=nil end end
function sleep(t) local s=c.uptime()+t;while c.uptime()<s do c.pullSignal(s-c.uptime()) end end
local function getFile(path)
local h,err=b_fs.open(path,"r")
if not h then throw("Cannot open: "..path) end
local buf,chk="",""
repeat chk=b_fs.read(h,math.huge);buf=buf..(chk or "") until not chk
b_fs.close(h)
return buf
end
local Kernel=load(getFile("/kernel.lua"),"@Kernel")
local initFs=load(getFile("/oc/initdisks"),"@Init_disks")
local fs=load(getFile("/initfs"),"@InitFs")
if not Kernel then throw("Kernel load failed.") end
if initFs then initFs=initFs(apis, b_fs, b_addr) end
if fs then fs=fs() end
local eQ={}
local function qEv(e,...) table.insert(eQ,{e,...}) end
local efi={
getEpochMs=function() return math.floor(c.uptime()*1000) end,
getUptime=function() return c.uptime()*1000 end,
date=function() return tostring(apis.os.date()) end,
getMachineEvent=function()
if #eQ > 0 then
return table.unpack(table.remove(eQ, 1))
else
return nil
end
end,
getEEPROM=function() return e_rom and e_rom.get() or "" end,
setEEPROM=function(_,t) if e_rom then e_rom.set(t) end end,
getNvram=function() return e_rom and e_rom.getData() or "" end,
setNvram=function(_,t) if e_rom then e_rom.setData(t) end end,
beep=function(freq, timeMs) c.beep(freq, timeMs / 1000) end,
initfs=fs,
disks=initFs,
architecture="oc",
firmware=apis,
reboot=false,
yield=function() coroutine.yield() end,
screenCtl={
print=function(_,t) write(tostring(t).."\n") end,
printInline=function(_,t) write(tostring(t)) end,
clear=function() if gpu then for i=1, #screens do local scr=screens[i];gpu.bind(scr.addr);gpu.fill(1,1,scr.w,scr.h," ");scr.cx,scr.cy=1,1 end end end,
resetCursor=function() for i=1, #screens do local scr=screens[i];scr.cx,scr.cy=1,1 end end,
setBackgroundColor=function(_,cl) if gpu then gpu.setBackground(cl) end end,
setTextColor=function(_,cl) if gpu then gpu.setForeground(cl) end end,
enable=function() end,
disable=function() end
}
local ok, err = xpcall(function()
local apis = {}
local lua = {
coroutine = true,
debug = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getmetatable = true,
ipairs = true,
__inext = true,
load = true,
math = true,
next = true,
pairs = true,
pcall = true,
rawequal = true,
rawget = true,
rawlen = true,
rawset = true,
select = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true,
_G = true
}
local kCo=coroutine.create(function()
local s,e=xpcall(Kernel,debug.traceback,efi)
if not s and not efi.reboot then throw(e) end
if efi.reboot then c.shutdown(true) else c.shutdown() end
end)
efi.screenCtl:print("Loaded in "..tostring(c.uptime()).."s")
while true do
local st,e=coroutine.resume(kCo)
c.pushSignal("NoSleep")
local ex=false
while not ex do
local ev={c.pullSignal(0)}
if ev[1]=="key_down" then qEv("keyPressed",1,ev[3]);qEv("keyTyped",1,string.char(ev[3]))
elseif ev[1]=="key_up" then qEv("keyReleased",1,ev[3])
end
if ev[1]=="NoSleep" then ex=true else qEv(table.unpack(ev)) end
end
if st=="error" or coroutine.status(kCo)=="dead" then
if efi.reboot then c.shutdown(true) end
throw("Kernel fault: "..tostring(e))
local debug = debug
for i, v in pairs(_G) do
if not lua[i] or lua[i] == nil then
apis[i] = v
_G[i] = nil
end
end
end,debug.traceback)
if not ok then throw("Boot fault: "..err) end
local function string_file(file)
local str = file:read()
local buf = {str or ""}
local pos = 1
local closed = false
local function content()
return table.concat(buf)
end
local function set_content(s)
buf = {s}
end
local function flush()
file.write(content())
end
local file = {}
function file.read(n)
assert(not closed, "file is closed")
local s = content()
local len = #s
if not n then
local out = s:sub(pos)
pos = len + 1
return out
end
local out = s:sub(pos, pos + n - 1)
pos = pos + #out
return out
end
function file.write(data)
assert(not closed, "file is closed")
local s = content()
local before = s:sub(1, pos - 1)
local after = s:sub(pos + #data)
set_content(before .. data .. after)
pos = pos + #data
return true
end
function file.seek(whence, offset)
assert(not closed, "file is closed")
local s = content()
local len = #s
whence = whence or "cur"
offset = offset or 0
if whence == "set" then
pos = offset + 1
elseif whence == "cur" then
pos = pos + offset
elseif whence == "end" then
pos = len + offset + 1
else
error("invalid whence")
end
if pos < 1 then pos = 1 end
if pos > len + 1 then pos = len + 1 end
return pos - 1
end
function file:close()
assert(not closed, "file is closed")
flush()
closed = true
end
function file:flush()
assert(not closed, "file is closed")
flush()
end
return file
end
local function getFile(path)
local file = bootdrive:open(path, "r")
if not file then
displaySuperBadError("Could not open file: " .. path)
end
local content = file:read()
return content
end
local Kernel = load(getFile("/boot/kernel.lua"),"@Kernel")
local initFs = load(getFile("/boot/ac/initdisks"),"@Init_disks")(apis)
local fs = load(getFile("/boot/initfs"), "@InitFs")()
if not Kernel then displaySuperBadError("Could not load kernel.") end
if not initFs then displaySuperBadError("Could not load initdisks.") end
if not fs then displaySuperBadError("Could not load initfs.") end
local computercomp=apis.components:getFirst("computer")
local uefi=apis.components:getFirst("uefi")
local computer = {
time = function() return apis.os.epoch("utc") end,
clock = function() return apis.os.clock() * 1000 end,
shutdown = apis.os.shutdown,
reboot = apis.os.reboot,
getMachineEvent = function()
return computercomp:getMachineEvent()
end,
getEEPROM = function() return uefi.data end,
setEEPROM = function(_, text)
uefi.data=text
end
}
local icolors = {
[0x1] = 1, -- #000000
[0x2] = 2, -- #FFFFFF
[0x4] = 3, -- #FF0000
[0x8] = 4, -- #00FF00
[0x10] = 5, -- #0000FF
[0x20] = 6, -- #00FFFF
[0x40] = 7, -- #FF00FF
[0x80] = 8, -- #FFFF00
[0x100] = 9, -- #FF6D00
[0x200] = 10, -- #6DFF55
[0x400] = 11, -- #24FFFF
[0x800] = 12, -- #924900
[0x1000] = 13, -- #6D6D55
[0x2000] = 14, -- #DBDBAA
[0x4000] = 15, -- #6D00FF
[0x8000] = 16 -- #B6FF00
}
local colors = {
0x0001, -- #000000
0x0002, -- #FFFFFF
0x0004, -- #FF0000
0x0008, -- #00FF00
0x0010, -- #0000FF
0x0020, -- #00FFFF
0x0040, -- #FF00FF
0x0080, -- #FFFF00
0x0100, -- #FF6D00
0x0200, -- #6DFF55
0x0400, -- #24FFFF
0x0800, -- #924900
0x1000, -- #6D6D55
0x2000, -- #DBDBAA
0x4000, -- #6D00FF
0x8000 -- #B6FF00
}
apis.term.setBackgroundColor(0x8000)
apis.term.setTextColor(0x1000)
apis.term.clear()
apis.term.setCursorPos(1, 1)
local kernelCoro = coroutine.create(function()
---@diagnostic disable-next-line: param-type-mismatch
local ok, err = xpcall(Kernel, debug.traceback, apis, initFs, "cct", "/sbin/init",
{
print = function(_, text) write(text .. "\n") end,
printInline = function(_, text) write(text) end,
clear = function()
apis.term.clear()
apis.term.setCursorPos(1, 1)
end,
setCursorPos = function(_, x, y)
apis.term.setCursorPos(x, y)
end,
getCursorPos = function() return apis.term.getCursorPos() end,
getSize = function() return apis.term.getSize() end,
setBackgroundColor = function(_, color)
apis.term.setBackgroundColor(colors[color])
end,
setTextColor = function(_, color)
apis.term.setTextColor(colors[color])
end,
getBackgroundColor = function()
return icolors[apis.term.getBackgroundColor()]
end,
getTextColor = function()
return icolors[apis.term.getTextColor()]
end
}, computer, fs, "$")
if not ok then displaySuperBadError(err) end
end)
function coroutine.resumeWithTimeout(co, timeout, ...)
local startTime = computer.time()
debug.sethook(co, function()
if computer.time() > startTime + timeout then
return coroutine.yield("timeout")
end
end, "", 1000)
local ret = {coroutine.resume(co, ...)}
if ret[1] and ret[2] == "timeout" then
return "timeout"
elseif ret[1] == false then
return "error", ret[2]
else
debug.sethook(co)
return "success", table.unpack(ret, 2)
end
end
write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
while true do
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50)
apis.os.queueEvent("NoSleep")
local exit = false
while not exit do
local event = {coroutine.yield()}
if event[1] == "key" then
queueEvent("keyPressed", 1, event[2])
if acekeys[event[2]] then
queueEvent("keyTyped", 1, acekeys[event[2]])
end
elseif event[1] == "char" then
queueEvent("keyTyped", 1, event[2])
elseif event[1] == "key_up" then
queueEvent("keyReleased", 1, event[2])
elseif event[1] == "disk" then
queueEvent("componentAdded", "disk")
elseif event[1] == "disk_eject" then
queueEvent("componentRemoved", "disk")
elseif event[1] == "modem_message" then
queueEvent("modem_message", table.unpack(event, 2))
elseif event[1] == "rednet_message" then
queueEvent("rednet_message", table.unpack(event, 2))
elseif event[1] == "http_success" then
queueEvent("http_success", table.unpack(event, 2))
elseif event[1] == "http_failure" then
queueEvent("http_failure", table.unpack(event, 2))
elseif event[1] == "NoSleep" then
exit = true
end
end
if status == "error" or coroutine.status(kernelCoro) == "dead" then
displaySuperBadError("Kernel error: " .. tostring(err))
coroutine.yield("key")
end
end
end, debug.traceback)
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
while true do coroutine.yield() end
@@ -1,68 +0,0 @@
local init
do
local component_invoke = component.invoke
local function boot_invoke(address, method, ...)
local result = table.pack(pcall(component_invoke, address, method, ...))
if not result[1] then
return nil, result[2]
else
return table.unpack(result, 2, result.n)
end
end
-- backwards compatibility, may remove later
local eeprom = component.list("eeprom")()
computer.getBootAddress = function()
return boot_invoke(eeprom, "getData")
end
computer.setBootAddress = function(address)
return boot_invoke(eeprom, "setData", address)
end
do
local screen = component.list("screen")()
local gpu = component.list("gpu")()
if gpu and screen then
boot_invoke(gpu, "bind", screen)
end
end
local function tryLoadFrom(address)
local handle, reason = boot_invoke(address, "open", "/oc/boot.lua")
if not handle then
return nil, reason
end
local buffer = ""
repeat
local data, reason = boot_invoke(address, "read", handle, math.maxinteger or math.huge)
if not data and reason then
return nil, reason
end
buffer = buffer .. (data or "")
until not data
boot_invoke(address, "close", handle)
return load(buffer, "=init")
end
local reason
if computer.getBootAddress() then
init, reason = tryLoadFrom(computer.getBootAddress())
end
if not init then
computer.setBootAddress()
for address in component.list("filesystem") do
init, reason = tryLoadFrom(address)
if init then
computer.setBootAddress(address)
break
end
end
end
if not init then
error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0)
end
end
local ok, err = xpcall(init,debug.traceback)
if not ok then
error(err)
else
return err
end
@@ -1,136 +0,0 @@
local args = {...}
local apis = args[1]
local bootdrive = args[2]
local bootaddr = args[3]
local disks = {}
local internal = {}
local function createDisk(id, hw)
local disk = {
address = id,
isReadOnly = function() return hw.isReadOnly() end
}
function disk:spaceUsed() return hw.spaceUsed() end
function disk:spaceTotal() return hw.spaceTotal() end
function disk:list(path)
if not hw.exists(path) or not hw.isDirectory(path) then
return nil, "not directory"
end
return hw.list(path)
end
function disk:fileExists(path)
return hw.exists(path) and not hw.isDirectory(path)
end
function disk:directoryExists(path)
return hw.exists(path) and hw.isDirectory(path)
end
function disk:type(path)
if not hw.exists(path) then
return nil
elseif hw.isDirectory(path) then
return "directory"
else
return "file"
end
end
function disk:makeDirectory(path)
hw.makeDirectory(path)
end
function disk:remove(path)
if hw.exists(path) then hw.remove(path) end
end
function disk:setLabel(label) hw.setLabel(label) end
function disk:getLabel() return hw.getLabel() end
function disk:attributes(path)
return {
size = hw.size(path),
isDir = hw.isDirectory(path),
isReadOnly = hw.isReadOnly(),
modified = hw.lastModified(path),
created = hw.lastModified(path)
}
end
function disk:open(path, mode)
local fd = hw.open(path, mode)
if not fd then
local dir = path:match("^(.*)/[^/]+$")
if dir and not hw.exists(dir) then
local ok, err = hw.makeDirectory(dir)
if not ok then
return nil, err or "could not create parent directory"
end
end
fd = hw.open(path, mode)
if not fd then
return nil, "file not found or access denied"
end
end
return {
read = function(num) return hw.read(fd, num) end,
readAll = function()
local data = {}
while true do
local chunk = hw.read(fd, math.huge)
if not chunk then break end
data[#data + 1] = chunk
end
return table.concat(data)
end,
write = function(data) return hw.write(fd, data) end,
seek = function(whence, offset)
return hw.seek(fd, whence, offset)
end,
flush = function()
hw.close(fd)
fd = hw.open(path, mode)
end,
close = function()
hw.close(fd)
fd = nil
end
}
end
return disk
end
internal["$"] = createDisk("$", bootdrive)
local function refresh()
disks = {}
for addr in apis.component.list("filesystem") do
if addr ~= bootaddr then
disks[addr] = createDisk(addr, apis.component.proxy(addr))
end
end
end
local function iter()
refresh()
local combined = {}
for id, obj in pairs(internal) do combined[id] = obj end
for id, obj in pairs(disks) do combined[id] = obj end
return pairs(combined)
end
return {refresh = refresh, list = iter}
@@ -1,15 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc={}
kernel.oc.component=kernel.apis.component
kernel.oc.computer=kernel.apis.computer
kernel.log("Installed components:")
for addr, typ in kernel.oc.component.list() do
local dev=kernel.oc.component.proxy(addr)
local tier=""
if dev.getTier then
tier=dev.getTier()
end
kernel.log(" "..addr.." : "..typ..tier)
end
@@ -1,23 +0,0 @@
--:Minify:--
local kernel=...
local component=kernel.oc.component
local function wrap(p)
return function(op, mode)
if op=="type" then
return "device"
elseif op=="open" then
if kernel.uid~=0 then error("EACCES") end
return component.proxy(p)
end
end
end
for addr, typ in kernel.oc.component.list() do
local obj=wrap(addr)
kernel.devfs.data["raw"][addr]=obj
local typefolder=kernel.devfs.data["raw"]["by-type"][typ]
if not typefolder then typefolder={} end
typefolder[tostring(#table.keys(typefolder)+1)] = obj
kernel.devfs.data["raw"]["by-type"][typ]=typefolder
end
@@ -1,177 +0,0 @@
-- OpenComputers TTY driver
local kernel = ...
local component = kernel.oc.component
local computer = kernel.oc.computer
local plt = {
0x000000, 0x000040, 0x000080, 0x0000C0, 0x0000FF,
0x002400, 0x002440, 0x002480, 0x0024C0, 0x0024FF,
0x004900, 0x004940, 0x004980, 0x0049C0, 0x0049FF,
0x006D00, 0x006D40, 0x006D80, 0x006DC0, 0x006DFF,
0x009200, 0x009240, 0x009280, 0x0092C0, 0x0092FF,
0x00B600, 0x00B640, 0x00B680, 0x00B6C0, 0x00B6FF,
0x00DB00, 0x00DB40, 0x00DB80, 0x00DBC0, 0x00DBFF,
0x00FF00, 0x00FF40, 0x00FF80, 0x00FFC0, 0x00FFFF,
0x330000, 0x330040, 0x330080, 0x3300C0, 0x3300FF,
0x332400, 0x332440, 0x332480, 0x3324C0, 0x3324FF,
0x334900, 0x334940, 0x334980, 0x3349C0, 0x3349FF,
0x336D00, 0x336D40, 0x336D80, 0x336DC0, 0x336DFF,
0x339200, 0x339240, 0x339280, 0x3392C0, 0x3392FF,
0x33B600, 0x33B640, 0x33B680, 0x33B6C0, 0x33B6FF,
0x33DB00, 0x33DB40, 0x33DB80, 0x33DBC0, 0x33DBFF,
0x33FF00, 0x33FF40, 0x33FF80, 0x33FFC0, 0x33FFFF,
0x660000, 0x660040, 0x660080, 0x6600C0, 0x6600FF,
0x662400, 0x662440, 0x662480, 0x6624C0, 0x6624FF,
0x664900, 0x664940, 0x664980, 0x6649C0, 0x6649FF,
0x666D00, 0x666D40, 0x666D80, 0x666DC0, 0x666DFF,
0x669200, 0x669240, 0x669280, 0x6692C0, 0x6692FF,
0x66B600, 0x66B640, 0x66B680, 0x66B6C0, 0x66B6FF,
0x66DB00, 0x66DB40, 0x66DB80, 0x66DBC0, 0x66DBFF,
0x66FF00, 0x66FF40, 0x66FF80, 0x66FFC0, 0x66FFFF,
0x990000, 0x990040, 0x990080, 0x9900C0, 0x9900FF,
0x992400, 0x992440, 0x992480, 0x9924C0, 0x9924FF,
0x994900, 0x994940, 0x994980, 0x9949C0, 0x9949FF,
0x996D00, 0x996D40, 0x996D80, 0x996DC0, 0x996DFF,
0x999200, 0x999240, 0x999280, 0x9992C0, 0x9992FF,
0x99B600, 0x99B640, 0x99B680, 0x99B6C0, 0x99B6FF,
0x99DB00, 0x99DB40, 0x99DB80, 0x99DBC0, 0x99DBFF,
0x99FF00, 0x99FF40, 0x99FF80, 0x99FFC0, 0x99FFFF,
0xCC0000, 0xCC0040, 0xCC0080, 0xCC00C0, 0xCC00FF,
0xCC2400, 0xCC2440, 0xCC2480, 0xCC24C0, 0xCC24FF,
0xCC4900, 0xCC4940, 0xCC4980, 0xCC49C0, 0xCC49FF,
0xCC6D00, 0xCC6D40, 0xCC6D80, 0xCC6DC0, 0xCC6DFF,
0xCC9200, 0xCC9240, 0xCC9280, 0xCC92C0, 0xCC92FF,
0xCCB600, 0xCCB640, 0xCCB680, 0xCCB6C0, 0xCCB6FF,
0xCCDB00, 0xCCDB40, 0xCCDB80, 0xCCDBC0, 0xCCDBFF,
0xCCFF00, 0xCCFF40, 0xCCFF80, 0xCCFFC0, 0xCCFFFF,
0xFF0000, 0xFF0040, 0xFF0080, 0xFF00C0, 0xFF00FF,
0xFF2400, 0xFF2440, 0xFF2480, 0xFF24C0, 0xFF24FF,
0xFF4900, 0xFF4940, 0xFF4980, 0xFF49C0, 0xFF49FF,
0xFF6D00, 0xFF6D40, 0xFF6D80, 0xFF6DC0, 0xFF6DFF,
0xFF9200, 0xFF9240, 0xFF9280, 0xFF92C0, 0xFF92FF,
0xFFB600, 0xFFB640, 0xFFB680, 0xFFB6C0, 0xFFB6FF,
0xFFDB00, 0xFFDB40, 0xFFDB80, 0xFFDBC0, 0xFFDBFF,
0xFFFF00, 0xFFFF40, 0xFFFF80, 0xFFFFC0, 0xFFFFFF,
0x000000, 0x0F0F0F, 0x1E1E1E, 0x2D2D2D,
0x3C3C3C, 0x4B4B4B, 0x5A5A5A, 0x696969,
0x787878, 0x878787, 0x969696, 0xA5A5A5,
0xB4B4B4, 0xC3C3C3, 0xD2D2D2, 0xE1E1E1
}
local gpus,screens = {},{}
for addr, typ in component.list("gpu") do
if typ == "gpu" then
gpus[#gpus+1]=component.proxy(addr)
end
end
if #gpus>0 then
for addr, typ in component.list("screen") do
if typ == "screen" then
gpus[1].bind(addr)
local w,h = gpus[1].maxResolution()
gpus[1].setResolution(w,h)
screens[addr]={cx=1,cy=1,w=w,h=h,addr=addr,fg=0,bg=0,gpu=nil}
end
end
end
local scrnum = 0
for i,v in pairs(screens) do
scrnum=scrnum+1
end
kernel.log("initialized "..tostring(#gpus).." gpus and "..tostring(scrnum).." screens")
local binds,newid={},0
local curaddr=""
local function scroll(scr, gpu) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(text, addr)
local g=gpus[1]
local scr=screens[addr]
if not scr then error("NODEV") end
if curaddr~=addr then g.bind(addr); g.setForeground(scr.fg); g.setBackground(scr.bg) end
for i=1,#text do
local char=text:sub(i,i)
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;g.set(scr.cx,scr.cy," ") end
else g.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr, g);scr.cy=scr.cy-1 end
end
end
local function newtty(addr)
newid=newid+1
kernel.devfs.data["tty"][tostring(newid)]=function(op, mode)
if op=="type" then
return "Terminal"
elseif op=="open" then
local h = {
read=function(amount) end,
write=function(content)
write(content, addr)
end,
size=function()
return screens[addr].w, screens[addr].h
end,
clear=function()
local g=gpus[1]
local scr=screens[addr]
if addr~=curaddr then g.bind(addr) end
g.fill(1,1,scr.w,scr.h," ");
scr.cx,scr.cy=1,1
end,
gpos=function()
return screens[addr].cx, screens[addr].cy
end,
spos=function(x,y)
if not tonumber(x) or not tonumber(y) then error("Invailid arg") end
screens[addr].cx, screens[addr].cy = x,y
end,
sfgc=function(c)
screens[addr].fg=c
end,
sbgc=function(c)
screens[addr].bg=c
end,
gfgc=function()
return screens[addr].fg
end,
gbgc=function()
return screens[addr].bg
end,
isvirt=function()
return false
end,
gplt=function()
return plt
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
if #gpus>=1 and scrnum>=1 then
for addr,obj in pairs(screens) do
newtty(addr)
end
end
@@ -1,113 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc.keyboards={}
local kbs=kernel.oc.keyboards
local kbidx=0
local keyboard = {}
keyboard.keys = {
back = 0x0E, -- backspace
delete = 0xD3,
down = 0xD0,
enter = 0x1C,
home = 0xC7,
lcontrol = 0x1D,
left = 0xCB,
lmenu = 0x38, -- left Alt
lshift = 0x2A,
pageDown = 0xD1,
rcontrol = 0x9D,
right = 0xCD,
rmenu = 0xB8, -- right Alt
rshift = 0x36,
space = 0x39,
tab = 0x0F,
up = 0xC8,
["end"] = 0xCF,
numpadenter = 0x9C,
}
kernel.oc.keys=keyboard.keys
for i=0, 255 do
kernel.oc.keys[string.char(i)]=i
end
-------------------------------------------------------------------------------
function keyboard.isAltDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lmenu] or kbs[addr].pressedCodes[keyboard.keys.rmenu]
end
function keyboard.isControl(char)
return type(char) == "number" and (char < 0x20 or (char >= 0x7F and char <= 0x9F))
end
function keyboard.isControlDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lcontrol] or kbs[addr].pressedCodes[keyboard.keys.rcontrol]
end
function keyboard.isKeyDown(addr,charOrCode)
if type(charOrCode) == "string" then
return kbs[addr].pressedChars[utf8 and utf8.codepoint(charOrCode) or charOrCode:byte()]
elseif type(charOrCode) == "number" then
return kbs[addr].pressedCodes[charOrCode]
end
end
function keyboard.isShiftDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lshift] or kbs[addr].pressedCodes[keyboard.keys.rshift]
end
kernel.oc.keyboard=keyboard
local function serializeBool(bool)
if bool then
return "T"
else
return "F"
end
end
for addr, typ in kernel.oc.component.list("keyboard") do
if typ=="keyboard" then
kbidx=kbidx+1
kbs[addr]={pressedChars = {}, pressedCodes = {}, events=kernel.newFifo()}
kernel.devfs.data["input"]["keyboard"..tostring(kbidx)]=function(op,mode)
if op=="type" then
return "Keyboard"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {kernel.oc.keyboards[addr].events.pop()}
if event[1] then
rv=rv..event[1]
end
end
if rv=="" then rv=nil end
return rv
end,
write=function(content)
end,
gctrl=function()
return serializeBool(keyboard.isControlDown(addr))..";"..serializeBool(keyboard.isAltDown(addr))
end,
isKeyDown=function(char)
return keyboard.isKeyDown(addr,char)
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
end
@@ -1,99 +0,0 @@
--:Minify:--
local kernel=...
local keys=kernel.oc.keys
kernel.processes.ocdaemon = function()
local timeout = false
kernel.log("OC daemon started")
local ctrlKeyMap = {
[keys.a]=1, [keys.b]=2, [keys.c]=3,
[keys.d]=4, [keys.e]=5, [keys.f]=6,
[keys.g]=7, [keys.h]=8, [keys.i]=9,
[keys.j]=10, [keys.k]=11, [keys.l]=12,
[keys.m]=13, [keys.n]=14, [keys.o]=15,
[keys.p]=16, [keys.q]=17, [keys.r]=18,
[keys.s]=19, [keys.t]=20, [keys.u]=21,
[keys.v]=22, [keys.w]=23, [keys.x]=24,
[keys.y]=25, [keys.z]=26,
}
local specialKeyMap = {
[keys.up] = "\27[A",
[keys.down] = "\27[B",
[keys.right] = "\27[C",
[keys.left] = "\27[D",
[keys.home] = "\27[H",
[keys["end"]] = "\27[F",
--[keys.pageUp] = "\27[5~",
--[keys.pageDown] = "\27[6~",
[keys.delete] = "\27[3~",
[keys.enter] = "\n",
[keys.back] = "\b",
[keys.tab] = "\t",
}
while true do
local event = {kernel.EFI.getMachineEvent()}
if event[1] then
local eventType = event[1]
local addr = event[2]
local char = event[3]
local keyCode = event[4]
if eventType == "key_down" then
local keyboard = kernel.oc.keyboards[addr]
if keyboard.ctrl then
local ctrlByte = ctrlKeyMap[keyCode]
if ctrlByte then
if ctrlByte == 3 then
for _, task in ipairs(syscall.getTasks()) do
syscall.sigsend(task, 1)
end
else
keyboard.events.push(string.char(ctrlByte))
end
end
else
local special = specialKeyMap[keyCode]
if special then
keyboard.events.push(special)
elseif char and char > 0 then
keyboard.events.push(kernel.apis.unicode.char(char))
end
end
elseif eventType == "key_up" then
end
timeout = false
else
timeout = true
end
if timeout then
sleep(0.05)
end
end
end
kernel.log("OC daemon queued for execution")
@@ -1,146 +0,0 @@
--:Minify:--
local kernel=...
local alpha = 0.85
local C_target = 0.01
local Tmin = 0.0005
local Tmax = 0.5
local lambda_budget = 0.08
local lambda_clamp = 0.03
local lambda_var = 0.02
local k_min = 0.5
local k_max = 0.5
local B = 0.01
function kernel.main()
kernel.log("Starting main loop...")
kernel.saveLog()
local stopLog=5
local logTasks=100
while not kernel.exitMain do
if kernel.config.logTasks then
if logTasks<0 then
kernel.log("Active Tasks:")
for i,v in pairs(kernel.tasks) do
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
end
kernel.log("[END BLOCK]")
logTasks=100
end
logTasks=logTasks-1
end
local N = 0
local Tmin_hit = 0
local Tmax_hit = 0
local totalTaskTime = 0
local taskTimes = {}
for pid, task in pairs(kernel.tasks) do
if kernel.exitMain then break end
for _,list in ipairs(kernel.perTaskHooks) do
for id,hook in ipairs(list) do
local ok,err = xpcall(hook, debug.traceback, task, pid)
if not ok then
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
list[id]=nil
end
end
end
if task.status == "R" then
N = N + 1
task.timeSlice = math.min(Tmax, math.max(Tmin, B / (N ^ alpha)))
if task.status == "R" then
local startTime = kernel.EFI:getEpochMs()
local ret
if stopLog > 0 then
kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF)
end
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
local elapsed = kernel.EFI:getEpochMs() - startTime
task.lastTime = elapsed
task.totalTime = (task.totalTime or 0) + elapsed
task.numRuns = (task.numRuns or 0) + 1
taskTimes[#taskTimes+1] = elapsed
totalTaskTime = totalTaskTime + elapsed
if elapsed <= Tmin then Tmin_hit = Tmin_hit + 1 end
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
if ret[1] == "error" or ret[1] == false then
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
task.status = "Z"
task.exit = "processHandlerException: " .. tostring(ret[2])
elseif ret[1] == "timeout" then
task.ivs = task.ivs + 1
task.syscallReturn = {}
elseif ret[1] == "success" or ret[1] == true then
task.vs = task.vs + 1
if ret[2] == "syscall" then
local scname = ret[3]
if kernel.syscalls[scname] then
if kernel.config.debugSyscalls then
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
for i = 4, #ret do
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
end
end
local sysret = { xpcall(kernel.syscalls[scname], debug.traceback, table.unpack(ret, 4)) }
if kernel.config.debugSyscalls then
if not sysret[1] then
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
else
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
for i = 2, #sysret do
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
end
end
end
if not sysret[1] then
task.syscallReturn = { false, sysret[2] }
else
task.syscallReturn = { true, table.unpack(sysret, 2) }
end
else
task.syscallReturn = { false, "Unknown syscall: " .. tostring(scname) }
end
end
end
end
end
kernel.EFI:yield()
end
local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0
local T_prev_var = 0
for _, t in ipairs(taskTimes) do
T_prev_var = T_prev_var + (t - T_prev_avg) ^ 2
end
if N > 0 then T_prev_var = T_prev_var / N end
if N > 0 then
local f_clamp = k_min * (Tmin_hit / N) - k_max * (Tmax_hit / N)
local B_budget = (C_target * (N ^ (alpha - 1))) / math.max(T_prev_avg, 1e-8)
B = B + lambda_budget * (B_budget - B) + lambda_clamp * f_clamp - lambda_var * T_prev_var
end
kernel.hpv.reapDeadTasks()
if stopLog > 0 then
kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B))
stopLog = stopLog - 1
kernel.saveLog()
end
end
end
@@ -321,7 +321,7 @@ local ok, err = xpcall(function()
end
end)
function EFI.resumeWithTimeout(co, timeout, ...)
function coroutine.resumeWithTimeout(co, timeout, ...)
local startTime = EFI.getEpochMs()
debug.sethook(co, function()
if EFI.getEpochMs() > startTime + timeout then
@@ -342,7 +342,7 @@ local ok, err = xpcall(function()
write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
while true do
local status, err = EFI.resumeWithTimeout(kernelCoro, 50)
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50)
apis.os.queueEvent("NoSleep")
local exit = false
while not exit do
@@ -47,7 +47,7 @@ local function write(text, term)
term.setCursorPos(x, y)
end
local function displaySuperBadError(err, noyield)
local function displaySuperBadError(err)
lterm.setBackgroundColor(0x1)
lterm.setTextColor(0x4)
lterm.clear()
@@ -145,9 +145,9 @@ local ok, err = xpcall(function()
return content
end
local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/kernel.lua"),"@Kernel")
local initFs = load(getFile(BOOT_DRIVE_PATH .. "/cct/initdisks"),"@Init_disks")(apis)
local fs = load(getFile(BOOT_DRIVE_PATH .. "/initfs"), "@InitFs")()
local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/boot/kernel.lua"),"@Kernel")
local initFs = load(getFile(BOOT_DRIVE_PATH .. "/boot/cct/initdisks"),"@Init_disks")(apis)
local fs = load(getFile(BOOT_DRIVE_PATH .. "/boot/initfs"), "@InitFs")()
if not Kernel then displaySuperBadError("Could not load kernel.") end
if not initFs then displaySuperBadError("Could not load initdisks.") end
@@ -419,7 +419,6 @@ local ok, err = xpcall(function()
end
local EFI = {
yield=function() end,
getEpochMs = function() return apis.os.epoch("utc") end,
getUptime = function() return apis.os.clock() * 1000 end,
date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end,
@@ -507,14 +506,15 @@ local ok, err = xpcall(function()
--pf
---@diagnostic disable-next-line: param-type-mismatch-
local ok, err = xpcall(Kernel, debug.traceback, EFI)
if not ok then
error(err)
if not ok and not EFI.reboot then displaySuperBadError(err) end
if err then
apis.os.reboot()
else
apis.os.shutdown()
end
end)
function EFI.resumeWithTimeout(co, timeout, ...)
function coroutine.resumeWithTimeout(co, timeout, ...)
local startTime = EFI.getEpochMs()
debug.sethook(co, function()
if EFI.getEpochMs() > startTime + timeout then
@@ -536,7 +536,7 @@ local ok, err = xpcall(function()
--p
while true do
local status, err = EFI.resumeWithTimeout(kernelCoro, 50)
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50)
apis.os.queueEvent("NoSleep")
local exit = false
while not exit do
@@ -58,11 +58,11 @@ function _G.term.native()
term.setCursorPos(1, 1)
term.setCursorBlink(true)
term.clear()
local file = fs.open(BOOT_DRIVE_PATH.."/cct/boot.lua", "r")
local file = fs.open(BOOT_DRIVE_PATH.."/boot/cct/boot.lua", "r")
if file == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not find /cct/boot.lua. UnBIOS cannot continue.")
term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.")
term.setCursorPos(1, 2)
term.write("Press any key to continue")
coroutine.yield("key")
@@ -73,7 +73,7 @@ function _G.term.native()
if fn == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not load /cc/boot.lua. UnBIOS cannot continue.")
term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.")
term.setCursorPos(1, 2)
term.write(err)
term.setCursorPos(1, 3)
@@ -250,21 +250,6 @@ internal["rom"] = createDisk("rom", "/rom", true, {
end
})
internal["root"] = createDisk("root", "/root", false, {
setLabel = function(label)
local h = fs.open("/.rootlabel", "w")
h.write(label)
h.close()
end,
getLabel = function()
local h = fs.open("/.rootlabel", "r")
if not h then return "$" end
local label = h.readAll()
h.close()
return label
end
})
local function refresh()
disks={}
for _, disk in ipairs({peripheral.find("drive")}) do
@@ -191,14 +191,16 @@ local function newtty(obj, id, ev)
write(content, obj)
end,
size=function()
return obj.getSize()
local s={obj.getSize()}
return table.concat(s,";")
end,
clear=function()
obj.clear()
obj.setCursorPos(1,1)
end,
gpos=function()
return obj.getCursorPos()
local s={obj.getCursorPos()}
return table.concat(s,";")
end,
spos=function(x,y)
return obj.setCursorPos(x,y)
@@ -1,151 +0,0 @@
--:Minify:--
local kernel=...
local alpha = 0.85
local C_target = 0.01
local Tmin = 0.0005
local Tmax = 0.5
local lambda_budget = 0.08
local lambda_clamp = 0.03
local lambda_var = 0.02
local k_min = 0.5
local k_max = 0.5
local B = 0.01
function kernel.main()
kernel.log("Starting main loop...")
kernel.saveLog()
local stopLog=5
local logTasks=100
while not kernel.exitMain do
if kernel.config.logTasks then
if logTasks<0 then
kernel.log("Active Tasks:")
for i,v in pairs(kernel.tasks) do
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
end
kernel.log("[END BLOCK]")
logTasks=100
end
logTasks=logTasks-1
end
local N = 0
local Tmin_hit = 0
local Tmax_hit = 0
local totalTaskTime = 0
local taskTimes = {}
for pid, task in pairs(kernel.tasks) do
if kernel.exitMain then break end
for _,list in ipairs(kernel.perTaskHooks) do
for id,hook in ipairs(list) do
local ok,err = xpcall(hook, debug.traceback, task, pid)
if not ok then
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
list[id]=nil
end
end
end
if task.status == "R" then
N = N + 1
task.timeSlice = math.min(Tmax, math.max(Tmin, B / (N ^ alpha)))
if task.status == "R" then
local startTime = kernel.EFI:getEpochMs()
local ret
if stopLog > 0 then
kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF)
end
if kernel.config.preempt then
if not task.debugger then
ret = { kernel.EFI.resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
else
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
end
else
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
end
local elapsed = kernel.EFI:getEpochMs() - startTime
task.lastTime = elapsed
task.totalTime = (task.totalTime or 0) + elapsed
task.numRuns = (task.numRuns or 0) + 1
taskTimes[#taskTimes+1] = elapsed
totalTaskTime = totalTaskTime + elapsed
if elapsed <= Tmin then Tmin_hit = Tmin_hit + 1 end
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
if ret[1] == "error" or ret[1] == false then
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
task.status = "Z"
task.exit = "processHandlerException: " .. tostring(ret[2])
elseif ret[1] == "timeout" then
task.ivs = task.ivs + 1
task.syscallReturn = {}
elseif ret[1] == "success" or ret[1] == true then
task.vs = task.vs + 1
if ret[2] == "syscall" then
local scname = ret[3]
if kernel.syscalls[scname] then
if kernel.config.debugSyscalls then
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
for i = 4, #ret do
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
end
end
local sysret = { xpcall(kernel.syscalls[scname], debug.traceback, table.unpack(ret, 4)) }
if kernel.config.debugSyscalls then
if not sysret[1] then
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
else
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
for i = 2, #sysret do
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
end
end
end
if not sysret[1] then
task.syscallReturn = { false, sysret[2] }
else
task.syscallReturn = { true, table.unpack(sysret, 2) }
end
else
task.syscallReturn = { false, "Unknown syscall: " .. tostring(scname) }
end
end
end
end
end
end
local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0
local T_prev_var = 0
for _, t in ipairs(taskTimes) do
T_prev_var = T_prev_var + (t - T_prev_avg) ^ 2
end
if N > 0 then T_prev_var = T_prev_var / N end
if N > 0 then
local f_clamp = k_min * (Tmin_hit / N) - k_max * (Tmax_hit / N)
local B_budget = (C_target * (N ^ (alpha - 1))) / math.max(T_prev_avg, 1e-8)
B = B + lambda_budget * (B_budget - B) + lambda_clamp * f_clamp - lambda_var * T_prev_var
end
kernel.hpv.reapDeadTasks()
if stopLog > 0 then
kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B))
stopLog = stopLog - 1
kernel.saveLog()
end
end
end
-2
View File
@@ -1,3 +1 @@
Hyperion
Astronand
Xtimhedae
+39 -119
View File
@@ -1,121 +1,41 @@
local cp,c=component,computer;local b_addr=c.getBootAddress();local b_fs=cp.proxy(b_addr)
local gpu=cp.list("gpu")() and cp.proxy(cp.list("gpu")())
local e_rom=cp.list("eeprom")() and cp.proxy(cp.list("eeprom")())
local screens={}
for addr in cp.list("screen") do
if gpu then
gpu.bind(addr)
local w,h=gpu.maxResolution()
gpu.setResolution(w,h)
gpu.fill(1,1,w,h," ")
cp.proxy(addr).turnOn()
screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
local lua = {
coroutine = true,
debug = true,
_HOST = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getfenv = true,
getmetatable = true,
ipairs = true,
__inext = true,
load = true,
math = true,
next = true,
pairs = true,
pcall = true,
rawequal = true,
rawget = true,
rawlen = true,
rawset = true,
select = true,
setfenv = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true,
_G=true
}
local apis={}
for i,v in pairs(_G) do
if not lua[i] or lua[i]==nil then
apis[i]=v
_G[i]=nil
end
end
local function scroll(scr) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(t)
if not gpu then return end
for s=1, #screens do
local scr=screens[s]
gpu.bind(scr.addr)
for i=1,#t do
local char=t:sub(i,i)
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;gpu.set(scr.cx,scr.cy," ") end
else gpu.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr);scr.cy=scr.cy-1 end
end
end
end
local function throw(err)
if gpu then
gpu.setBackground(0x0000AA);
gpu.setForeground(0xFFFFFF);
for i=1, #screens do
gpu.fill(1,1,screens[i].w,screens[i].h," ");
screens[i].cx,screens[i].cy=1,1;
end
write("CRITICAL KERNEL ERROR:\n"..tostring(err))
end
while true do c.pullSignal() end
end
local ok,err=xpcall(function()
local apis={}
local _l={coroutine=1,debug=1,_VERSION=1,assert=1,collectgarbage=1,error=1,getmetatable=1,ipairs=1,load=1,math=1,next=1,pairs=1,pcall=1,rawequal=1,rawget=1,rawlen=1,rawset=1,select=1,setmetatable=1,string=1,table=1,tonumber=1,tostring=1,type=1,xpcall=1,_G=1}
for k,v in pairs(_G) do if not _l[k] then apis[k]=v;_G[k]=nil end end
function sleep(t) local s=c.uptime()+t;while c.uptime()<s do c.pullSignal(s-c.uptime()) end end
local function getFile(path)
local h,err=b_fs.open(path,"r")
if not h then throw("Cannot open: "..path) end
local buf,chk="",""
repeat chk=b_fs.read(h,math.huge);buf=buf..(chk or "") until not chk
b_fs.close(h)
return buf
end
local Kernel=load(getFile("/kernel.lua"),"@Kernel")
local initFs=load(getFile("/oc/initdisks"),"@Init_disks")
local fs=load(getFile("/initfs"),"@InitFs")
if not Kernel then throw("Kernel load failed.") end
if initFs then initFs=initFs(apis, b_fs, b_addr) end
if fs then fs=fs() end
local eQ={}
local function qEv(e,...) table.insert(eQ,{e,...}) end
local efi={
getEpochMs=function() return math.floor(c.uptime()*1000) end,
getUptime=function() return c.uptime()*1000 end,
date=function() return tostring(apis.os.date()) end,
getMachineEvent=function()
if #eQ > 0 then
return table.unpack(table.remove(eQ, 1))
else
return nil
end
end,
getEEPROM=function() return e_rom and e_rom.get() or "" end,
setEEPROM=function(_,t) if e_rom then e_rom.set(t) end end,
getNvram=function() return e_rom and e_rom.getData() or "" end,
setNvram=function(_,t) if e_rom then e_rom.setData(t) end end,
beep=function(freq, timeMs) c.beep(freq, timeMs / 1000) end,
initfs=fs,
disks=initFs,
architecture="oc",
firmware=apis,
reboot=false,
yield=function() coroutine.yield() end,
screenCtl={
print=function(_,t) write(tostring(t).."\n") end,
printInline=function(_,t) write(tostring(t)) end,
clear=function() if gpu then for i=1, #screens do local scr=screens[i];gpu.bind(scr.addr);gpu.fill(1,1,scr.w,scr.h," ");scr.cx,scr.cy=1,1 end end end,
resetCursor=function() for i=1, #screens do local scr=screens[i];scr.cx,scr.cy=1,1 end end,
setBackgroundColor=function(_,cl) if gpu then gpu.setBackground(cl) end end,
setTextColor=function(_,cl) if gpu then gpu.setForeground(cl) end end,
enable=function() end,
disable=function() end
}
}
local kCo=coroutine.create(function()
local s,e=xpcall(Kernel,debug.traceback,efi)
if not s and not efi.reboot then throw(e) end
if efi.reboot then c.shutdown(true) else c.shutdown() end
end)
efi.screenCtl:print("Loaded in "..tostring(c.uptime()).."s")
while true do
local st,e=coroutine.resume(kCo)
c.pushSignal("NoSleep")
local ex=false
while not ex do
local ev={c.pullSignal(0)}
if ev[1]=="key_down" then qEv("keyPressed",1,ev[3]);qEv("keyTyped",1,string.char(ev[3]))
elseif ev[1]=="key_up" then qEv("keyReleased",1,ev[3])
end
if ev[1]=="NoSleep" then ex=true else qEv(table.unpack(ev)) end
end
if st=="error" or coroutine.status(kCo)=="dead" then
if efi.reboot then c.shutdown(true) end
throw("Kernel fault: "..tostring(e))
end
end
end,debug.traceback)
if not ok then throw("Boot fault: "..err) end
+16 -66
View File
@@ -1,68 +1,18 @@
local init
do
local component_invoke = component.invoke
local function boot_invoke(address, method, ...)
local result = table.pack(pcall(component_invoke, address, method, ...))
if not result[1] then
return nil, result[2]
else
return table.unpack(result, 2, result.n)
end
end
checkArg=nil
local oldcomputer=computer
_G.computer=nil
local os=os
_G.os=nil
-- backwards compatibility, may remove later
local eeprom = component.list("eeprom")()
computer.getBootAddress = function()
return boot_invoke(eeprom, "getData")
end
computer.setBootAddress = function(address)
return boot_invoke(eeprom, "setData", address)
end
function component.wrap(address)
local methods=oldcomponent.methods(address)
local object={}
for _,method in ipairs(methods) do
object[method]=function(_,...)
return oldcomponent.invoke(address,method,...)
end
end
return object
end
do
local screen = component.list("screen")()
local gpu = component.list("gpu")()
if gpu and screen then
boot_invoke(gpu, "bind", screen)
end
end
local function tryLoadFrom(address)
local handle, reason = boot_invoke(address, "open", "/oc/boot.lua")
if not handle then
return nil, reason
end
local buffer = ""
repeat
local data, reason = boot_invoke(address, "read", handle, math.maxinteger or math.huge)
if not data and reason then
return nil, reason
end
buffer = buffer .. (data or "")
until not data
boot_invoke(address, "close", handle)
return load(buffer, "=init")
end
local reason
if computer.getBootAddress() then
init, reason = tryLoadFrom(computer.getBootAddress())
end
if not init then
computer.setBootAddress()
for address in component.list("filesystem") do
init, reason = tryLoadFrom(address)
if init then
computer.setBootAddress(address)
break
end
end
end
if not init then
error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0)
end
end
local ok, err = xpcall(init,debug.traceback)
if not ok then
error(err)
else
return err
end
local
@@ -1,136 +0,0 @@
local args = {...}
local apis = args[1]
local bootdrive = args[2]
local bootaddr = args[3]
local disks = {}
local internal = {}
local function createDisk(id, hw)
local disk = {
address = id,
isReadOnly = function() return hw.isReadOnly() end
}
function disk:spaceUsed() return hw.spaceUsed() end
function disk:spaceTotal() return hw.spaceTotal() end
function disk:list(path)
if not hw.exists(path) or not hw.isDirectory(path) then
return nil, "not directory"
end
return hw.list(path)
end
function disk:fileExists(path)
return hw.exists(path) and not hw.isDirectory(path)
end
function disk:directoryExists(path)
return hw.exists(path) and hw.isDirectory(path)
end
function disk:type(path)
if not hw.exists(path) then
return nil
elseif hw.isDirectory(path) then
return "directory"
else
return "file"
end
end
function disk:makeDirectory(path)
hw.makeDirectory(path)
end
function disk:remove(path)
if hw.exists(path) then hw.remove(path) end
end
function disk:setLabel(label) hw.setLabel(label) end
function disk:getLabel() return hw.getLabel() end
function disk:attributes(path)
return {
size = hw.size(path),
isDir = hw.isDirectory(path),
isReadOnly = hw.isReadOnly(),
modified = hw.lastModified(path),
created = hw.lastModified(path)
}
end
function disk:open(path, mode)
local fd = hw.open(path, mode)
if not fd then
local dir = path:match("^(.*)/[^/]+$")
if dir and not hw.exists(dir) then
local ok, err = hw.makeDirectory(dir)
if not ok then
return nil, err or "could not create parent directory"
end
end
fd = hw.open(path, mode)
if not fd then
return nil, "file not found or access denied"
end
end
return {
read = function(num) return hw.read(fd, num) end,
readAll = function()
local data = {}
while true do
local chunk = hw.read(fd, math.huge)
if not chunk then break end
data[#data + 1] = chunk
end
return table.concat(data)
end,
write = function(data) return hw.write(fd, data) end,
seek = function(whence, offset)
return hw.seek(fd, whence, offset)
end,
flush = function()
hw.close(fd)
fd = hw.open(path, mode)
end,
close = function()
hw.close(fd)
fd = nil
end
}
end
return disk
end
internal["$"] = createDisk("$", bootdrive)
local function refresh()
disks = {}
for addr in apis.component.list("filesystem") do
if addr ~= bootaddr then
disks[addr] = createDisk(addr, apis.component.proxy(addr))
end
end
end
local function iter()
refresh()
local combined = {}
for id, obj in pairs(internal) do combined[id] = obj end
for id, obj in pairs(disks) do combined[id] = obj end
return pairs(combined)
end
return {refresh = refresh, list = iter}
@@ -0,0 +1 @@
local fs={}
@@ -1,15 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc={}
kernel.oc.component=kernel.apis.component
kernel.oc.computer=kernel.apis.computer
kernel.log("Installed components:")
for addr, typ in kernel.oc.component.list() do
local dev=kernel.oc.component.proxy(addr)
local tier=""
if dev.getTier then
tier=dev.getTier()
end
kernel.log(" "..addr.." : "..typ..tier)
end
@@ -1,23 +0,0 @@
--:Minify:--
local kernel=...
local component=kernel.oc.component
local function wrap(p)
return function(op, mode)
if op=="type" then
return "device"
elseif op=="open" then
if kernel.uid~=0 then error("EACCES") end
return component.proxy(p)
end
end
end
for addr, typ in kernel.oc.component.list() do
local obj=wrap(addr)
kernel.devfs.data["raw"][addr]=obj
local typefolder=kernel.devfs.data["raw"]["by-type"][typ]
if not typefolder then typefolder={} end
typefolder[tostring(#table.keys(typefolder)+1)] = obj
kernel.devfs.data["raw"]["by-type"][typ]=typefolder
end
@@ -1,177 +0,0 @@
-- OpenComputers TTY driver
local kernel = ...
local component = kernel.oc.component
local computer = kernel.oc.computer
local plt = {
0x000000, 0x000040, 0x000080, 0x0000C0, 0x0000FF,
0x002400, 0x002440, 0x002480, 0x0024C0, 0x0024FF,
0x004900, 0x004940, 0x004980, 0x0049C0, 0x0049FF,
0x006D00, 0x006D40, 0x006D80, 0x006DC0, 0x006DFF,
0x009200, 0x009240, 0x009280, 0x0092C0, 0x0092FF,
0x00B600, 0x00B640, 0x00B680, 0x00B6C0, 0x00B6FF,
0x00DB00, 0x00DB40, 0x00DB80, 0x00DBC0, 0x00DBFF,
0x00FF00, 0x00FF40, 0x00FF80, 0x00FFC0, 0x00FFFF,
0x330000, 0x330040, 0x330080, 0x3300C0, 0x3300FF,
0x332400, 0x332440, 0x332480, 0x3324C0, 0x3324FF,
0x334900, 0x334940, 0x334980, 0x3349C0, 0x3349FF,
0x336D00, 0x336D40, 0x336D80, 0x336DC0, 0x336DFF,
0x339200, 0x339240, 0x339280, 0x3392C0, 0x3392FF,
0x33B600, 0x33B640, 0x33B680, 0x33B6C0, 0x33B6FF,
0x33DB00, 0x33DB40, 0x33DB80, 0x33DBC0, 0x33DBFF,
0x33FF00, 0x33FF40, 0x33FF80, 0x33FFC0, 0x33FFFF,
0x660000, 0x660040, 0x660080, 0x6600C0, 0x6600FF,
0x662400, 0x662440, 0x662480, 0x6624C0, 0x6624FF,
0x664900, 0x664940, 0x664980, 0x6649C0, 0x6649FF,
0x666D00, 0x666D40, 0x666D80, 0x666DC0, 0x666DFF,
0x669200, 0x669240, 0x669280, 0x6692C0, 0x6692FF,
0x66B600, 0x66B640, 0x66B680, 0x66B6C0, 0x66B6FF,
0x66DB00, 0x66DB40, 0x66DB80, 0x66DBC0, 0x66DBFF,
0x66FF00, 0x66FF40, 0x66FF80, 0x66FFC0, 0x66FFFF,
0x990000, 0x990040, 0x990080, 0x9900C0, 0x9900FF,
0x992400, 0x992440, 0x992480, 0x9924C0, 0x9924FF,
0x994900, 0x994940, 0x994980, 0x9949C0, 0x9949FF,
0x996D00, 0x996D40, 0x996D80, 0x996DC0, 0x996DFF,
0x999200, 0x999240, 0x999280, 0x9992C0, 0x9992FF,
0x99B600, 0x99B640, 0x99B680, 0x99B6C0, 0x99B6FF,
0x99DB00, 0x99DB40, 0x99DB80, 0x99DBC0, 0x99DBFF,
0x99FF00, 0x99FF40, 0x99FF80, 0x99FFC0, 0x99FFFF,
0xCC0000, 0xCC0040, 0xCC0080, 0xCC00C0, 0xCC00FF,
0xCC2400, 0xCC2440, 0xCC2480, 0xCC24C0, 0xCC24FF,
0xCC4900, 0xCC4940, 0xCC4980, 0xCC49C0, 0xCC49FF,
0xCC6D00, 0xCC6D40, 0xCC6D80, 0xCC6DC0, 0xCC6DFF,
0xCC9200, 0xCC9240, 0xCC9280, 0xCC92C0, 0xCC92FF,
0xCCB600, 0xCCB640, 0xCCB680, 0xCCB6C0, 0xCCB6FF,
0xCCDB00, 0xCCDB40, 0xCCDB80, 0xCCDBC0, 0xCCDBFF,
0xCCFF00, 0xCCFF40, 0xCCFF80, 0xCCFFC0, 0xCCFFFF,
0xFF0000, 0xFF0040, 0xFF0080, 0xFF00C0, 0xFF00FF,
0xFF2400, 0xFF2440, 0xFF2480, 0xFF24C0, 0xFF24FF,
0xFF4900, 0xFF4940, 0xFF4980, 0xFF49C0, 0xFF49FF,
0xFF6D00, 0xFF6D40, 0xFF6D80, 0xFF6DC0, 0xFF6DFF,
0xFF9200, 0xFF9240, 0xFF9280, 0xFF92C0, 0xFF92FF,
0xFFB600, 0xFFB640, 0xFFB680, 0xFFB6C0, 0xFFB6FF,
0xFFDB00, 0xFFDB40, 0xFFDB80, 0xFFDBC0, 0xFFDBFF,
0xFFFF00, 0xFFFF40, 0xFFFF80, 0xFFFFC0, 0xFFFFFF,
0x000000, 0x0F0F0F, 0x1E1E1E, 0x2D2D2D,
0x3C3C3C, 0x4B4B4B, 0x5A5A5A, 0x696969,
0x787878, 0x878787, 0x969696, 0xA5A5A5,
0xB4B4B4, 0xC3C3C3, 0xD2D2D2, 0xE1E1E1
}
local gpus,screens = {},{}
for addr, typ in component.list("gpu") do
if typ == "gpu" then
gpus[#gpus+1]=component.proxy(addr)
end
end
if #gpus>0 then
for addr, typ in component.list("screen") do
if typ == "screen" then
gpus[1].bind(addr)
local w,h = gpus[1].maxResolution()
gpus[1].setResolution(w,h)
screens[addr]={cx=1,cy=1,w=w,h=h,addr=addr,fg=0,bg=0,gpu=nil}
end
end
end
local scrnum = 0
for i,v in pairs(screens) do
scrnum=scrnum+1
end
kernel.log("initialized "..tostring(#gpus).." gpus and "..tostring(scrnum).." screens")
local binds,newid={},0
local curaddr=""
local function scroll(scr, gpu) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
local function write(text, addr)
local g=gpus[1]
local scr=screens[addr]
if not scr then error("NODEV") end
if curaddr~=addr then g.bind(addr); g.setForeground(scr.fg); g.setBackground(scr.bg) end
for i=1,#text do
local char=text:sub(i,i)
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;g.set(scr.cx,scr.cy," ") end
else g.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
if scr.cy>scr.h then scroll(scr, g);scr.cy=scr.cy-1 end
end
end
local function newtty(addr)
newid=newid+1
kernel.devfs.data["tty"][tostring(newid)]=function(op, mode)
if op=="type" then
return "Terminal"
elseif op=="open" then
local h = {
read=function(amount) end,
write=function(content)
write(content, addr)
end,
size=function()
return screens[addr].w, screens[addr].h
end,
clear=function()
local g=gpus[1]
local scr=screens[addr]
if addr~=curaddr then g.bind(addr) end
g.fill(1,1,scr.w,scr.h," ");
scr.cx,scr.cy=1,1
end,
gpos=function()
return screens[addr].cx, screens[addr].cy
end,
spos=function(x,y)
if not tonumber(x) or not tonumber(y) then error("Invailid arg") end
screens[addr].cx, screens[addr].cy = x,y
end,
sfgc=function(c)
screens[addr].fg=c
end,
sbgc=function(c)
screens[addr].bg=c
end,
gfgc=function()
return screens[addr].fg
end,
gbgc=function()
return screens[addr].bg
end,
isvirt=function()
return false
end,
gplt=function()
return plt
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
if #gpus>=1 and scrnum>=1 then
for addr,obj in pairs(screens) do
newtty(addr)
end
end
@@ -1,113 +0,0 @@
--:Minify:--
local kernel=...
kernel.oc.keyboards={}
local kbs=kernel.oc.keyboards
local kbidx=0
local keyboard = {}
keyboard.keys = {
back = 0x0E, -- backspace
delete = 0xD3,
down = 0xD0,
enter = 0x1C,
home = 0xC7,
lcontrol = 0x1D,
left = 0xCB,
lmenu = 0x38, -- left Alt
lshift = 0x2A,
pageDown = 0xD1,
rcontrol = 0x9D,
right = 0xCD,
rmenu = 0xB8, -- right Alt
rshift = 0x36,
space = 0x39,
tab = 0x0F,
up = 0xC8,
["end"] = 0xCF,
numpadenter = 0x9C,
}
kernel.oc.keys=keyboard.keys
for i=0, 255 do
kernel.oc.keys[string.char(i)]=i
end
-------------------------------------------------------------------------------
function keyboard.isAltDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lmenu] or kbs[addr].pressedCodes[keyboard.keys.rmenu]
end
function keyboard.isControl(char)
return type(char) == "number" and (char < 0x20 or (char >= 0x7F and char <= 0x9F))
end
function keyboard.isControlDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lcontrol] or kbs[addr].pressedCodes[keyboard.keys.rcontrol]
end
function keyboard.isKeyDown(addr,charOrCode)
if type(charOrCode) == "string" then
return kbs[addr].pressedChars[utf8 and utf8.codepoint(charOrCode) or charOrCode:byte()]
elseif type(charOrCode) == "number" then
return kbs[addr].pressedCodes[charOrCode]
end
end
function keyboard.isShiftDown(addr)
return kbs[addr].pressedCodes[keyboard.keys.lshift] or kbs[addr].pressedCodes[keyboard.keys.rshift]
end
kernel.oc.keyboard=keyboard
local function serializeBool(bool)
if bool then
return "T"
else
return "F"
end
end
for addr, typ in kernel.oc.component.list("keyboard") do
if typ=="keyboard" then
kbidx=kbidx+1
kbs[addr]={pressedChars = {}, pressedCodes = {}, events=kernel.newFifo()}
kernel.devfs.data["input"]["keyboard"..tostring(kbidx)]=function(op,mode)
if op=="type" then
return "Keyboard"
elseif op=="open" then
local h = {
read=function(amount)
local rv=""
for i=1, amount or 1 do
local event = {kernel.oc.keyboards[addr].events.pop()}
if event[1] then
rv=rv..event[1]
end
end
if rv=="" then rv=nil end
return rv
end,
write=function(content)
end,
gctrl=function()
return serializeBool(keyboard.isControlDown(addr))..";"..serializeBool(keyboard.isAltDown(addr))
end,
isKeyDown=function(char)
return keyboard.isKeyDown(addr,char)
end
}
if mode=="rw" then
return h
elseif mode=="r" then
h["write"]=nil
return h
elseif mode=="w" then
h["read"]=nil
return h
end
end
end
end
end
@@ -1,99 +0,0 @@
--:Minify:--
local kernel=...
local keys=kernel.oc.keys
kernel.processes.ocdaemon = function()
local timeout = false
kernel.log("OC daemon started")
local ctrlKeyMap = {
[keys.a]=1, [keys.b]=2, [keys.c]=3,
[keys.d]=4, [keys.e]=5, [keys.f]=6,
[keys.g]=7, [keys.h]=8, [keys.i]=9,
[keys.j]=10, [keys.k]=11, [keys.l]=12,
[keys.m]=13, [keys.n]=14, [keys.o]=15,
[keys.p]=16, [keys.q]=17, [keys.r]=18,
[keys.s]=19, [keys.t]=20, [keys.u]=21,
[keys.v]=22, [keys.w]=23, [keys.x]=24,
[keys.y]=25, [keys.z]=26,
}
local specialKeyMap = {
[keys.up] = "\27[A",
[keys.down] = "\27[B",
[keys.right] = "\27[C",
[keys.left] = "\27[D",
[keys.home] = "\27[H",
[keys["end"]] = "\27[F",
--[keys.pageUp] = "\27[5~",
--[keys.pageDown] = "\27[6~",
[keys.delete] = "\27[3~",
[keys.enter] = "\n",
[keys.back] = "\b",
[keys.tab] = "\t",
}
while true do
local event = {kernel.EFI.getMachineEvent()}
if event[1] then
local eventType = event[1]
local addr = event[2]
local char = event[3]
local keyCode = event[4]
if eventType == "key_down" then
local keyboard = kernel.oc.keyboards[addr]
if keyboard.ctrl then
local ctrlByte = ctrlKeyMap[keyCode]
if ctrlByte then
if ctrlByte == 3 then
for _, task in ipairs(syscall.getTasks()) do
syscall.sigsend(task, 1)
end
else
keyboard.events.push(string.char(ctrlByte))
end
end
else
local special = specialKeyMap[keyCode]
if special then
keyboard.events.push(special)
elseif char and char > 0 then
keyboard.events.push(kernel.apis.unicode.char(char))
end
end
elseif eventType == "key_up" then
end
timeout = false
else
timeout = true
end
if timeout then
sleep(0.05)
end
end
end
kernel.log("OC daemon queued for execution")
@@ -1,150 +0,0 @@
--:Minify:--
local kernel=...
local alpha = 0.85
local C_target = 0.01
local Tmin = 0.0005
local Tmax = 0.5
local lambda_budget = 0.08
local lambda_clamp = 0.03
local lambda_var = 0.02
local k_min = 0.5
local k_max = 0.5
local B = 0.01
local nextyield=0
function kernel.main()
kernel.log("Starting main loop...")
kernel.saveLog()
local stopLog=5
local logTasks=100
while not kernel.exitMain do
if kernel.config.logTasks then
if logTasks<0 then
kernel.log("Active Tasks:")
for i,v in pairs(kernel.tasks) do
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
end
kernel.log("[END BLOCK]")
logTasks=100
end
logTasks=logTasks-1
end
local N = 0
local Tmin_hit = 0
local Tmax_hit = 0
local totalTaskTime = 0
local taskTimes = {}
for pid, task in pairs(kernel.tasks) do
if kernel.exitMain then break end
for _,list in ipairs(kernel.perTaskHooks) do
for id,hook in ipairs(list) do
local ok,err = xpcall(hook, debug.traceback, task, pid)
if not ok then
kernel.log("[MAIN HOOK ERR]: "..err, "ERROR", 0xFF0000)
list[id]=nil
end
end
end
if task.status == "R" then
N = N + 1
task.timeSlice = math.min(Tmax, math.max(Tmin, B / (N ^ alpha)))
if task.status == "R" then
local startTime = kernel.EFI:getEpochMs()
local ret
if stopLog > 0 then
kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF)
end
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
local elapsed = kernel.EFI:getEpochMs() - startTime
task.lastTime = elapsed
task.totalTime = (task.totalTime or 0) + elapsed
task.numRuns = (task.numRuns or 0) + 1
taskTimes[#taskTimes+1] = elapsed
totalTaskTime = totalTaskTime + elapsed
if elapsed <= Tmin then Tmin_hit = Tmin_hit + 1 end
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
if ret[1] == "error" or ret[1] == false then
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
task.status = "Z"
task.exit = "processHandlerException: " .. tostring(ret[2])
elseif ret[1] == "timeout" then
task.ivs = task.ivs + 1
task.syscallReturn = {}
elseif ret[1] == "success" or ret[1] == true then
task.vs = task.vs + 1
if ret[2] == "syscall" then
local scname = ret[3]
if kernel.syscalls[scname] then
if kernel.config.debugSyscalls then
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
for i = 4, #ret do
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
end
end
local sysret = { xpcall(kernel.syscalls[scname], debug.traceback, table.unpack(ret, 4)) }
if kernel.config.debugSyscalls then
if not sysret[1] then
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
else
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
for i = 2, #sysret do
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
end
end
end
if not sysret[1] then
task.syscallReturn = { false, sysret[2] }
else
task.syscallReturn = { true, table.unpack(sysret, 2) }
end
else
task.syscallReturn = { false, "Unknown syscall: " .. tostring(scname) }
end
end
end
end
end
if kernel.EFI:getEpochMs()>=nextyield then
kernel.EFI:yield()
nextyield=kernel.EFI:getEpochMs()+5000
end
end
local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0
local T_prev_var = 0
for _, t in ipairs(taskTimes) do
T_prev_var = T_prev_var + (t - T_prev_avg) ^ 2
end
if N > 0 then T_prev_var = T_prev_var / N end
if N > 0 then
local f_clamp = k_min * (Tmin_hit / N) - k_max * (Tmax_hit / N)
local B_budget = (C_target * (N ^ (alpha - 1))) / math.max(T_prev_avg, 1e-8)
B = B + lambda_budget * (B_budget - B) + lambda_clamp * f_clamp - lambda_var * T_prev_var
end
kernel.hpv.reapDeadTasks()
if stopLog > 0 then
kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B))
stopLog = stopLog - 1
kernel.saveLog()
end
end
end
+1 -1
View File
@@ -1 +1 @@
firmware for Opencomputers mod
firmware for Opencomputers
+1 -1
View File
@@ -1 +1 @@
1.0.0
0.1.0
+4 -4
View File
@@ -1,4 +1,4 @@
U $;/boot/
V devfs0000;/dev/
V tmpfs0000;/tmp/
V procfs0000;/proc/
U $;/
U devfs0000;/dev/
U tmpfs0000;/tmp/
U procfs0000;/proc/
+1 -1
View File
@@ -77,7 +77,7 @@ end
function fs.load(path) return load(fs.readAllText(path), path) end
function fs.mount(disk, mountPoint)
if not disks[disk] then error("NODISK : "..disk) end
if not disks[disk] then return end
mounts[mountPoint] = disk
end
+2 -62
View File
@@ -68,7 +68,6 @@ function kernel.PANIC(msg)
kernel.exitMain = true
end
while true do
EFI:yield()
local event={EFI:getMachineEvent()}
if event[1]=="keyPressed" then
break
@@ -99,7 +98,7 @@ kernel.disks={}
for _,v in disks.list() do
kernel.disks[v.address] = v
end
ifs.mount("$", "/boot/")
ifs.mount("$", "/")
local fstab=ifs.readAllText("/boot/fstab")
local split = function(str, delim, maxResultCountOrNil)
@@ -139,10 +138,8 @@ end
kernel.config = config
local skip=false
local mounted={}
local root=false
for i,v in ipairs(split(fstab,"\n")) do
if v:sub(1,1)=="U" or v:sub(1,1)=="F" then
if v:sub(1,1)=="U" then
local id=""
for i=3,#v do
if v:sub(i,i)==";" then
@@ -152,43 +149,12 @@ for i,v in ipairs(split(fstab,"\n")) do
end
if not skip then
local path=v:sub(#id+4)
if path=="/" then root=true end
mounted[id]=true
ifs.mount(id,path)
else
skip=false
end
end
end
if not root then
kernel.log("No rootdisk found, prompting user...", "WARN", 0xFF8800)
screen:setTextColor(0xDDDDDD)
screen:print("Disk to mount to /:")
local idx=1
local canadates={}
for i,v in pairs(kernel.disks) do
if not mounted[i] then
screen:print("("..idx..") : "..i)
canadates[idx]=i
idx=idx+1
end
end
while true do
EFI:yield()
local event={EFI:getMachineEvent()}
if event[1]=="keyTyped" then
if tonumber(event[3]) then
if canadates[tonumber(event[3])] then
ifs.writeAllText("/boot/fstab", "U "..canadates[tonumber(event[3])]..";/\n"..fstab)
fstab="U "..canadates[tonumber(event[3])]..";/\n"..fstab
ifs.mount(canadates[tonumber(event[3])], "/")
break
end
end
screen:print(event[1], event[3])
end
end
end
kernel.log("Disks initialized")
function kernel.saveLog()
@@ -355,26 +321,6 @@ kernel.processes={}
kernel.fstab=fstab
kernel.denied={}
kernel.loadingModule="kernel"
kernel.perTaskHooks={}
kernel.mainHooks={}
kernel.runhooks={}
-- args {taskobj}
function kernel.execPerTask(func, prior)
if not kernel.perTaskHooks[prior] then kernel.perTaskHooks[prior]={} end
kernel.perTaskHooks[prior][#kernel.perTaskHooks[prior]+1] = func
return #kernel.perTaskHooks[prior]
end
function kernel.execOnMain(func)
kernel.mainHooks[#kernel.mainHooks+1] = func
return #kernel.mainHooks
end
function kernel.runWhenLoaded(func)
kernel.runhooks[#kernel.runhooks+1] = func
return #kernel.runhooks
end
kernel.kernelTask = {
name="kernel",
@@ -483,17 +429,11 @@ for _,p in ipairs(modules) do
end
end
for i=1, #kernel.runhooks do
local ok,err = xpcall(kernel.runhooks[i], debug.traceback)
if not ok then kernel.panic(err) end
end
kernel.log("Kernel initialized successfully.")
kernel.saveLog()
kernel.status="running"
kernel.loadingModule=nil
screen:disable()
if not kernel.main then kernel.panic("No scheduler implemented from firmware") end
local ok,err = xpcall(kernel.main, debug.traceback)
if not ok then
kernel.panic(err)
+1
View File
@@ -0,0 +1 @@
0:0:root:/root:/bin/hysh
@@ -2,7 +2,7 @@
local kernel = ...
local vfs = {}
kernel.vfs = vfs
vfs.mounts = {}
vfs.mounts = {["$"] = "/"}
vfs.disks = kernel.disks
-- Metafile format (version 2)
@@ -556,19 +556,17 @@ function vfs.newfd(fdobj)
return fd
end
function vfs.mount(target, diskOrId, bind, floating)
if not floating and target ~= "/" then
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
if _euid ~= 0 then error("EPERM") end
if not target then error("EINVAL") end
target = normalizeMountPoint(target)
local drive, path = resolvePath(target)
if not drive:directoryExists(path) then
drive:makeDirectory(path)
end
if drive:type(path) ~= "directory" then
error("EINVAL")
end
function vfs.mount(target, diskOrId, bind)
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
if _euid ~= 0 then error("EPERM") end
if not target then error("EINVAL") end
target = normalizeMountPoint(target)
local drive, path = resolvePath(target)
if not drive:directoryExists(path) then
drive:makeDirectory(path)
end
if drive:type(path) ~= "directory" then
error("EINVAL")
end
local disk, id
-- bind mount
@@ -1068,9 +1066,8 @@ function vfs.chown(path, uid, gid)
if kernel.unixSockets[namei(path)] then error("EINVAL") end
local disk = resolveMount(path)
if disk:isReadOnly() then error("ERDONLY") end
local meta = getFileMeta(path)
local euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
if euid ~= 0 and euid ~= meta.owner then error("EPERM") end
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
if _euid ~= 0 then error("EPERM") end
updateMeta(path, function(e) e.owner = uid; e.group = gid end)
end
@@ -1,6 +1,8 @@
--:Minify:--
local kernel = ...
kernel.vfs.remove("/tmp")
kernel.vfs.mkdir("/tmp")
if not kernel.config.tmpToDisk then
local proxy = {}
local data = {}
@@ -136,8 +138,4 @@ if not kernel.config.tmpToDisk then
else
kernel.log("tmpToDisk enabled, skipping tmpfs module")
kernel.log("tmpfs0000 will passthrough to /tmp on the disk")
kernel.runWhenLoaded(function()
kernel.vfs.remove("/tmp")
kernel.vfs.mkdir("/tmp")
end)
end
@@ -11,7 +11,7 @@ end
for _, line in ipairs(string.split(kernel.fstab, "\n")) do
line = trim(line)
if line:sub(1,1) == "U" or line:sub(1,1) == "V" or line:sub(1,1) == "F" then
if line ~= "" and line:sub(1,1) == "U" then
local semicolon_pos
for i = 3, #line do
if line:sub(i,i) == ";" then
@@ -26,7 +26,9 @@ for _, line in ipairs(string.split(kernel.fstab, "\n")) do
local id = line:sub(3, semicolon_pos - 1)
local path = trim(line:sub(semicolon_pos + 1))
kernel.log("Mounting '"..id.."' to '"..path.."'")
kernel.vfs.mount(path, id, nil, line:sub(1,1) == "F")
if id ~= "$" then
kernel.vfs.mount(path, id)
end
kernel.log("Mounted "..id.." to "..path)
end
end
@@ -32,31 +32,6 @@ function signal.sigignore()
task.sigd=nil
end
kernel.execPerTask(function(task)
if task.status=="R" then
if task.sigq and #task.sigq ~= 0 and task.sigh then
local coro = coroutine.create(task.sigh)
local status,err=coroutine.resume(coro, table.remove(task.sigq, 1))
EFI:yeild()
if status=="error" or status==false then
task.sigd.error=err or "Unknown"
task.sigd.active=false
task.sigh=nil
task.sigq=nil
task.sigd=nil
elseif status=="success" or status==true then
if err=="syscall" then
task.sigd.error="Cannot execute syscalls from signals"
task.sigd.active=false
task.sigh=nil
task.sigq=nil
task.sigd=nil
end
end
end
end
end,2)
local s=kernel.syscalls
s["sigsend"] = signal.sigsend
s["sigcatch"] = signal.sigcatch
@@ -155,21 +155,7 @@ end
local function hashPassword(password, salt)
local key = (pepper .. salt)
return blake2s(password..salt, key)
end
if not kernel.vfs.exists("/etc/passwd") then
kernel.log("PASSWD FILE NOT FOUND CREATING...", "WARN", 0xFF8800)
local handle = kernel.vfs.open("/etc/passwd", "w")
kernel.vfs.write(handle, "0:0:root:/root:/bin/hysh")
kernel.vfs.close(handle)
end
if not kernel.vfs.exists("/etc/shadow") then
kernel.log("SHADOW FILE NOT FOUND CREATING...", "WARN", 0xFF8800)
local handle = kernel.vfs.open("/etc/shadow", "w")
kernel.vfs.write(handle, "")
kernel.vfs.close(handle)
return blake2s(password, key)
end
local passwdFile = getFile("/etc/passwd")
@@ -5,6 +5,7 @@ local sys = {}
local nextpid = 2
kernel.exitMain = false
local resumeWithTimeout = coroutine.resumeWithTimeout
local function bit_is_set(num, bit)
return math.floor(num / (2 ^ bit)) % 2 == 1
@@ -30,18 +31,10 @@ local function loadExecutable(path)
return func, euid, suid_set
end
local function createTask(func, name, envars, args, tgid, real_uid, eff_uid, clearFds)
local function createTask(func, name, envars, args, tgid, real_uid, eff_uid)
local id = nextpid
nextpid = nextpid + 1
local fds={}
if not clearFds then
for id, file in pairs(kernel.currentTask.fd) do
file.refcount=file.refcount+1
fds[id]=file
end
end
tasks[tostring(id)] = {
coro = coroutine.create(function()
local ok, err = xpcall(func, debug.traceback, table.unpack(args or {}))
@@ -78,7 +71,7 @@ local function createTask(func, name, envars, args, tgid, real_uid, eff_uid, cle
euid = eff_uid,
gid = (kernel.currentTask and kernel.currentTask.gid) or 0,
groups = (kernel.currentTask and kernel.currentTask.groups) or {},
fd = fds,
fd = {},
sleep = 0,
ivs = 0,
vs = 0,
@@ -100,14 +93,14 @@ local function createTask(func, name, envars, args, tgid, real_uid, eff_uid, cle
return id
end
function sys.spawn(func, name, envars, args, tgid, clearFds)
function sys.spawn(func, name, envars, args, tgid)
local caller = kernel.currentTask
local real_uid = caller and caller.uid or kernel.uid
local eff_uid = caller and caller.euid or real_uid
return createTask(func, name, envars, args, tgid, real_uid, eff_uid, clearFds)
return createTask(func, name, envars, args, tgid, real_uid, eff_uid)
end
function sys.execspawn(path, name, envars, args, tgid, keepFds)
function sys.execspawn(path, name, envars, args, tgid)
local func, euid, suid_active = loadExecutable(path, kernel._U)
local caller = kernel.currentTask
@@ -121,23 +114,22 @@ function sys.execspawn(path, name, envars, args, tgid, keepFds)
)
end
return createTask(func, name or path, envars, args, tgid, real_uid, euid, not keepFds)
return createTask(func, name or path, envars, args, tgid, real_uid, euid)
end
function sys.exec(path, args, envars)
local task = kernel.currentTask
local func, euid, _ = loadExecutable(path, kernel._U)
-- no idea why this is here?
--if task.fd then
-- for fd, _ in pairs(task.fd) do
-- if fd > 2 then pcall(kernel.vfs.close, fd) end
-- end
--end
if task.fd then
for fd, _ in pairs(task.fd) do
if fd > 2 then pcall(kernel.vfs.close, fd) end
end
end
task.euid = euid
task.args = args or {}
task.envars = envars or task.envars or {}
task.envars = envars or task.envars
task.name = path
task.coro = coroutine.create(function()
@@ -309,7 +301,7 @@ end
function sys.getuid() return kernel.currentTask.uid end
function sys.reapDeadTasks()
local function reapDeadTasks()
for pid, task in pairs(tasks) do
if task.status == "Z" and not task.reapTime then
if task.pid == 1 then kernel.panic("Attempted to gc init!") end
@@ -346,41 +338,205 @@ function sys.reapDeadTasks()
end
end
kernel.execPerTask(function(task)
kernel.currentTask = task
kernel.uid = task.euid or task.uid
kernel.process = task.name
local alpha = 0.85
local C_target = 0.01
local Tmin = 0.0005
local Tmax = 0.5
local lambda_budget = 0.08
local lambda_clamp = 0.03
local lambda_var = 0.02
local k_min = 0.5
local k_max = 0.5
local B = 0.01
if task.status == "S" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "R"
task.sleep = 0
end
function kernel.main()
kernel.log("Starting main loop...")
kernel.saveLog()
local stopLog=5
local logTasks=100
if task.status == "ST" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "T"
task.sleep = 0
end
while not kernel.exitMain do
if kernel.config.logTasks then
if logTasks<0 then
kernel.log("Active Tasks:")
for i,v in pairs(tasks) do
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
end
kernel.log("[END BLOCK]")
logTasks=100
end
logTasks=logTasks-1
end
local N = 0
local Tmin_hit = 0
local Tmax_hit = 0
local totalTaskTime = 0
local taskTimes = {}
if task.status == "DS" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "D"
task.sleep = 0
end
for pid, task in pairs(tasks) do
if kernel.exitMain then break end
kernel.currentTask = task
kernel.uid = task.euid or task.uid
kernel.process = task.name
if task.status == "D" then
if task.io then
local ret = {xpcall(task.io, debug.traceback)}
if not ret[1] then
task.syscallReturn = {false, table.unpack(ret, 2)}
if task.status == "S" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "R"
task.io=nil
elseif #ret>1 then
task.syscallReturn = {true, table.unpack(ret, 2)}
task.status = "R"
task.io=nil
task.sleep = 0
end
if task.status == "ST" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "T"
task.sleep = 0
end
if task.status == "DS" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "D"
task.sleep = 0
end
if task.status == "D" then
if task.io then
local ret = {xpcall(task.io, debug.traceback)}
if not ret[1] then
task.syscallReturn = {false, table.unpack(ret, 2)}
task.status = "R"
task.io=nil
elseif #ret>1 then
task.syscallReturn = {true, table.unpack(ret, 2)}
task.status = "R"
task.io=nil
end
end
end
if task.status == "R" then
N = N + 1
task.timeSlice = math.min(Tmax, math.max(Tmin, B / (N ^ alpha)))
if task.sigq and #task.sigq ~= 0 and task.sigh then
local coro = coroutine.create(task.sigh)
local status,err
if kernel.config.preempt then
status,err=coroutine.resumeWithTimeout(coro, 100, table.remove(task.sigq, 1))
else
status,err=coroutine.resume(coro, table.remove(task.sigq, 1))
end
if status=="error" or status==false then
task.sigd.error=err or "Unknown"
task.sigd.active=false
task.sigh=nil
task.sigq=nil
task.sigd=nil
elseif status=="success" or status==true then
if err=="syscall" then
task.sigd.error="Cannot execute syscalls from signals"
task.sigd.active=false
task.sigh=nil
task.sigq=nil
task.sigd=nil
end
end
end
if task.status == "R" then
local startTime = kernel.EFI:getEpochMs()
local ret
if stopLog > 0 then
kernel.log("Running task " .. tostring(task.pid) .. " (" .. task.name .. ") with time slice " .. string.format("%.3f", task.timeSlice) .. "s", "DBUG", 0x00FFFF)
end
if kernel.config.preempt then
if not task.debugger then
ret = { resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
else
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
end
else
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
end
local elapsed = kernel.EFI:getEpochMs() - startTime
task.lastTime = elapsed
task.totalTime = (task.totalTime or 0) + elapsed
task.numRuns = (task.numRuns or 0) + 1
taskTimes[#taskTimes+1] = elapsed
totalTaskTime = totalTaskTime + elapsed
if elapsed <= Tmin then Tmin_hit = Tmin_hit + 1 end
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
if ret[1] == "error" or ret[1] == false then
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
task.status = "Z"
task.exit = "processHandlerException: " .. tostring(ret[2])
elseif ret[1] == "timeout" then
task.ivs = task.ivs + 1
task.syscallReturn = {}
elseif ret[1] == "success" or ret[1] == true then
task.vs = task.vs + 1
if ret[2] == "syscall" then
local scname = ret[3]
if kernel.syscalls[scname] then
if kernel.config.debugSyscalls then
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
for i = 4, #ret do
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
end
end
local sysret = { xpcall(kernel.syscalls[scname], debug.traceback, table.unpack(ret, 4)) }
if kernel.config.debugSyscalls then
if not sysret[1] then
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
else
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
for i = 2, #sysret do
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
end
end
end
if not sysret[1] then
task.syscallReturn = { false, sysret[2] }
else
task.syscallReturn = { true, table.unpack(sysret, 2) }
end
else
task.syscallReturn = { false, "Unknown syscall: " .. tostring(scname) }
end
end
end
end
end
end
local T_prev_avg = (N > 0) and (totalTaskTime / N) or 0
local T_prev_var = 0
for _, t in ipairs(taskTimes) do
T_prev_var = T_prev_var + (t - T_prev_avg) ^ 2
end
if N > 0 then T_prev_var = T_prev_var / N end
if N > 0 then
local f_clamp = k_min * (Tmin_hit / N) - k_max * (Tmax_hit / N)
local B_budget = (C_target * (N ^ (alpha - 1))) / math.max(T_prev_avg, 1e-8)
B = B + lambda_budget * (B_budget - B) + lambda_clamp * f_clamp - lambda_var * T_prev_var
end
reapDeadTasks()
if stopLog > 0 then
kernel.log("Executed " .. N .. " tasks, avg time: " .. string.format("%.2f", T_prev_avg) .. "ms, var: " .. string.format("%.2f", T_prev_var) .. ", B: " .. string.format("%.5f", B))
stopLog = stopLog - 1
kernel.saveLog()
end
end
end,1)
end
local sysc = kernel.syscalls
sysc["spawn"] = sys.spawn
@@ -2,8 +2,6 @@
local kernel = ...
if kernel.firstBoot then
kernel.log("Seeding filesystem permissions...")
local P = kernel.vfs.P
local PERM = kernel.vfs.PERM
@@ -16,44 +14,107 @@ if kernel.firstBoot then
local RWXRWXRWX = PERM.RWXRWXRWX
local SUID_755 = PERM.SUID_755
local function seed(root, data)
for i=1,#data do
local entry=data[1]
kernel.vfs.chmod(root..entry[1],entry[2],entry[3])
kernel.vfs.chown(root..entry[1],entry[4])
local META_VERSION = 0x02
local rootDisk = kernel.disks["$"]
local function makeEntry(name, etype, owner, group, perms, cmeta)
cmeta = cmeta or ""
local plo = perms % 256
local phi = math.floor(perms / 256) % 256
local olo = (owner or 0) % 256
local ohi = math.floor((owner or 0) / 256) % 256
local glo = (group or 0) % 256
local ghi = math.floor((group or 0) / 256) % 256
return string.char(#name) .. name
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
.. string.char(#cmeta) .. cmeta
end
local REG = 0x00
local function mergeMeta(dir, entries)
local diskDir = dir
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
local existing = {}
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
if rok and rf then
local raw = rf.read(65535)
if rf.close then rf.close() end
existing = (kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw)) or {}
end
for _, e in ipairs(entries) do
local name = e[1]
local etype = e[2] or REG
local owner = e[3] or 0
local group = e[4] or 0
local perms = e[5] or RWX_RX_RX
local cmeta = e[6] or ""
existing[name] = {
etype = etype,
owner = owner,
group = group,
perms = perms,
cmeta = cmeta,
}
end
local data = string.char(META_VERSION)
for name, m in pairs(existing) do
data = data .. makeEntry(
name,
m.etype or REG,
m.owner or 0,
m.group or 0,
m.perms or RWX_RX_RX,
m.cmeta or ""
)
end
local ok, err = pcall(function()
local f = rootDisk:open(metaPath, "w")
f.write(data)
f.close()
end)
if not ok then
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 0xFF8800)
end
end
seed("/", {
{"bin", 0, 0, RWX_RX_RX},
{"boot", 0, 0, RWX_RX_RX},
{"dev", 0, 0, RWXRWXRWX},
{"etc", 0, 0, RWX_RX_RX},
{"home", 0, 0, RWX_RX_RX},
{"lib", 0, 0, RWX_RX_RX},
{"proc", 0, 0, RWXRWXRWX},
{"root", 0, 0, RW____ },
{"sbin", 0, 0, RWX_RX_RX},
{"tmp", 0, 0, RWXRWXRWX},
{"usr", 0, 0, RWX_RX_RX},
{"var", 0, 0, RWXRWXRWX},
{"opt", 0, 0, RWX_RX_RX},
kernel.log("Seeding filesystem permissions...")
mergeMeta("/", {
{"bin", REG, 0, 0, RWX_RX_RX},
{"boot", REG, 0, 0, RWX_RX_RX},
{"dev", REG, 0, 0, RWXRWXRWX},
{"etc", REG, 0, 0, RWX_RX_RX},
{"home", REG, 0, 0, RWX_RX_RX},
{"lib", REG, 0, 0, RWX_RX_RX},
{"proc", REG, 0, 0, RWXRWXRWX},
{"root", REG, 0, 0, RW____ },
{"sbin", REG, 0, 0, RWX_RX_RX},
{"tmp", REG, 0, 0, RWXRWXRWX},
{"usr", REG, 0, 0, RWX_RX_RX},
{"var", REG, 0, 0, RWXRWXRWX},
{"opt", REG, 0, 0, RWX_RX_RX},
})
seed("/bin/", {
{"login", 0, 0, SUID_755 },
{"su", 0, 0, SUID_755 },
{"sudo", 0, 0, SUID_755 },
mergeMeta("/bin", {
{"login", REG, 0, 0, SUID_755 },
{"su", REG, 0, 0, SUID_755 },
{"sudo", REG, 0, 0, SUID_755 },
})
seed("/etc/", {
{"passwd", 0, 0, RW_R_R },
{"shadow", 0, 0, RW____ },
{"pam.d", 0, 0, RW____ },
mergeMeta("/etc", {
{"passwd", REG, 0, 0, RW_R_R },
{"shadow", REG, 0, 0, RW____ },
{"pam.d", REG, 0, 0, RW____ },
})
seed("/etc/pam.d/", {
{"secret", 0, 0, RW____},
mergeMeta("/etc/pam.d", {
{"secret", REG, 0, 0, RW____},
})
kernel.log("Filesystem permissions seeded.")
+2 -5
View File
@@ -3,7 +3,6 @@ syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2)
local fs=require("fs")
local MAX_ATTEMPTS = 3
@@ -101,9 +100,7 @@ local function spawnShell(username, uid, shell, homedir)
pcall(syscall.chdir, "/")
end
local shellfunc, err = load(fs.readAllText(shell))
local ok, err = pcall(syscall.spawn, shellfunc, username .. ":shell", nil,nil,nil,true)
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2)
@@ -148,7 +145,7 @@ local function doLogin()
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3)
pcall(spawnShell, username, uid, shell, homedir)
spawnShell(username, uid, shell, homedir)
return -- back to login prompt
else
attempts = attempts + 1
+2 -5
View File
@@ -3,7 +3,6 @@ syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2)
local fs=require("fs")
local MAX_ATTEMPTS = 3
@@ -101,9 +100,7 @@ local function spawnShell(username, uid, shell, homedir)
pcall(syscall.chdir, "/")
end
local shellfunc, err = load(fs.readAllText(shell))
local ok, err = pcall(syscall.spawn, shellfunc, username .. ":shell", nil,nil,nil,true)
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2)
@@ -148,7 +145,7 @@ local function doLogin()
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3)
pcall(spawnShell, username, uid, shell, homedir)
spawnShell(username, uid, shell, homedir)
return -- back to login prompt
else
attempts = attempts + 1
-40
View File
@@ -1,40 +0,0 @@
--:Minify:--
local lib = {}
function lib.frame(frame)
local handle = {}
function handle.setPixel(x,y,color24)
end
function handle.getPixel(x,y)
end
function handle.setPixels(x,y,framebuffer)
end
function handle.getPixels(x,y,w,h)
end
function handle.frame(x,y,w,h,writeonly)
end
function handle.framectl(id,x,y,w,h,writeonly)
end
function handle.drawframe()
end
function handle.line()
end
return handle
end
-256
View File
@@ -1,256 +0,0 @@
#000000
#0b0b0b
#222222
#444444
#555555
#777777
#888888
#aaaaaa
#bbbbbb
#dddddd
#eeeeee
#00000b
#000022
#000044
#000055
#000077
#000088
#0000aa
#0000bb
#0000dd
#0000ee
#000b00
#002200
#004400
#005500
#007700
#008800
#00aa00
#00bb00
#00dd00
#00ee00
#0b0000
#220000
#440000
#550000
#770000
#880000
#aa0000
#bb0000
#dd0000
#ee0000
#000033
#000066
#000099
#0000cc
#0000ff
#003300
#003333
#003366
#003399
#0033cc
#0033ff
#006600
#006633
#006666
#006699
#0066cc
#0066ff
#009900
#009933
#009966
#009999
#0099cc
#0099ff
#00cc00
#00cc33
#00cc66
#00cc99
#00cccc
#00ccff
#00ff00
#00ff33
#00ff66
#00ff99
#00ffcc
#00ffff
#330000
#330033
#330066
#330099
#3300cc
#3300ff
#333300
#333333
#333366
#333399
#3333cc
#3333ff
#336600
#336633
#336666
#336699
#3366cc
#3366ff
#339900
#339933
#339966
#339999
#3399cc
#3399ff
#33cc00
#33cc33
#33cc66
#33cc99
#33cccc
#33ccff
#33ff00
#33ff33
#33ff66
#33ff99
#33ffcc
#33ffff
#660000
#660033
#660066
#660099
#6600cc
#6600ff
#663300
#663333
#663366
#663399
#6633cc
#6633ff
#666600
#666633
#666666
#666699
#6666cc
#6666ff
#669900
#669933
#669966
#669999
#6699cc
#6699ff
#66cc00
#66cc33
#66cc66
#66cc99
#66cccc
#66ccff
#66ff00
#66ff33
#66ff66
#66ff99
#66ffcc
#66ffff
#990000
#990033
#990066
#990099
#9900cc
#9900ff
#993300
#993333
#993366
#993399
#9933cc
#9933ff
#996600
#996633
#996666
#996699
#9966cc
#9966ff
#999900
#999933
#999966
#999999
#9999cc
#9999ff
#99cc00
#99cc33
#99cc66
#99cc99
#99cccc
#99ccff
#99ff00
#99ff33
#99ff66
#99ff99
#99ffcc
#99ffff
#cc0000
#cc0033
#cc0066
#cc0099
#cc00cc
#cc00ff
#cc3300
#cc3333
#cc3366
#cc3399
#cc33cc
#cc33ff
#cc6600
#cc6633
#cc6666
#cc6699
#cc66cc
#cc66ff
#cc9900
#cc9933
#cc9966
#cc9999
#cc99cc
#cc99ff
#cccc00
#cccc33
#cccc66
#cccc99
#cccccc
#ccccff
#ccff00
#ccff33
#ccff66
#ccff99
#ccffcc
#ccffff
#ff0000
#ff0033
#ff0066
#ff0099
#ff00cc
#ff00ff
#ff3300
#ff3333
#ff3366
#ff3399
#ff33cc
#ff33ff
#ff6600
#ff6633
#ff6666
#ff6699
#ff66cc
#ff66ff
#ff9900
#ff9933
#ff9966
#ff9999
#ff99cc
#ff99ff
#ffcc00
#ffcc33
#ffcc66
#ffcc99
#ffcccc
#ffccff
#ffff00
#ffff33
#ffff66
#ffff99
#ffffcc
#ffffff
-350
View File
@@ -1,350 +0,0 @@
term.setGraphicsMode(2)
local w,h = term.getSize(2)
local fb={}
for i=1, h do
fb[i]={}
for x=1, w do
fb[i][x]=0
end
end
local function setPixel(x,y,c)
--local old=fb[y]
--fb[y]=string.sub(old,1,x-1)..string.char(c)..string.sub(old,x+1)
fb[y][x]=c
end
local function setPixels(x,y,frame)
local w,h = #fb[1], #fb
for i=1, #frame do
for j=1, #frame[i] do
fb[y+i-1][x+j-1]=frame[i][j]
end
end
end
local function getPixel(x,y)
return fb[y][x]
end
local function getPixels(x,y,w,h)
local ret={}
for i=y, y+h do
ret[#ret+1] = {table.unpack(fb[i], x, x+w)}
end
return ret
end
local colors = {
[0]=0x000000,
0x0b0b0b,
0x222222,
0x444444,
0x555555,
0x777777,
0x888888,
0xaaaaaa,
0xbbbbbb,
0xdddddd,
0xeeeeee,
0x00000b,
0x000022,
0x000044,
0x000055,
0x000077,
0x000088,
0x0000aa,
0x0000bb,
0x0000dd,
0x0000ee,
0x000b00,
0x002200,
0x004400,
0x005500,
0x007700,
0x008800,
0x00aa00,
0x00bb00,
0x00dd00,
0x00ee00,
0x0b0000,
0x220000,
0x440000,
0x550000,
0x770000,
0x880000,
0xaa0000,
0xbb0000,
0xdd0000,
0xee0000,
0x000033,
0x000066,
0x000099,
0x0000cc,
0x0000ff,
0x003300,
0x003333,
0x003366,
0x003399,
0x0033cc,
0x0033ff,
0x006600,
0x006633,
0x006666,
0x006699,
0x0066cc,
0x0066ff,
0x009900,
0x009933,
0x009966,
0x009999,
0x0099cc,
0x0099ff,
0x00cc00,
0x00cc33,
0x00cc66,
0x00cc99,
0x00cccc,
0x00ccff,
0x00ff00,
0x00ff33,
0x00ff66,
0x00ff99,
0x00ffcc,
0x00ffff,
0x330000,
0x330033,
0x330066,
0x330099,
0x3300cc,
0x3300ff,
0x333300,
0x333333,
0x333366,
0x333399,
0x3333cc,
0x3333ff,
0x336600,
0x336633,
0x336666,
0x336699,
0x3366cc,
0x3366ff,
0x339900,
0x339933,
0x339966,
0x339999,
0x3399cc,
0x3399ff,
0x33cc00,
0x33cc33,
0x33cc66,
0x33cc99,
0x33cccc,
0x33ccff,
0x33ff00,
0x33ff33,
0x33ff66,
0x33ff99,
0x33ffcc,
0x33ffff,
0x660000,
0x660033,
0x660066,
0x660099,
0x6600cc,
0x6600ff,
0x663300,
0x663333,
0x663366,
0x663399,
0x6633cc,
0x6633ff,
0x666600,
0x666633,
0x666666,
0x666699,
0x6666cc,
0x6666ff,
0x669900,
0x669933,
0x669966,
0x669999,
0x6699cc,
0x6699ff,
0x66cc00,
0x66cc33,
0x66cc66,
0x66cc99,
0x66cccc,
0x66ccff,
0x66ff00,
0x66ff33,
0x66ff66,
0x66ff99,
0x66ffcc,
0x66ffff,
0x990000,
0x990033,
0x990066,
0x990099,
0x9900cc,
0x9900ff,
0x993300,
0x993333,
0x993366,
0x993399,
0x9933cc,
0x9933ff,
0x996600,
0x996633,
0x996666,
0x996699,
0x9966cc,
0x9966ff,
0x999900,
0x999933,
0x999966,
0x999999,
0x9999cc,
0x9999ff,
0x99cc00,
0x99cc33,
0x99cc66,
0x99cc99,
0x99cccc,
0x99ccff,
0x99ff00,
0x99ff33,
0x99ff66,
0x99ff99,
0x99ffcc,
0x99ffff,
0xcc0000,
0xcc0033,
0xcc0066,
0xcc0099,
0xcc00cc,
0xcc00ff,
0xcc3300,
0xcc3333,
0xcc3366,
0xcc3399,
0xcc33cc,
0xcc33ff,
0xcc6600,
0xcc6633,
0xcc6666,
0xcc6699,
0xcc66cc,
0xcc66ff,
0xcc9900,
0xcc9933,
0xcc9966,
0xcc9999,
0xcc99cc,
0xcc99ff,
0xcccc00,
0xcccc33,
0xcccc66,
0xcccc99,
0xcccccc,
0xccccff,
0xccff00,
0xccff33,
0xccff66,
0xccff99,
0xccffcc,
0xccffff,
0xff0000,
0xff0033,
0xff0066,
0xff0099,
0xff00cc,
0xff00ff,
0xff3300,
0xff3333,
0xff3366,
0xff3399,
0xff33cc,
0xff33ff,
0xff6600,
0xff6633,
0xff6666,
0xff6699,
0xff66cc,
0xff66ff,
0xff9900,
0xff9933,
0xff9966,
0xff9999,
0xff99cc,
0xff99ff,
0xffcc00,
0xffcc33,
0xffcc66,
0xffcc99,
0xffcccc,
0xffccff,
0xffff00,
0xffff33,
0xffff66,
0xffff99,
0xffffcc,
0xffffff,
}
for i=0,255 do
term.setPaletteColor(i,colors[i])
end
term.drawPixels(0,0,fb)
for i=0,255 do
for y=1+i, h-i do
for x=1+i, w-i do
setPixel(x,y,i)
end
end
term.drawPixels(1,1,fb)
os.queueEvent("nosleep")
os.pullEvent()
end
for i=1, 1000 do
pcall(function()
setPixels(math.random(1,w),math.random(1,h),getPixels(math.random(1,w),math.random(1,h),math.random(1,w),math.random(1,h)))
end)
term.drawPixels(1,1,fb)
os.queueEvent("nosleep")
os.pullEvent()
end
setPixels(1,1,getPixels(w-50,h-50,50,50))
term.drawPixels(0,0,fb)
local i=0
for x=1, 16*4, 4 do
for y=1, 16*4, 4 do
setPixel(x,y,i)
setPixel(x+1,y,i)
setPixel(x+2,y,i)
setPixel(x+3,y,i)
setPixel(x,y+1,i)
setPixel(x+1,y+1,i)
setPixel(x+2,y+1,i)
setPixel(x+3,y+1,i)
setPixel(x,y+2,i)
setPixel(x+1,y+2,i)
setPixel(x+2,y+2,i)
setPixel(x+3,y+2,i)
setPixel(x,y+3,i)
setPixel(x+1,y+3,i)
setPixel(x+2,y+3,i)
setPixel(x+3,y+3,i)
i=i+1
end
end
term.drawPixels(0,0,fb)
sleep(5)
term.setGraphicsMode(false)
+84
View File
@@ -0,0 +1,84 @@
--:Minify:--
local lib = {}
--[[
Example framebuffer object
fb = {
r={
"","" -- repeat for # of rows length of string is the # of collums
},
g = {
"",""
},
b = {
"",""
}
}
Example font object
font = {
width=int,
hight=int,
data={
A={
"Ga","gs","Gk" -- length of string is byte alligned with the string being a binary bitmap
}
}
}
]]
function lib.newFbObj(fb)
local handle = {}
function handle.setPixel(x,y,color24)
end
function handle.line(x1,y1,x2,y2,color24)
end
function handle.box(x1,y1,x2,y2,color24)
end
function handle.filledBox(x1,y1,x2,y2,color24)
end
function handle.tri(x1,y1,x2,y2,x3,y3,color24)
end
function handle.filledTri(x1,y1,x2,y2,x3,y3,color24)
end
function handle.window(id,x,y,w,h,writeonly)
end
function handle.editWindow(id,x,y,w,h)
end
function handle.text(x,y,font,color24)
end
function handle.draw()
end
function handle.getPixel(x,y)
end
function handle.getPixels(x1y1,x2,y2)
end
return handle
end
+3 -1
View File
@@ -239,7 +239,9 @@ else
for _, cmd in ipairs(COMMANDS) do addCmd(cmd) end
end
local screenW, screenH = syscall.devctl(1, "size")
local sizeStr = syscall.devctl(1, "size")
local screenW = tonumber(sizeStr:match("^(%d+)")) or 51
local screenH = tonumber(sizeStr:match(";(%d+)")) or 19
local pageSize = screenH - 2
local scroll = 0
+17 -8
View File
@@ -1009,7 +1009,9 @@ local function getUserInput()
syscall.write(1, syscall.getcwd())
syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.write(1, "$ ")
local curOffsetX,curOffsetY = syscall.devctl(1, "gpos")
local curOffsetStr = syscall.devctl(1, "gpos")
local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1))
local curOffsetY = tonumber(curOffsetStr:sub(curOffsetStr:find(";")+1))
local input = ""
local blinkState = false
@@ -1107,10 +1109,14 @@ local function getUserInput()
local newInput, newCursor, needsRedraw = doTabComplete(input, cursorPos)
if needsRedraw then
input = newInput; cursorPos = newCursor
local px,py = syscall.devctl(1, "gpos")
local posStr = syscall.devctl(1, "gpos")
local sep = posStr:find(";")
local px = tonumber(posStr:sub(1, sep-1))
local py = tonumber(posStr:sub(sep+1))
if px > 1 then
syscall.devctl(1,"spos",1,py)
local tw = syscall.devctl(1,"size")
local tsz = syscall.devctl(1,"size") or "51;19"
local tw = tonumber(tsz:match("^(%d+)")) or 51
syscall.write(1, string.rep(" ", tw))
syscall.devctl(1,"spos",1,py)
end
@@ -1118,7 +1124,10 @@ local function getUserInput()
syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, ":")
syscall.devctl(1,"sfgc",0x00FFFF); syscall.write(1, syscall.getcwd())
syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, "$ ")
curOffsetX,curOffsetY = syscall.devctl(1, "gpos")
posStr = syscall.devctl(1, "gpos")
sep = posStr:find(";")
curOffsetX = tonumber(posStr:sub(1, sep-1))
curOffsetY = tonumber(posStr:sub(sep+1))
dirty = true
end
elseif key=="\b" then
@@ -1206,9 +1215,9 @@ local function runCommand(command)
local proc = syscall.spawn(function()
-- Open standard fds so programs that don't do it themselves work correctly.
--syscall.open("/proc/self/parent/fd/0", "r") -- fd 0 stdin
--syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout
--syscall.open("/proc/self/parent/fd/2", "w") -- fd 2 stderr
syscall.open("/proc/self/parent/fd/0", "r") -- fd 0 stdin
syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout
syscall.open("/proc/self/parent/fd/2", "w") -- fd 2 stderr
-- exec replaces this coroutine's code with a fresh isolated environment
-- compiled from disk by the kernel (via loadExecutable -> freshUserEnv),
-- so the child cannot share any upvalue or syscall table state with hysh.
@@ -1222,7 +1231,7 @@ local function runCommand(command)
return
end
if terminate then
local ok2 = syscall.kill(proc, true)
local ok2 = syscall.kill(proc)
if ok2 then
syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",0xFF0000)
print("\nProgram Terminated."); syscall.devctl(1,"sfgc",0xFFFFFF)
+2 -1
View File
@@ -91,7 +91,8 @@ local function humanSize(size)
return math.floor(size) .. sizePrefixes[scale]
end
local sizeX = syscall.devctl(1, "size")
local screenSizeStr = syscall.devctl(1, "size")
local sizeX = tonumber(screenSizeStr:match("^(%d+)")) or 80
local list = fs.list(dir)
list[#list+1] = "."
-10
View File
@@ -1,10 +0,0 @@
--:Minify:--
local args={...}
if #args<1 then print("trace [filepath] args") syscall.exit() end
local fs=require("fs")
local file = fs.readAllText(args[1])
if not file then print("File not found") end
local func, err = load(file, args[1], "t", _G)
if not func then print(err) syscall.exit() end
local ok,err = xpcall(func, debug.traceback, table.unpack(args, 2))
if not ok then print(err) end
+3 -1
View File
@@ -237,7 +237,9 @@ end
local function getUserInput(prompt, history)
c(C_PROMPT); w(prompt); c(1)
local ox, oy = syscall.devctl(1, "gpos")
local pos = syscall.devctl(1, "gpos")
local ox = tonumber(pos:sub(1, pos:find(";")-1))
local oy = tonumber(pos:sub(pos:find(";")+1))
local input = ""
local cursor = 1
+3 -1
View File
@@ -12,7 +12,9 @@
local args = { ... }
local function termSize()
return syscall.devctl(1, "size")
local s = syscall.devctl(1, "size")
return tonumber(s:match("^(%d+)")) or 80,
tonumber(s:match(";(%d+)$")) or 24
end
local function tpos(x,y) syscall.devctl(1,"spos",x,y) end
local function tfg(c) syscall.devctl(1,"sfgc",c) end
+14 -49
View File
@@ -20,8 +20,7 @@ local spm = function(...)
sysroot = "",
init = false,
help = false,
overwrite = false,
clean = false
overwrite = false
}
local i = 1
@@ -217,7 +216,8 @@ local spm = function(...)
local function printpkgs(list)
local colWidth=0
local sizeX, sizeY = syscall.devctl(1, "size")
local tmp = syscall.devctl(1, "size")
local sizeX, sizeY = tonumber(tmp:sub(1, tmp:find(";")-1)), tonumber(tmp:sub(tmp:find(";")+1))
for _, v in ipairs(list) do
if #v + 2 > colWidth then colWidth = #v + 2 end
end
@@ -547,7 +547,7 @@ local spm = function(...)
if cloptions.u then
for i,v in ipairs(table.keys(pkgdb)) do
local pkg, err = getPkg(v)
if pkg and not found[v] then
if pkg then
needed[#needed+1] = pkg
found[v]=true
end
@@ -586,7 +586,7 @@ local spm = function(...)
local files = {}
for _,v in ipairs(needed) do
if (not pkgdb[v.id]) or pkgdb[v.id].hash~=v.hash or cloptions.clean then
if not pkgdb[v.id] or not pkgdb[v.id].hash==v.hash then
w("Downloading "..v.id)
local resp = get(v.tar)
if not resp then
@@ -689,46 +689,6 @@ local spm = function(...)
syscall.exit()
end
end
w("Writing files...")
for i,v in pairs(files) do
w("Writing package "..i)
for f,c in pairs(v.data) do
if not block[f] then
fs.writeAllText(f,c)
end
end
end
w("Proccessing control files...")
for i,v in pairs(files) do
if v.control then
for f,c in pairs(v.control) do
if f=="symlinks.json" then
local symlinks=json.decode(c)
for src,dest in pairs(symlinks) do
if syscall.exists(src) then
if syscall.type(src)~="symlink" then
if not v.data[src] then
w("Failed to create symlink "..src)
end
else
syscall.remove(src)
end
end
w(src.." -> "..dest)
syscall.symlink(dest, src)
end
elseif f=="setup.lua" then
local func, err = load(c, "setupscript", "t", _G)
if not func then
w("Failed to load setup script for package "..i)
else
local ok, err = xpcall(func, debug.traceback)
if not ok then w("Setup script for package "..i.." exited with error: "..err) end
end
end
end
end
end
w("Updatating db...")
for i,v in pairs(files) do
local content={}
@@ -737,12 +697,17 @@ local spm = function(...)
content.files[f]=md5(c)
end
content.hash=v.hash
content.symlinks={}
if v.control and v.control["symlinks.json"] then
content.symlinks=json.decode(v.control["symlinks.json"])
end
fs.writeAllText("var/spm/db/installed/"..i, json.encode(content))
end
w("Writing changes...")
for i,v in pairs(files) do
w("Writing "..i)
for f,c in pairs(v.data) do
if not block[f] then
fs.writeAllText(f,c)
end
end
end
w("Install complete")
log.close()
+3 -4
View File
@@ -14,7 +14,7 @@ for i,v in pairs(kernel.processes) do
else
kernel.log("Successfully executed kernel task: " .. i)
end
end, i, nil,nil,nil,true)
end, i)
end
-- config file path setup
@@ -36,16 +36,15 @@ for i,v in ipairs(files) do
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else
syscall.spawn(function()
local status, err = xpcall(startupFunc, debug.traceback)
local status, err = pcall(startupFunc)
if not status then
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else
kernel.log("Successfully executed startup script: " .. filepath)
end
end, "startup:" .. v, nil,nil,nil,true)
end, "startup:" .. v)
end
end
kernel.log("sysinit complete")
kernel.saveLog()
while true do
+2 -13
View File
@@ -142,19 +142,13 @@ def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool, arch
def install_bootloader(arch: str, release: bool):
boot_dir = BUILD_ROOT / "root" / ARCH_BOOT_DIR[arch]
boot_dir = BUILD_ROOT / "$" / ARCH_BOOT_DIR[arch]
eeprom = boot_dir / "eeprom"
eeprom_dst_name = "startup.lua" if release else "eeprom"
print(f" Installing: eeprom -> Build/{eeprom_dst_name}")
shutil.copy2(eeprom, BUILD_ROOT / eeprom_dst_name)
if arch=="cct":
with open(BUILD_ROOT / "root/boot/fstab", "r") as file:
content=file.read()
with open(BUILD_ROOT / "root/boot/fstab", "w") as file:
file.write("U root;/\n"+content)
def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, None], release: bool, prod: bool):
clean()
@@ -163,7 +157,7 @@ def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, No
cleanprod()
PROD_ROOT.mkdir()
out_root = BUILD_ROOT / "root" if arch else BUILD_ROOT
out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT
process_root(SRC_ROOT, out_root, minify, micro, arch, False)
if prod:
@@ -176,11 +170,6 @@ def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, No
print("Installing bootloader files ...")
install_bootloader(arch, release)
print()
boot_root = out_root / "boot"
disk_root = BUILD_ROOT / "$"
boot_root.rename(disk_root)
def _make_firstboot_kmod(users):
+4 -30
View File
@@ -2,8 +2,8 @@
import hashlib
import json
import shutil, io
import tarfile, gzip
import shutil
import tarfile
from pathlib import Path
ROOT = Path(__file__).resolve().parent
@@ -89,15 +89,6 @@ def read_dependencies(folder):
return dependencies if dependencies else DEFAULT_DEPENDENCIES
def reproducible_filter(info):
info.mtime = 0
info.uid = 0
info.gid = 0
info.uname = ""
info.gname = ""
return info
def create_package(folder):
name = folder.name
@@ -111,25 +102,8 @@ def create_package(folder):
debug(f"Packing {name}")
# Create deterministic TAR
tar_data = io.BytesIO()
with tarfile.open(fileobj=tar_data, mode="w") as archive:
archive.add(
folder,
arcname=name,
filter=reproducible_filter,
)
# Create deterministic gzip
compressed = gzip.compress(
tar_data.getvalue(),
compresslevel=9,
mtime=0,
)
with open(tarball, "wb") as file:
file.write(compressed)
with tarfile.open(tarball, "w:gz") as archive:
archive.add(folder, arcname=name, filter=exclude)
package_hash = sha256(tarball)
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "32ab474f175e911f0625c8ab33202fae",
"hash": "10231c287c97ab72adf77117886d2de3",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-core.tar.gz"
}
+1 -1
View File
@@ -8,6 +8,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "a4e33985213691b829940e014685ba0d",
"hash": "a44f05701db0feef517f196047a198d7",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ac.tar.gz"
}
+1 -1
View File
@@ -4,6 +4,6 @@
"authors": [],
"dependencies": [],
"version": "0.0.0",
"hash": "dd93f2bd27640aea671155c26c3c47c5",
"hash": "cba0823f33d942e92ddad54c2d4a7004",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-addon-cct.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "b6c3a1bff52636f79f4c8f39def03aa2",
"hash": "4021ef17d9a26200b255e5fdad3766cc",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ccpc.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.3.0",
"hash": "15dbb52d9c151a30de521f13e2a16278",
"hash": "341e92ee642399fb7b6892be669ad881",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-cct.tar.gz"
}
+1 -1
View File
@@ -4,6 +4,6 @@
"authors": [],
"dependencies": [],
"version": "0.0.0",
"hash": "c8fec163cdbcda36fe01d8bb9fd4e327",
"hash": "f9fcd282170185f174fd5c1e7b9cb93e",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-lua.tar.gz"
}
+4 -6
View File
@@ -1,13 +1,11 @@
{
"id": "Hyperion-firmware-oc",
"description": "firmware for Opencomputers mod",
"description": "firmware for Opencomputers",
"authors": [
"Hyperion",
"Astronand",
"Xtimhedae"
"Hyperion"
],
"dependencies": [],
"version": "1.0.0",
"hash": "913d68c1c1a42afd42bfbab61a10729e",
"version": "0.1.0",
"hash": "3090e7b03b8212052fb697987b1f5024",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-oc.tar.gz"
}
+1 -1
View File
@@ -4,6 +4,6 @@
"authors": [],
"dependencies": [],
"version": "0.0.0",
"hash": "c7971267c5306ee06ba943e241647e64",
"hash": "ceb96ec6a50538e6d162215639698077",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-vm.tar.gz"
}
+1 -1
View File
@@ -8,6 +8,6 @@
],
"dependencies": [],
"version": "1.5.0",
"hash": "d45b18adc188a3090e5f1d9aca687347",
"hash": "21a9ab0c0637273e97527870acc24bba",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-kernel.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "85daa009881b6be44b84b3641138670a",
"hash": "89efe44800c2559b125c3e5315a5d5a4",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/bit32.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "4193c27a6b98ed75bfcaaddc3e21f967",
"hash": "c41dc8025c5bcf657e5b52c40ddfe6be",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/blake2s.tar.gz"
}
+1 -1
View File
@@ -8,6 +8,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "34996938f359f52e92a388483c3fb5c9",
"hash": "988c894f0faa19ff79f26270e6567c5f",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/coreutils.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0-release",
"hash": "821c762d067ab72abe100351c2f74f63",
"hash": "23ef21eef7e266d416bddee1eb673e30",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/deflate.tar.gz"
}
+3 -3
View File
@@ -1,5 +1,5 @@
{
"id": "gfx",
"id": "gfxterm",
"description": "package providing kernel support for framebuffers and graphics",
"authors": [
"Hyperion",
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "aaf9664adb4d85aa6d0d504692e8ec26",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/gfx.tar.gz"
"hash": "5c423cc612d946e70e54fb517a71d22e",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/gfxterm.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.3.0",
"hash": "cbc352d49cb9837ee825471351dd9ffc",
"hash": "c3c914f7aecc642464cb5b14f2e135fa",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/hysh.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "1f69e2cfa0d86c419ab1927221230ae8",
"hash": "81177ba78d1febbd6fff59bb23a16080",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/iniparse.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "897e5abc980bda9051fff8f72c864251",
"hash": "203ace7ad9135d21691e2a6b9e62be9f",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/installer.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "f22c3b6c445f9390195654246b6dca03",
"hash": "6602fa70ec8e1288015168eddf817664",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/json.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.2.0",
"hash": "7479232dae56ad762119a8c57767e617",
"hash": "31e0103563ca3443e5c3ab8257325138",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/lua.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "8fa15ac698fe19927d0d860f9b813c5f",
"hash": "916d8f4dabdcef58524e9a4c59ea8957",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/micro.tar.gz"
}
+1 -1
View File
@@ -8,6 +8,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "a6f6beecb0828a355cca23f90c77dbd9",
"hash": "87cb37074598899bf446d76bee0945a4",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/minify.tar.gz"
}
+1 -1
View File
@@ -7,6 +7,6 @@
],
"dependencies": [],
"version": "1.0.0",
"hash": "90583ad14ffc68fbbec09f03b926cdaf",
"hash": "c48c7078c5b5c9309ed3d6ee4fb38c2c",
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/pid.tar.gz"
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More