13 Commits
Author SHA1 Message Date
Astronand 429a1489d2 Merge pull request '1.2 dev' (#24) from 1.2-dev into main
Reviewed-on: #24
2026-08-25 21:17:07 -04:00
Astronand 05ca0f10a2 forgot var def 2026-08-25 21:16:48 -04:00
Astronand 125baaebf5 oc firmware 1.0 2026-08-25 21:16:16 -04:00
Astronand 211b7fc75b Merge pull request '1.2 dev' (#23) from 1.2-dev into main
Reviewed-on: #23
2026-08-24 09:16:38 -04:00
Astronand faf4f27987 update 2026-08-23 21:51:56 -04:00
Astronand d70328c224 updated kernel and working on oc tty impl 2026-08-23 21:51:19 -04:00
Astronand 4e7cec2ce1 Merge pull request 'testing update' (#22) from 1.2-dev into main
Reviewed-on: #22
2026-08-21 07:36:55 -04:00
Astronand d4f74e950c testing update 2026-08-21 07:35:11 -04:00
Astronand 7ddc527e00 Merge pull request '1.2 dev' (#21) from 1.2-dev into main
Reviewed-on: #21
2026-08-15 22:41:41 -04:00
Astronand 3b86113425 UPDATE HYPERVISOR 2026-08-15 22:40:25 -04:00
Astronand bb28d24674 update hypervisor 2026-08-15 22:38:35 -04:00
Astronand 3a33bd0264 Merge pull request 'fix spm files' (#20) from 1.2-dev into main
Reviewed-on: #20
2026-08-14 21:13:19 -04:00
Astronand 4ed82a23a1 fix spm files 2026-08-14 21:12:49 -04:00
118 changed files with 3058 additions and 975 deletions
+106 -329
View File
@@ -1,344 +1,121 @@
--:Minify:-- local cp,c=component,computer;local b_addr=c.getBootAddress();local b_fs=cp.proxy(b_addr)
local args={...} local gpu=cp.list("gpu")() and cp.proxy(cp.list("gpu")())
local bootdrive=args[1] local e_rom=cp.list("eeprom")() and cp.proxy(cp.list("eeprom")())
local gpu=components:getFirst("gpu") local screens={}
local screenTextBuffer=nil for addr in cp.list("screen") do
local cursorX,cursorY=0,0 if gpu then
local screenSizeX,screenSizeY=128,25 gpu.bind(addr)
local w,h=gpu.maxResolution()
gpu.setResolution(w,h)
if gpu then gpu.fill(1,1,w,h," ")
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY) cp.proxy(addr).turnOn()
for t,v in components:list() do screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
if t == "screen" then end
gpu:assignBuffer(screenTextBuffer, v)
end
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(text) local function write(t)
cursorX, cursorY = screenTextBuffer:pasteText(cursorX, cursorY, "SCROLL_SPILL_CLEAR", text) if not gpu then return end
cursorY = cursorY + 1 for s=1, #screens do
cursorX = 0 local scr=screens[s]
if cursorY >= screenSizeY then gpu.bind(scr.addr)
cursorY = screenSizeY-1 for i=1,#t do
screenTextBuffer:newline() local char=t:sub(i,i)
end if char=="\n" then scr.cx=1;scr.cy=scr.cy+1
end 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
local function displaySuperBadError(err) else gpu.set(scr.cx,scr.cy,char);scr.cx=scr.cx+1 end
gpu:freeAllBuffers() if scr.cx>scr.w then scr.cx=1;scr.cy=scr.cy+1 end
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY) if scr.cy>scr.h then scroll(scr);scr.cy=scr.cy-1 end
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 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 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 end
end
local function string_file(file) local function throw(err)
local str = file:read() if gpu then
local buf = {str or ""} gpu.setBackground(0x0000AA);
local pos = 1 gpu.setForeground(0xFFFFFF);
local closed = false for i=1, #screens do
gpu.fill(1,1,screens[i].w,screens[i].h," ");
local function content() screens[i].cx,screens[i].cy=1,1;
return table.concat(buf)
end end
write("CRITICAL KERNEL ERROR:\n"..tostring(err))
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 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 function getFile(path)
local file = bootdrive:open(path, "r") local h,err=b_fs.open(path,"r")
if not file then if not h then throw("Cannot open: "..path) end
displaySuperBadError("Could not open file: " .. path) local buf,chk="",""
end repeat chk=b_fs.read(h,math.huge);buf=buf..(chk or "") until not chk
local content = file:read() b_fs.close(h)
return content return buf
end end
local Kernel=load(getFile("/kernel.lua"),"@Kernel")
local Kernel = load(getFile("/boot/kernel.lua"),"@Kernel") local initFs=load(getFile("/oc/initdisks"),"@Init_disks")
local initFs = load(getFile("/boot/ac/initdisks"),"@Init_disks")(apis) local fs=load(getFile("/initfs"),"@InitFs")
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 not Kernel then displaySuperBadError("Could not load kernel.") end if fs then fs=fs() end
if not initFs then displaySuperBadError("Could not load initdisks.") end local eQ={}
if not fs then displaySuperBadError("Could not load initfs.") end local function qEv(e,...) table.insert(eQ,{e,...}) end
local efi={
local computercomp=apis.components:getFirst("computer") getEpochMs=function() return math.floor(c.uptime()*1000) end,
local uefi=apis.components:getFirst("uefi") getUptime=function() return c.uptime()*1000 end,
local computer = { date=function() return tostring(apis.os.date()) end,
time = function() return apis.os.epoch("utc") end, getMachineEvent=function()
clock = function() return apis.os.clock() * 1000 end, if #eQ > 0 then
shutdown = apis.os.shutdown, return table.unpack(table.remove(eQ, 1))
reboot = apis.os.reboot, else
getMachineEvent = function() return nil
return computercomp:getMachineEvent() end
end, end,
getEEPROM = function() return uefi.data end, getEEPROM=function() return e_rom and e_rom.get() or "" end,
setEEPROM = function(_, text) setEEPROM=function(_,t) if e_rom then e_rom.set(t) end end,
uefi.data=text getNvram=function() return e_rom and e_rom.getData() or "" end,
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 icolors = { local s,e=xpcall(Kernel,debug.traceback,efi)
[0x1] = 1, -- #000000 if not s and not efi.reboot then throw(e) end
[0x2] = 2, -- #FFFFFF if efi.reboot then c.shutdown(true) else c.shutdown() end
[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) end)
efi.screenCtl:print("Loaded in "..tostring(c.uptime()).."s")
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 while true do
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50) local st,e=coroutine.resume(kCo)
apis.os.queueEvent("NoSleep") c.pushSignal("NoSleep")
local exit = false local ex=false
while not exit do while not ex do
local event = {coroutine.yield()} local ev={c.pullSignal(0)}
if event[1] == "key" then if ev[1]=="key_down" then qEv("keyPressed",1,ev[3]);qEv("keyTyped",1,string.char(ev[3]))
queueEvent("keyPressed", 1, event[2]) elseif ev[1]=="key_up" then qEv("keyReleased",1,ev[3])
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 ev[1]=="NoSleep" then ex=true else qEv(table.unpack(ev)) end
end end
if status == "error" or coroutine.status(kernelCoro) == "dead" then if st=="error" or coroutine.status(kCo)=="dead" then
displaySuperBadError("Kernel error: " .. tostring(err)) if efi.reboot then c.shutdown(true) end
coroutine.yield("key") throw("Kernel fault: "..tostring(e))
end end
end end
end, debug.traceback) end,debug.traceback)
if not ok then throw("Boot fault: "..err) end
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
while true do coroutine.yield() end
@@ -0,0 +1,68 @@
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
@@ -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}
@@ -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,177 @@
-- 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
@@ -0,0 +1,113 @@
--: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
@@ -0,0 +1,99 @@
--: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")
@@ -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
@@ -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
+2
View File
@@ -1 +1,3 @@
Hyperion Hyperion
Astronand
Xtimhedae
+119 -39
View File
@@ -1,41 +1,121 @@
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, if gpu then
collectgarbage = true, gpu.bind(addr)
error = true, local w,h=gpu.maxResolution()
gcinfo = true, gpu.setResolution(w,h)
getfenv = true, gpu.fill(1,1,w,h," ")
getmetatable = true, cp.proxy(addr).turnOn()
ipairs = true, screens[#screens+1] = {cx=1,cy=1,w=w,h=h,addr=addr}
__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
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
+66 -16
View File
@@ -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
object[method]=function(_,...)
return oldcomponent.invoke(address,method,...)
end
end end
return object end
end
local -- 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
@@ -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,177 @@
-- 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
@@ -0,0 +1,113 @@
--: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
@@ -0,0 +1,99 @@
--: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")
@@ -0,0 +1,150 @@
--: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 firmware for Opencomputers mod
+1 -1
View File
@@ -1 +1 @@
0.1.0 1.0.0
+4 -4
View File
@@ -1,4 +1,4 @@
U $;/ U $;/boot/
U devfs0000;/dev/ V devfs0000;/dev/
U tmpfs0000;/tmp/ V tmpfs0000;/tmp/
U procfs0000;/proc/ V procfs0000;/proc/
+1 -1
View File
@@ -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
+62 -2
View File
@@ -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,10 @@ end
kernel.config = config kernel.config = config
local skip=false local skip=false
local mounted={}
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 +152,43 @@ 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
mounted[id]=true
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.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") kernel.log("Disks initialized")
function kernel.saveLog() function kernel.saveLog()
@@ -321,6 +355,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 +483,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
View File
@@ -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
@@ -1066,8 +1068,9 @@ function vfs.chown(path, uid, gid)
if kernel.unixSockets[namei(path)] then error("EINVAL") end if kernel.unixSockets[namei(path)] then error("EINVAL") end
local disk = resolveMount(path) local disk = resolveMount(path)
if disk:isReadOnly() then error("ERDONLY") end if disk:isReadOnly() then error("ERDONLY") end
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid local meta = getFileMeta(path)
if _euid ~= 0 then error("EPERM") end 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
updateMeta(path, function(e) e.owner = uid; e.group = gid end) updateMeta(path, function(e) e.owner = uid; e.group = gid end)
end end
@@ -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
@@ -31,10 +30,18 @@ local function loadExecutable(path)
return func, euid, suid_set return func, euid, suid_set
end end
local function createTask(func, name, envars, args, tgid, real_uid, eff_uid) local function createTask(func, name, envars, args, tgid, real_uid, eff_uid, clearFds)
local id = nextpid local id = nextpid
nextpid = nextpid + 1 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)] = { tasks[tostring(id)] = {
coro = coroutine.create(function() coro = coroutine.create(function()
local ok, err = xpcall(func, debug.traceback, table.unpack(args or {})) local ok, err = xpcall(func, debug.traceback, table.unpack(args or {}))
@@ -71,7 +78,7 @@ local function createTask(func, name, envars, args, tgid, real_uid, eff_uid)
euid = eff_uid, euid = eff_uid,
gid = (kernel.currentTask and kernel.currentTask.gid) or 0, gid = (kernel.currentTask and kernel.currentTask.gid) or 0,
groups = (kernel.currentTask and kernel.currentTask.groups) or {}, groups = (kernel.currentTask and kernel.currentTask.groups) or {},
fd = {}, fd = fds,
sleep = 0, sleep = 0,
ivs = 0, ivs = 0,
vs = 0, vs = 0,
@@ -93,14 +100,14 @@ local function createTask(func, name, envars, args, tgid, real_uid, eff_uid)
return id return id
end end
function sys.spawn(func, name, envars, args, tgid) function sys.spawn(func, name, envars, args, tgid, clearFds)
local caller = kernel.currentTask local caller = kernel.currentTask
local real_uid = caller and caller.uid or kernel.uid local real_uid = caller and caller.uid or kernel.uid
local eff_uid = caller and caller.euid or real_uid local eff_uid = caller and caller.euid or real_uid
return createTask(func, name, envars, args, tgid, real_uid, eff_uid) return createTask(func, name, envars, args, tgid, real_uid, eff_uid, clearFds)
end end
function sys.execspawn(path, name, envars, args, tgid) function sys.execspawn(path, name, envars, args, tgid, keepFds)
local func, euid, suid_active = loadExecutable(path, kernel._U) local func, euid, suid_active = loadExecutable(path, kernel._U)
local caller = kernel.currentTask local caller = kernel.currentTask
@@ -114,22 +121,23 @@ function sys.execspawn(path, name, envars, args, tgid)
) )
end end
return createTask(func, name or path, envars, args, tgid, real_uid, euid) return createTask(func, name or path, envars, args, tgid, real_uid, euid, not keepFds)
end end
function sys.exec(path, args, envars) function sys.exec(path, args, envars)
local task = kernel.currentTask local task = kernel.currentTask
local func, euid, _ = loadExecutable(path, kernel._U) local func, euid, _ = loadExecutable(path, kernel._U)
if task.fd then -- no idea why this is here?
for fd, _ in pairs(task.fd) do --if task.fd then
if fd > 2 then pcall(kernel.vfs.close, fd) end -- for fd, _ in pairs(task.fd) do
end -- if fd > 2 then pcall(kernel.vfs.close, fd) end
end -- end
--end
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()
@@ -301,7 +309,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
@@ -338,205 +346,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
@@ -2,6 +2,8 @@
local kernel = ... local kernel = ...
if kernel.firstBoot then if kernel.firstBoot then
kernel.log("Seeding filesystem permissions...")
local P = kernel.vfs.P local P = kernel.vfs.P
local PERM = kernel.vfs.PERM local PERM = kernel.vfs.PERM
@@ -14,107 +16,44 @@ if kernel.firstBoot then
local RWXRWXRWX = PERM.RWXRWXRWX local RWXRWXRWX = PERM.RWXRWXRWX
local SUID_755 = PERM.SUID_755 local SUID_755 = PERM.SUID_755
local META_VERSION = 0x02 local function seed(root, data)
local rootDisk = kernel.disks["$"] for i=1,#data do
local entry=data[1]
local function makeEntry(name, etype, owner, group, perms, cmeta) kernel.vfs.chmod(root..entry[1],entry[2],entry[3])
cmeta = cmeta or "" kernel.vfs.chown(root..entry[1],entry[4])
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
end end
kernel.log("Seeding filesystem permissions...") seed("/", {
{"bin", 0, 0, RWX_RX_RX},
mergeMeta("/", { {"boot", 0, 0, RWX_RX_RX},
{"bin", REG, 0, 0, RWX_RX_RX}, {"dev", 0, 0, RWXRWXRWX},
{"boot", REG, 0, 0, RWX_RX_RX}, {"etc", 0, 0, RWX_RX_RX},
{"dev", REG, 0, 0, RWXRWXRWX}, {"home", 0, 0, RWX_RX_RX},
{"etc", REG, 0, 0, RWX_RX_RX}, {"lib", 0, 0, RWX_RX_RX},
{"home", REG, 0, 0, RWX_RX_RX}, {"proc", 0, 0, RWXRWXRWX},
{"lib", REG, 0, 0, RWX_RX_RX}, {"root", 0, 0, RW____ },
{"proc", REG, 0, 0, RWXRWXRWX}, {"sbin", 0, 0, RWX_RX_RX},
{"root", REG, 0, 0, RW____ }, {"tmp", 0, 0, RWXRWXRWX},
{"sbin", REG, 0, 0, RWX_RX_RX}, {"usr", 0, 0, RWX_RX_RX},
{"tmp", REG, 0, 0, RWXRWXRWX}, {"var", 0, 0, RWXRWXRWX},
{"usr", REG, 0, 0, RWX_RX_RX}, {"opt", 0, 0, RWX_RX_RX},
{"var", REG, 0, 0, RWXRWXRWX},
{"opt", REG, 0, 0, RWX_RX_RX},
}) })
mergeMeta("/bin", { seed("/bin/", {
{"login", REG, 0, 0, SUID_755 }, {"login", 0, 0, SUID_755 },
{"su", REG, 0, 0, SUID_755 }, {"su", 0, 0, SUID_755 },
{"sudo", REG, 0, 0, SUID_755 }, {"sudo", 0, 0, SUID_755 },
}) })
mergeMeta("/etc", { seed("/etc/", {
{"passwd", REG, 0, 0, RW_R_R }, {"passwd", 0, 0, RW_R_R },
{"shadow", REG, 0, 0, RW____ }, {"shadow", 0, 0, RW____ },
{"pam.d", REG, 0, 0, RW____ }, {"pam.d", 0, 0, RW____ },
}) })
mergeMeta("/etc/pam.d", { seed("/etc/pam.d/", {
{"secret", REG, 0, 0, RW____}, {"secret", 0, 0, RW____},
}) })
kernel.log("Filesystem permissions seeded.") kernel.log("Filesystem permissions seeded.")
+5 -2
View File
@@ -3,6 +3,7 @@ syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1) syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2) syscall.open("/dev/null", "w") --stderr (fd 2)
local fs=require("fs")
local MAX_ATTEMPTS = 3 local MAX_ATTEMPTS = 3
@@ -100,7 +101,9 @@ local function spawnShell(username, uid, shell, homedir)
pcall(syscall.chdir, "/") pcall(syscall.chdir, "/")
end end
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell") local shellfunc, err = load(fs.readAllText(shell))
local ok, err = pcall(syscall.spawn, shellfunc, username .. ":shell", nil,nil,nil,true)
if not ok then if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n") syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2) sleep(2)
@@ -145,7 +148,7 @@ local function doLogin()
syscall.devctl(1, "sfgc", 0xFFFFFF) syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3) sleep(0.3)
spawnShell(username, uid, shell, homedir) pcall(spawnShell, username, uid, shell, homedir)
return -- back to login prompt return -- back to login prompt
else else
attempts = attempts + 1 attempts = attempts + 1
+5 -2
View File
@@ -3,6 +3,7 @@ syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1) syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2) syscall.open("/dev/null", "w") --stderr (fd 2)
local fs=require("fs")
local MAX_ATTEMPTS = 3 local MAX_ATTEMPTS = 3
@@ -100,7 +101,9 @@ local function spawnShell(username, uid, shell, homedir)
pcall(syscall.chdir, "/") pcall(syscall.chdir, "/")
end end
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell") local shellfunc, err = load(fs.readAllText(shell))
local ok, err = pcall(syscall.spawn, shellfunc, username .. ":shell", nil,nil,nil,true)
if not ok then if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n") syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2) sleep(2)
@@ -145,7 +148,7 @@ local function doLogin()
syscall.devctl(1, "sfgc", 0xFFFFFF) syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3) sleep(0.3)
spawnShell(username, uid, shell, homedir) pcall(spawnShell, username, uid, shell, homedir)
return -- back to login prompt return -- back to login prompt
else else
attempts = attempts + 1 attempts = attempts + 1
+40
View File
@@ -0,0 +1,40 @@
--: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
@@ -0,0 +1,256 @@
#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
@@ -0,0 +1,350 @@
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
@@ -1,84 +0,0 @@
--: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
+1 -3
View File
@@ -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
+8 -17
View File
@@ -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
@@ -1215,9 +1206,9 @@ local function runCommand(command)
local proc = syscall.spawn(function() local proc = syscall.spawn(function()
-- Open standard fds so programs that don't do it themselves work correctly. -- 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/0", "r") -- fd 0 stdin
syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout --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/2", "w") -- fd 2 stderr
-- exec replaces this coroutine's code with a fresh isolated environment -- exec replaces this coroutine's code with a fresh isolated environment
-- compiled from disk by the kernel (via loadExecutable -> freshUserEnv), -- compiled from disk by the kernel (via loadExecutable -> freshUserEnv),
-- so the child cannot share any upvalue or syscall table state with hysh. -- so the child cannot share any upvalue or syscall table state with hysh.
@@ -1231,7 +1222,7 @@ local function runCommand(command)
return return
end end
if terminate then if terminate then
local ok2 = syscall.kill(proc) local ok2 = syscall.kill(proc, true)
if ok2 then if ok2 then
syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",0xFF0000) syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",0xFF0000)
print("\nProgram Terminated."); syscall.devctl(1,"sfgc",0xFFFFFF) print("\nProgram Terminated."); syscall.devctl(1,"sfgc",0xFFFFFF)
+1 -2
View File
@@ -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] = "."
+10
View File
@@ -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
+1 -3
View File
@@ -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
+1 -3
View File
@@ -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
+49 -14
View File
@@ -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
@@ -547,7 +547,7 @@ local spm = function(...)
if cloptions.u then if cloptions.u then
for i,v in ipairs(table.keys(pkgdb)) do for i,v in ipairs(table.keys(pkgdb)) do
local pkg, err = getPkg(v) local pkg, err = getPkg(v)
if pkg then if pkg and not found[v] then
needed[#needed+1] = pkg needed[#needed+1] = pkg
found[v]=true found[v]=true
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 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,6 +689,46 @@ local spm = function(...)
syscall.exit() syscall.exit()
end end
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...") w("Updatating db...")
for i,v in pairs(files) do for i,v in pairs(files) do
local content={} local content={}
@@ -697,16 +737,11 @@ local spm = function(...)
content.files[f]=md5(c) content.files[f]=md5(c)
end end
content.hash=v.hash content.hash=v.hash
fs.writeAllText("var/spm/db/installed/"..i, json.encode(content)) content.symlinks={}
end if v.control and v.control["symlinks.json"] then
w("Writing changes...") content.symlinks=json.decode(v.control["symlinks.json"])
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
fs.writeAllText("var/spm/db/installed/"..i, json.encode(content))
end end
w("Install complete") w("Install complete")
log.close() log.close()
+4 -3
View File
@@ -14,7 +14,7 @@ for i,v in pairs(kernel.processes) do
else else
kernel.log("Successfully executed kernel task: " .. i) kernel.log("Successfully executed kernel task: " .. i)
end end
end, i) end, i, nil,nil,nil,true)
end end
-- config file path setup -- config file path setup
@@ -36,15 +36,16 @@ for i,v in ipairs(files) do
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000) kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else else
syscall.spawn(function() syscall.spawn(function()
local status, err = pcall(startupFunc) local status, err = xpcall(startupFunc, debug.traceback)
if not status then if not status then
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000) kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else else
kernel.log("Successfully executed startup script: " .. filepath) kernel.log("Successfully executed startup script: " .. filepath)
end end
end, "startup:" .. v) end, "startup:" .. v, nil,nil,nil,true)
end end
end end
kernel.log("sysinit complete")
kernel.saveLog() kernel.saveLog()
while true do while true do
+13 -2
View File
@@ -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):
+32 -6
View File
@@ -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
@@ -12,10 +12,10 @@ PACKAGE_ROOT = ROOT / "packages"
PACKAGE_DIR = PACKAGE_ROOT / "raw" PACKAGE_DIR = PACKAGE_ROOT / "raw"
# main repo # main repo
#API_ROOT = "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main" API_ROOT = "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main"
# local repo # local repo
API_ROOT = "http://localhost:8000" #API_ROOT = "http://localhost:8000"
DEFAULT_VERSION = "0.0.0" DEFAULT_VERSION = "0.0.0"
DEFAULT_DESCRIPTION = "No description provided" DEFAULT_DESCRIPTION = "No description provided"
@@ -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)
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "e4de9d3d66a1a13e65b502ebd1404739", "hash": "32ab474f175e911f0625c8ab33202fae",
"tarball": "http://localhost:8000/packages/raw/Hyperion-core.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-core.tar.gz"
} }
+2 -2
View File
@@ -8,6 +8,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "79e9de8d0e639f1f7183d380f93082c3", "hash": "a4e33985213691b829940e014685ba0d",
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ac.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ac.tar.gz"
} }
+2 -2
View File
@@ -4,6 +4,6 @@
"authors": [], "authors": [],
"dependencies": [], "dependencies": [],
"version": "0.0.0", "version": "0.0.0",
"hash": "5ee70c898fb350c5b0a40a0b8cfc4a97", "hash": "dd93f2bd27640aea671155c26c3c47c5",
"tarball": "http://localhost:8000/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"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "282807ec0aefa87c7077b0b848a491b0", "hash": "b6c3a1bff52636f79f4c8f39def03aa2",
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ccpc.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ccpc.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.3.0", "version": "1.3.0",
"hash": "4139f847ee8c2095dc2d561c794e5a3f", "hash": "15dbb52d9c151a30de521f13e2a16278",
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-cct.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-cct.tar.gz"
} }
+2 -2
View File
@@ -4,6 +4,6 @@
"authors": [], "authors": [],
"dependencies": [], "dependencies": [],
"version": "0.0.0", "version": "0.0.0",
"hash": "122ff4566fe42c48335b198567938c17", "hash": "c8fec163cdbcda36fe01d8bb9fd4e327",
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-lua.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-lua.tar.gz"
} }
+7 -5
View File
@@ -1,11 +1,13 @@
{ {
"id": "Hyperion-firmware-oc", "id": "Hyperion-firmware-oc",
"description": "firmware for Opencomputers", "description": "firmware for Opencomputers mod",
"authors": [ "authors": [
"Hyperion" "Hyperion",
"Astronand",
"Xtimhedae"
], ],
"dependencies": [], "dependencies": [],
"version": "0.1.0", "version": "1.0.0",
"hash": "4a3445e77b744698734dde9a03e0f5b7", "hash": "913d68c1c1a42afd42bfbab61a10729e",
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-oc.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-oc.tar.gz"
} }
+2 -2
View File
@@ -4,6 +4,6 @@
"authors": [], "authors": [],
"dependencies": [], "dependencies": [],
"version": "0.0.0", "version": "0.0.0",
"hash": "cd6e3d268d9f7789e766bf8311bd755f", "hash": "c7971267c5306ee06ba943e241647e64",
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-vm.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-vm.tar.gz"
} }
+2 -2
View File
@@ -8,6 +8,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.5.0", "version": "1.5.0",
"hash": "2e0d256069112c59e69f7f4b2bf42a0e", "hash": "d45b18adc188a3090e5f1d9aca687347",
"tarball": "http://localhost:8000/packages/raw/Hyperion-kernel.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-kernel.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "e142c639ebae6ce8b346ff241cbce0b9", "hash": "85daa009881b6be44b84b3641138670a",
"tarball": "http://localhost:8000/packages/raw/bit32.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/bit32.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "0cd816ee2dbc61f93aa129a32407e962", "hash": "4193c27a6b98ed75bfcaaddc3e21f967",
"tarball": "http://localhost:8000/packages/raw/blake2s.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/blake2s.tar.gz"
} }
+2 -2
View File
@@ -8,6 +8,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "69f888fabb92d8e736200f949160e632", "hash": "34996938f359f52e92a388483c3fb5c9",
"tarball": "http://localhost:8000/packages/raw/coreutils.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/coreutils.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0-release", "version": "1.0.0-release",
"hash": "2c6544d7c8e72522f84b5d88ba30e7e7", "hash": "821c762d067ab72abe100351c2f74f63",
"tarball": "http://localhost:8000/packages/raw/deflate.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/deflate.tar.gz"
} }
+3 -3
View File
@@ -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": "63a3b040d50c915bb60db7948109953d", "hash": "aaf9664adb4d85aa6d0d504692e8ec26",
"tarball": "http://localhost:8000/packages/raw/gfxterm.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/gfx.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.3.0", "version": "1.3.0",
"hash": "80514eb2984bb8fa249b49bd0aae7847", "hash": "cbc352d49cb9837ee825471351dd9ffc",
"tarball": "http://localhost:8000/packages/raw/hysh.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/hysh.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "386a212dee133206759c17809dced5d9", "hash": "1f69e2cfa0d86c419ab1927221230ae8",
"tarball": "http://localhost:8000/packages/raw/iniparse.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/iniparse.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "11d7d6211673eb000c2fa59cc62e1e88", "hash": "897e5abc980bda9051fff8f72c864251",
"tarball": "http://localhost:8000/packages/raw/installer.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/installer.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "0ced136c9ac9324fe869515283839a23", "hash": "f22c3b6c445f9390195654246b6dca03",
"tarball": "http://localhost:8000/packages/raw/json.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/json.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.2.0", "version": "1.2.0",
"hash": "8523c88be2eeaf3a437fe455581df80c", "hash": "7479232dae56ad762119a8c57767e617",
"tarball": "http://localhost:8000/packages/raw/lua.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/lua.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "d2ddcba471746b54e55ce44eec8fcff6", "hash": "8fa15ac698fe19927d0d860f9b813c5f",
"tarball": "http://localhost:8000/packages/raw/micro.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/micro.tar.gz"
} }
+2 -2
View File
@@ -8,6 +8,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "d728bd2e85437a8a96d668cd731c5a22", "hash": "a6f6beecb0828a355cca23f90c77dbd9",
"tarball": "http://localhost:8000/packages/raw/minify.tar.gz" "tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/minify.tar.gz"
} }
+2 -2
View File
@@ -7,6 +7,6 @@
], ],
"dependencies": [], "dependencies": [],
"version": "1.0.0", "version": "1.0.0",
"hash": "a0f49db23415afc4d75f87aab12ece00", "hash": "90583ad14ffc68fbbec09f03b926cdaf",
"tarball": "http://localhost:8000/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.

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