updated kernel and working on oc tty impl
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
U $;/
|
||||
U devfs0000;/dev/
|
||||
U tmpfs0000;/tmp/
|
||||
U procfs0000;/proc/
|
||||
F $;/boot/
|
||||
V devfs0000;/dev/
|
||||
V tmpfs0000;/tmp/
|
||||
V procfs0000;/proc/
|
||||
|
||||
@@ -77,7 +77,7 @@ end
|
||||
function fs.load(path) return load(fs.readAllText(path), path) end
|
||||
|
||||
function fs.mount(disk, mountPoint)
|
||||
if not disks[disk] then return end
|
||||
if not disks[disk] then error("NODISK : "..disk) end
|
||||
mounts[mountPoint] = disk
|
||||
end
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ function kernel.PANIC(msg)
|
||||
kernel.exitMain = true
|
||||
end
|
||||
while true do
|
||||
EFI:yield()
|
||||
local event={EFI:getMachineEvent()}
|
||||
if event[1]=="keyPressed" then
|
||||
break
|
||||
@@ -98,7 +99,7 @@ kernel.disks={}
|
||||
for _,v in disks.list() do
|
||||
kernel.disks[v.address] = v
|
||||
end
|
||||
ifs.mount("$", "/")
|
||||
ifs.mount("$", "/boot/")
|
||||
|
||||
local fstab=ifs.readAllText("/boot/fstab")
|
||||
local split = function(str, delim, maxResultCountOrNil)
|
||||
@@ -138,8 +139,9 @@ end
|
||||
kernel.config = config
|
||||
|
||||
local skip=false
|
||||
local root=false
|
||||
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=""
|
||||
for i=3,#v do
|
||||
if v:sub(i,i)==";" then
|
||||
@@ -149,12 +151,14 @@ for i,v in ipairs(split(fstab,"\n")) do
|
||||
end
|
||||
if not skip then
|
||||
local path=v:sub(#id+4)
|
||||
if path=="/" then root=true end
|
||||
ifs.mount(id,path)
|
||||
else
|
||||
skip=false
|
||||
end
|
||||
end
|
||||
end
|
||||
if not root then kernel.panic("No disk mounted to /") end
|
||||
kernel.log("Disks initialized")
|
||||
|
||||
function kernel.saveLog()
|
||||
@@ -321,6 +325,26 @@ kernel.processes={}
|
||||
kernel.fstab=fstab
|
||||
kernel.denied={}
|
||||
kernel.loadingModule="kernel"
|
||||
kernel.perTaskHooks={}
|
||||
kernel.mainHooks={}
|
||||
kernel.runhooks={}
|
||||
|
||||
-- args {taskobj}
|
||||
function kernel.execPerTask(func, prior)
|
||||
if not kernel.perTaskHooks[prior] then kernel.perTaskHooks[prior]={} end
|
||||
kernel.perTaskHooks[prior][#kernel.perTaskHooks[prior]+1] = func
|
||||
return #kernel.perTaskHooks[prior]
|
||||
end
|
||||
|
||||
function kernel.execOnMain(func)
|
||||
kernel.mainHooks[#kernel.mainHooks+1] = func
|
||||
return #kernel.mainHooks
|
||||
end
|
||||
|
||||
function kernel.runWhenLoaded(func)
|
||||
kernel.runhooks[#kernel.runhooks+1] = func
|
||||
return #kernel.runhooks
|
||||
end
|
||||
|
||||
kernel.kernelTask = {
|
||||
name="kernel",
|
||||
@@ -429,11 +453,17 @@ for _,p in ipairs(modules) do
|
||||
end
|
||||
end
|
||||
|
||||
for i=1, #kernel.runhooks do
|
||||
local ok,err = xpcall(kernel.runhooks[i], debug.traceback)
|
||||
if not ok then kernel.panic(err) end
|
||||
end
|
||||
|
||||
kernel.log("Kernel initialized successfully.")
|
||||
kernel.saveLog()
|
||||
kernel.status="running"
|
||||
kernel.loadingModule=nil
|
||||
screen:disable()
|
||||
if not kernel.main then kernel.panic("No scheduler implemented from firmware") end
|
||||
local ok,err = xpcall(kernel.main, debug.traceback)
|
||||
if not ok then
|
||||
kernel.panic(err)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
0:0:root:/root:/bin/hysh
|
||||
@@ -2,7 +2,7 @@
|
||||
local kernel = ...
|
||||
local vfs = {}
|
||||
kernel.vfs = vfs
|
||||
vfs.mounts = {["$"] = "/"}
|
||||
vfs.mounts = {}
|
||||
vfs.disks = kernel.disks
|
||||
|
||||
-- Metafile format (version 2)
|
||||
@@ -556,17 +556,19 @@ function vfs.newfd(fdobj)
|
||||
return fd
|
||||
end
|
||||
|
||||
function vfs.mount(target, diskOrId, bind)
|
||||
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
|
||||
if _euid ~= 0 then error("EPERM") end
|
||||
if not target then error("EINVAL") end
|
||||
target = normalizeMountPoint(target)
|
||||
local drive, path = resolvePath(target)
|
||||
if not drive:directoryExists(path) then
|
||||
drive:makeDirectory(path)
|
||||
end
|
||||
if drive:type(path) ~= "directory" then
|
||||
error("EINVAL")
|
||||
function vfs.mount(target, diskOrId, bind, floating)
|
||||
if not floating and target ~= "/" then
|
||||
local _euid = (kernel.currentTask and (kernel.currentTask.euid or kernel.currentTask.uid)) or kernel.uid
|
||||
if _euid ~= 0 then error("EPERM") end
|
||||
if not target then error("EINVAL") end
|
||||
target = normalizeMountPoint(target)
|
||||
local drive, path = resolvePath(target)
|
||||
if not drive:directoryExists(path) then
|
||||
drive:makeDirectory(path)
|
||||
end
|
||||
if drive:type(path) ~= "directory" then
|
||||
error("EINVAL")
|
||||
end
|
||||
end
|
||||
local disk, id
|
||||
-- bind mount
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
--:Minify:--
|
||||
local kernel = ...
|
||||
|
||||
kernel.vfs.remove("/tmp")
|
||||
kernel.vfs.mkdir("/tmp")
|
||||
if not kernel.config.tmpToDisk then
|
||||
local proxy = {}
|
||||
local data = {}
|
||||
@@ -138,4 +136,8 @@ if not kernel.config.tmpToDisk then
|
||||
else
|
||||
kernel.log("tmpToDisk enabled, skipping tmpfs module")
|
||||
kernel.log("tmpfs0000 will passthrough to /tmp on the disk")
|
||||
kernel.runWhenLoaded(function()
|
||||
kernel.vfs.remove("/tmp")
|
||||
kernel.vfs.mkdir("/tmp")
|
||||
end)
|
||||
end
|
||||
@@ -11,7 +11,7 @@ end
|
||||
|
||||
for _, line in ipairs(string.split(kernel.fstab, "\n")) do
|
||||
line = trim(line)
|
||||
if line ~= "" 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
|
||||
for i = 3, #line do
|
||||
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 path = trim(line:sub(semicolon_pos + 1))
|
||||
kernel.log("Mounting '"..id.."' to '"..path.."'")
|
||||
if id ~= "$" then
|
||||
kernel.vfs.mount(path, id)
|
||||
end
|
||||
kernel.vfs.mount(path, id, nil, line:sub(1,1) == "F")
|
||||
kernel.log("Mounted "..id.." to "..path)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,6 +32,31 @@ function signal.sigignore()
|
||||
task.sigd=nil
|
||||
end
|
||||
|
||||
kernel.execPerTask(function(task)
|
||||
if task.status=="R" then
|
||||
if task.sigq and #task.sigq ~= 0 and task.sigh then
|
||||
local coro = coroutine.create(task.sigh)
|
||||
local status,err=coroutine.resume(coro, table.remove(task.sigq, 1))
|
||||
EFI:yeild()
|
||||
if status=="error" or status==false then
|
||||
task.sigd.error=err or "Unknown"
|
||||
task.sigd.active=false
|
||||
task.sigh=nil
|
||||
task.sigq=nil
|
||||
task.sigd=nil
|
||||
elseif status=="success" or status==true then
|
||||
if err=="syscall" then
|
||||
task.sigd.error="Cannot execute syscalls from signals"
|
||||
task.sigd.active=false
|
||||
task.sigh=nil
|
||||
task.sigq=nil
|
||||
task.sigd=nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,2)
|
||||
|
||||
local s=kernel.syscalls
|
||||
s["sigsend"] = signal.sigsend
|
||||
s["sigcatch"] = signal.sigcatch
|
||||
|
||||
@@ -155,7 +155,21 @@ end
|
||||
|
||||
local function hashPassword(password, 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
|
||||
|
||||
local passwdFile = getFile("/etc/passwd")
|
||||
|
||||
@@ -5,7 +5,6 @@ local sys = {}
|
||||
local nextpid = 2
|
||||
kernel.exitMain = false
|
||||
|
||||
local resumeWithTimeout = coroutine.resumeWithTimeout
|
||||
|
||||
local function bit_is_set(num, bit)
|
||||
return math.floor(num / (2 ^ bit)) % 2 == 1
|
||||
@@ -137,7 +136,7 @@ function sys.exec(path, args, envars)
|
||||
|
||||
task.euid = euid
|
||||
task.args = args or {}
|
||||
task.envars = envars or task.envars
|
||||
task.envars = envars or task.envars or {}
|
||||
task.name = path
|
||||
|
||||
task.coro = coroutine.create(function()
|
||||
@@ -309,7 +308,7 @@ end
|
||||
|
||||
function sys.getuid() return kernel.currentTask.uid end
|
||||
|
||||
local function reapDeadTasks()
|
||||
function sys.reapDeadTasks()
|
||||
for pid, task in pairs(tasks) do
|
||||
if task.status == "Z" and not task.reapTime then
|
||||
if task.pid == 1 then kernel.panic("Attempted to gc init!") end
|
||||
@@ -346,205 +345,41 @@ local function reapDeadTasks()
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
kernel.execPerTask(function(task)
|
||||
kernel.currentTask = task
|
||||
kernel.uid = task.euid or task.uid
|
||||
kernel.process = task.name
|
||||
|
||||
function kernel.main()
|
||||
kernel.log("Starting main loop...")
|
||||
kernel.saveLog()
|
||||
local stopLog=5
|
||||
local logTasks=100
|
||||
if task.status == "S" and kernel.EFI:getEpochMs() >= task.sleep then
|
||||
task.status = "R"
|
||||
task.sleep = 0
|
||||
end
|
||||
|
||||
while not kernel.exitMain do
|
||||
if kernel.config.logTasks then
|
||||
if logTasks<0 then
|
||||
kernel.log("Active Tasks:")
|
||||
for i,v in pairs(tasks) do
|
||||
kernel.log(v.name.." : "..v.status.." : "..tostring(v.pid).." : "..tostring(v.exit))
|
||||
end
|
||||
kernel.log("[END BLOCK]")
|
||||
logTasks=100
|
||||
end
|
||||
logTasks=logTasks-1
|
||||
end
|
||||
local N = 0
|
||||
local Tmin_hit = 0
|
||||
local Tmax_hit = 0
|
||||
local totalTaskTime = 0
|
||||
local taskTimes = {}
|
||||
if task.status == "ST" and kernel.EFI:getEpochMs() >= task.sleep then
|
||||
task.status = "T"
|
||||
task.sleep = 0
|
||||
end
|
||||
|
||||
for pid, task in pairs(tasks) do
|
||||
if kernel.exitMain then break end
|
||||
kernel.currentTask = task
|
||||
kernel.uid = task.euid or task.uid
|
||||
kernel.process = task.name
|
||||
if task.status == "DS" and kernel.EFI:getEpochMs() >= task.sleep then
|
||||
task.status = "D"
|
||||
task.sleep = 0
|
||||
end
|
||||
|
||||
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.sleep = 0
|
||||
task.io=nil
|
||||
elseif #ret>1 then
|
||||
task.syscallReturn = {true, table.unpack(ret, 2)}
|
||||
task.status = "R"
|
||||
task.io=nil
|
||||
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,1)
|
||||
|
||||
local sysc = kernel.syscalls
|
||||
sysc["spawn"] = sys.spawn
|
||||
|
||||
Reference in New Issue
Block a user