Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Mar 2015 02:17:08 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r280651 - projects/lua-bootloader/sys/boot/lua
Message-ID:  <201503260217.t2Q2H848055173@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Thu Mar 26 02:17:07 2015
New Revision: 280651
URL: https://svnweb.freebsd.org/changeset/base/280651

Log:
  Add Lua scripts written by Pedro.

Added:
  projects/lua-bootloader/sys/boot/lua/
  projects/lua-bootloader/sys/boot/lua/config.lua
  projects/lua-bootloader/sys/boot/lua/core.lua
  projects/lua-bootloader/sys/boot/lua/drawer.lua
  projects/lua-bootloader/sys/boot/lua/loader.lua
  projects/lua-bootloader/sys/boot/lua/menu.lua
  projects/lua-bootloader/sys/boot/lua/password.lua
  projects/lua-bootloader/sys/boot/lua/screen.lua

Added: projects/lua-bootloader/sys/boot/lua/config.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/lua-bootloader/sys/boot/lua/config.lua	Thu Mar 26 02:17:07 2015	(r280651)
@@ -0,0 +1,339 @@
+--[[
+ * Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ --]]
+config = {};
+modules = {};
+
+function config.setKey(k, n, v)
+    if modules[k] == nil then 
+        modules[k] = {};
+    end
+    modules[k][n] = v;
+end
+
+pattern_table = {
+    [1] = {
+        str = "^%s*(#.*)",
+        process = function(k, v)  end
+    },
+--  module_load="value"
+    [2] = {
+        str = "^%s*([%w_]+)_load%s*=%s*\"([%w%s%p]-)\"%s*(.*)", 
+        process = function(k, v) 
+            if modules[k] == nil then 
+                modules[k] = {};
+            end 
+            modules[k].load = string.upper(v);
+        end 
+    },
+--  module_name="value"
+    [3] = {
+        str = "^%s*([%w_]+)_name%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            config.setKey(k, "name", v);
+        end
+    }, 
+--  module_type="value"    
+    [4] = {
+        str = "^%s*([%w_]+)_type%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            config.setKey(k, "type", v);
+        end 
+    },
+--  module_flags="value"
+    [5] = {
+        str = "^%s*([%w_]+)_flags%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            config.setKey(k, "flags", v);
+        end
+    },
+--  module_before="value"
+    [6] = {
+        str = "^%s*([%w_]+)_before%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            config.setKey(k, "before", v);
+        end
+    },
+--  module_after="value"
+    [7] = {
+        str = "^%s*([%w_]+)_after%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            config.setKey(k, "after", v);
+        end
+    },
+--  module_error="value"
+    [8] = {
+        str = "^%s*([%w_]+)_error%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            config.setKey(k, "error", v);
+        end
+    },
+--  exec="command"
+    [9] = {
+        str = "^%s*exec%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            if loader.perform(k) ~= 0 then
+                print("Failed to exec '"..k.."'\n");
+            end
+        end
+    },
+--  env_var="value"
+    [10] = {
+        str = "^%s*([%w%p]+)%s*=%s*\"([%w%s%p]-)\"%s*(.*)",
+        process = function(k, v) 
+            if loader.perform("set "..k.."=\""..v.."\"") ~= 0 then
+                print("Failed to set '"..k.."' with value: "..v.."\n");
+            end
+        end
+    }
+};
+
+function config.isValidComment(c)
+    if c ~= nil then
+        local s = string.match(c, "^%s*#.*");
+        if s == nil then s = string.match(c, "^%s*$"); end
+        if s == nil then return false; end
+    end
+    return true;
+end
+
+function config.loadmod(mod, silent)
+    local status = true;
+    for k, v in pairs(mod) do
+        if v.load == "YES" then
+            local str = "load ";
+            if v.flags ~= nil then str = str .. v.flags .. " "; end
+            if v.type ~= nil then str = str .. "-t " .. v.type .. " "; end
+            if v.name ~= nil then str = str .. v.name; else str = str .. k; end
+            
+            if v.before ~= nil then
+                if loader.perform(v.before) ~= 0 then
+                    if not silent then
+                        print("Failed to execute '"..v.before.."' before loading '"..k.."'\n");
+                    end
+                    status = false;
+                end
+            end
+            
+            if loader.perform(str) ~= 0 then
+                if not silent then print("Failed to execute '" .. str .. "'\n"); end
+                if v.error ~= nil then
+                    loader.perform(v.error);
+                end 
+                status = false;
+            end
+            
+            if v.after ~= nil then
+                if loader.perform(v.after) ~= 0 then
+                    if not silent then 
+                        print("Failed to execute '"..v.after.."' after loading '"..k.."'\n");
+                    end
+                    status = false;
+                end
+            end
+            
+        else
+            --if not silent then print("Skiping module '".. k .. "'\n"); end
+        end
+    end
+    
+    return status;
+end
+
+function config.parse(name, silent)
+    local f = io.open(name);
+    if f == nil then
+        if not silent then print("Failed to open config : '" .. name.."'\n"); end
+        return false;
+    end
+    
+    local text;
+    local r;
+    
+    text, r = io.read(f);
+    
+    if text == nil then
+        if not silent then print("Failed to read confif : '" .. name.."'\n"); end
+        return false;
+    end
+    
+    local n = 1;
+    local status = true;
+    
+    for line in string.gmatch(text, "([^\n]+)") do
+    
+        if string.match(line, "^%s*$") == nil then
+            local found = false;
+            
+            for i, val in ipairs(pattern_table) do
+                local k, v, c = string.match(line, val.str);
+                if k ~= nil then
+                    found = true;
+                    
+                    if config.isValidComment(c) then
+                        val.process(k, v);
+                    else
+                        print("Malformed line ("..n.."):\n\t'"..line.."'\n");
+                        status = false;
+                    end
+                    
+                    break;
+                end
+            end
+            
+            if found == false then
+                print("Malformed line ("..n.."):\n\t'"..line.."'\n");
+                status = false;
+            end
+        end
+        n = n + 1;
+    end
+    
+    return status;
+end
+
+function config.loadkernel()
+    local flags = loader.getenv("kernel_options") or "";
+    local kernel = loader.getenv("kernel");
+    
+    
+    local try_load = function (names)
+        for name in names:gmatch("([^;]+)%s*;?") do
+            r = loader.perform("load "..flags.." "..name);
+            if r == 0 then
+                return name;
+            end
+        end
+        return nil;
+    end;
+    
+    local load_bootfile = function()
+        local bootfile = loader.getenv("bootfile");
+        
+        -- append default kernel name
+        if not bootfile then
+            bootfile = "kernel";
+        else
+            bootfile = bootfile..";kernel";
+        end
+        
+        return try_load(bootfile);
+    end;
+    
+    -- kernel not set, try load from default module_path
+    if kernel == nil then
+        local res = load_bootfile();
+        
+        if res ~= nil then
+            return true;
+        else
+            print("Failed to load kernel '"..res.."'\n");
+            return false;
+        end
+    else
+        local module_path = loader.getenv("module_path");
+        local res = nil;
+        
+        -- first try load kernel with module_path = /boot/${kernel}
+        -- then try load with module_path=${kernel}
+        local paths = {"/boot/"..kernel, kernel};
+        
+        for k,v in pairs(paths) do
+            
+            loader.perform("set module_path="..v);
+            res = load_bootfile();
+            
+            -- succeeded add path to module_path
+            if res ~= nil then
+                loader.perform("set module_path="..v..";"..module_path);
+                return true;
+            end
+        end
+        
+        -- failed to load with ${kernel} as a directory
+        -- try as a file
+        res = try_load(kernel);
+        if res ~= nil then
+            return true;
+        else
+            print("Failed to load kernel '"..res.."'\n");
+            return false;
+        end
+    end
+end
+
+
+function config.load(file)
+
+    if not file then file = "/boot/defaults/loader.conf"; end
+    
+    if not config.parse(file) then 
+        print("Failed to parse configuration: '"..file.."'\n");
+    end
+    
+    local f = loader.getenv("loader_conf_files");
+    if f ~= nil then
+        for name in string.gmatch(f, "([%w%p]+)%s*") do
+            if not config.parse(name) then 
+                print("Failed to parse configuration: '"..name.."'\n");
+            end
+        end
+    end
+
+    print("Loading kernel . . .\n");
+    config.loadkernel();
+
+    print("Loading configurations . . .\n");
+    if config.loadmod(modules) then
+        print("Configurations loaded successful!\n");
+    else
+        print("Configurations load failed!\n");
+    end
+end
+
+function config.reload(kernel)
+    local res = 1;
+    
+    -- unload all modules
+    print("unloading modules . . .\n");
+    loader.perform("unload");
+    
+    if kernel ~= nil then
+        res = loader.perform("load "..kernel);
+        if res == 0 then print("Kernel '"..kernel.."' loaded!"); end
+    end
+    
+    -- failed to load kernel or it is nil
+    -- then load default
+    if res == 1 then
+        print("loading default kernel\n");
+        config.loadkernel();
+    end
+    
+    -- load modules
+    config.loadmod(modules);
+end
\ No newline at end of file

Added: projects/lua-bootloader/sys/boot/lua/core.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/lua-bootloader/sys/boot/lua/core.lua	Thu Mar 26 02:17:07 2015	(r280651)
@@ -0,0 +1,151 @@
+--[[
+ * Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ --]]
+core = {};
+
+function core.setVerbose(b)
+    if (b == nil) then
+        b = not core.verbose;
+    end
+
+    if (b == true) then
+        loader.perform("set boot_verbose=YES");
+    else
+        loader.perform("unset boot_verbose");
+    end
+    core.verbose = b;
+end
+
+function core.setSingleUser(b)
+    if (b == nil) then
+        b = not core.su;
+    end
+
+    if (b == true) then
+        loader.perform("set boot_single=YES");
+    else
+        loader.perform("unset boot_single");
+    end
+    core.su = b;
+end
+
+function core.setACPI(b)
+    if (b == nil) then
+        b = not core.acpi;
+    end
+    
+    if (b == true) then
+        loader.perform("set acpi_load=YES");
+        loader.perform("set hint.acpi.0.disabled=0");
+        loader.perform("unset loader.acpi_disabled_by_user");
+    else
+        loader.perform("unset acpi_load");
+        loader.perform("set hint.acpi.0.disabled=1");
+        loader.perform("set loader.acpi_disabled_by_user=1");
+    end
+    core.acpi = b;
+end
+
+function core.setSafeMode(b)
+    if (b == nil) then
+        b = not core.sm;
+    end
+    if (b == true) then
+        loader.perform("set kern.smp.disabled=1");
+        loader.perform("set hw.ata.ata_dma=0");
+        loader.perform("set hw.ata.atapi_dma=0");
+        loader.perform("set hw.ata.wc=0");
+        loader.perform("set hw.eisa_slots=0");
+        loader.perform("set kern.eventtimer.periodic=1");
+        loader.perform("set kern.geom.part.check_integrity=0");
+    else
+        loader.perform("unset kern.smp.disabled");
+        loader.perform("unset hw.ata.ata_dma");
+        loader.perform("unset hw.ata.atapi_dma");
+        loader.perform("unset hw.ata.wc");
+        loader.perform("unset hw.eisa_slots");
+        loader.perform("unset kern.eventtimer.periodic");
+        loader.perform("unset kern.geom.part.check_integrity");
+    end
+    core.sm = b;
+end
+
+function core.kernelList()
+    local k = loader.getenv("kernel");
+    local v = loader.getenv("kernels") or "";
+    
+    local kernels = {};
+    local i = 0;
+    if k ~= nil then
+        i = i + 1;
+        kernels[i] = k;
+    end
+    
+    for n in v:gmatch("([^; ]+)[; ]?") do
+        if n ~= k then
+            i = i + 1;
+            kernels[i] = n;
+        end
+    end
+    return kernels;
+end
+
+function core.setDefaults()
+    core.setACPI(true);
+    core.setSafeMode(false);
+    core.setSingleUser(false);
+    core.setVerbose(false);
+end
+
+function core.autoboot()
+    loader.perform("autoboot");
+end
+
+function core.boot()
+    loader.perform("boot");
+end
+
+function core.bootserial()
+    local c = loader.getenv("console");
+
+    if c ~= nil then
+        if c:find("comconsole") ~= nil then
+            return true;
+        end
+    end
+    
+    local s = loader.getenv("boot_serial");
+    if s ~= nil then
+        return true;
+    end
+
+    local m = loader.getenv("boot_multicons");
+    if m ~= nil then
+        return true;
+    end
+    return false;
+end
\ No newline at end of file

