Advertisement
DOGGYWOOF

Bootloader

Apr 7th, 2024 (edited)
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.32 KB | None | 0 0
  1. local function main()
  2. local component_invoke = component.invoke
  3. local function boot_invoke(address, method, ...)
  4. local result = table.pack(pcall(component_invoke, address, method, ...))
  5. if not result[1] then
  6. return nil, result[2]
  7. else
  8. return table.unpack(result, 2, result.n)
  9. end
  10. end
  11.  
  12. local eeprom = component.list("eeprom")()
  13. computer.getBootAddress = function()
  14. return boot_invoke(eeprom, "getData")
  15. end
  16. computer.setBootAddress = function(address)
  17. return boot_invoke(eeprom, "setData", address)
  18. end
  19.  
  20. do
  21. local screen = component.list("screen")()
  22. local gpu = component.list("gpu")()
  23. if gpu and screen then
  24. boot_invoke(gpu, "bind", screen)
  25. end
  26. end
  27.  
  28. local function tryLoadFrom(address)
  29. local handle, reason = boot_invoke(address, "open", "/init.lua")
  30. if not handle then
  31. return nil, reason
  32. end
  33. local buffer = ""
  34. repeat
  35. local data, reason = boot_invoke(address, "read", handle, math.maxinteger or math.huge)
  36. if not data and reason then
  37. return nil, reason
  38. end
  39. buffer = buffer .. (data or "")
  40. until not data
  41. boot_invoke(address, "close", handle)
  42. return load(buffer, "=init")
  43. end
  44.  
  45. -- Get a list of bootable drives and their names
  46. local osList = {}
  47. for address in component.list("filesystem") do
  48. local label = boot_invoke(address, "getLabel") or "Unnamed Drive"
  49. table.insert(osList, {address = address, label = label})
  50. end
  51.  
  52. -- Function to display boot menu
  53. local function displayBootMenu(selectedIndex)
  54. local gpu = component.list("gpu")()
  55. local w, h = boot_invoke(gpu, "getResolution")
  56. boot_invoke(gpu, "fill", 1, 1, w, h, " ") -- Clear screen
  57. boot_invoke(gpu, "setForeground", 0xFFFFFF) -- Set text color to white
  58. boot_invoke(gpu, "set", 1, 1, "Select OS to boot:")
  59. for i, os in ipairs(osList) do
  60. local line = i + 1
  61. local textColor = i == selectedIndex and 0xFF0000 or 0xFFFFFF
  62. boot_invoke(gpu, "setForeground", textColor)
  63. boot_invoke(gpu, "set", 1, line, os.label .. " (" .. os.address .. ")")
  64. end
  65. computer.beep(1000, 0.10) -- Beep when boot menu appears
  66. end
  67.  
  68. -- Main boot menu logic
  69. local selectedIndex = math.ceil(#osList / 2) -- Select middle OS initially
  70. displayBootMenu(selectedIndex)
  71. while true do
  72. local event = {computer.pullSignal()}
  73. if event[1] == "key_down" then
  74. if event[4] == 200 and selectedIndex > 1 then -- Arrow up
  75. selectedIndex = selectedIndex - 1
  76. displayBootMenu(selectedIndex)
  77. elseif event[4] == 208 and selectedIndex < #osList then -- Arrow down
  78. selectedIndex = selectedIndex + 1
  79. displayBootMenu(selectedIndex)
  80. elseif event[4] == 28 then -- Enter key
  81. local selectedOS = osList[selectedIndex]
  82. local init, reason = tryLoadFrom(selectedOS.address)
  83. if init then
  84. computer.setBootAddress(selectedOS.address)
  85. computer.beep(1500, 0.10) -- Beep when booting into the operating system
  86. return init() -- Return the result of running loaded code
  87. else
  88. print("Failed to boot from " .. selectedOS.label .. ": " .. tostring(reason))
  89. end
  90. end
  91. end
  92. end
  93. end
  94.  
  95. main() -- Call the main function to execute the boot process
  96.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement