updated kernel and working on oc tty impl
This commit is contained in:
@@ -321,7 +321,7 @@ local ok, err = xpcall(function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function coroutine.resumeWithTimeout(co, timeout, ...)
|
function EFI.resumeWithTimeout(co, timeout, ...)
|
||||||
local startTime = EFI.getEpochMs()
|
local startTime = EFI.getEpochMs()
|
||||||
debug.sethook(co, function()
|
debug.sethook(co, function()
|
||||||
if EFI.getEpochMs() > startTime + timeout then
|
if EFI.getEpochMs() > startTime + timeout then
|
||||||
@@ -342,7 +342,7 @@ local ok, err = xpcall(function()
|
|||||||
write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
|
write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50)
|
local status, err = EFI.resumeWithTimeout(kernelCoro, 50)
|
||||||
apis.os.queueEvent("NoSleep")
|
apis.os.queueEvent("NoSleep")
|
||||||
local exit = false
|
local exit = false
|
||||||
while not exit do
|
while not exit do
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ local function write(text, term)
|
|||||||
term.setCursorPos(x, y)
|
term.setCursorPos(x, y)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function displaySuperBadError(err)
|
local function displaySuperBadError(err, noyield)
|
||||||
lterm.setBackgroundColor(0x1)
|
lterm.setBackgroundColor(0x1)
|
||||||
lterm.setTextColor(0x4)
|
lterm.setTextColor(0x4)
|
||||||
lterm.clear()
|
lterm.clear()
|
||||||
@@ -145,9 +145,9 @@ local ok, err = xpcall(function()
|
|||||||
return content
|
return content
|
||||||
end
|
end
|
||||||
|
|
||||||
local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/boot/kernel.lua"),"@Kernel")
|
local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/kernel.lua"),"@Kernel")
|
||||||
local initFs = load(getFile(BOOT_DRIVE_PATH .. "/boot/cct/initdisks"),"@Init_disks")(apis)
|
local initFs = load(getFile(BOOT_DRIVE_PATH .. "/cct/initdisks"),"@Init_disks")(apis)
|
||||||
local fs = load(getFile(BOOT_DRIVE_PATH .. "/boot/initfs"), "@InitFs")()
|
local fs = load(getFile(BOOT_DRIVE_PATH .. "/initfs"), "@InitFs")()
|
||||||
|
|
||||||
if not Kernel then displaySuperBadError("Could not load kernel.") end
|
if not Kernel then displaySuperBadError("Could not load kernel.") end
|
||||||
if not initFs then displaySuperBadError("Could not load initdisks.") end
|
if not initFs then displaySuperBadError("Could not load initdisks.") end
|
||||||
@@ -419,6 +419,7 @@ local ok, err = xpcall(function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local EFI = {
|
local EFI = {
|
||||||
|
yield=function() end,
|
||||||
getEpochMs = function() return apis.os.epoch("utc") end,
|
getEpochMs = function() return apis.os.epoch("utc") end,
|
||||||
getUptime = function() return apis.os.clock() * 1000 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,
|
date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end,
|
||||||
@@ -506,15 +507,14 @@ local ok, err = xpcall(function()
|
|||||||
--pf
|
--pf
|
||||||
---@diagnostic disable-next-line: param-type-mismatch-
|
---@diagnostic disable-next-line: param-type-mismatch-
|
||||||
local ok, err = xpcall(Kernel, debug.traceback, EFI)
|
local ok, err = xpcall(Kernel, debug.traceback, EFI)
|
||||||
if not ok and not EFI.reboot then displaySuperBadError(err) end
|
if not ok then
|
||||||
if err then
|
error(err)
|
||||||
apis.os.reboot()
|
|
||||||
else
|
else
|
||||||
apis.os.shutdown()
|
apis.os.shutdown()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function coroutine.resumeWithTimeout(co, timeout, ...)
|
function EFI.resumeWithTimeout(co, timeout, ...)
|
||||||
local startTime = EFI.getEpochMs()
|
local startTime = EFI.getEpochMs()
|
||||||
debug.sethook(co, function()
|
debug.sethook(co, function()
|
||||||
if EFI.getEpochMs() > startTime + timeout then
|
if EFI.getEpochMs() > startTime + timeout then
|
||||||
@@ -536,7 +536,7 @@ local ok, err = xpcall(function()
|
|||||||
--p
|
--p
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50)
|
local status, err = EFI.resumeWithTimeout(kernelCoro, 50)
|
||||||
apis.os.queueEvent("NoSleep")
|
apis.os.queueEvent("NoSleep")
|
||||||
local exit = false
|
local exit = false
|
||||||
while not exit do
|
while not exit do
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ function _G.term.native()
|
|||||||
term.setCursorPos(1, 1)
|
term.setCursorPos(1, 1)
|
||||||
term.setCursorBlink(true)
|
term.setCursorBlink(true)
|
||||||
term.clear()
|
term.clear()
|
||||||
local file = fs.open(BOOT_DRIVE_PATH.."/boot/cct/boot.lua", "r")
|
local file = fs.open(BOOT_DRIVE_PATH.."/cct/boot.lua", "r")
|
||||||
if file == nil then
|
if file == nil then
|
||||||
term.setCursorBlink(false)
|
term.setCursorBlink(false)
|
||||||
term.setTextColor(16384)
|
term.setTextColor(16384)
|
||||||
term.write("Could not find /boot/cct/boot.lua. UnBIOS cannot continue.")
|
term.write("Could not find /cct/boot.lua. UnBIOS cannot continue.")
|
||||||
term.setCursorPos(1, 2)
|
term.setCursorPos(1, 2)
|
||||||
term.write("Press any key to continue")
|
term.write("Press any key to continue")
|
||||||
coroutine.yield("key")
|
coroutine.yield("key")
|
||||||
@@ -73,7 +73,7 @@ function _G.term.native()
|
|||||||
if fn == nil then
|
if fn == nil then
|
||||||
term.setCursorBlink(false)
|
term.setCursorBlink(false)
|
||||||
term.setTextColor(16384)
|
term.setTextColor(16384)
|
||||||
term.write("Could not load /boot/cc/boot.lua. UnBIOS cannot continue.")
|
term.write("Could not load /cc/boot.lua. UnBIOS cannot continue.")
|
||||||
term.setCursorPos(1, 2)
|
term.setCursorPos(1, 2)
|
||||||
term.write(err)
|
term.write(err)
|
||||||
term.setCursorPos(1, 3)
|
term.setCursorPos(1, 3)
|
||||||
|
|||||||
@@ -250,6 +250,21 @@ internal["rom"] = createDisk("rom", "/rom", true, {
|
|||||||
end
|
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()
|
local function refresh()
|
||||||
disks={}
|
disks={}
|
||||||
for _, disk in ipairs({peripheral.find("drive")}) do
|
for _, disk in ipairs({peripheral.find("drive")}) do
|
||||||
|
|||||||
@@ -191,16 +191,14 @@ local function newtty(obj, id, ev)
|
|||||||
write(content, obj)
|
write(content, obj)
|
||||||
end,
|
end,
|
||||||
size=function()
|
size=function()
|
||||||
local s={obj.getSize()}
|
return obj.getSize()
|
||||||
return table.concat(s,";")
|
|
||||||
end,
|
end,
|
||||||
clear=function()
|
clear=function()
|
||||||
obj.clear()
|
obj.clear()
|
||||||
obj.setCursorPos(1,1)
|
obj.setCursorPos(1,1)
|
||||||
end,
|
end,
|
||||||
gpos=function()
|
gpos=function()
|
||||||
local s={obj.getCursorPos()}
|
return obj.getCursorPos()
|
||||||
return table.concat(s,";")
|
|
||||||
end,
|
end,
|
||||||
spos=function(x,y)
|
spos=function(x,y)
|
||||||
return obj.setCursorPos(x,y)
|
return obj.setCursorPos(x,y)
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
--: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
|
||||||
@@ -1 +0,0 @@
|
|||||||
Hyperion
|
|
||||||
@@ -1,41 +1,122 @@
|
|||||||
local lua = {
|
local cp,c=component,computer;local b_addr=c.getBootAddress();local b_fs=cp.proxy(b_addr)
|
||||||
coroutine = true,
|
local gpu=cp.list("gpu")() and cp.proxy(cp.list("gpu")())
|
||||||
debug = true,
|
local e_rom=cp.list("eeprom")() and cp.proxy(cp.list("eeprom")())
|
||||||
_HOST = true,
|
local screens={}
|
||||||
_VERSION = true,
|
for addr in cp.list("screen") do
|
||||||
assert = true,
|
local w,h=gpu and gpu.maxResolution() or 20,10
|
||||||
collectgarbage = true,
|
gpu.setResolution(w,h)
|
||||||
error = true,
|
gpu.fill(1,1,w,h," ")
|
||||||
gcinfo = true,
|
cp.proxy(addr).turnOn()
|
||||||
getfenv = true,
|
screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
|
||||||
getmetatable = true,
|
end
|
||||||
ipairs = true,
|
local function scroll(scr) gpu.copy(1,2,scr.w,scr.h-1,0,-1);gpu.fill(1,scr.h,scr.w,1," ") end
|
||||||
__inext = true,
|
local function write(t)
|
||||||
load = true,
|
if not gpu then return end
|
||||||
math = true,
|
for s=1, #screens do
|
||||||
next = true,
|
local scr=screens[s]
|
||||||
pairs = true,
|
gpu.bind(scr.addr)
|
||||||
pcall = true,
|
for i=1,#t do
|
||||||
rawequal = true,
|
local char=t:sub(i,i)
|
||||||
rawget = true,
|
if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
|
||||||
rawlen = true,
|
elseif char=="\t" then scr.cx=scr.cx+(4-((scr.cx-1)%4))
|
||||||
rawset = true,
|
elseif char=="\b" then if scr.cx>1 then scr.cx=scr.cx-1;gpu.set(scr.cx,scr.cy," ") end
|
||||||
select = true,
|
else gpu.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
|
||||||
setfenv = true,
|
if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
|
||||||
setmetatable = true,
|
if scr.cy>scr.h then error("executed")scroll(scr);scr.cy=scr.cy-1 end
|
||||||
string = true,
|
end
|
||||||
table = true,
|
end
|
||||||
tonumber = true,
|
end
|
||||||
tostring = true,
|
local function throw(err)
|
||||||
type = true,
|
if gpu then
|
||||||
xpcall = true,
|
gpu.setBackground(0x0000AA);
|
||||||
_G=true
|
gpu.setForeground(0xFFFFFF);
|
||||||
}
|
for i=1, #screens do
|
||||||
|
gpu.fill(1,1,screens[i].w,screens[i].h," ");
|
||||||
local apis={}
|
screens[i].cx,screens[i].cy=1,1;
|
||||||
for i,v in pairs(_G) do
|
end
|
||||||
if not lua[i] or lua[i]==nil then
|
write("CRITICAL KERNEL ERROR:\n"..tostring(err))
|
||||||
apis[i]=v
|
end
|
||||||
_G[i]=nil
|
while true do c.pullSignal() end
|
||||||
end
|
end
|
||||||
end
|
local ok,err=xpcall(function()
|
||||||
|
local apis={os={},fs={},peripheral={},term={}}
|
||||||
|
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
|
||||||
|
apis.os.clock=c.uptime;apis.os.epoch=function()return math.floor(c.uptime()*1000) end
|
||||||
|
apis.os.queueEvent=c.pushSignal
|
||||||
|
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("/boot/kernel.lua"),"@Kernel")
|
||||||
|
local initFs=load(getFile("/boot/oc/initdisks"),"@Init_disks")
|
||||||
|
local fs=load(getFile("/boot/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 n_addr=cp.list("filesystem")()
|
||||||
|
local eQ={}
|
||||||
|
local function qEv(e,...) table.insert(eQ,{e,...}) end
|
||||||
|
apis.peripheral.getNames=function() local res={};for k in cp.list() do table.insert(res,k) end return res end
|
||||||
|
apis.peripheral.isPresent=function(a) return cp.type(a)~=nil end
|
||||||
|
apis.peripheral.getType=cp.type
|
||||||
|
apis.peripheral.getMethods=cp.methods
|
||||||
|
apis.peripheral.call=cp.invoke
|
||||||
|
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() return #eQ>0 and table.unpack(table.remove(eQ,1)) or nil 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 gpu.fill(1,1,w,h," ");cx,cy=1,1 end end,
|
||||||
|
resetCursor=function() cx,cy=1,1 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])
|
||||||
|
elseif ev[1]=="component_added" then qEv("componentAdded",ev[3])
|
||||||
|
elseif ev[1]=="component_removed" then qEv("componentRemoved",ev[3])
|
||||||
|
elseif ev[1]=="modem_message" then qEv("modem_message",table.unpack(ev,2))
|
||||||
|
elseif ev[1]=="NoSleep" then ex=true 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
|
||||||
@@ -1,18 +1,68 @@
|
|||||||
checkArg=nil
|
local init
|
||||||
local oldcomputer=computer
|
do
|
||||||
_G.computer=nil
|
local component_invoke = component.invoke
|
||||||
local os=os
|
local function boot_invoke(address, method, ...)
|
||||||
_G.os=nil
|
local result = table.pack(pcall(component_invoke, address, method, ...))
|
||||||
|
if not result[1] then
|
||||||
function component.wrap(address)
|
return nil, result[2]
|
||||||
local methods=oldcomponent.methods(address)
|
else
|
||||||
local object={}
|
return table.unpack(result, 2, result.n)
|
||||||
for _,method in ipairs(methods) do
|
end
|
||||||
object[method]=function(_,...)
|
end
|
||||||
return oldcomponent.invoke(address,method,...)
|
|
||||||
end
|
-- backwards compatibility, may remove later
|
||||||
end
|
local eeprom = component.list("eeprom")()
|
||||||
return object
|
computer.getBootAddress = function()
|
||||||
end
|
return boot_invoke(eeprom, "getData")
|
||||||
|
end
|
||||||
local
|
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", "/boot/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
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
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 +0,0 @@
|
|||||||
local fs={}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
--: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
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
--: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
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
-- 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() do
|
||||||
|
if typ == "gpu" then
|
||||||
|
gpus[#gpus]=component.proxy(addr)
|
||||||
|
elseif typ == "screen" then
|
||||||
|
screens[addr]={cx=1,cy=1,w=w,h=h}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local binds,newid={},0
|
||||||
|
|
||||||
|
local function write(text, addr)
|
||||||
|
local g=gpus[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function newtty(addr)
|
||||||
|
newid=newid+1
|
||||||
|
kernel.devfs.data["tty"][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()
|
||||||
|
local s={obj.getSize()}
|
||||||
|
return tostring(screens[addr].w)..":"
|
||||||
|
end,
|
||||||
|
clear=function()
|
||||||
|
obj.clear()
|
||||||
|
obj.setCursorPos(1,1)
|
||||||
|
end,
|
||||||
|
gpos=function()
|
||||||
|
local s={obj.getCursorPos()}
|
||||||
|
return table.concat(s,";")
|
||||||
|
end,
|
||||||
|
spos=function(x,y)
|
||||||
|
return obj.setCursorPos(x,y)
|
||||||
|
end,
|
||||||
|
sfgc=function(c)
|
||||||
|
fg=c
|
||||||
|
return obj.setTextColor(aprox(c))
|
||||||
|
end,
|
||||||
|
sbgc=function(c)
|
||||||
|
bg=c
|
||||||
|
return obj.setBackgroundColor(aprox(c))
|
||||||
|
end,
|
||||||
|
gfgc=function()
|
||||||
|
return fg
|
||||||
|
end,
|
||||||
|
gbgc=function()
|
||||||
|
return 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 #screens>=1 then
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
--: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
|
||||||
@@ -1 +0,0 @@
|
|||||||
firmware for Opencomputers
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
0.1.0
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
U $;/
|
F $;/boot/
|
||||||
U devfs0000;/dev/
|
V devfs0000;/dev/
|
||||||
U tmpfs0000;/tmp/
|
V tmpfs0000;/tmp/
|
||||||
U procfs0000;/proc/
|
V procfs0000;/proc/
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ end
|
|||||||
function fs.load(path) return load(fs.readAllText(path), path) end
|
function fs.load(path) return load(fs.readAllText(path), path) end
|
||||||
|
|
||||||
function fs.mount(disk, mountPoint)
|
function fs.mount(disk, mountPoint)
|
||||||
if not disks[disk] then return end
|
if not disks[disk] then error("NODISK : "..disk) end
|
||||||
mounts[mountPoint] = disk
|
mounts[mountPoint] = disk
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ function kernel.PANIC(msg)
|
|||||||
kernel.exitMain = true
|
kernel.exitMain = true
|
||||||
end
|
end
|
||||||
while true do
|
while true do
|
||||||
|
EFI:yield()
|
||||||
local event={EFI:getMachineEvent()}
|
local event={EFI:getMachineEvent()}
|
||||||
if event[1]=="keyPressed" then
|
if event[1]=="keyPressed" then
|
||||||
break
|
break
|
||||||
@@ -98,7 +99,7 @@ kernel.disks={}
|
|||||||
for _,v in disks.list() do
|
for _,v in disks.list() do
|
||||||
kernel.disks[v.address] = v
|
kernel.disks[v.address] = v
|
||||||
end
|
end
|
||||||
ifs.mount("$", "/")
|
ifs.mount("$", "/boot/")
|
||||||
|
|
||||||
local fstab=ifs.readAllText("/boot/fstab")
|
local fstab=ifs.readAllText("/boot/fstab")
|
||||||
local split = function(str, delim, maxResultCountOrNil)
|
local split = function(str, delim, maxResultCountOrNil)
|
||||||
@@ -138,8 +139,9 @@ end
|
|||||||
kernel.config = config
|
kernel.config = config
|
||||||
|
|
||||||
local skip=false
|
local skip=false
|
||||||
|
local root=false
|
||||||
for i,v in ipairs(split(fstab,"\n")) do
|
for i,v in ipairs(split(fstab,"\n")) do
|
||||||
if v:sub(1,1)=="U" then
|
if v:sub(1,1)=="U" or v:sub(1,1)=="F" then
|
||||||
local id=""
|
local id=""
|
||||||
for i=3,#v do
|
for i=3,#v do
|
||||||
if v:sub(i,i)==";" then
|
if v:sub(i,i)==";" then
|
||||||
@@ -149,12 +151,14 @@ for i,v in ipairs(split(fstab,"\n")) do
|
|||||||
end
|
end
|
||||||
if not skip then
|
if not skip then
|
||||||
local path=v:sub(#id+4)
|
local path=v:sub(#id+4)
|
||||||
|
if path=="/" then root=true end
|
||||||
ifs.mount(id,path)
|
ifs.mount(id,path)
|
||||||
else
|
else
|
||||||
skip=false
|
skip=false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if not root then kernel.panic("No disk mounted to /") end
|
||||||
kernel.log("Disks initialized")
|
kernel.log("Disks initialized")
|
||||||
|
|
||||||
function kernel.saveLog()
|
function kernel.saveLog()
|
||||||
@@ -321,6 +325,26 @@ kernel.processes={}
|
|||||||
kernel.fstab=fstab
|
kernel.fstab=fstab
|
||||||
kernel.denied={}
|
kernel.denied={}
|
||||||
kernel.loadingModule="kernel"
|
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 = {
|
kernel.kernelTask = {
|
||||||
name="kernel",
|
name="kernel",
|
||||||
@@ -429,11 +453,17 @@ for _,p in ipairs(modules) do
|
|||||||
end
|
end
|
||||||
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.log("Kernel initialized successfully.")
|
||||||
kernel.saveLog()
|
kernel.saveLog()
|
||||||
kernel.status="running"
|
kernel.status="running"
|
||||||
kernel.loadingModule=nil
|
kernel.loadingModule=nil
|
||||||
screen:disable()
|
screen:disable()
|
||||||
|
if not kernel.main then kernel.panic("No scheduler implemented from firmware") end
|
||||||
local ok,err = xpcall(kernel.main, debug.traceback)
|
local ok,err = xpcall(kernel.main, debug.traceback)
|
||||||
if not ok then
|
if not ok then
|
||||||
kernel.panic(err)
|
kernel.panic(err)
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
0:0:root:/root:/bin/hysh
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
local kernel = ...
|
local kernel = ...
|
||||||
local vfs = {}
|
local vfs = {}
|
||||||
kernel.vfs = vfs
|
kernel.vfs = vfs
|
||||||
vfs.mounts = {["$"] = "/"}
|
vfs.mounts = {}
|
||||||
vfs.disks = kernel.disks
|
vfs.disks = kernel.disks
|
||||||
|
|
||||||
-- Metafile format (version 2)
|
-- Metafile format (version 2)
|
||||||
@@ -556,17 +556,19 @@ function vfs.newfd(fdobj)
|
|||||||
return fd
|
return fd
|
||||||
end
|
end
|
||||||
|
|
||||||
function vfs.mount(target, diskOrId, bind)
|
function vfs.mount(target, diskOrId, bind, floating)
|
||||||
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
|
if not floating and target ~= "/" then
|
||||||
if _euid ~= 0 then error("EPERM") end
|
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
|
||||||
if not target then error("EINVAL") end
|
if _euid ~= 0 then error("EPERM") end
|
||||||
target = normalizeMountPoint(target)
|
if not target then error("EINVAL") end
|
||||||
local drive, path = resolvePath(target)
|
target = normalizeMountPoint(target)
|
||||||
if not drive:directoryExists(path) then
|
local drive, path = resolvePath(target)
|
||||||
drive:makeDirectory(path)
|
if not drive:directoryExists(path) then
|
||||||
end
|
drive:makeDirectory(path)
|
||||||
if drive:type(path) ~= "directory" then
|
end
|
||||||
error("EINVAL")
|
if drive:type(path) ~= "directory" then
|
||||||
|
error("EINVAL")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local disk, id
|
local disk, id
|
||||||
-- bind mount
|
-- bind mount
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
--:Minify:--
|
--:Minify:--
|
||||||
local kernel = ...
|
local kernel = ...
|
||||||
|
|
||||||
kernel.vfs.remove("/tmp")
|
|
||||||
kernel.vfs.mkdir("/tmp")
|
|
||||||
if not kernel.config.tmpToDisk then
|
if not kernel.config.tmpToDisk then
|
||||||
local proxy = {}
|
local proxy = {}
|
||||||
local data = {}
|
local data = {}
|
||||||
@@ -138,4 +136,8 @@ if not kernel.config.tmpToDisk then
|
|||||||
else
|
else
|
||||||
kernel.log("tmpToDisk enabled, skipping tmpfs module")
|
kernel.log("tmpToDisk enabled, skipping tmpfs module")
|
||||||
kernel.log("tmpfs0000 will passthrough to /tmp on the disk")
|
kernel.log("tmpfs0000 will passthrough to /tmp on the disk")
|
||||||
|
kernel.runWhenLoaded(function()
|
||||||
|
kernel.vfs.remove("/tmp")
|
||||||
|
kernel.vfs.mkdir("/tmp")
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
@@ -11,7 +11,7 @@ end
|
|||||||
|
|
||||||
for _, line in ipairs(string.split(kernel.fstab, "\n")) do
|
for _, line in ipairs(string.split(kernel.fstab, "\n")) do
|
||||||
line = trim(line)
|
line = trim(line)
|
||||||
if line ~= "" and line:sub(1,1) == "U" then
|
if line:sub(1,1) == "U" or line:sub(1,1) == "V" or line:sub(1,1) == "F" then
|
||||||
local semicolon_pos
|
local semicolon_pos
|
||||||
for i = 3, #line do
|
for i = 3, #line do
|
||||||
if line:sub(i,i) == ";" then
|
if line:sub(i,i) == ";" then
|
||||||
@@ -26,9 +26,7 @@ for _, line in ipairs(string.split(kernel.fstab, "\n")) do
|
|||||||
local id = line:sub(3, semicolon_pos - 1)
|
local id = line:sub(3, semicolon_pos - 1)
|
||||||
local path = trim(line:sub(semicolon_pos + 1))
|
local path = trim(line:sub(semicolon_pos + 1))
|
||||||
kernel.log("Mounting '"..id.."' to '"..path.."'")
|
kernel.log("Mounting '"..id.."' to '"..path.."'")
|
||||||
if id ~= "$" then
|
kernel.vfs.mount(path, id, nil, line:sub(1,1) == "F")
|
||||||
kernel.vfs.mount(path, id)
|
|
||||||
end
|
|
||||||
kernel.log("Mounted "..id.." to "..path)
|
kernel.log("Mounted "..id.." to "..path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -32,6 +32,31 @@ function signal.sigignore()
|
|||||||
task.sigd=nil
|
task.sigd=nil
|
||||||
end
|
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
|
local s=kernel.syscalls
|
||||||
s["sigsend"] = signal.sigsend
|
s["sigsend"] = signal.sigsend
|
||||||
s["sigcatch"] = signal.sigcatch
|
s["sigcatch"] = signal.sigcatch
|
||||||
|
|||||||
@@ -155,7 +155,21 @@ end
|
|||||||
|
|
||||||
local function hashPassword(password, salt)
|
local function hashPassword(password, salt)
|
||||||
local key = (pepper .. salt)
|
local key = (pepper .. salt)
|
||||||
return blake2s(password, key)
|
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)
|
||||||
end
|
end
|
||||||
|
|
||||||
local passwdFile = getFile("/etc/passwd")
|
local passwdFile = getFile("/etc/passwd")
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ local sys = {}
|
|||||||
local nextpid = 2
|
local nextpid = 2
|
||||||
kernel.exitMain = false
|
kernel.exitMain = false
|
||||||
|
|
||||||
local resumeWithTimeout = coroutine.resumeWithTimeout
|
|
||||||
|
|
||||||
local function bit_is_set(num, bit)
|
local function bit_is_set(num, bit)
|
||||||
return math.floor(num / (2 ^ bit)) % 2 == 1
|
return math.floor(num / (2 ^ bit)) % 2 == 1
|
||||||
@@ -137,7 +136,7 @@ function sys.exec(path, args, envars)
|
|||||||
|
|
||||||
task.euid = euid
|
task.euid = euid
|
||||||
task.args = args or {}
|
task.args = args or {}
|
||||||
task.envars = envars or task.envars
|
task.envars = envars or task.envars or {}
|
||||||
task.name = path
|
task.name = path
|
||||||
|
|
||||||
task.coro = coroutine.create(function()
|
task.coro = coroutine.create(function()
|
||||||
@@ -309,7 +308,7 @@ end
|
|||||||
|
|
||||||
function sys.getuid() return kernel.currentTask.uid end
|
function sys.getuid() return kernel.currentTask.uid end
|
||||||
|
|
||||||
local function reapDeadTasks()
|
function sys.reapDeadTasks()
|
||||||
for pid, task in pairs(tasks) do
|
for pid, task in pairs(tasks) do
|
||||||
if task.status == "Z" and not task.reapTime then
|
if task.status == "Z" and not task.reapTime then
|
||||||
if task.pid == 1 then kernel.panic("Attempted to gc init!") end
|
if task.pid == 1 then kernel.panic("Attempted to gc init!") end
|
||||||
@@ -346,205 +345,41 @@ local function reapDeadTasks()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local alpha = 0.85
|
kernel.execPerTask(function(task)
|
||||||
local C_target = 0.01
|
kernel.currentTask = task
|
||||||
local Tmin = 0.0005
|
kernel.uid = task.euid or task.uid
|
||||||
local Tmax = 0.5
|
kernel.process = task.name
|
||||||
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()
|
if task.status == "S" and kernel.EFI:getEpochMs() >= task.sleep then
|
||||||
kernel.log("Starting main loop...")
|
task.status = "R"
|
||||||
kernel.saveLog()
|
task.sleep = 0
|
||||||
local stopLog=5
|
end
|
||||||
local logTasks=100
|
|
||||||
|
|
||||||
while not kernel.exitMain do
|
if task.status == "ST" and kernel.EFI:getEpochMs() >= task.sleep then
|
||||||
if kernel.config.logTasks then
|
task.status = "T"
|
||||||
if logTasks<0 then
|
task.sleep = 0
|
||||||
kernel.log("Active Tasks:")
|
end
|
||||||
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 = {}
|
|
||||||
|
|
||||||
for pid, task in pairs(tasks) do
|
if task.status == "DS" and kernel.EFI:getEpochMs() >= task.sleep then
|
||||||
if kernel.exitMain then break end
|
task.status = "D"
|
||||||
kernel.currentTask = task
|
task.sleep = 0
|
||||||
kernel.uid = task.euid or task.uid
|
end
|
||||||
kernel.process = task.name
|
|
||||||
|
|
||||||
if task.status == "S" and kernel.EFI:getEpochMs() >= task.sleep then
|
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.status = "R"
|
||||||
task.sleep = 0
|
task.io=nil
|
||||||
|
elseif #ret>1 then
|
||||||
|
task.syscallReturn = {true, table.unpack(ret, 2)}
|
||||||
|
task.status = "R"
|
||||||
|
task.io=nil
|
||||||
end
|
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
|
end
|
||||||
end
|
end,1)
|
||||||
|
|
||||||
local sysc = kernel.syscalls
|
local sysc = kernel.syscalls
|
||||||
sysc["spawn"] = sys.spawn
|
sysc["spawn"] = sys.spawn
|
||||||
|
|||||||
@@ -239,9 +239,7 @@ else
|
|||||||
for _, cmd in ipairs(COMMANDS) do addCmd(cmd) end
|
for _, cmd in ipairs(COMMANDS) do addCmd(cmd) end
|
||||||
end
|
end
|
||||||
|
|
||||||
local sizeStr = syscall.devctl(1, "size")
|
local screenW, screenH = 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 pageSize = screenH - 2
|
||||||
|
|
||||||
local scroll = 0
|
local scroll = 0
|
||||||
|
|||||||
+4
-13
@@ -1009,9 +1009,7 @@ local function getUserInput()
|
|||||||
syscall.write(1, syscall.getcwd())
|
syscall.write(1, syscall.getcwd())
|
||||||
syscall.devctl(1,"sfgc",0xFFFFFF)
|
syscall.devctl(1,"sfgc",0xFFFFFF)
|
||||||
syscall.write(1, "$ ")
|
syscall.write(1, "$ ")
|
||||||
local curOffsetStr = syscall.devctl(1, "gpos")
|
local curOffsetX,curOffsetY = syscall.devctl(1, "gpos")
|
||||||
local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1))
|
|
||||||
local curOffsetY = tonumber(curOffsetStr:sub(curOffsetStr:find(";")+1))
|
|
||||||
|
|
||||||
local input = ""
|
local input = ""
|
||||||
local blinkState = false
|
local blinkState = false
|
||||||
@@ -1109,14 +1107,10 @@ local function getUserInput()
|
|||||||
local newInput, newCursor, needsRedraw = doTabComplete(input, cursorPos)
|
local newInput, newCursor, needsRedraw = doTabComplete(input, cursorPos)
|
||||||
if needsRedraw then
|
if needsRedraw then
|
||||||
input = newInput; cursorPos = newCursor
|
input = newInput; cursorPos = newCursor
|
||||||
local posStr = syscall.devctl(1, "gpos")
|
local px,py = 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
|
if px > 1 then
|
||||||
syscall.devctl(1,"spos",1,py)
|
syscall.devctl(1,"spos",1,py)
|
||||||
local tsz = syscall.devctl(1,"size") or "51;19"
|
local tw = syscall.devctl(1,"size")
|
||||||
local tw = tonumber(tsz:match("^(%d+)")) or 51
|
|
||||||
syscall.write(1, string.rep(" ", tw))
|
syscall.write(1, string.rep(" ", tw))
|
||||||
syscall.devctl(1,"spos",1,py)
|
syscall.devctl(1,"spos",1,py)
|
||||||
end
|
end
|
||||||
@@ -1124,10 +1118,7 @@ local function getUserInput()
|
|||||||
syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, ":")
|
syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, ":")
|
||||||
syscall.devctl(1,"sfgc",0x00FFFF); syscall.write(1, syscall.getcwd())
|
syscall.devctl(1,"sfgc",0x00FFFF); syscall.write(1, syscall.getcwd())
|
||||||
syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, "$ ")
|
syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, "$ ")
|
||||||
posStr = syscall.devctl(1, "gpos")
|
curOffsetX,curOffsetY = syscall.devctl(1, "gpos")
|
||||||
sep = posStr:find(";")
|
|
||||||
curOffsetX = tonumber(posStr:sub(1, sep-1))
|
|
||||||
curOffsetY = tonumber(posStr:sub(sep+1))
|
|
||||||
dirty = true
|
dirty = true
|
||||||
end
|
end
|
||||||
elseif key=="\b" then
|
elseif key=="\b" then
|
||||||
|
|||||||
@@ -91,8 +91,7 @@ local function humanSize(size)
|
|||||||
return math.floor(size) .. sizePrefixes[scale]
|
return math.floor(size) .. sizePrefixes[scale]
|
||||||
end
|
end
|
||||||
|
|
||||||
local screenSizeStr = syscall.devctl(1, "size")
|
local sizeX = syscall.devctl(1, "size")
|
||||||
local sizeX = tonumber(screenSizeStr:match("^(%d+)")) or 80
|
|
||||||
|
|
||||||
local list = fs.list(dir)
|
local list = fs.list(dir)
|
||||||
list[#list+1] = "."
|
list[#list+1] = "."
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
--: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
|
||||||
@@ -237,9 +237,7 @@ end
|
|||||||
|
|
||||||
local function getUserInput(prompt, history)
|
local function getUserInput(prompt, history)
|
||||||
c(C_PROMPT); w(prompt); c(1)
|
c(C_PROMPT); w(prompt); c(1)
|
||||||
local pos = syscall.devctl(1, "gpos")
|
local ox, oy = syscall.devctl(1, "gpos")
|
||||||
local ox = tonumber(pos:sub(1, pos:find(";")-1))
|
|
||||||
local oy = tonumber(pos:sub(pos:find(";")+1))
|
|
||||||
|
|
||||||
local input = ""
|
local input = ""
|
||||||
local cursor = 1
|
local cursor = 1
|
||||||
|
|||||||
@@ -12,9 +12,7 @@
|
|||||||
local args = { ... }
|
local args = { ... }
|
||||||
|
|
||||||
local function termSize()
|
local function termSize()
|
||||||
local s = syscall.devctl(1, "size")
|
return syscall.devctl(1, "size")
|
||||||
return tonumber(s:match("^(%d+)")) or 80,
|
|
||||||
tonumber(s:match(";(%d+)$")) or 24
|
|
||||||
end
|
end
|
||||||
local function tpos(x,y) syscall.devctl(1,"spos",x,y) end
|
local function tpos(x,y) syscall.devctl(1,"spos",x,y) end
|
||||||
local function tfg(c) syscall.devctl(1,"sfgc",c) end
|
local function tfg(c) syscall.devctl(1,"sfgc",c) end
|
||||||
|
|||||||
+35
-20
@@ -20,7 +20,8 @@ local spm = function(...)
|
|||||||
sysroot = "",
|
sysroot = "",
|
||||||
init = false,
|
init = false,
|
||||||
help = false,
|
help = false,
|
||||||
overwrite = false
|
overwrite = false,
|
||||||
|
clean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
local i = 1
|
local i = 1
|
||||||
@@ -216,8 +217,7 @@ local spm = function(...)
|
|||||||
|
|
||||||
local function printpkgs(list)
|
local function printpkgs(list)
|
||||||
local colWidth=0
|
local colWidth=0
|
||||||
local tmp = syscall.devctl(1, "size")
|
local sizeX, sizeY = 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
|
for _, v in ipairs(list) do
|
||||||
if #v + 2 > colWidth then colWidth = #v + 2 end
|
if #v + 2 > colWidth then colWidth = #v + 2 end
|
||||||
end
|
end
|
||||||
@@ -586,7 +586,7 @@ local spm = function(...)
|
|||||||
|
|
||||||
local files = {}
|
local files = {}
|
||||||
for _,v in ipairs(needed) do
|
for _,v in ipairs(needed) do
|
||||||
if not pkgdb[v.id] or not pkgdb[v.id].hash==v.hash or cloptions.u then
|
if (not pkgdb[v.id]) or pkgdb[v.id].hash~=v.hash or cloptions.clean then
|
||||||
w("Downloading "..v.id)
|
w("Downloading "..v.id)
|
||||||
local resp = get(v.tar)
|
local resp = get(v.tar)
|
||||||
if not resp then
|
if not resp then
|
||||||
@@ -689,16 +689,6 @@ local spm = function(...)
|
|||||||
syscall.exit()
|
syscall.exit()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
w("Updatating db...")
|
|
||||||
for i,v in pairs(files) do
|
|
||||||
local content={}
|
|
||||||
content.files={}
|
|
||||||
for f,c in pairs(v.data) do
|
|
||||||
content.files[f]=md5(c)
|
|
||||||
end
|
|
||||||
content.hash=v.hash
|
|
||||||
fs.writeAllText("var/spm/db/installed/"..i, json.encode(content))
|
|
||||||
end
|
|
||||||
w("Writing files...")
|
w("Writing files...")
|
||||||
for i,v in pairs(files) do
|
for i,v in pairs(files) do
|
||||||
w("Writing package "..i)
|
w("Writing package "..i)
|
||||||
@@ -710,16 +700,41 @@ local spm = function(...)
|
|||||||
end
|
end
|
||||||
w("Proccessing control files...")
|
w("Proccessing control files...")
|
||||||
for i,v in pairs(files) do
|
for i,v in pairs(files) do
|
||||||
for f,c in pairs(v.control) do
|
if v.control then
|
||||||
if f=="symlinks.json" then
|
for f,c in pairs(v.control) do
|
||||||
local symlinks=json.decode(c)
|
if f=="symlinks.json" then
|
||||||
for src,dest in pairs(symlinks) do
|
local symlinks=json.decode(c)
|
||||||
w(src.." -> "..dest)
|
for src,dest in pairs(symlinks) do
|
||||||
syscall.symlink(dest, src)
|
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
w("Updatating db...")
|
||||||
|
for i,v in pairs(files) do
|
||||||
|
local content={}
|
||||||
|
content.files={}
|
||||||
|
for f,c in pairs(v.data) do
|
||||||
|
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("Install complete")
|
w("Install complete")
|
||||||
log.close()
|
log.close()
|
||||||
|
|
||||||
|
|||||||
@@ -142,13 +142,19 @@ def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool, arch
|
|||||||
|
|
||||||
|
|
||||||
def install_bootloader(arch: str, release: bool):
|
def install_bootloader(arch: str, release: bool):
|
||||||
boot_dir = BUILD_ROOT / "$" / ARCH_BOOT_DIR[arch]
|
boot_dir = BUILD_ROOT / "root" / ARCH_BOOT_DIR[arch]
|
||||||
eeprom = boot_dir / "eeprom"
|
eeprom = boot_dir / "eeprom"
|
||||||
|
|
||||||
eeprom_dst_name = "startup.lua" if release else "eeprom"
|
eeprom_dst_name = "startup.lua" if release else "eeprom"
|
||||||
print(f" Installing: eeprom -> Build/{eeprom_dst_name}")
|
print(f" Installing: eeprom -> Build/{eeprom_dst_name}")
|
||||||
shutil.copy2(eeprom, BUILD_ROOT / 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):
|
def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, None], release: bool, prod: bool):
|
||||||
clean()
|
clean()
|
||||||
@@ -157,7 +163,7 @@ def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, No
|
|||||||
cleanprod()
|
cleanprod()
|
||||||
PROD_ROOT.mkdir()
|
PROD_ROOT.mkdir()
|
||||||
|
|
||||||
out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT
|
out_root = BUILD_ROOT / "root" if arch else BUILD_ROOT
|
||||||
|
|
||||||
process_root(SRC_ROOT, out_root, minify, micro, arch, False)
|
process_root(SRC_ROOT, out_root, minify, micro, arch, False)
|
||||||
if prod:
|
if prod:
|
||||||
@@ -170,6 +176,11 @@ def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, No
|
|||||||
print("Installing bootloader files ...")
|
print("Installing bootloader files ...")
|
||||||
install_bootloader(arch, release)
|
install_bootloader(arch, release)
|
||||||
print()
|
print()
|
||||||
|
boot_root = out_root / "boot"
|
||||||
|
disk_root = BUILD_ROOT / "$"
|
||||||
|
boot_root.rename(disk_root)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _make_firstboot_kmod(users):
|
def _make_firstboot_kmod(users):
|
||||||
|
|||||||
+30
-4
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil, io
|
||||||
import tarfile
|
import tarfile, gzip
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parent
|
ROOT = Path(__file__).resolve().parent
|
||||||
@@ -89,6 +89,15 @@ def read_dependencies(folder):
|
|||||||
|
|
||||||
return dependencies if dependencies else DEFAULT_DEPENDENCIES
|
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):
|
def create_package(folder):
|
||||||
name = folder.name
|
name = folder.name
|
||||||
@@ -102,8 +111,25 @@ def create_package(folder):
|
|||||||
|
|
||||||
debug(f"Packing {name}")
|
debug(f"Packing {name}")
|
||||||
|
|
||||||
with tarfile.open(tarball, "w:gz") as archive:
|
# Create deterministic TAR
|
||||||
archive.add(folder, arcname=name, filter=exclude)
|
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)
|
||||||
|
|
||||||
package_hash = sha256(tarball)
|
package_hash = sha256(tarball)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "af3fa83604356e01837ef388e5ea363a",
|
"hash": "32ab474f175e911f0625c8ab33202fae",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-core.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-core.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "82e3fa59d3fb04c867b623d9a6a150ac",
|
"hash": "149200eb06cf1d63a4dc44c7b22d3fa6",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ac.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ac.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
"authors": [],
|
"authors": [],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"hash": "58aecd4f830670f8885987848b9abdf8",
|
"hash": "dd93f2bd27640aea671155c26c3c47c5",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-addon-cct.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-addon-cct.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "f064c4564e596e884c5b9e9abe2008e6",
|
"hash": "b6c3a1bff52636f79f4c8f39def03aa2",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ccpc.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ccpc.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"hash": "d0e086d322e07bb60822294857ccc7f6",
|
"hash": "0e3d8eb6af70a7f23d642e1f291553c8",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-cct.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-cct.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
"authors": [],
|
"authors": [],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"hash": "6e9aef51eb3f4d0c202ec4135b5a8de2",
|
"hash": "c8fec163cdbcda36fe01d8bb9fd4e327",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-lua.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-lua.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
{
|
{
|
||||||
"id": "Hyperion-firmware-oc",
|
"id": "Hyperion-firmware-oc",
|
||||||
"description": "firmware for Opencomputers",
|
"description": "No description provided",
|
||||||
"authors": [
|
"authors": [],
|
||||||
"Hyperion"
|
|
||||||
],
|
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "0.1.0",
|
"version": "0.0.0",
|
||||||
"hash": "c3f760d7997c6d913f0c2ce8f61627ce",
|
"hash": "c49b20a151b1512d7371a0f2127d1e74",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-oc.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-oc.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
"authors": [],
|
"authors": [],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"hash": "3a6b960a217aca9e1d2e3547fe5afcaf",
|
"hash": "c7971267c5306ee06ba943e241647e64",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-vm.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-vm.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"hash": "1c7e260453de521e90d68855d8f7d416",
|
"hash": "975ef619a9a505d08931a036ed770c1e",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-kernel.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-kernel.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "0842e57bd3a76687f68ea01f9ccd4f23",
|
"hash": "85daa009881b6be44b84b3641138670a",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/bit32.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/bit32.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "75df789d1d9d72bf958c31f3c8167f2e",
|
"hash": "4193c27a6b98ed75bfcaaddc3e21f967",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/blake2s.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/blake2s.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "2e23edbc1f537971ff5e59e4fbe47ea0",
|
"hash": "62188c73a708084a818781d91b8fe0eb",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/coreutils.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/coreutils.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0-release",
|
"version": "1.0.0-release",
|
||||||
"hash": "6df4e0439eb721a4c1ea8b37796aafd9",
|
"hash": "821c762d067ab72abe100351c2f74f63",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/deflate.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/deflate.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"id": "gfxterm",
|
"id": "gfx",
|
||||||
"description": "package providing kernel support for framebuffers and graphics",
|
"description": "package providing kernel support for framebuffers and graphics",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Hyperion",
|
"Hyperion",
|
||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "ea8adbf3f614647990a628a7f9c67488",
|
"hash": "aaf9664adb4d85aa6d0d504692e8ec26",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/gfxterm.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/gfx.tar.gz"
|
||||||
}
|
}
|
||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"hash": "5810e20de2568a072f48c5fd0364abd3",
|
"hash": "7bee8c7e7a7feabb9db5491e5c1f952a",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/hysh.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/hysh.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "a3492bf4185d5d4d5cc140619d1e03fa",
|
"hash": "1f69e2cfa0d86c419ab1927221230ae8",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/iniparse.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/iniparse.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "4151d8db4e6fd6b6f6de1f87cdb08137",
|
"hash": "897e5abc980bda9051fff8f72c864251",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/installer.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/installer.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "ea9cabab165595bb50cc34306832d6a2",
|
"hash": "f22c3b6c445f9390195654246b6dca03",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/json.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/json.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"hash": "9c94a610906c21d369ce1ff173adafac",
|
"hash": "7479232dae56ad762119a8c57767e617",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/lua.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/lua.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "095330f4599e0a4607a24ccb141b58b5",
|
"hash": "8fa15ac698fe19927d0d860f9b813c5f",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/micro.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/micro.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,6 +8,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "6e2cf617969c9faa15a3ab712c74930a",
|
"hash": "a6f6beecb0828a355cca23f90c77dbd9",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/minify.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/minify.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "4a07e6c4cf138b239e8c97985a212c21",
|
"hash": "90583ad14ffc68fbbec09f03b926cdaf",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/pid.tar.gz"
|
"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.
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.
+1
-1
@@ -14,6 +14,6 @@
|
|||||||
"Hyperion-core"
|
"Hyperion-core"
|
||||||
],
|
],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "36055f8aea21098ca120f648292505b0",
|
"hash": "4cd02eed9e91a8e458dde2227725e2ad",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/spm.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/spm.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"hash": "d46f83d262d515921ba300bfe081922b",
|
"hash": "cab61038368a1d215852edd1ff411988",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/sysinit.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/sysinit.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "",
|
"version": "",
|
||||||
"hash": "d92473f303903d807e53276a6819f150",
|
"hash": "a46d51ae1a64a89caa0dc5d27fb2decf",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/tar.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/tar.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -10,6 +10,6 @@
|
|||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"hash": "fe9b62794a71bf0ecae6e93eefde1b55",
|
"hash": "c7dec4f4bfc7928026f96dd50aad471f",
|
||||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/xz.tar.gz"
|
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/xz.tar.gz"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"blake2s": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/blake2s.pkg",
|
"blake2s": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/blake2s.pkg",
|
||||||
"coreutils": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/coreutils.pkg",
|
"coreutils": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/coreutils.pkg",
|
||||||
"deflate": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/deflate.pkg",
|
"deflate": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/deflate.pkg",
|
||||||
"gfxterm": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/gfxterm.pkg",
|
"gfx": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/gfx.pkg",
|
||||||
"hysh": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/hysh.pkg",
|
"hysh": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/hysh.pkg",
|
||||||
"iniparse": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/iniparse.pkg",
|
"iniparse": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/iniparse.pkg",
|
||||||
"installer": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/installer.pkg",
|
"installer": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/installer.pkg",
|
||||||
|
|||||||
Reference in New Issue
Block a user