added netboot to SEBIOS.

This commit is contained in:
Izaya 2017-09-04 20:12:18 +10:00
parent 24e5d76527
commit caeeb10d25
1 changed files with 102 additions and 80 deletions

View File

@ -1,54 +1,71 @@
local component_invoke = component.invoke local component_invoke = component.invoke
function boot_invoke(address, method, ...) function boot_invoke(address, method, ...)
local result = table.pack(pcall(component_invoke, address, method, ...)) local result = table.pack(pcall(component_invoke, address, method, ...))
if not result[1] then if not result[1] then
return nil, result[2] return nil, result[2]
else else
return table.unpack(result, 2, result.n) return table.unpack(result, 2, result.n)
end end
end end
-- backwards compatibility, may remove later -- backwards compatibility, may remove later
local eeprom = component.list("eeprom")() local eeprom = component.list("eeprom")()
computer.getBootAddress = function() computer.getBootAddress = function()
return boot_invoke(eeprom, "getData") return boot_invoke(eeprom, "getData")
end end
computer.setBootAddress = function(address) computer.setBootAddress = function(address)
return boot_invoke(eeprom, "setData", address) return boot_invoke(eeprom, "setData", address)
end end
do do
local screen = component.list("screen")() local screen = component.list("screen")()
local gpu = component.list("gpu")() local gpu = component.list("gpu")()
if gpu and screen then if gpu and screen then
boot_invoke(gpu, "bind", screen) boot_invoke(gpu, "bind", screen)
end end
end end
local function tryLoadFrom(address) local function tryLoadFrom(address)
if component.type(address) == "filesystem" then if component.type(address) == "filesystem" then
local handle, reason = boot_invoke(address, "open", "/init.lua") local handle, reason = boot_invoke(address, "open", "/init.lua")
if not handle then if not handle then
return nil, reason return nil, reason
end
local buffer = ""
repeat
local data, reason = boot_invoke(address, "read", handle, 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")
elseif component.type(address) == "tape_drive" then
boot_invoke(address,"seek",-math.huge)
local boottype = boot_invoke(address,"read",1)
if boottype == "!" then
local rl = tonumber(boot_invoke(address,"read",8))
local buffer = boot_invoke(address,"read",rl)
return load(buffer, "=init")
end
end end
local buffer = ""
repeat
local data, reason = boot_invoke(address, "read", handle, 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")
elseif component.type(address) == "tape_drive" then
boot_invoke(address,"seek",-math.huge)
local boottype = boot_invoke(address,"read",1)
if boottype == "!" then
local rl = tonumber(boot_invoke(address,"read",8))
local buffer = boot_invoke(address,"read",rl)
return load(buffer, "=init")
end
elseif component.type(address) == "modem" then
boot_invoke(address,"open",9671)
boot_invoke(address,"broadcast",9671,computer.address())
s=""
local bt = computer.uptime()
while bt+10 > computer.uptime() do
computer.beep()
local ev={computer.pullSignal(0.5)}
if ev[1] == "modem_message" and ev[4] == 9671 then
bt=computer.uptime()
if ev[6] == "." then break end
s=s..ev[6]
end
end
if s ~= "" then
return load(s,"=init")
end
end
end end
local bootdevs = {} local bootdevs = {}
@ -58,67 +75,72 @@ end
for address in component.list("tape_drive") do for address in component.list("tape_drive") do
bootdevs[#bootdevs+1] = address bootdevs[#bootdevs+1] = address
end end
for address in component.list("modem") do
bootdevs[#bootdevs+1] = address
end
do do
local gA,sA = component.list("gpu")(),component.list("screen")() local gA,sA = component.list("gpu")(),component.list("screen")()
if gA and sA then if gA and sA then
local gP,cy = component.proxy(gA),1 local gP,cy = component.proxy(gA),1
gP.bind(sA) gP.bind(sA)
local sx, sy = gP.getResolution() local sx, sy = gP.getResolution()
local function wl(s) local function wl(s)
gP.set(1,cy,s) gP.set(1,cy,s)
cy=cy+1 cy=cy+1
end end
local cba = computer.getBootAddress() local cba = computer.getBootAddress()
local S = " " local S = " "
local function rdraw() local function rdraw()
gP.fill(1,1,sx,sy," ") gP.fill(1,1,sx,sy," ")
cy=1 cy=1
wl("SKS Enhanced BIOS v1") wl("SKS Enhanced BIOS v1")
wl("Memory: "..tostring(computer.totalMemory()/1024).."K") wl("Memory: "..tostring(computer.totalMemory()/1024).."K")
wl(" ") wl(" ")
for k,v in ipairs(bootdevs) do for k,v in ipairs(bootdevs) do
if v == cba then S = " * " else S = " " end if v == cba then S = " * " else S = " " end
wl(S..tostring(k).." "..v.." "..component.type(v).." "..(component.invoke(v,"getLabel") or "")) local e,l = pcall(component.invoke,v,"getLabel")
end if not e then l = "" end
wl(S..tostring(k).." "..v.." "..component.type(v).." "..(l or ""))
end end
end
rdraw()
local timer = 5
local bhc = false
while computer.uptime() < timer do
t,_,c,C = computer.pullSignal(0.5)
if t == "key_down" and c > 48 and c < 58 then
cba = bootdevs[c-48]
bhc = true
rdraw() rdraw()
local timer = 5 elseif t == "key_down" and c == 32 then
local bhc = false timer = timer + 10
while computer.uptime() < timer do elseif t == "key_down" and c == 13 and C == 28 then
t,_,c,C = computer.pullSignal(0.5) timer = 0
if t == "key_down" and c > 48 and c < 58 then
cba = bootdevs[c-48]
bhc = true
rdraw()
elseif t == "key_down" and c == 32 then
timer = timer + 10
elseif t == "key_down" and c == 13 and C == 28 then
timer = 0
end
end
if bhc then
computer.setBootAddress(cba)
end end
end end
if bhc then
computer.setBootAddress(cba)
end
end
end end
local init, reason local init, reason
if computer.getBootAddress() then if computer.getBootAddress() then
init, reason = tryLoadFrom(computer.getBootAddress()) init, reason = tryLoadFrom(computer.getBootAddress())
end end
if not init then if not init then
computer.setBootAddress() computer.setBootAddress()
for k,address in ipairs(bootdevs) do for k,address in ipairs(bootdevs) do
init, reason = tryLoadFrom(address) init, reason = tryLoadFrom(address)
if init then if init then
computer.setBootAddress(address) computer.setBootAddress(address)
break break
end
end end
end
end end
if not init then if not init then
error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0)
end end
computer.beep(1000, 0.2) computer.beep(1000, 0.2)
init() init()