From 322d3cb59e1762edb331b87546bdf0c2908d2d30 Mon Sep 17 00:00:00 2001 From: Igor Timofeev Date: Wed, 6 Feb 2019 13:42:13 +0300 Subject: [PATCH] Added support for OpenOS booting in EFI filesystem selection --- EFI/Full.lua | 106 +++++++++++++++++++++++-------------------- EFI/Minified.lua | 2 +- Libraries/System.lua | 10 ++-- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/EFI/Full.lua b/EFI/Full.lua index 459d5962..37007604 100644 --- a/EFI/Full.lua +++ b/EFI/Full.lua @@ -1,26 +1,24 @@ -local stringsMain, stringsInit, stringsChangeLabel, stringKeyDown, stringsFilesystem, colorsTitle, colorsBackground, colorsText, colorsSelectionBackground, colorsSelectionText, componentProxy, componentList, pullSignal, uptime, tableInsert, mathMax, mathMin, mathHuge, mathFloor = "MineOS EFI", "/OS.lua", "Change label", "key_down", "filesystem", 0x2D2D2D, 0xE1E1E1, 0x878787, 0x878787, 0xE1E1E1, component.proxy, component.list, computer.pullSignal, computer.uptime, table.insert, math.max, math.min, math.huge, math.floor +local stringsMain, stringsChangeLabel, stringKeyDown, stringsFilesystem, colorsTitle, colorsBackground, colorsText, colorsSelectionBackground, colorsSelectionText, componentProxy, componentList, pullSignal, uptime, tableInsert, mathMax, mathMin, mathHuge, mathFloor = "MineOS EFI", "Change label", "key_down", "filesystem", 0x2D2D2D, 0xE1E1E1, 0x878787, 0x878787, 0xE1E1E1, component.proxy, component.list, computer.pullSignal, computer.uptime, table.insert, math.max, math.min, math.huge, math.floor local eeprom, gpu, internetAddress = componentProxy(componentList("eeprom")()), componentProxy(componentList("gpu")()), componentList("internet")() -local shutdown, gpuSet, gpuFill, eepromSetData, eepromGetData, screenWidth, screenHeight, curentBackground, currentForeground = computer.shutdown, gpu.set, gpu.fill, eeprom.setData, eeprom.getData, gpu.getResolution() +local shutdown, gpuSet, gpuSetBackground, gpuSetForeground, gpuFill, eepromSetData, eepromGetData, screenWidth, screenHeight = computer.shutdown, gpu.set, gpu.setBackground, gpu.setForeground, gpu.fill, eeprom.setData, eeprom.getData, gpu.getResolution() -local resetColors, setBackground, setForeground, restrict = - function() - curentBackground, currentForeground = nil, nil - end, - function(color) - if color ~= curentBackground then - gpu.setBackground(color) - curentBackground = color - end - end, - function(color) - if color ~= currentForeground then - gpu.setForeground(color) - currentForeground = color - end - end, +local OSList, restrict, rectangle, centrizedText, menuElement = + { + { + "/OS.lua", + function() + end + }, + { + "/init.lua", + function() + computer.getBootAddress, computer.setBootAddress = eepromGetData, eepromSetData + end + } + }, function(text, limit, skip) if #text < limit then text = text .. string.rep(" ", limit - #text) @@ -29,16 +27,14 @@ local resetColors, setBackground, setForeground, restrict = end return text .. (skip and "" or " ") - end - -local rectangle, centrizedText, menuElement = + end, function(x, y, width, height, color) - setBackground(color) + gpuSetBackground(color) gpuFill(x, y, width, height, " ") end, function(y, foreground, text) local x = mathFloor(screenWidth / 2 - #text / 2) - setForeground(foreground) + gpuSetForeground(foreground) gpuSet(x, y, text) end, function(text, callback, breakLoop) @@ -86,29 +82,44 @@ local function executeString(...) end end - resetColors() status(stringsMain, reason, 1) end -local loadInit, menuBack, menu, input = +local boot, menuBack, menu, input = function(proxy) - status(stringsMain, "Booting from " .. proxy.address) + for i = 1, #OSList do + if proxy.exists(OSList[i][1]) then + status(stringsMain, "Booting from " .. proxy.address) - local handle, data, chunk, success, reason = proxy.open(stringsInit, "rb"), "", "" - repeat - chunk = proxy.read(handle, mathHuge) - data = data .. (chunk or "") - until not chunk + -- Updating current EEPROM boot address if it's differs from given proxy address + if eepromGetData() ~= proxy.address then + eepromSetData(proxy.address) + end - proxy.close(handle) + -- Running OS pre-boot function + OSList[i][2]() - executeString(data, "=" .. stringsInit) + -- Reading boot file + local handle, data, chunk, success, reason = proxy.open(OSList[i][1], "rb"), "" + repeat + chunk = proxy.read(handle, mathHuge) + data = data .. (chunk or "") + until not chunk + + proxy.close(handle) + + -- Running boot file + executeString(data, "=" .. OSList[i][1]) + + return 1 + end + end end, function() return menuElement("Back", nil, 1) end, function(titleText, elements) - local spacing, selectedElement, maxLength = 2, 1, 0 + local selectedElement, maxLength = 1, 0 for i = 1, #elements do maxLength = math.max(maxLength, #elements[i].s) end @@ -121,11 +132,11 @@ local loadInit, menuBack, menu, input = if i == selectedElement then rectangle(mathFloor(screenWidth / 2 - maxLength / 2) - 2, y, maxLength + 4, 1, colorsSelectionBackground) - setForeground(colorsSelectionText) + gpuSetForeground(colorsSelectionText) gpuSet(x, y, elements[i].s) + gpuSetBackground(colorsBackground) else - setBackground(colorsBackground) - setForeground(colorsText) + gpuSetForeground(colorsText) gpuSet(x, y, elements[i].s) end @@ -155,7 +166,7 @@ local loadInit, menuBack, menu, input = while 1 do eblo = prefix .. text gpuFill(1, y, screenWidth, 1, " ") - setForeground(colorsText) + gpuSetForeground(colorsText) gpuSet(mathFloor(screenWidth / 2 - #eblo / 2), y, eblo .. (state and "█" or "")) eventData = {pullSignal(0.5)} @@ -181,7 +192,7 @@ local loadInit, menuBack, menu, input = end gpu.bind(componentList("screen")(), true) -status(stringsMain, "Hold Alt to show boot options menu") +status(stringsMain, "Hold Alt to show boot options") local deadline, eventData = uptime() + 1 while uptime() < deadline do @@ -221,13 +232,13 @@ while uptime() < deadline do end, 1)) end - tableInsert(filesystemOptions, 1, menuElement("Set as startup", function() + tableInsert(filesystemOptions, 1, menuElement("Set as bootable", function() eepromSetData(address) end, 1)) menu(label .. " (" .. address .. ")", filesystemOptions) - end - , 1) + end, 1 + ) ) end @@ -254,7 +265,7 @@ while uptime() < deadline do if result then data = data .. result else - handle:close() + handle.close() if reason then status(stringsMain, reason, 1) @@ -276,14 +287,11 @@ while uptime() < deadline do end local proxy = componentProxy(eepromGetData()) -if proxy and proxy.exists(stringsInit) then - loadInit(proxy) -else +if not (proxy and boot(proxy)) then for address in componentList(stringsFilesystem) do proxy = componentProxy(address) - if proxy.exists(stringsInit) then - eepromSetData(address) - loadInit(proxy) + + if boot(proxy) then break else proxy = nil diff --git a/EFI/Minified.lua b/EFI/Minified.lua index 3c35cf7e..f560d090 100644 --- a/EFI/Minified.lua +++ b/EFI/Minified.lua @@ -1 +1 @@ -local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="MineOS EFI","/OS.lua","Change label","key_down","filesystem",0x2D2D2D,0xE1E1E1,0x878787,0x878787,0xE1E1E1,component.proxy,component.list,computer.pullSignal,computer.uptime,table.insert,math.max,math.min,math.huge,math.floor;local t,u,v=k(l("eeprom")()),k(l("gpu")()),l("internet")()local w,x,y,z,A,B,C,D,E=computer.shutdown,u.set,u.fill,t.setData,t.getData,u.getResolution()local F,G,H,I=function()D,E=nil,nil end,function(J)if J~=D then u.setBackground(J)D=J end end,function(J)if J~=E then u.setForeground(J)E=J end end,function(K,L,M)if#K1 then ai=ai-1 elseif ak[4]==208 and ai<#ag then ai=ai+1 elseif ak[4]==28 then if ag[ai].c then ag[ai].c()end;if ag[ai].b then return end end end end end,function(R,al)local K,am,an,ak,ao="",true;while 1 do an=al..K;y(1,R,B,1," ")H(h)x(s(B/2-#an/2),R,an..(am and"█"or""))ak={m(0.5)}if ak[1]==d then if ak[4]==28 then return K elseif ak[4]==14 then K=K:sub(1,-2)else ao=unicode.char(ak[3])if ao:match("^[%w%d%p%s]+")then K=K..ao end end;am=true elseif ak[1]=="clipboard"then K=K..ak[3]elseif not ak[1]then am=not am end end end;u.bind(l("screen")(),true)Z(a,"Hold Alt to show boot options menu")local ap,ak=n()+1;while n() "or" ")..I(au,10)..I(ab.spaceTotal()>1048576 and"HDD"or ab.spaceTotal()>65536 and"FDD"or"SYS",3)..I(av and"R"or"R/W",3)..at:sub(1,8).." "..I(string.format("%.2f",ab.spaceUsed()/ab.spaceTotal()*100).."%",6,1),function()local aw={a8()}if not av then o(aw,1,P(c,function()ab.setLabel(aa(X(2,c),"Enter new name: "))end,1))o(aw,2,P("Format",function()Z(a,"Formatting filesystem "..at)for ax,ay in ipairs(ab.list("/"))do ab.remove(ay)end;Z(a,"Formatting finished",1)end,1))end;o(aw,1,P("Set as startup",function()z(at)end,1))a9(au.." ("..at..")",aw)end,1))end;a9("Select filesystem",ar)end),P("Shutdown",function()w()end),a8()}if v then o(aq,2,P("Internet recovery",function()local ac,ad,a5,a6=k(v).request("https://raw.githubusercontent.com/IgorTimofeev/MineOS/master/Installer/Main.lua"),""if ac then Z(a,"Downloading recovery script")while 1 do a5,a6=ac.read(r)if a5 then ad=ad..a5 else ac:close()if a6 then Z(a,a6,1)else a4(ad,"=string")end;break end end else Z(a,"invalid URL-address",1)end end))end;a9(a,aq)end end;local ab=k(A())if ab and ab.exists(b)then a7(ab)else for at in l(e)do ab=k(at)if ab.exists(b)then z(at)a7(ab)break else ab=nil end end;if not ab then Z(a,"No bootable mediums found",1)end end;w() \ No newline at end of file +local a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r="MineOS EFI","Change label","key_down","filesystem",0x2D2D2D,0xE1E1E1,0x878787,0x878787,0xE1E1E1,component.proxy,component.list,computer.pullSignal,computer.uptime,table.insert,math.max,math.min,math.huge,math.floor;local s,t,u=j(k("eeprom")()),j(k("gpu")()),k("internet")()local v,w,x,y,z,A,B,C,D=computer.shutdown,t.set,t.setBackground,t.setForeground,t.fill,s.setData,s.getData,t.getResolution()local E,F,G,H,I={{"/OS.lua",function()end},{"/init.lua",function()computer.getBootAddress,computer.setBootAddress=B,A end}},function(J,K,L)if#J1 then ae=ae-1 elseif ag[4]==208 and ae<#ad then ae=ae+1 elseif ag[4]==28 then if ad[ae].c then ad[ae].c()end;if ad[ae].b then return end end end end end,function(N,ah)local J,ai,aj,ag,ak="",true;while 1 do aj=ah..J;z(1,N,C,1," ")y(g)w(r(C/2-#aj/2),N,aj..(ai and"█"or""))ag={l(0.5)}if ag[1]==c then if ag[4]==28 then return J elseif ag[4]==14 then J=J:sub(1,-2)else ak=unicode.char(ag[3])if ak:match("^[%w%d%p%s]+")then J=J..ak end end;ai=true elseif ag[1]=="clipboard"then J=J..ag[3]elseif not ag[1]then ai=not ai end end end;t.bind(k("screen")(),true)W(a,"Hold Alt to show boot options")local al,ag=m()+1;while m() "or" ")..F(aq,10)..F(a8.spaceTotal()>1048576 and"HDD"or a8.spaceTotal()>65536 and"FDD"or"SYS",3)..F(ar and"R"or"R/W",3)..ap:sub(1,8).." "..F(string.format("%.2f",a8.spaceUsed()/a8.spaceTotal()*100).."%",6,1),function()local as={a5()}if not ar then n(as,1,I(b,function()a8.setLabel(a7(U(2,b),"Enter new name: "))end,1))n(as,2,I("Format",function()W(a,"Formatting filesystem "..ap)for at,au in ipairs(a8.list("/"))do a8.remove(au)end;W(a,"Formatting finished",1)end,1))end;n(as,1,I("Set as bootable",function()A(ap)end,1))a6(aq.." ("..ap..")",as)end,1))end;a6("Select filesystem",an)end),I("Shutdown",function()v()end),a5()}if u then n(am,2,I("Internet recovery",function()local a9,aa,a2,a3=j(u).request("https://raw.githubusercontent.com/IgorTimofeev/MineOS/master/Installer/Main.lua"),""if a9 then W(a,"Downloading recovery script")while 1 do a2,a3=a9.read(q)if a2 then aa=aa..a2 else a9.close()if a3 then W(a,a3,1)else a1(aa,"=string")end;break end end else W(a,"invalid URL-address",1)end end))end;a6(a,am)end end;local a8=j(B())if not(a8 and a4(a8))then for ap in k(d)do a8=j(ap)if a4(a8)then break else a8=nil end end;if not a8 then W(a,"No bootable mediums found",1)end end;v() \ No newline at end of file diff --git a/Libraries/System.lua b/Libraries/System.lua index d4953c17..654b124e 100755 --- a/Libraries/System.lua +++ b/Libraries/System.lua @@ -508,7 +508,7 @@ local function iconAnalyseExtension(icon, launchers) if icon.extension == ".lnk" then icon.shortcutPath = system.readShortcut(icon.path) icon.shortcutExtension = filesystem.extension(icon.shortcutPath) - icon.shortcutIsDirectory = filesystem.isDirectory(icon.shortcutPath) + icon.shortcutIsDirectory = icon.shortcutPath:sub(-1) == "/" icon.isShortcut = true local shortcutIcon = iconAnalyseExtension( @@ -580,8 +580,8 @@ function system.icon(x, y, path, textColor, selectionColor) } icon.path = path - icon.extension = filesystem.extension(icon.path) - icon.isDirectory = filesystem.isDirectory(icon.path) + icon.extension = filesystem.extension(path) + icon.isDirectory = path:sub(-1) == "/" icon.name = icon.isDirectory and filesystem.name(path):sub(1, -2) or filesystem.name(path) icon.nameWithoutExtension = filesystem.hideExtension(icon.name) icon.isShortcut = false @@ -879,7 +879,7 @@ local function iconOnRightClick(icon, e1, e2, e3, e4) for i = 1, #list do local path = paths.system.applications .. list[i] - if filesystem.isDirectory(path) and filesystem.extension(list[i]) == ".app" then + if path:sub(-1) == "/" and filesystem.extension(list[i]) == ".app" then subMenu:addItem(filesystem.hideExtension(list[i])).onTouch = function() setAssociation(path) end @@ -2572,7 +2572,7 @@ function system.authorize() local userList = filesystem.list(paths.system.users) local i = 1 while i <= #userList do - if filesystem.isDirectory(paths.system.users .. userList[i]) then + if userList[i]:sub(-1) == "/" then i = i + 1 else table.remove(userList, i)