Added: projects/lua-bootloader/sys/boot/lua/drawer.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/lua-bootloader/sys/boot/lua/drawer.lua	Thu Mar 26 02:17:07 2015	(r280651)
@@ -0,0 +1,195 @@
+--[[
+ * Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ --]]
+include("/boot/screen.lua");
+drawer = {};
+
+drawer.brand_position = {x = 2, y = 1};
+drawer.fbsd_logo = {
+    "  ______               ____   _____ _____  ",
+    " |  ____|             |  _ \\ / ____|  __ \\ ",
+    " | |___ _ __ ___  ___ | |_) | (___ | |  | |",
+    " |  ___| '__/ _ \\/ _ \\|  _ < \\___ \\| |  | |",
+    " | |   | | |  __/  __/| |_) |____) | |__| |",
+    " | |   | | |    |    ||     |      |      |",
+    " |_|   |_|  \\___|\\___||____/|_____/|_____/ "
+};
+
+drawer.logo_position = {x = 46, y = 4};
+drawer.beastie_color = {
+    "               \027[31m,        ,",
+    "              /(        )`",
+    "              \\ \\___   / |",
+    "              /- \027[37m_\027[31m  `-/  '",
+    "             (\027[37m/\\/ \\\027[31m \\   /\\",
+    "             \027[37m/ /   |\027[31m `    \\",
+    "             \027[34mO O   \027[37m) \027[31m/    |",
+    "             \027[37m`-^--'\027[31m`<     '",
+    "            (_.)  _  )   /",
+    "             `.___/`    /",
+    "               `-----' /",
+    "  \027[33m<----.\027[31m     __ / __   \\",
+    "  \027[33m<----|====\027[31mO)))\027[33m==\027[31m) \\) /\027[33m====|",
+    "  \027[33m<----'\027[31m    `--' `.__,' \\",
+    "               |        |",
+    "                \\       /       /\\",
+    "           \027[36m______\027[31m( (_  / \\______/",
+    "         \027[36m,'  ,-----'   |",
+    "         `--{__________)\027[37m"
+};
+
+drawer.beastie = {
+    "               ,        ,",
+    "              /(        )`",
+    "              \\ \\___   / |",
+    "              /- _  `-/  '",
+    "             (/\\/ \\ \\   /\\",
+    "             / /   | `    \\",
+    "             O O   ) /    |",
+    "             `-^--'`<     '",
+    "            (_.)  _  )   /",
+    "             `.___/`    /",
+    "               `-----' /",
+    "  <----.     __ / __   \\",
+    "  <----|====O)))==) \\) /====|",
+    "  <----'    `--' `.__,' \\",
+    "               |        |",
+    "                \\       /       /\\",
+    "           ______( (_  / \\______/",
+    "         ,'  ,-----'   |",
+    "         `--{__________)"
+};
+
+drawer.fbsd_logo_shift = {x = 5, y = 6};
+drawer.fbsd_logo_v = {
+    "  ______",
+    " |  ____| __ ___  ___ ",
+    " | |__ | '__/ _ \\/ _ \\",
+    " |  __|| | |  __/  __/",
+    " | |   | | |    |    |",
+    " |_|   |_|  \\___|\\___|",
+    "  ____   _____ _____",
+    " |  _ \\ / ____|  __ \\",
+    " | |_) | (___ | |  | |",
+    " |  _ < \\___ \\| |  | |",
+    " | |_) |____) | |__| |",
+    " |     |      |      |",
+    " |____/|_____/|_____/"
+};
+
+drawer.orb_shift = {x = 3, y = 0};
+drawer.orb_color = {
+    "  \027[31m```                        \027[31;1m`\027[31m",
+    " s` `.....---...\027[31;1m....--.```   -/\027[31m",
+    " +o   .--`         \027[31;1m/y:`      +.\027[31m",
+    "  yo`:.            \027[31;1m:o      `+-\027[31m",
+    "   y/               \027[31;1m-/`   -o/\027[31m",
+    "  .-                  \027[31;1m::/sy+:.\027[31m",
+    "  /                     \027[31;1m`--  /\027[31m",
+    " `:                          \027[31;1m:`\027[31m",
+    " `:                          \027[31;1m:`\027[31m",
+    "  /                          \027[31;1m/\027[31m",
+    "  .-                        \027[31;1m-.\027[31m",
+    "   --                      \027[31;1m-.\027[31m",
+    "    `:`                  \027[31;1m`:`",
+    "      \027[31;1m.--             `--.",
+    "         .---.....----.\027[37m"
+};
+
+drawer.orb = {
+    "  ```                        `",
+    " s` `.....---.......--.```   -/",
+    " +o   .--`         /y:`      +.",
+    "  yo`:.            :o      `+-",
+    "   y/               -/`   -o/",
+    "  .-                  ::/sy+:.",
+    "  /                     `--  /",
+    " `:                          :`",
+    " `:                          :`",
+    "  /                          /",
+    "  .-                        -.",
+    "   --                      -.",
+    "    `:`                  `:`",
+    "      .--             `--.",
+    "         .---.....----."
+};
+
+
+function drawer.draw(x, y, logo)
+    for i = 1, #logo do
+        screen.setcursor(x, y + i);
+        print(logo[i]);
+    end
+end
+
+function drawer.drawbrand()
+    local x = tonumber(loader.getenv("loader_brand_x"));
+    local y = tonumber(loader.getenv("loader_brand_y"));
+    
+    if not x then x = drawer.brand_position.x; end
+    if not y then y = drawer.brand_position.y; end
+    
+    local logo = load("return " .. tostring(loader.getenv("loader_brand")))();
+    if not logo then logo = drawer.fbsd_logo; end
+    drawer.draw(x, y, logo);
+end
+
+function drawer.drawlogo()
+    local x = tonumber(loader.getenv("loader_logo_x"));
+    local y = tonumber(loader.getenv("loader_logo_y"));
+    
+    if not x then x = drawer.logo_position.x; end
+    if not y then y = drawer.logo_position.y; end
+    
+    local logo = loader.getenv("loader_logo");
+    local s = {x = 0, y = 0};
+    local colored = color.isEnabled();
+    
+    if logo == "beastie" then
+        if colored then logo = drawer.beastie_color; end
+    elseif logo == "beastiebw" then
+        logo = drawer.beastie;
+    elseif logo == "fbsdbw" then
+        logo = drawer.fbsd_logo_v;
+        s = drawer.fbsd_logo_shift;
+    elseif logo == "orb" then
+        if colored then logo = drawer.orb_color; end
+        s = drawer.orb_shift;
+    elseif logo == "orbbw" then
+        logo = drawer.orb;
+        s = drawer.orb_shift;
+    elseif logo == "tribute" then
+        logo = drawer.fbsd_logo;
+    elseif logo == "tributebw" then
+        logo = drawer.fbsd_logo;
+    end
+    if not logo then
+        if colored then logo = drawer.orb_color;
+        else logo = drawer.orb; end
+    end
+    drawer.draw(x + s.x, y + s.y, logo);
+end
\ No newline at end of file

