xref: /freebsd/stand/lua/core.lua (revision b57465454b35f6e24a6df02a93a27d0136c016d9)
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