· 5 years ago · Dec 28, 2020, 06:26 PM
1do
2 _G._OSVERSION = "OpenOS 1.6"
3
4 local component = component
5 local computer = computer
6 local unicode = unicode
7
8 -- Runlevel information.
9 local runlevel, shutdown = "S", computer.shutdown
10 computer.runlevel = function() return runlevel end
11 computer.shutdown = function(reboot)
12 runlevel = reboot and 6 or 0
13 if os.sleep then
14 computer.pushSignal("shutdown")
15 os.sleep(0.1) -- Allow shutdown processing.
16 end
17 shutdown(reboot)
18 end
19
20 -- Low level dofile implementation to read filesystem libraries.
21 local rom = {}
22 function rom.invoke(method, ...)
23 return component.invoke(computer.getBootAddress(), method, ...)
24 end
25 function rom.open(file) return rom.invoke("open", file) end
26 function rom.read(handle) return rom.invoke("read", handle, math.huge) end
27 function rom.close(handle) return rom.invoke("close", handle) end
28 function rom.inits() return ipairs(rom.invoke("list", "boot")) end
29 function rom.isDirectory(path) return rom.invoke("isDirectory", path) end
30
31 local screen = component.list('screen', true)()
32 for address in component.list('screen', true) do
33 if #component.invoke(address, 'getKeyboards') > 0 then
34 screen = address
35 break
36 end
37 end
38
39 _G.boot_screen = screen
40
41 -- Report boot progress if possible.
42 local gpu = component.list("gpu", true)()
43 local w, h
44 if gpu and screen then
45 component.invoke(gpu, "bind", screen)
46 w, h = component.invoke(gpu, "maxResolution")
47 component.invoke(gpu, "setResolution", w, h)
48 component.invoke(gpu, "setBackground", 0x000000)
49 component.invoke(gpu, "setForeground", 0xFFFFFF)
50 component.invoke(gpu, "fill", 1, 1, w, h, " ")
51 end
52 local y = 1
53 local function status(msg)
54 if gpu and screen then
55 component.invoke(gpu, "set", 1, y, msg)
56 if y == h then
57 component.invoke(gpu, "copy", 1, 2, w, h - 1, 0, -1)
58 component.invoke(gpu, "fill", 1, h, w, 1, " ")
59 else
60 y = y + 1
61 end
62 end
63 end
64
65 status("Booting " .. _OSVERSION .. "...")
66
67 -- Custom low-level loadfile/dofile implementation reading from our ROM.
68 local function loadfile(file)
69 status("> " .. file)
70 local handle, reason = rom.open(file)
71 if not handle then
72 error(reason)
73 end
74 local buffer = ""
75 repeat
76 local data, reason = rom.read(handle)
77 if not data and reason then
78 error(reason)
79 end
80 buffer = buffer .. (data or "")
81 until not data
82 rom.close(handle)
83 return load(buffer, "=" .. file)
84 end
85
86 local function dofile(file)
87 local program, reason = loadfile(file)
88 if program then
89 local result = table.pack(pcall(program))
90 if result[1] then
91 return table.unpack(result, 2, result.n)
92 else
93 error(result[2])
94 end
95 else
96 error(reason)
97 end
98 end
99
100 status("Initializing package management...")
101
102 -- Load file system related libraries we need to load other stuff moree
103 -- comfortably. This is basically wrapper stuff for the file streams
104 -- provided by the filesystem components.
105 local package = dofile("/lib/package.lua")
106
107 do
108 -- Unclutter global namespace now that we have the package module.
109 _G.component = nil
110 _G.computer = nil
111 _G.process = nil
112 _G.unicode = nil
113
114 -- Initialize the package module with some of our own APIs.
115 package.loaded.component = component
116 package.loaded.computer = computer
117 package.loaded.unicode = unicode
118 package.preload["buffer"] = loadfile("/lib/buffer.lua")
119 package.preload["filesystem"] = loadfile("/lib/filesystem.lua")
120
121 -- Inject the package and io modules into the global namespace, as in Lua.
122 _G.package = package
123 _G.io = loadfile("/lib/io.lua")()
124
125 --mark modules for delay loaded api
126 package.delayed["text"] = true
127 package.delayed["sh"] = true
128 package.delayed["transforms"] = true
129 package.delayed["term"] = true
130 end
131
132 status("Initializing file system...")
133
134 -- Mount the ROM and temporary file systems to allow working on the file
135 -- system module from this point on.
136 require("filesystem").mount(computer.getBootAddress(), "/")
137 package.preload={}
138
139 status("Running boot scripts...")
140
141 -- Run library startup scripts. These mostly initialize event handlers.
142 local scripts = {}
143 for _, file in rom.inits() do
144 local path = "boot/" .. file
145 if not rom.isDirectory(path) then
146 table.insert(scripts, path)
147 end
148 end
149 table.sort(scripts)
150 for i = 1, #scripts do
151 dofile(scripts[i])
152 end
153
154 status("Initializing components...")
155
156 for c, t in component.list() do
157 computer.pushSignal("component_added", c, t)
158 end
159 os.sleep(0.5) -- Allow signal processing by libraries.
160 status("Initializing system...")
161
162 computer.pushSignal("init") -- so libs know components are initialized.
163 require("event").pull(1, "init") -- Allow init processing.
164 runlevel = 1
165end
166
167while true do
168 local result, reason = xpcall(require("shell").getShell(), function(msg)
169 return tostring(msg).."\n"..debug.traceback()
170 end)
171 if not result then
172 io.stderr:write((reason ~= nil and tostring(reason) or "unknown error") .. "\n")
173 io.write("Press any key to continue.\n")
174 os.sleep(0.5)
175 require("event").pull("key")
176 end
177end