core.lua (6d3bcc06e27a9f0c860770442b50dd9650dc8e24) | core.lua (aedd6be5c7c3096828fafa6c1528f3966b9e3aa5) |
---|---|
1-- 2-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> 3-- All rights reserved. 4-- 5-- Redistribution and use in source and binary forms, with or without 6-- modification, are permitted provided that the following conditions 7-- are met: 8-- 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24-- SUCH DAMAGE. 25-- 26-- $FreeBSD$ 27-- 28 | 1-- 2-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> 3-- All rights reserved. 4-- 5-- Redistribution and use in source and binary forms, with or without 6-- modification, are permitted provided that the following conditions 7-- are met: 8-- 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24-- SUCH DAMAGE. 25-- 26-- $FreeBSD$ 27-- 28 |
29local config = require('config'); | 29local config = require('config') |
30 | 30 |
31local core = {}; | 31local core = {} |
32 33local compose_loader_cmd = function(cmd_name, argstr) 34 if (argstr ~= nil) then | 32 33local compose_loader_cmd = function(cmd_name, argstr) 34 if (argstr ~= nil) then |
35 cmd_name = cmd_name .. " " .. argstr; | 35 cmd_name = cmd_name .. " " .. argstr |
36 end | 36 end |
37 return cmd_name; | 37 return cmd_name |
38end 39 40-- Internal function 41-- Parses arguments to boot and returns two values: kernel_name, argstr 42-- Defaults to nil and "" respectively. 43-- This will also parse arguments to autoboot, but the with_kernel argument 44-- will need to be explicitly overwritten to false 45local parse_boot_args = function(argv, with_kernel) 46 if (#argv == 0) then | 38end 39 40-- Internal function 41-- Parses arguments to boot and returns two values: kernel_name, argstr 42-- Defaults to nil and "" respectively. 43-- This will also parse arguments to autoboot, but the with_kernel argument 44-- will need to be explicitly overwritten to false 45local parse_boot_args = function(argv, with_kernel) 46 if (#argv == 0) then |
47 return nil, ""; | 47 return nil, "" |
48 end 49 if (with_kernel == nil) then | 48 end 49 if (with_kernel == nil) then |
50 with_kernel = true; | 50 with_kernel = true |
51 end | 51 end |
52 local kernel_name; 53 local argstr = ""; | 52 local kernel_name 53 local argstr = "" |
54 55 for k, v in ipairs(argv) do 56 if (with_kernel) and (v:sub(1,1) ~= "-") then | 54 55 for k, v in ipairs(argv) do 56 if (with_kernel) and (v:sub(1,1) ~= "-") then |
57 kernel_name = v; | 57 kernel_name = v |
58 else | 58 else |
59 argstr = argstr .. " " .. v; | 59 argstr = argstr .. " " .. v |
60 end 61 end 62 if (with_kernel) then | 60 end 61 end 62 if (with_kernel) then |
63 return kernel_name, argstr; | 63 return kernel_name, argstr |
64 else | 64 else |
65 return argstr; | 65 return argstr |
66 end 67end 68 69-- Globals 70function boot(...) | 66 end 67end 68 69-- Globals 70function boot(...) |
71 local argv = {...}; 72 local cmd_name = ""; 73 cmd_name, argv = core.popFrontTable(argv); 74 local kernel, argstr = parse_boot_args(argv); | 71 local argv = {...} 72 local cmd_name = "" 73 cmd_name, argv = core.popFrontTable(argv) 74 local kernel, argstr = parse_boot_args(argv) |
75 if (kernel ~= nil) then | 75 if (kernel ~= nil) then |
76 loader.perform("unload"); 77 config.selectkernel(kernel); | 76 loader.perform("unload") 77 config.selectkernel(kernel) |
78 end | 78 end |
79 core.boot(argstr); | 79 core.boot(argstr) |
80end 81 82function autoboot(...) 83 local argv = {...} | 80end 81 82function autoboot(...) 83 local argv = {...} |
84 local cmd_name = ""; 85 cmd_name, argv = core.popFrontTable(argv); 86 local argstr = parse_boot_args(argv, false); 87 core.autoboot(argstr); | 84 local cmd_name = "" 85 cmd_name, argv = core.popFrontTable(argv) 86 local argstr = parse_boot_args(argv, false) 87 core.autoboot(argstr) |
88end 89 90-- Module exports 91-- Commonly appearing constants | 88end 89 90-- Module exports 91-- Commonly appearing constants |
92core.KEY_BACKSPACE = 8; 93core.KEY_ENTER = 13; 94core.KEY_DELETE = 127; | 92core.KEY_BACKSPACE = 8 93core.KEY_ENTER = 13 94core.KEY_DELETE = 127 |
95 | 95 |
96core.KEYSTR_ESCAPE = "\027"; | 96core.KEYSTR_ESCAPE = "\027" |
97 | 97 |
98core.MENU_RETURN = "return"; 99core.MENU_ENTRY = "entry"; 100core.MENU_SEPARATOR = "separator"; 101core.MENU_SUBMENU = "submenu"; 102core.MENU_CAROUSEL_ENTRY = "carousel_entry"; | 98core.MENU_RETURN = "return" 99core.MENU_ENTRY = "entry" 100core.MENU_SEPARATOR = "separator" 101core.MENU_SUBMENU = "submenu" 102core.MENU_CAROUSEL_ENTRY = "carousel_entry" |
103 104function core.setVerbose(b) 105 if (b == nil) then | 103 104function core.setVerbose(b) 105 if (b == nil) then |
106 b = not core.verbose; | 106 b = not core.verbose |
107 end 108 109 if (b == true) then | 107 end 108 109 if (b == true) then |
110 loader.setenv("boot_verbose", "YES"); | 110 loader.setenv("boot_verbose", "YES") |
111 else | 111 else |
112 loader.unsetenv("boot_verbose"); | 112 loader.unsetenv("boot_verbose") |
113 end | 113 end |
114 core.verbose = b; | 114 core.verbose = b |
115end 116 117function core.setSingleUser(b) 118 if (b == nil) then | 115end 116 117function core.setSingleUser(b) 118 if (b == nil) then |
119 b = not core.su; | 119 b = not core.su |
120 end 121 122 if (b == true) then | 120 end 121 122 if (b == true) then |
123 loader.setenv("boot_single", "YES"); | 123 loader.setenv("boot_single", "YES") |
124 else | 124 else |
125 loader.unsetenv("boot_single"); | 125 loader.unsetenv("boot_single") |
126 end | 126 end |
127 core.su = b; | 127 core.su = b |
128end 129 130function core.getACPIPresent(checkingSystemDefaults) | 128end 129 130function core.getACPIPresent(checkingSystemDefaults) |
131 local c = loader.getenv("hint.acpi.0.rsdp"); | 131 local c = loader.getenv("hint.acpi.0.rsdp") |
132 133 if (c ~= nil) then 134 if (checkingSystemDefaults == true) then | 132 133 if (c ~= nil) then 134 if (checkingSystemDefaults == true) then |
135 return true; | 135 return true |
136 end 137 -- Otherwise, respect disabled if it's set | 136 end 137 -- Otherwise, respect disabled if it's set |
138 c = loader.getenv("hint.acpi.0.disabled"); 139 return (c == nil) or (tonumber(c) ~= 1); | 138 c = loader.getenv("hint.acpi.0.disabled") 139 return (c == nil) or (tonumber(c) ~= 1) |
140 end | 140 end |
141 return false; | 141 return false |
142end 143 144function core.setACPI(b) 145 if (b == nil) then | 142end 143 144function core.setACPI(b) 145 if (b == nil) then |
146 b = not core.acpi; | 146 b = not core.acpi |
147 end 148 149 if (b == true) then | 147 end 148 149 if (b == true) then |
150 loader.setenv("acpi_load", "YES"); 151 loader.setenv("hint.acpi.0.disabled", "0"); 152 loader.unsetenv("loader.acpi_disabled_by_user"); | 150 loader.setenv("acpi_load", "YES") 151 loader.setenv("hint.acpi.0.disabled", "0") 152 loader.unsetenv("loader.acpi_disabled_by_user") |
153 else | 153 else |
154 loader.unsetenv("acpi_load"); 155 loader.setenv("hint.acpi.0.disabled", "1"); 156 loader.setenv("loader.acpi_disabled_by_user", "1"); | 154 loader.unsetenv("acpi_load") 155 loader.setenv("hint.acpi.0.disabled", "1") 156 loader.setenv("loader.acpi_disabled_by_user", "1") |
157 end | 157 end |
158 core.acpi = b; | 158 core.acpi = b |
159end 160 161function core.setSafeMode(b) 162 if (b == nil) then | 159end 160 161function core.setSafeMode(b) 162 if (b == nil) then |
163 b = not core.sm; | 163 b = not core.sm |
164 end 165 if (b == true) then | 164 end 165 if (b == true) then |
166 loader.setenv("kern.smp.disabled", "1"); 167 loader.setenv("hw.ata.ata_dma", "0"); 168 loader.setenv("hw.ata.atapi_dma", "0"); 169 loader.setenv("hw.ata.wc", "0"); 170 loader.setenv("hw.eisa_slots", "0"); 171 loader.setenv("kern.eventtimer.periodic", "1"); 172 loader.setenv("kern.geom.part.check_integrity", "0"); | 166 loader.setenv("kern.smp.disabled", "1") 167 loader.setenv("hw.ata.ata_dma", "0") 168 loader.setenv("hw.ata.atapi_dma", "0") 169 loader.setenv("hw.ata.wc", "0") 170 loader.setenv("hw.eisa_slots", "0") 171 loader.setenv("kern.eventtimer.periodic", "1") 172 loader.setenv("kern.geom.part.check_integrity", "0") |
173 else | 173 else |
174 loader.unsetenv("kern.smp.disabled"); 175 loader.unsetenv("hw.ata.ata_dma"); 176 loader.unsetenv("hw.ata.atapi_dma"); 177 loader.unsetenv("hw.ata.wc"); 178 loader.unsetenv("hw.eisa_slots"); 179 loader.unsetenv("kern.eventtimer.periodic"); 180 loader.unsetenv("kern.geom.part.check_integrity"); | 174 loader.unsetenv("kern.smp.disabled") 175 loader.unsetenv("hw.ata.ata_dma") 176 loader.unsetenv("hw.ata.atapi_dma") 177 loader.unsetenv("hw.ata.wc") 178 loader.unsetenv("hw.eisa_slots") 179 loader.unsetenv("kern.eventtimer.periodic") 180 loader.unsetenv("kern.geom.part.check_integrity") |
181 end | 181 end |
182 core.sm = b; | 182 core.sm = b |
183end 184 185function core.kernelList() | 183end 184 185function core.kernelList() |
186 local k = loader.getenv("kernel"); 187 local v = loader.getenv("kernels") or ""; | 186 local k = loader.getenv("kernel") 187 local v = loader.getenv("kernels") or "" |
188 | 188 |
189 local kernels = {}; 190 local unique = {}; 191 local i = 0; | 189 local kernels = {} 190 local unique = {} 191 local i = 0 |
192 if (k ~= nil) then | 192 if (k ~= nil) then |
193 i = i + 1; 194 kernels[i] = k; 195 unique[k] = true; | 193 i = i + 1 194 kernels[i] = k 195 unique[k] = true |
196 end 197 198 for n in v:gmatch("([^; ]+)[; ]?") do 199 if (unique[n] == nil) then | 196 end 197 198 for n in v:gmatch("([^; ]+)[; ]?") do 199 if (unique[n] == nil) then |
200 i = i + 1; 201 kernels[i] = n; 202 unique[n] = true; | 200 i = i + 1 201 kernels[i] = n 202 unique[n] = true |
203 end 204 end 205 206 -- Automatically detect other bootable kernel directories using a 207 -- heuristic. Any directory in /boot that contains an ordinary file 208 -- named "kernel" is considered eligible. 209 for file in lfs.dir("/boot") do | 203 end 204 end 205 206 -- Automatically detect other bootable kernel directories using a 207 -- heuristic. Any directory in /boot that contains an ordinary file 208 -- named "kernel" is considered eligible. 209 for file in lfs.dir("/boot") do |
210 local fname = "/boot/" .. file; | 210 local fname = "/boot/" .. file |
211 212 if (file == "." or file == "..") then | 211 212 if (file == "." or file == "..") then |
213 goto continue; | 213 goto continue |
214 end 215 216 if (lfs.attributes(fname, "mode") ~= "directory") then | 214 end 215 216 if (lfs.attributes(fname, "mode") ~= "directory") then |
217 goto continue; | 217 goto continue |
218 end 219 220 if (lfs.attributes(fname .. "/kernel", "mode") ~= "file") then | 218 end 219 220 if (lfs.attributes(fname .. "/kernel", "mode") ~= "file") then |
221 goto continue; | 221 goto continue |
222 end 223 224 if (unique[file] == nil) then | 222 end 223 224 if (unique[file] == nil) then |
225 i = i + 1; 226 kernels[i] = file; 227 unique[file] = true; | 225 i = i + 1 226 kernels[i] = file 227 unique[file] = true |
228 end 229 230 ::continue:: 231 end | 228 end 229 230 ::continue:: 231 end |
232 return kernels; | 232 return kernels |
233end 234 235function core.setDefaults() | 233end 234 235function core.setDefaults() |
236 core.setACPI(core.getACPIPresent(true)); 237 core.setSafeMode(false); 238 core.setSingleUser(false); 239 core.setVerbose(false); | 236 core.setACPI(core.getACPIPresent(true)) 237 core.setSafeMode(false) 238 core.setSingleUser(false) 239 core.setVerbose(false) |
240end 241 242function core.autoboot(argstr) | 240end 241 242function core.autoboot(argstr) |
243 config.loadelf(); 244 loader.perform(compose_loader_cmd("autoboot", argstr)); | 243 config.loadelf() 244 loader.perform(compose_loader_cmd("autoboot", argstr)) |
245end 246 247function core.boot(argstr) | 245end 246 247function core.boot(argstr) |
248 config.loadelf(); 249 loader.perform(compose_loader_cmd("boot", argstr)); | 248 config.loadelf() 249 loader.perform(compose_loader_cmd("boot", argstr)) |
250end 251 252function core.isSingleUserBoot() | 250end 251 252function core.isSingleUserBoot() |
253 local single_user = loader.getenv("boot_single"); 254 return single_user ~= nil and single_user:lower() == "yes"; | 253 local single_user = loader.getenv("boot_single") 254 return single_user ~= nil and single_user:lower() == "yes" |
255end 256 257function core.isSerialBoot() | 255end 256 257function core.isSerialBoot() |
258 local c = loader.getenv("console"); | 258 local c = loader.getenv("console") |
259 260 if (c ~= nil) then 261 if (c:find("comconsole") ~= nil) then | 259 260 if (c ~= nil) then 261 if (c:find("comconsole") ~= nil) then |
262 return true; | 262 return true |
263 end 264 end 265 | 263 end 264 end 265 |
266 local s = loader.getenv("boot_serial"); | 266 local s = loader.getenv("boot_serial") |
267 if (s ~= nil) then | 267 if (s ~= nil) then |
268 return true; | 268 return true |
269 end 270 | 269 end 270 |
271 local m = loader.getenv("boot_multicons"); | 271 local m = loader.getenv("boot_multicons") |
272 if (m ~= nil) then | 272 if (m ~= nil) then |
273 return true; | 273 return true |
274 end | 274 end |
275 return false; | 275 return false |
276end 277 278function core.isSystem386() | 276end 277 278function core.isSystem386() |
279 return (loader.machine_arch == "i386"); | 279 return (loader.machine_arch == "i386") |
280end 281 282-- This may be a better candidate for a 'utility' module. 283function core.shallowCopyTable(tbl) | 280end 281 282-- This may be a better candidate for a 'utility' module. 283function core.shallowCopyTable(tbl) |
284 local new_tbl = {}; | 284 local new_tbl = {} |
285 for k, v in pairs(tbl) do 286 if (type(v) == "table") then | 285 for k, v in pairs(tbl) do 286 if (type(v) == "table") then |
287 new_tbl[k] = core.shallowCopyTable(v); | 287 new_tbl[k] = core.shallowCopyTable(v) |
288 else | 288 else |
289 new_tbl[k] = v; | 289 new_tbl[k] = v |
290 end 291 end | 290 end 291 end |
292 return new_tbl; | 292 return new_tbl |
293end 294 295-- XXX This should go away if we get the table lib into shape for importing. 296-- As of now, it requires some 'os' functions, so we'll implement this in lua 297-- for our uses 298function core.popFrontTable(tbl) 299 -- Shouldn't reasonably happen 300 if (#tbl == 0) then | 293end 294 295-- XXX This should go away if we get the table lib into shape for importing. 296-- As of now, it requires some 'os' functions, so we'll implement this in lua 297-- for our uses 298function core.popFrontTable(tbl) 299 -- Shouldn't reasonably happen 300 if (#tbl == 0) then |
301 return nil, nil; | 301 return nil, nil |
302 elseif (#tbl == 1) then | 302 elseif (#tbl == 1) then |
303 return tbl[1], {}; | 303 return tbl[1], {} |
304 end 305 | 304 end 305 |
306 local first_value = tbl[1]; 307 local new_tbl = {}; | 306 local first_value = tbl[1] 307 local new_tbl = {} |
308 -- This is not a cheap operation 309 for k, v in ipairs(tbl) do 310 if (k > 1) then | 308 -- This is not a cheap operation 309 for k, v in ipairs(tbl) do 310 if (k > 1) then |
311 new_tbl[k - 1] = v; | 311 new_tbl[k - 1] = v |
312 end 313 end 314 | 312 end 313 end 314 |
315 return first_value, new_tbl; | 315 return first_value, new_tbl |
316end 317 318-- On i386, hint.acpi.0.rsdp will be set before we're loaded. On !i386, it will 319-- generally be set upon execution of the kernel. Because of this, we can't (or 320-- don't really want to) detect/disable ACPI on !i386 reliably. Just set it 321-- enabled if we detect it and leave well enough alone if we don't. 322if (core.isSystem386()) and (core.getACPIPresent(false)) then | 316end 317 318-- On i386, hint.acpi.0.rsdp will be set before we're loaded. On !i386, it will 319-- generally be set upon execution of the kernel. Because of this, we can't (or 320-- don't really want to) detect/disable ACPI on !i386 reliably. Just set it 321-- enabled if we detect it and leave well enough alone if we don't. 322if (core.isSystem386()) and (core.getACPIPresent(false)) then |
323 core.setACPI(true); | 323 core.setACPI(true) |
324end | 324end |
325return core; | 325return core |