Added: projects/lua-bootloader/sys/boot/lua/loader.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/lua-bootloader/sys/boot/lua/loader.lua	Thu Mar 26 02:17:07 2015	(r280651)
@@ -0,0 +1,45 @@
+--[[
+ * Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ --]]
+LOADED = {};
+
+function include(filename)
+    if LOADED[filename] == nil then
+        loader.include(filename);
+        LOADED[filename] = true;
+    end
+end
+
+
+include("/boot/password.lua");
+include("/boot/config.lua");
+
+config.load();
+password.check();
+
+include("/boot/menu.lua");
+menu.run();

Added: projects/lua-bootloader/sys/boot/lua/menu.lua
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/lua-bootloader/sys/boot/lua/menu.lua	Thu Mar 26 02:17:07 2015	(r280651)
@@ -0,0 +1,310 @@
+--[[
+ * Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ --]]
+include("/boot/core.lua");
+include("/boot/config.lua");
+include("/boot/screen.lua");
+include("/boot/drawer.lua");
+
+menu = {};
+
+function menu.draw(x, y, opts)
+    screen.setcursor(x, y);
+    print("Boot Menu");
+    for k, v in pairs(opts) do
+        -- skip alias
+        if k ~= "alias" then
+            screen.setcursor(x, y + v.index);
+            local name = v.name;
+            
+            if (name == nil) then
+                name = v.getName();
+            end
+            print(k .. " - " .. name);
+        end
+    end
+end
+
+function menu.skip()
+    if core.bootserial() then
+        return true;
+    end
+    local c = string.lower(loader.getenv("console") or "");
+    if (c:match("^efi[ ;]") or c:match("[ ;]efi[ ;]")) ~= nil then
+        return true;
+    end
+
+    c = string.lower(loader.getenv("beastie_disable") or "");
+    return c == "yes";
+
+end
+
+function menu.run(opts)
+
+    if menu.skip() then
+        core.autoboot();
+        return;
+    end
+
+    if (opts == nil) then
+        opts = menu.options;
+    end
+    
+    local draw = function() 
+        screen.clear();
+        menu.draw(6, 11, opts);
+        menu.drawbox(4, 10, 40, 10);
+        drawer.drawbrand();
+        drawer.drawlogo();
+        screen.defcursor();
+    end
+    
+    draw();
+    menu.autoboot();
+    while true do
+        local ch = string.char(io.getchar());
+        if (opts[ch] ~= nil) then
+            local ret = opts[ch].func();
+            if (ret) then
+                print("Exiting menu!\n");
+                return;
+            end
+        else
+        --try alias key
+            if opts.alias ~= nil then
+                if opts.alias[ch] ~= nil then
+                    local ret = opts.alias[ch].func();
+                    if (ret) then
+                        print("Exiting menu!\n");
+                        return;
+                    end
+                end
+            end
+        end
+        draw();
+    end
+end
+
+function menu.drawbox(x, y, w, h)
+    local hl = string.char(0xCD);
+    local vl = string.char(0xBA);
+    
+    local tl = string.char(0xC9);
+    local bl = string.char(0xC8);
+    local tr = string.char(0xBB);
+    local br = string.char(0xBC);
+    
+    screen.setcursor(x, y); print(tl);
+    screen.setcursor(x, y+h); print(bl);
+    screen.setcursor(x+w, y); print(tr);
+    screen.setcursor(x+w, y+h); print(br);
+    
+    screen.setcursor(x+1, y);
+    for i = 0, w-2 do print(hl); end
+    screen.setcursor(x+1, y+h);
+    for i = 0, w-2 do print(hl); end
+    
+    
+    for i = 1, h-1 do screen.setcursor(x, y+i); print(vl); end
+    for i = 1, h-1 do screen.setcursor(x+w, y+i); print(vl); end
+end
+
+function menu.autoboot()
+    if menu.already_autoboot == true then
+        return;
+    end
+    menu.already_autoboot = true;
+    
+    local ab = loader.getenv("autoboot_delay");
+    if ab == "NO" or ab == "no" then
+        core.boot();
+    end
+    ab = tonumber(ab) or 10;
+    
+    local x = loader.getenv("loader_menu_timeout_x") or 5;
+    local y = loader.getenv("loader_menu_timeout_y") or 22;
+    
+    local endtime = loader.time() + ab;
+    local time;
+    repeat
+    
+        time = endtime - loader.time();
+        screen.setcursor(x, y);
+        print("Autoboot in "..time.." seconds, hit [Enter] to boot"
+            .." or any other key to stop     ");
+        screen.defcursor();
+        if io.ischar() then
+            local ch = io.getchar();
+            if ch == 13 then
+                break;
+            else
+                -- prevent autoboot when escaping to interpreter
+                loader.perform("set autoboot_delay=NO");
+                -- erase autoboot msg
+                screen.setcursor(0, y);
+                print("                                        "
+                    .."                                        ");
+                screen.defcursor();
+                return;
+            end
+        end
+
+        loader.delay(50000);
+    until time <= 0
+    core.boot();
+    
+end
+
+menu.options = {
+    -- Boot multi user
+    ["1"] = {
+        index = 1, 
+        name = "Boot Multi user "..color.highlight("[Enter]"), 
+        func = function () core.setSingleUser(false); core.boot(); end
+    },
+    -- boot single user
+    ["2"] = {
+        index = 2, 
+        name = "Boot "..color.highlight("S").."ingle user", 
+        func = function () core.setSingleUser(true); core.boot(); end
+    },
+    -- escape to interpreter
+    ["3"] = {
+        index = 3,
+        name = color.highlight("Esc").."ape to lua interpreter", 
+        func = function () return true; end
+    },
+    -- reboot
+    ["4"] = {
+        index = 4, 
+        name = color.highlight("R").."eboot", 
+        func = function () loader.perform("reboot"); end
+    },
+    -- boot options
+    ["5"] = {
+        index = 5, 
+        name = "Boot "..color.highlight("O").."ptions", 
+        func = function () menu.run(boot_options); return false; end
+    },
+    ["6"] = {
+        index = 6,
+        getName = function ()
+            local k = core.kernelList();
+            if #k == 0 then 
+                return "Kernels (not availabe)";
+            end
+            return "Kernels";
+        end,
+        func = function() 
+            local kernels = {};
+            local ker = core.kernelList();
+            if #ker == 0 then return false; end
+            
+            kernels["1"] = {
+                index = 1,
+                name = "Return to menu "..color.highlight("[Backspace]"),
+                func = function() return true; end
+            };
+            kernels.alias = {["\008"] = kernels["1"]};
+            for k, v in ipairs(ker) do
+                kernels[tostring(k+1)] = {
+                    index = k+1,
+                    name = v,
+                    func = function() config.reload(v); end
+                };
+            end
+            menu.run(kernels);
+            return false;
+        end
+    }
+};
+
+menu.options.alias = {
+    ["\013"] = menu.options["1"],
+    ["s"] = menu.options["2"],
+    ["\027"] = menu.options["3"],
+    ["r"] = menu.options["4"],
+    ["o"] = menu.options["5"]
+};

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503260217.t2Q2H848055173>