mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2026-02-15 04:03:49 +01:00
103 lines
2.4 KiB
Lua
103 lines
2.4 KiB
Lua
-- Minimum viable BIOS, effectively a blend between LuaBIOS and AdvancedLoader
|
|
|
|
local component, computer = component, computer
|
|
local gpu = component.list("gpu")()
|
|
local screen = component.list("screen")()
|
|
local eeprom = component.list("eeprom")()
|
|
|
|
computer.getBootAddress = function()
|
|
return component.invoke(eeprom, "getData")
|
|
end
|
|
computer.setBootAddress = function(addr)
|
|
return component.invoke(eeprom, "setData", addr)
|
|
end
|
|
|
|
if gpu and screen then
|
|
component.invoke(gpu, "bind", screen)
|
|
local w, h = component.invoke(gpu, "maxResolution")
|
|
component.invoke(gpu, "maxResolution")
|
|
component.invoke(gpu, "setForeground", 0xFFFFFF)
|
|
component.invoke(gpu, "setBackground", 0x000000)
|
|
component.invoke(gpu, "fill", 1, 1, w, h, " ")
|
|
end
|
|
|
|
local function romRead(addr, path)
|
|
local fs = component.proxy(addr)
|
|
local fd = fs.open(path)
|
|
if not fd then return end
|
|
local data = ""
|
|
while true do
|
|
local chunk, err = fs.read(fd, math.huge)
|
|
if err then
|
|
fs.close(fd)
|
|
return nil
|
|
end
|
|
if not chunk then break end
|
|
data = data .. chunk
|
|
end
|
|
fs.close(fd)
|
|
return data
|
|
end
|
|
|
|
local function getBootCode(addr)
|
|
local drive = component.proxy(addr)
|
|
local sectorSize = drive.getSectorSize()
|
|
local firstSector = drive.readSector(1)
|
|
|
|
-- Generic MBR bootcode
|
|
if firstSector:sub(-2, -1) == "\x55\xAA" then
|
|
local codeEnd = sectorSize - 67 -- no laughing!!!!
|
|
local term = string.find(firstSector, "\0", 5, true)
|
|
return load(string.sub(firstSector, 5, term and (term - 1) or codeEnd))
|
|
end
|
|
-- TODO: whatever else NC might be testing
|
|
end
|
|
|
|
local paths = {
|
|
"init.lua",
|
|
"OS.lua",
|
|
"boot/pipes/kernel",
|
|
}
|
|
|
|
local prevboot = computer.getBootAddress()
|
|
if prevboot then
|
|
if component.type(prevboot) == "filesystem" then
|
|
for _, path in ipairs(paths) do
|
|
local code = romRead(prevboot, path)
|
|
if code then
|
|
assert(load(code))(prevboot)
|
|
error("halted")
|
|
end
|
|
end
|
|
end
|
|
if component.type(prevboot) == "drive" then
|
|
local f = getBootCode(prevboot)
|
|
if f then
|
|
f(prevboot)
|
|
error("halted")
|
|
end
|
|
end
|
|
end
|
|
|
|
for addr in component.list("filesystem", true) do
|
|
for _, path in ipairs(paths) do
|
|
local code = romRead(addr, path)
|
|
if code then
|
|
computer.setBootAddress(addr)
|
|
assert(load(code))(addr)
|
|
error("halted")
|
|
end
|
|
end
|
|
end
|
|
|
|
for addr in component.list("drive", true) do
|
|
local f = getBootCode(addr)
|
|
if f then
|
|
computer.setBootAddress(addr)
|
|
f(addr)
|
|
error("halted")
|
|
end
|
|
end
|
|
|
|
error("no bootable medium found")
|