local component, error, math, select = component, error, math, select local cl, ci, ct = component.list, component.invoke, component.type local function bail(msg, ...) if select('#', ...) > 0 then msg = msg:format(...) end return error(msg, 0) end local function unique(addr1, addr2, what) if addr1 and addr2 then return bail('multiple %s: %s, %s', what, addr1, addr2) end return addr1 or addr2 or bail('no %s', what) end local eeprom for addr in cl('eeprom') do eeprom = unique(eeprom, addr, 'eeproms') end eeprom = unique(eeprom, nil, 'eeprom') local data = ci(eeprom, 'getData') local bootfs, bootpath if data == '' then for fs in cl('filesystem') do if ci(fs, 'exists', '/init.lua') then bootfs = unique(bootfs, fs, 'bootable filesystems') bootpath = '/init.lua' end end bootfs = unique(bootfs, nil, 'bootable filesystem') else local split = data:find(':') if split then bootfs, bootpath = data:sub(1, split - 1), data:sub(split + 1) else bootfs, bootpath = data, '/init.lua' end local ty, err = ct(bootfs) if not ty then bail('bootfs %s absent', bootfs) end if ty ~= 'filesystem' then bail('bootfs %s is a %s', bootfs, ty) end end --polyfill {get,set}BootAddress like openloader does --lua bios says these are for "backwards compatibility", but neither [lua bios, openloader] provide --other ways to find the boot filesystem and both [openos, plan9k] call getBootAddress during boot function computer.getBootAddress() return bootfs end function computer.setBootAddress(addr) return ci(eeprom, 'setData', addr) end local fd, err = ci(bootfs, 'open', bootpath) if not fd then bail('open %s:%s failed: %s', bootfs:sub(1, 8), bootpath, err) end local code = '' local lots = math.maxinteger or math.huge --read as much as possible repeat local chunk, err = ci(bootfs, 'read', fd, lots) if err then bail('read %s:%s failed: %s', bootfs:sub(1, 8), bootpath, err) end code = code .. (chunk or '') until not chunk ci(bootfs, 'close', fd) local fn = assert(load(code, '@' .. bootpath)) return fn(bootfs, bootpath) -- vi: set ts=2: