1088b4f5fSWarner Losh-- 2088b4f5fSWarner Losh-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> 3088b4f5fSWarner Losh-- All rights reserved. 4088b4f5fSWarner Losh-- 5088b4f5fSWarner Losh-- Redistribution and use in source and binary forms, with or without 6088b4f5fSWarner Losh-- modification, are permitted provided that the following conditions 7088b4f5fSWarner Losh-- are met: 8088b4f5fSWarner Losh-- 1. Redistributions of source code must retain the above copyright 9088b4f5fSWarner Losh-- notice, this list of conditions and the following disclaimer. 10088b4f5fSWarner Losh-- 2. Redistributions in binary form must reproduce the above copyright 11088b4f5fSWarner Losh-- notice, this list of conditions and the following disclaimer in the 12088b4f5fSWarner Losh-- documentation and/or other materials provided with the distribution. 13088b4f5fSWarner Losh-- 14088b4f5fSWarner Losh-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15088b4f5fSWarner Losh-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16088b4f5fSWarner Losh-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17088b4f5fSWarner Losh-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18088b4f5fSWarner Losh-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19088b4f5fSWarner Losh-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20088b4f5fSWarner Losh-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21088b4f5fSWarner Losh-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22088b4f5fSWarner Losh-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23088b4f5fSWarner Losh-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24088b4f5fSWarner Losh-- SUCH DAMAGE. 25088b4f5fSWarner Losh-- 26088b4f5fSWarner Losh-- $FreeBSD$ 27088b4f5fSWarner Losh-- 28088b4f5fSWarner Losh 29fa4a2394SKyle Evanslocal config = require('config'); 30fa4a2394SKyle Evans 31088b4f5fSWarner Loshlocal core = {}; 32088b4f5fSWarner Losh 33*b5746545SKyle Evans-- Module exports 34fe672a15SKyle Evans-- Commonly appearing constants 351504bce3SKyle Evanscore.KEY_BACKSPACE = 8; 3627fac8ffSKyle Evanscore.KEY_ENTER = 13; 371504bce3SKyle Evanscore.KEY_DELETE = 127; 38fe672a15SKyle Evans 3939006570SKyle Evanscore.KEYSTR_ESCAPE = "\027"; 4039006570SKyle Evans 41a7cf0562SKyle Evanscore.MENU_RETURN = "return"; 42a7cf0562SKyle Evanscore.MENU_ENTRY = "entry"; 43a7cf0562SKyle Evanscore.MENU_SEPARATOR = "separator"; 44a7cf0562SKyle Evanscore.MENU_SUBMENU = "submenu"; 45a7cf0562SKyle Evanscore.MENU_CAROUSEL_ENTRY = "carousel_entry"; 46a7cf0562SKyle Evans 47088b4f5fSWarner Loshfunction core.setVerbose(b) 48088b4f5fSWarner Losh if (b == nil) then 49088b4f5fSWarner Losh b = not core.verbose; 50088b4f5fSWarner Losh end 51088b4f5fSWarner Losh 52088b4f5fSWarner Losh if (b == true) then 53088b4f5fSWarner Losh loader.setenv("boot_verbose", "YES"); 54088b4f5fSWarner Losh else 55088b4f5fSWarner Losh loader.unsetenv("boot_verbose"); 56088b4f5fSWarner Losh end 57088b4f5fSWarner Losh core.verbose = b; 58088b4f5fSWarner Loshend 59088b4f5fSWarner Losh 60088b4f5fSWarner Loshfunction core.setSingleUser(b) 61088b4f5fSWarner Losh if (b == nil) then 62088b4f5fSWarner Losh b = not core.su; 63088b4f5fSWarner Losh end 64088b4f5fSWarner Losh 65088b4f5fSWarner Losh if (b == true) then 66088b4f5fSWarner Losh loader.setenv("boot_single", "YES"); 67088b4f5fSWarner Losh else 68088b4f5fSWarner Losh loader.unsetenv("boot_single"); 69088b4f5fSWarner Losh end 70088b4f5fSWarner Losh core.su = b; 71088b4f5fSWarner Loshend 72088b4f5fSWarner Losh 736401094fSKyle Evansfunction core.getACPIPresent(checkingSystemDefaults) 746401094fSKyle Evans local c = loader.getenv("hint.acpi.0.rsdp"); 756401094fSKyle Evans 766401094fSKyle Evans if (c ~= nil) then 776401094fSKyle Evans if (checkingSystemDefaults == true) then 786401094fSKyle Evans return true; 796401094fSKyle Evans end 806401094fSKyle Evans -- Otherwise, respect disabled if it's set 816401094fSKyle Evans c = loader.getenv("hint.acpi.0.disabled"); 826401094fSKyle Evans return (c == nil) or (tonumber(c) ~= 1); 836401094fSKyle Evans end 846401094fSKyle Evans return false; 856401094fSKyle Evansend 866401094fSKyle Evans 87088b4f5fSWarner Loshfunction core.setACPI(b) 88088b4f5fSWarner Losh if (b == nil) then 89088b4f5fSWarner Losh b = not core.acpi; 90088b4f5fSWarner Losh end 91088b4f5fSWarner Losh 92088b4f5fSWarner Losh if (b == true) then 93088b4f5fSWarner Losh loader.setenv("acpi_load", "YES"); 94088b4f5fSWarner Losh loader.setenv("hint.acpi.0.disabled", "0"); 95088b4f5fSWarner Losh loader.unsetenv("loader.acpi_disabled_by_user"); 96088b4f5fSWarner Losh else 97088b4f5fSWarner Losh loader.unsetenv("acpi_load"); 98088b4f5fSWarner Losh loader.setenv("hint.acpi.0.disabled", "1"); 99088b4f5fSWarner Losh loader.setenv("loader.acpi_disabled_by_user", "1"); 100088b4f5fSWarner Losh end 101088b4f5fSWarner Losh core.acpi = b; 102088b4f5fSWarner Loshend 103088b4f5fSWarner Losh 104088b4f5fSWarner Loshfunction core.setSafeMode(b) 105088b4f5fSWarner Losh if (b == nil) then 106088b4f5fSWarner Losh b = not core.sm; 107088b4f5fSWarner Losh end 108088b4f5fSWarner Losh if (b == true) then 109088b4f5fSWarner Losh loader.setenv("kern.smp.disabled", "1"); 110088b4f5fSWarner Losh loader.setenv("hw.ata.ata_dma", "0"); 111088b4f5fSWarner Losh loader.setenv("hw.ata.atapi_dma", "0"); 112088b4f5fSWarner Losh loader.setenv("hw.ata.wc", "0"); 113088b4f5fSWarner Losh loader.setenv("hw.eisa_slots", "0"); 114088b4f5fSWarner Losh loader.setenv("kern.eventtimer.periodic", "1"); 115088b4f5fSWarner Losh loader.setenv("kern.geom.part.check_integrity", "0"); 116088b4f5fSWarner Losh else 117088b4f5fSWarner Losh loader.unsetenv("kern.smp.disabled"); 118088b4f5fSWarner Losh loader.unsetenv("hw.ata.ata_dma"); 119088b4f5fSWarner Losh loader.unsetenv("hw.ata.atapi_dma"); 120088b4f5fSWarner Losh loader.unsetenv("hw.ata.wc"); 121088b4f5fSWarner Losh loader.unsetenv("hw.eisa_slots"); 122088b4f5fSWarner Losh loader.unsetenv("kern.eventtimer.periodic"); 123088b4f5fSWarner Losh loader.unsetenv("kern.geom.part.check_integrity"); 124088b4f5fSWarner Losh end 125088b4f5fSWarner Losh core.sm = b; 126088b4f5fSWarner Loshend 127088b4f5fSWarner Losh 128088b4f5fSWarner Loshfunction core.kernelList() 129088b4f5fSWarner Losh local k = loader.getenv("kernel"); 130088b4f5fSWarner Losh local v = loader.getenv("kernels") or ""; 131088b4f5fSWarner Losh 132088b4f5fSWarner Losh local kernels = {}; 133a108046fSConrad Meyer local unique = {}; 134088b4f5fSWarner Losh local i = 0; 13524a1bd54SKyle Evans if (k ~= nil) then 136088b4f5fSWarner Losh i = i + 1; 137088b4f5fSWarner Losh kernels[i] = k; 138a108046fSConrad Meyer unique[k] = true; 139088b4f5fSWarner Losh end 140088b4f5fSWarner Losh 141088b4f5fSWarner Losh for n in v:gmatch("([^; ]+)[; ]?") do 142a108046fSConrad Meyer if (unique[n] == nil) then 143088b4f5fSWarner Losh i = i + 1; 144088b4f5fSWarner Losh kernels[i] = n; 145a108046fSConrad Meyer unique[n] = true; 146088b4f5fSWarner Losh end 147088b4f5fSWarner Losh end 148a108046fSConrad Meyer 149a108046fSConrad Meyer -- Automatically detect other bootable kernel directories using a 150a108046fSConrad Meyer -- heuristic. Any directory in /boot that contains an ordinary file 151a108046fSConrad Meyer -- named "kernel" is considered eligible. 152a108046fSConrad Meyer for file in lfs.dir("/boot") do 153a108046fSConrad Meyer local fname = "/boot/" .. file; 154a108046fSConrad Meyer 155a108046fSConrad Meyer if (file == "." or file == "..") then 156a108046fSConrad Meyer goto continue; 157a108046fSConrad Meyer end 158a108046fSConrad Meyer 159a108046fSConrad Meyer if (lfs.attributes(fname, "mode") ~= "directory") then 160a108046fSConrad Meyer goto continue; 161a108046fSConrad Meyer end 162a108046fSConrad Meyer 163a108046fSConrad Meyer if (lfs.attributes(fname .. "/kernel", "mode") ~= "file") then 164a108046fSConrad Meyer goto continue; 165a108046fSConrad Meyer end 166a108046fSConrad Meyer 167a108046fSConrad Meyer if (unique[file] == nil) then 168a108046fSConrad Meyer i = i + 1; 169a108046fSConrad Meyer kernels[i] = file; 170a108046fSConrad Meyer unique[file] = true; 171a108046fSConrad Meyer end 172a108046fSConrad Meyer 173a108046fSConrad Meyer ::continue:: 174a108046fSConrad Meyer end 175088b4f5fSWarner Losh return kernels; 176088b4f5fSWarner Loshend 177088b4f5fSWarner Losh 178088b4f5fSWarner Loshfunction core.setDefaults() 1796401094fSKyle Evans core.setACPI(core.getACPIPresent(true)); 180088b4f5fSWarner Losh core.setSafeMode(false); 181088b4f5fSWarner Losh core.setSingleUser(false); 182088b4f5fSWarner Losh core.setVerbose(false); 183088b4f5fSWarner Loshend 184088b4f5fSWarner Losh 185088b4f5fSWarner Loshfunction core.autoboot() 186fa4a2394SKyle Evans config.loadelf(); 187088b4f5fSWarner Losh loader.perform("autoboot"); 188088b4f5fSWarner Loshend 189088b4f5fSWarner Losh 190088b4f5fSWarner Loshfunction core.boot() 191fa4a2394SKyle Evans config.loadelf(); 192088b4f5fSWarner Losh loader.perform("boot"); 193088b4f5fSWarner Loshend 194088b4f5fSWarner Losh 195e07fc39cSKyle Evansfunction core.isSingleUserBoot() 196e07fc39cSKyle Evans local single_user = loader.getenv("boot_single"); 197e07fc39cSKyle Evans return single_user ~= nil and single_user:lower() == "yes"; 198e07fc39cSKyle Evansend 199e07fc39cSKyle Evans 200b140d14bSKyle Evansfunction core.isSerialBoot() 201088b4f5fSWarner Losh local c = loader.getenv("console"); 202088b4f5fSWarner Losh 20324a1bd54SKyle Evans if (c ~= nil) then 20424a1bd54SKyle Evans if (c:find("comconsole") ~= nil) then 205088b4f5fSWarner Losh return true; 206088b4f5fSWarner Losh end 207088b4f5fSWarner Losh end 208088b4f5fSWarner Losh 209088b4f5fSWarner Losh local s = loader.getenv("boot_serial"); 21024a1bd54SKyle Evans if (s ~= nil) then 211088b4f5fSWarner Losh return true; 212088b4f5fSWarner Losh end 213088b4f5fSWarner Losh 214088b4f5fSWarner Losh local m = loader.getenv("boot_multicons"); 21524a1bd54SKyle Evans if (m ~= nil) then 216088b4f5fSWarner Losh return true; 217088b4f5fSWarner Losh end 218088b4f5fSWarner Losh return false; 219088b4f5fSWarner Loshend 220088b4f5fSWarner Losh 2215c1b5165SKyle Evans-- This may be a better candidate for a 'utility' module. 2225c1b5165SKyle Evansfunction core.shallowCopyTable(tbl) 2235c1b5165SKyle Evans local new_tbl = {}; 2245c1b5165SKyle Evans for k, v in pairs(tbl) do 2255c1b5165SKyle Evans if (type(v) == "table") then 2265c1b5165SKyle Evans new_tbl[k] = core.shallowCopyTable(v); 2275c1b5165SKyle Evans else 2285c1b5165SKyle Evans new_tbl[k] = v; 2295c1b5165SKyle Evans end 2305c1b5165SKyle Evans end 2315c1b5165SKyle Evans return new_tbl; 2325c1b5165SKyle Evansend 2335c1b5165SKyle Evans 2346f412147SKyle Evans-- On i386, hint.acpi.0.rsdp will be set before we're loaded. On !i386, it will 2356f412147SKyle Evans-- generally be set upon execution of the kernel. Because of this, we can't (or 2366f412147SKyle Evans-- don't really want to) detect/disable ACPI on !i386 reliably. Just set it 2376f412147SKyle Evans-- enabled if we detect it and leave well enough alone if we don't. 2386f412147SKyle Evansif (core.getACPIPresent(false)) then 2396f412147SKyle Evans core.setACPI(true); 2406f412147SKyle Evansend 24124a1bd54SKyle Evansreturn core; 242