forked from Hyperion/HyperionOS
stuff.mp4
This commit is contained in:
238
Test/Hyperion-kernel-v1.0.0/lib/modules/Hyperion/00_stdlib.kmod
Normal file
238
Test/Hyperion-kernel-v1.0.0/lib/modules/Hyperion/00_stdlib.kmod
Normal file
@@ -0,0 +1,238 @@
|
||||
local args={...}
|
||||
local kernel=args[1]
|
||||
function string.hasSuffix(str, suffix)
|
||||
return string.sub(str, #suffix+1) == suffix
|
||||
end
|
||||
|
||||
function string.hasPrefix(str, prefix)
|
||||
return string.sub(str, 1, #prefix) == prefix
|
||||
end
|
||||
|
||||
function string.getSuffix(str, prefix)
|
||||
return string.sub(str, #prefix+1)
|
||||
end
|
||||
|
||||
function string.getPrefix(str, suffix)
|
||||
return string.sub(str, 1, #suffix)
|
||||
end
|
||||
|
||||
function string.join(str, ...)
|
||||
return table.concat(table.pack(str, ...))
|
||||
end
|
||||
|
||||
function string.delim(str, ...)
|
||||
return table.concat(table.pack(...), str)
|
||||
end
|
||||
|
||||
function string.split(str, delim, maxResultCountOrNil)
|
||||
assert(#delim == 1, "only delim len 1 supported for now")
|
||||
maxResultCountOrNil = (maxResultCountOrNil or 0)-1
|
||||
local rv = {}
|
||||
local buf = ""
|
||||
for i = 1, #str do
|
||||
local c = string.sub(str,i,i)
|
||||
if #rv ~= maxResultCountOrNil and c == delim then
|
||||
table.insert(rv, buf)
|
||||
buf = ""
|
||||
else
|
||||
buf = buf..c
|
||||
end
|
||||
end
|
||||
table.insert(rv, buf)
|
||||
return rv
|
||||
end
|
||||
|
||||
function string.replace(str, search, replacement)
|
||||
local rv = ""
|
||||
local consumedLen = 1
|
||||
local i = 1
|
||||
while i<#str do
|
||||
if string.sub(str, i, i+#search-1) == search then
|
||||
rv = rv .. string.sub(str, consumedLen, i-1) .. replacement
|
||||
i=i+#search
|
||||
consumedLen = i
|
||||
end
|
||||
i=i+1
|
||||
end
|
||||
return rv .. string.sub(str, consumedLen)
|
||||
end
|
||||
|
||||
function table.deepcopy(orig, copies)
|
||||
copies = copies or {}
|
||||
|
||||
if type(orig) ~= 'table' then
|
||||
return orig
|
||||
elseif copies[orig] then
|
||||
return copies[orig]
|
||||
end
|
||||
|
||||
local copy = {}
|
||||
copies[orig] = copy
|
||||
|
||||
for k, v in next, orig, nil do
|
||||
local copied_key = table.deepcopy(k, copies)
|
||||
local copied_val = table.deepcopy(v, copies)
|
||||
copy[copied_key] = copied_val
|
||||
end
|
||||
|
||||
return copy
|
||||
end
|
||||
|
||||
function table.hasKey(tabl, query)
|
||||
for i,v in pairs(tabl) do
|
||||
if i==query then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function table.hasVal(tabl, query)
|
||||
for i,v in pairs(tabl) do
|
||||
if v==query then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function table.proxy(tbl)
|
||||
local proxies = setmetatable({}, {__mode = "k"}) -- Weak table to avoid cycles
|
||||
|
||||
local function createProxy(t)
|
||||
if type(t) ~= "table" then return t end
|
||||
if proxies[t] then return proxies[t] end -- reuse proxy for the same table (handle cycles)
|
||||
|
||||
local proxy = {}
|
||||
proxies[t] = proxy
|
||||
|
||||
local mt
|
||||
mt = {
|
||||
__index = function(_, k)
|
||||
local value = t[k]
|
||||
if type(value) == "table" then
|
||||
return createProxy(value) -- recursively proxy subtables
|
||||
else
|
||||
return value
|
||||
end
|
||||
end,
|
||||
__newindex = function()
|
||||
error("Attempt to modify table proxy", 2)
|
||||
end,
|
||||
__pairs = function()
|
||||
return function(_, k)
|
||||
local nextKey, nextValue = next(t, k)
|
||||
if type(nextValue) == "table" then
|
||||
nextValue = createProxy(nextValue)
|
||||
end
|
||||
return nextKey, nextValue
|
||||
end, nil, nil
|
||||
end,
|
||||
__ipairs = function()
|
||||
local i = 0
|
||||
local n = #t
|
||||
return function()
|
||||
i = i + 1
|
||||
if i <= n then
|
||||
local v = t[i]
|
||||
if type(v) == "table" then
|
||||
v = createProxy(v)
|
||||
end
|
||||
return i, v
|
||||
end
|
||||
end
|
||||
end,
|
||||
__metatable = false
|
||||
}
|
||||
|
||||
setmetatable(proxy, mt)
|
||||
return proxy
|
||||
end
|
||||
|
||||
return createProxy(tbl)
|
||||
end
|
||||
|
||||
local function serialize(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..serialize(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..tostring(v)
|
||||
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
|
||||
|
||||
local oldtype=type
|
||||
local oldgetmetatable=getmetatable
|
||||
function type(object)
|
||||
if oldtype(object)~="table" then
|
||||
return oldtype(object)
|
||||
else
|
||||
if oldtype(oldgetmetatable(object))=="table" then
|
||||
local metatable = oldgetmetatable(object)
|
||||
if metatable.__type then return metatable.__type end
|
||||
else
|
||||
return "table"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function getmetatable(object)
|
||||
if oldtype(object)~="table" then return end
|
||||
if oldtype(oldgetmetatable(object))=="table" then
|
||||
if oldgetmetatable(object).__isuserdata then
|
||||
if oldtype(oldgetmetatable(object).__usermeta)=="function" then
|
||||
return oldgetmetatable(object).__usermeta()
|
||||
else
|
||||
return oldgetmetatable(object).__usermeta
|
||||
end
|
||||
else
|
||||
return oldgetmetatable(object)
|
||||
end
|
||||
else
|
||||
return oldgetmetatable(object)
|
||||
end
|
||||
end
|
||||
|
||||
function isEqual(a, ...)
|
||||
local args={...}
|
||||
for i=0, #args do
|
||||
if a==args[i] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
table.serialize=serialize
|
||||
kernel.log("Loaded stdlib")
|
||||
@@ -0,0 +1,3 @@
|
||||
local args={...}
|
||||
local kernel=args[1]
|
||||
kernel._U=table.proxy(_G)
|
||||
185
Test/Hyperion-kernel-v1.0.0/lib/modules/Hyperion/10_vfs.kmod
Normal file
185
Test/Hyperion-kernel-v1.0.0/lib/modules/Hyperion/10_vfs.kmod
Normal file
@@ -0,0 +1,185 @@
|
||||
local kernel = ...
|
||||
local openFiles = {}
|
||||
kernel.openFiles = openFiles
|
||||
local vfs = {}
|
||||
vfs.mounts = {}
|
||||
local disks = kernel.disks
|
||||
vfs.cwd = ""
|
||||
|
||||
local function resolvePath(path)
|
||||
local mountPoint = "/"
|
||||
local mountId = "$"
|
||||
if path:sub(1,1)~="/" then path=vfs.cwd..path end
|
||||
for k,v in pairs(vfs.mounts) do
|
||||
if path:sub(1,#v) == v and #v > #mountPoint then
|
||||
mountPoint = v
|
||||
mountId = k
|
||||
end
|
||||
end
|
||||
local diskPath = path:sub(#mountPoint+1)
|
||||
return disks[mountId], diskPath
|
||||
end
|
||||
|
||||
function vfs.mount(diskId, path)
|
||||
if kernel.uid ~= 0 then error("Permission denied") end
|
||||
if not disks[diskId] then
|
||||
error("Attempted to mount unknown disk '"..diskId.."'")
|
||||
return false
|
||||
end
|
||||
if vfs.mounts[diskId] then
|
||||
error("Disk '"..diskId.."' is already mounted")
|
||||
return false
|
||||
end
|
||||
if path:sub(#path,#path)~="/" then path=path.."/" end
|
||||
for i,v in pairs(vfs.mounts) do
|
||||
if v == path then
|
||||
error("Mount point '"..path.."' is already in use")
|
||||
return false
|
||||
end
|
||||
end
|
||||
vfs.mounts[diskId] = path
|
||||
end
|
||||
|
||||
function vfs.unmount(path)
|
||||
if kernel.uid ~= 0 then error("Permission denied") end
|
||||
for k,v in pairs(vfs.mounts) do
|
||||
if v == path then
|
||||
vfs.mounts[k] = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function vfs.open(path, mode)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return nil
|
||||
end
|
||||
local uuid = kernel.newUUID()
|
||||
openFiles[uuid] = {disk=disk.address, path=path, mode=mode, handle=disk:open(diskPath, mode)}
|
||||
return uuid
|
||||
end
|
||||
|
||||
function vfs.close(fileId)
|
||||
local file = openFiles[fileId]
|
||||
if not file then
|
||||
error("Invalid file handle")
|
||||
return false
|
||||
end
|
||||
local disk = disks[file.disk]
|
||||
disk:close(file.handle)
|
||||
openFiles[fileId] = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function vfs.read(fileId, count)
|
||||
local file = openFiles[fileId]
|
||||
if not file then
|
||||
error("Invalid file handle")
|
||||
return nil
|
||||
end
|
||||
if not file.mode:find("r") then
|
||||
error("File not opened in read mode")
|
||||
return nil
|
||||
end
|
||||
local disk = disks[file.disk]
|
||||
return disk:read(file.handle, count)
|
||||
end
|
||||
|
||||
function vfs.write(fileId, data)
|
||||
local file = openFiles[fileId]
|
||||
if not file then
|
||||
error("Invalid file handle")
|
||||
return false
|
||||
end
|
||||
if not file.mode:find("w") then
|
||||
error("File not opened in write mode")
|
||||
return false
|
||||
end
|
||||
local disk = disks[file.disk]
|
||||
return disk:write(file.handle, data)
|
||||
end
|
||||
|
||||
function vfs.mkdir(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return false
|
||||
end
|
||||
return disk:mkdir(diskPath)
|
||||
end
|
||||
|
||||
function vfs.remove(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return false
|
||||
end
|
||||
return disk:remove(diskPath)
|
||||
end
|
||||
|
||||
function vfs.atributes(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return nil
|
||||
end
|
||||
return disk:attributes(diskPath)
|
||||
end
|
||||
|
||||
function vfs.list(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return nil
|
||||
end
|
||||
return disk:list(diskPath)
|
||||
end
|
||||
|
||||
function vfs.exists(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return false
|
||||
end
|
||||
return disk:directoryExists(diskPath) or disk:fileExists(diskPath)
|
||||
end
|
||||
|
||||
function vfs.type(path)
|
||||
local disk, diskPath = resolvePath(path)
|
||||
if not disk then
|
||||
error("No disk mounted for path '"..path.."'")
|
||||
return nil
|
||||
end
|
||||
return disk:type(diskPath)
|
||||
end
|
||||
|
||||
function vfs.getcwd()
|
||||
return vfs.cwd
|
||||
end
|
||||
|
||||
function vfs.setcwd(path)
|
||||
if path:sub(#path,#path)~="/" then path=path.."/" end
|
||||
if path:sub(1,1)~="/" then path="/"..path end
|
||||
vfs.cwd=path
|
||||
end
|
||||
|
||||
kernel.vfs = vfs
|
||||
kernel.registerSyscall(0x01, vfs.open)
|
||||
kernel.registerSyscall(0x02, vfs.read)
|
||||
kernel.registerSyscall(0x03, vfs.write)
|
||||
kernel.registerSyscall(0x04, vfs.close)
|
||||
kernel.registerSyscall(0x05, vfs.list)
|
||||
kernel.registerSyscall(0x06, vfs.type)
|
||||
kernel.registerSyscall(0x07, vfs.atributes)
|
||||
kernel.registerSyscall(0x08, vfs.mkdir)
|
||||
kernel.registerSyscall(0x09, vfs.remove)
|
||||
kernel.registerSyscall(0x0a, vfs.exists)
|
||||
kernel.registerSyscall(0x0b, vfs.mount)
|
||||
kernel.registerSyscall(0x0c, vfs.unmount)
|
||||
kernel.registerSyscall(0x0d, vfs.getcwd)
|
||||
kernel.registerSyscall(0x0e, vfs.setcwd)
|
||||
|
||||
kernel.log("VFS module loaded")
|
||||
@@ -0,0 +1,22 @@
|
||||
local args = {...}
|
||||
local kernel = args[1]
|
||||
kernel.log("Loading third party drivers")
|
||||
for _,subf in ipairs(kernel.fs.list("/lib/modules/")) do
|
||||
if kernel.fs.isDir("/lib/modules/"..subf) then
|
||||
if subf~="Hyperion" then
|
||||
for _,driver in ipairs(kernel.fs.list("/lib/modules/"..subf)) do
|
||||
kernel.log("Compiling driver \""..subf..":"..driver.."\"")
|
||||
local code = kernel.fs.readAllText("/lib/modules/"..subf.."/"..driver)
|
||||
local func, err = load(code, "@"..driver)
|
||||
if not func then
|
||||
kernel.log("DriverCompileErr: "..tostring(err), "ERROR")
|
||||
else
|
||||
local ok, err = xpcall(func, debug.traceback, table.unpack(args))
|
||||
if not ok then
|
||||
kernel.log("DriverExecErr: "..tostring(err), "ERROR")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
local args = {...}
|
||||
local kernel = args[1]
|
||||
kernel.log("Initializing third party drivers")
|
||||
for _,v in ipairs(kernel.drivers.raw) do
|
||||
if v.arch==kernel.arch then
|
||||
if v.load then
|
||||
kernel.log("Loading "..v.name)
|
||||
local ok,err = xpcall(v.load, debug.traceback)
|
||||
if not ok then
|
||||
kernel.log("DriverLoadErr: "..tostring(err))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1 @@
|
||||
local kernel = ...
|
||||
Reference in New Issue
Block a user