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 9-- notice, this list of conditions and the following disclaimer. 10-- 2. Redistributions in binary form must reproduce the above copyright 11-- notice, this list of conditions and the following disclaimer in the 12-- documentation and/or other materials provided with the distribution. 13-- 14-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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'); 30 31local core = {}; 32 33-- Commonly appearing constants 34core.KEY_BACKSPACE = 8; 35core.KEY_ENTER = 13; 36core.KEY_DELETE = 127; 37 38core.KEYSTR_ESCAPE = "\027"; 39 40core.MENU_RETURN = "return"; 41core.MENU_ENTRY = "entry"; 42core.MENU_SEPARATOR = "separator"; 43core.MENU_SUBMENU = "submenu"; 44core.MENU_CAROUSEL_ENTRY = "carousel_entry"; 45 46function core.setVerbose(b) 47 if (b == nil) then 48 b = not core.verbose; 49 end 50 51 if (b == true) then 52 loader.setenv("boot_verbose", "YES"); 53 else 54 loader.unsetenv("boot_verbose"); 55 end 56 core.verbose = b; 57end 58 59function core.setSingleUser(b) 60 if (b == nil) then 61 b = not core.su; 62 end 63 64 if (b == true) then 65 loader.setenv("boot_single", "YES"); 66 else 67 loader.unsetenv("boot_single"); 68 end 69 core.su = b; 70end 71 72function core.getACPIPresent(checkingSystemDefaults) 73 local c = loader.getenv("hint.acpi.0.rsdp"); 74 75 if (c ~= nil) then 76 if (checkingSystemDefaults == true) then 77 return true; 78 end 79 -- Otherwise, respect disabled if it's set 80 c = loader.getenv("hint.acpi.0.disabled"); 81 return (c == nil) or (tonumber(c) ~= 1); 82 end 83 return false; 84end 85 86function core.setACPI(b) 87 if (b == nil) then 88 b = not core.acpi; 89 end 90 91 if (b == true) then 92 loader.setenv("acpi_load", "YES"); 93 loader.setenv("hint.acpi.0.disabled", "0"); 94 loader.unsetenv("loader.acpi_disabled_by_user"); 95 else 96 loader.unsetenv("acpi_load"); 97 loader.setenv("hint.acpi.0.disabled", "1"); 98 loader.setenv("loader.acpi_disabled_by_user", "1"); 99 end 100 core.acpi = b; 101end 102 103function core.setSafeMode(b) 104 if (b == nil) then 105 b = not core.sm; 106 end 107 if (b == true) then 108 loader.setenv("kern.smp.disabled", "1"); 109 loader.setenv("hw.ata.ata_dma", "0"); 110 loader.setenv("hw.ata.atapi_dma", "0"); 111 loader.setenv("hw.ata.wc", "0"); 112 loader.setenv("hw.eisa_slots", "0"); 113 loader.setenv("kern.eventtimer.periodic", "1"); 114 loader.setenv("kern.geom.part.check_integrity", "0"); 115 else 116 loader.unsetenv("kern.smp.disabled"); 117 loader.unsetenv("hw.ata.ata_dma"); 118 loader.unsetenv("hw.ata.atapi_dma"); 119 loader.unsetenv("hw.ata.wc"); 120 loader.unsetenv("hw.eisa_slots"); 121 loader.unsetenv("kern.eventtimer.periodic"); 122 loader.unsetenv("kern.geom.part.check_integrity"); 123 end 124 core.sm = b; 125end 126 127function core.kernelList() 128 local k = loader.getenv("kernel"); 129 local v = loader.getenv("kernels") or ""; 130 131 local kernels = {}; 132 local unique = {}; 133 local i = 0; 134 if (k ~= nil) then 135 i = i + 1; 136 kernels[i] = k; 137 unique[k] = true; 138 end 139 140 for n in v:gmatch("([^; ]+)[; ]?") do 141 if (unique[n] == nil) then 142 i = i + 1; 143 kernels[i] = n; 144 unique[n] = true; 145 end 146 end 147 148 -- Automatically detect other bootable kernel directories using a 149 -- heuristic. Any directory in /boot that contains an ordinary file 150 -- named "kernel" is considered eligible. 151 for file in lfs.dir("/boot") do 152 local fname = "/boot/" .. file; 153 154 if (file == "." or file == "..") then 155 goto continue; 156 end 157 158 if (lfs.attributes(fname, "mode") ~= "directory") then 159 goto continue; 160 end 161 162 if (lfs.attributes(fname .. "/kernel", "mode") ~= "file") then 163 goto continue; 164 end 165 166 if (unique[file] == nil) then 167 i = i + 1; 168 kernels[i] = file; 169 unique[file] = true; 170 end 171 172 ::continue:: 173 end 174 return kernels; 175end 176 177function core.setDefaults() 178 core.setACPI(core.getACPIPresent(true)); 179 core.setSafeMode(false); 180 core.setSingleUser(false); 181 core.setVerbose(false); 182end 183 184function core.autoboot() 185 config.loadelf(); 186 loader.perform("autoboot"); 187end 188 189function core.boot() 190 config.loadelf(); 191 loader.perform("boot"); 192end 193 194function core.bootserial() 195 local c = loader.getenv("console"); 196 197 if (c ~= nil) then 198 if (c:find("comconsole") ~= nil) then 199 return true; 200 end 201 end 202 203 local s = loader.getenv("boot_serial"); 204 if (s ~= nil) then 205 return true; 206 end 207 208 local m = loader.getenv("boot_multicons"); 209 if (m ~= nil) then 210 return true; 211 end 212 return false; 213end 214 215core.setACPI(core.getACPIPresent(false)); 216return core; 217