Это заготовка статьи. Вы можете помочь проекту, дополнив и оформив её. |
Когда компьютер запускается и начинает работу, он прогоняет записанный на EEPROM код, который загружает файл инициализации( init.lua
для Lua BIOS EEPROM). Можно использовать стандартный Lua BIOS и загружать систему через init.lua
, находящийся в корневой директории, а можно написать свой BIOS, что позволит указать собственный путь и имя файла инициализации. При выборе этого способа нужно будет самому написать такие вещи, как, например, функцию загрузки файла.
После загрузки файла инициализации вам будет доступно лишь 2 API для взаимодействия с компьютером и его компонентами: "component" и "computer", а так же базовые функции BIOS вроде загрузки файла. Затем нужно будет загрузить базовые функции для вывода и базовые сервисы(Например: для взаимодействия с файловой системой), и после этого можно будет задуматься о написании командной строки и более продвинутого GUI.
Стоит заметить, что на EEPROM умещается не более 4КБ кода.
Сначала объявляем переменную, содержащую путь к файлу запуска (имя файла включительно).Например:
path = "/system/startup.lua
Далее необходимо привязать видеокарту к монитору, чтобы можно было выводить ошибки:
do
local screen = component.list("screen")()
local gpu = component.list("gpu")()
if gpu and screen then
component.invoke(gpu, "bind", screen)
end
end
Адрес файловой системы, в которой хранится файл инициализации, будем записывать на EEPROM. Для этого объявим две функции:
local eeprom = component.list("eeprom")()
local function getData() return component.invoke(eeprom,"getData") end
local function setData(data) return component.invoke(eeprom, "setData", data) end
Теперь необходимо создать функцию, загружающую файл:
Далее коментарии в коде. В целях экономии места на EEPROM рекомендуется их не переписывать.
_G.loadFile = function(_addr,_path)
local file,err = component.invoke(_addr,"open",_path) --Открываем файл
if not file then return nil,err end --Если файл не найден, возвращаем ошибку
local buffer = ""
repeat --"Читаем" файл до конца
local dat,err = component.invoke(_addr, "read", file, math.huge)
if not dat and err then return nil,err end
buffer = buffer..(dat or "")
until not dat
component.invoke(_addr, "close", file) --Закрываем файл
local chunk,err = load(buffer, "=".._path) --Преобразуем полученный участок кода в исполняемую функцию
if not chunk then return nil,err end --Если преобразовать не получилось - возвращаем ошибку
return chunk,nil --Возвращаем функцию
end
Далее нам нужно загрузить файл инициализации.
Для этого считываем с EEPROM адрес файловой системы:
local data = getData()
Если он есть, то загружаем файл воспользовавшись написанной ранее функцией:
if data and type(data) == "string" and #data > 0 then
boot,err = loadFile(data,bootpath,false)
end
Если же адреса нет или он не корректный, то получаем список адресов всех файловых систем, ищем и пытаемся загрузить файл в каждой из них, и записываем уже корректный адрес файловой системы с файлом инициализации (если он есть):
if not boot then
setData("")
for addr in component.list("filesystem") do
boot,err = loadFile(addr, bootpath,false)
if boot then setData(addr) break end
end
end
Если после этого файл всё еще не найден, то выводим на экран ошибку:
if not boot or err then
error("no bootable medium found"..(err and(": "..tostring(err)) or ""),0)
end
Если он найден то:
_G.SysAddr = data --Записываем адрес файловой системы в _G
computer.beep(1000, 0.2) --Гудком оповещаем пользователя о том, что файл найден
boot() --Запускаем полученный файл