Files
HyperionOS/src/disks/1h/boot/Hyprkrnl.sys
2025-11-10 14:31:18 -05:00

230 lines
6.6 KiB
Plaintext

local args={...}
local bootLoader=args[1]
local MODE=bootLoader[1]
local apis=bootLoader[2]
local bootDisk=bootLoader[3]
local term=bootLoader[4]
local getFile=bootLoader[5]
local bootData
do
local tmp=load("return "..(getFile("/var/log/kernel/bootData").readAllText() or "{}"))
if not tmp then error("Bootdata failed to load") end
bootData=tmp()
end
local list=bootLoader[6]
local computer=bootLoader[7]
local startup=true
local osleep=sleep
_G._SYSDEBUG=args[2]
bootData.debug=args[2]
local drivers={}
local eventCache={}
while true do
local event={computer.getMachineEvent()}
if event[1]==nil then break end
eventCache[#eventCache+1] = event
end
term.clear()
term.print("Welcome to Hyperion OS")
term.print("Creating logger")
osleep(1)
local log=load(getFile("/sys/util/logger.lua").readAllText())(computer)
term.clear()
local logHook=log.setHook(term.print)
log.api.log("Created logger")
local function saveLog()
local logNum=bootData.logNum
getFile("/var/log/kernel/"..tostring(logNum)..".log").writeAllText(log.api.get())
getFile("/var/log/kernel/latest.log").writeAllText(log.api.get())
if bootData.logNum==10 then
bootData.logNum=0
else
bootData.logNum=bootData.logNum+1
end
end
if bootData.debug then _G.saveLog=saveLog end
local function t2t(table)
local output = "{"
for i,v in pairs(table) do
local coma=true
if type(i) == "string" then
output=output.."[\""..i.."\"]="
end
if type(v) == "table" then
if v == table then
output=string.sub(output,1,#output-(#i+1))
coma=false
else
output=output..t2t(v)
end
elseif type(v) == "string" then
output=output.."[=["..v.."]=]"
elseif type(v) == "number" then
output=output..tostring(v)
elseif type(v) == "boolean" then
if v == true then
output=output.."true"
else
output=output.."false"
end
elseif type(v) == "function" then
output=output.."function()"
else
error("serialization of type \""..type(v).."\" is not supported")
end
if coma then
output=output..","
end
end
if #table>0 or string.sub(output,#output,#output) == "," then
output=string.sub(output,1,#output-1)
end
output=output.."}"
return output
end
-- Make PANIC
local function PANIC(err)
term.clear()
term.print(log.api.get())
saveLog()
if err==bootData.prevError then
bootData.errorCount=bootData.errorCount+1
else
bootData.prevError=err
bootData.errorCount=0
end
getFile("/var/log/kernel/bootData").writeAllText(t2t(bootData))
term.print("KERNEL PANIC: "..err)
term.print("Log saved to /var/log/kernel/"..tostring(bootData.logNum)..".log\n")
term.print("Press enter to continue...")
while true do
local event = {computer.getMachineEvent()}
if event[1]~=nil then
term.print(table.concat(event, " "))
end
if event[1] == "keyTyped" then
if event[3] == "\n" then
break
end
end
end
computer.reboot()
end
local function runAsKernel(path, ...)
local func, err = load(getFile(path).readAllText(), path, "t", _G)
if not func then return false, "\t"..err end
local ret = {xpcall(func, debug.traceback, ...)}
if not ret[1] then
return false, ret[2]
end
return true, table.unpack(ret, 2)
end
log.api.log("Loading globals...")
for i,v in ipairs(list("/sys/api/")) do
if bootData.debug then log.api.debug("Loading "..v) end
local ok, err = runAsKernel("/sys/api/"..v, getFile, log)
if not ok then log.api.warn(err) end
end
local driverutil={}
function driverutil.getFirst(type)
if drivers[type] then
if drivers[type][1] then
return drivers[type][1]
end
end
end
function driverutil.list(type)
if not type then
local tmp={}
for i,v in ipairs(drivers.raw) do
tmp[#tmp+1] = {type=v.type, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].type, tmp[i].obj
end
else
local tmp={}
for i,v in ipairs(drivers[type]) do
tmp[#tmp+1] = {type=v.type, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].type, tmp[i].obj
end
end
end
log.api.log("Loading drivers...")
for i,v in ipairs(list("/sys/modules/")) do
if bootData.debug then log.api.debug("Loading module "..v) end
local ok, err = runAsKernel("/sys/modules/"..v, apis, drivers, log, driverutil)
if not ok then log.api.warn("["..v.."] exited with ERR:\n"..err) end
end
log.api.log("Unloading non \""..MODE.."\" specific drivers...")
do
local tmp={}
for i,v in ipairs(drivers) do
if type(v.arch)=="table" then
for i2,v2 in ipairs(v.arch) do
if v2==MODE or v2=="ANY" then
tmp[#tmp+1] = v
end
end
else
if v.arch==MODE or v.arch=="ANY" then
tmp[#tmp+1] = v
end
end
end
drivers={}
drivers.raw=tmp
end
if bootData.debug then log.api.debug("Sorting drivers...") end
for i,v in ipairs(drivers.raw) do
if not drivers[v.type] then drivers[v.type]={} end
drivers[v.type][#drivers[v.type]+1] = v
end
if bootData.debug then log.api.debug("Initializing drivers...") end
for i,v in ipairs(drivers.raw) do
if v.init then
local ok, err = xpcall(v.init, debug.traceback)
if not ok then
log.api.warn("["..v.name.."]: Init function ERR:\n"..err)
if bootData.debug then log.api.debug("Removing driver ["..v.name.."]") end
table.remove(drivers.raw, i)
end
end
end
log.api.log("Loaded "..tostring(#drivers.raw).." drivers")
log.api.log("Loading filesystem...")
local ok, fs = runAsKernel("/sys/fs/init", drivers, log, bootDisk, driverutil)
if not ok then PANIC(fs) end
if not fs then PANIC("filesystem failed to load") end
fs.delete("/tmp")
fs.mkDir("/tmp")
log.api.log("Loading system...")
local ok, err = runAsKernel("/sys/Hyperion.sys", drivers, log)
if not ok then PANIC(err) end
local hyperion = err
if type(hyperion)~="function" then PANIC("Hyperion failed to load:\nHyperion was: "..tostring(hyperion)) end
hyperion(fs, log, drivers, PANIC, driverutil)
PANIC("OS EXITED MAIN()")