summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-07-05 14:23:50 -0700
committerH. Peter Anvin <hpa@zytor.com>2010-07-05 14:23:50 -0700
commit7072cf57e5f43449223c1fe75aebcbf82659e515 (patch)
treeddb56c4504a5f5f0c38e9dc71e9a707932d21d85
parent9a332c5f03c9f9cc81f6c247c6d248a715f6eabb (diff)
parent6841745fa86a45405de9bdd0e453f4abb26398b7 (diff)
downloadsyslinux-7072cf57e5f43449223c1fe75aebcbf82659e515.tar.gz
syslinux-7072cf57e5f43449223c1fe75aebcbf82659e515.tar.xz
syslinux-7072cf57e5f43449223c1fe75aebcbf82659e515.zip
Merge remote branch 'marcel/luaext'
Merge Marcel Ritter's work on the lua branch: The last time he wrote about the state of his lua branch: http://syslinux.zytor.com/archives/2009-October/013383.html The current state is: - VESA: - switching to vesa mode works - loading/displaying images works - display text works (s. com32/lua/test/vesa.lua) - PCI: - list PC devices + ID - get human-readable device name for device (s. com32/lua/test/pci.lua) - DMI: - get DMI info (BIOS, Hardware, etc). (s. com32/lua/test/dmi.lua) - syslinux: - loading files, kernel, initrd - start kernel, initrd, local boot ... just working on this, so no example lua file right now Most of the actual merging work was done by Gert Hulselmans <gerth@zytor.com>. Resolved Conflicts: com32/lib/sys/vesa/initvesa.c com32/lua/src/Makefile Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/lua/doc/syslinux.asc273
-rw-r--r--com32/lua/src/Makefile8
-rw-r--r--com32/lua/src/linit.c2
-rw-r--r--com32/lua/src/lualib.h7
-rw-r--r--com32/lua/src/pci.c183
-rw-r--r--com32/lua/src/syslinux.c417
-rw-r--r--com32/lua/src/vesa.c148
-rw-r--r--com32/lua/test/pci.lua34
-rw-r--r--com32/lua/test/vesa.lua55
9 files changed, 1116 insertions, 11 deletions
diff --git a/com32/lua/doc/syslinux.asc b/com32/lua/doc/syslinux.asc
new file mode 100644
index 00000000..71593066
--- /dev/null
+++ b/com32/lua/doc/syslinux.asc
@@ -0,0 +1,273 @@
+Syslinux LUA User Guide
+=======================
+Marcel Ritter <Marcel.Ritter@rrze.uni-erlangen.de>
+
+Invocation
+----------
+
+Running +lua.c32+ only results in an interactive shell.
+......................................................
+KERNEL lua.c32
+......................................................
+
+By using the +APPEND+ parameter you can specify a lua
+script to be executed:
+......................................................
+KERNEL lua.c32
+APPEND /testit.lua
+......................................................
+
+Modules
+-------
+
+SYSLINUX
+~~~~~~~~
+
+.syslinux.sleep(ms)
+
+Sleep for +ms+ milliseconds
+
+.run_command(command)
+
+Execute syslinux command line +command+.
+
+_Example_:
+......................................................
+ syslinux.run_command("memdisk initrd=/dos/BIOS/FSC-P7935-108.img raw")
+......................................................
+
+.run_default()
+
+FIXME
+
+.local_boot()
+
+FIXME
+
+.final_cleanup()
+
+FIXME
+
+.boot_linux(kernel, cmdline, [mem_limit], [videomode])
+
+FIXME
+
+.run_kernel_image(kernel, cmdline, ipappend_flags, type)
+
+FIXME
+
+.loadfile(filname)
+
+Load file +filename+ (via TFTP)
+
+.filesize(file)
+
+Return size of +file+ (loaded by loadfile())
+
+.filename(file)
+
+Return name of +file+ (loaded by loadfile())
+
+.in itramfs_init()
+
+Return empty initramfs object
+
+.initramfs_load_archive(initramfs, filename)
+
+Load contents of +filename+ into +initramfs+. Initialize
++initramfs+ with initramfs_init() before use.
+
+.initramfs_add_file(initramfs, file)
+
+Adds +file+ to +initramfs+. +initramfs+ needs to be
+initialized, +file+ has been loaded by loadfile().
+
+_Example_:
+......................................................
+ -- get nice output
+ printf = function(s,...)
+ return io.write(s:format(...))
+ end -- function
+
+ kernel = syslinux.loadfile("/SuSE-11.1/x86_64/linux")
+
+ printf("Filename/size: %s %d\n", syslinux.filename(kernel), syslinux.filesize(kernel))
+
+ initrd = syslinux.loadfile("/SuSE-11.1/x86_64/initrd")
+
+ printf("Filename/size: %s %d\n", syslinux.filename(initrd), syslinux.filesize(initrd))
+
+ initrd = syslinux.initramfs_init()
+ syslinux.initramfs_load_archive(initrd, "/SuSE-11.1/x86_64/initrd");
+
+ syslinux.boot_it(kernel, initrd, "init=/bin/bash")
+
+ syslinux.sleep(20000)
+
+......................................................
+
+
+
+DMI
+~~~
+
+.dmi_supported()
+
+Returns +true+ if DMI is supported on machine, +false+ otherwise.
+
+.dmi_gettable()
+
+Returns a list if key-value pairs. The key is one of the DMI property strings:
+FIXME list
+
+_Example_:
+......................................................
+ if (dmi.supported()) then
+
+ dmitable = dmi.gettable()
+
+ for k,v in pairs(dmitable) do
+ print(k, v)
+ end
+
+ print(dmitable["system.manufacturer"])
+ print(dmitable["system.product_name"])
+ print(dmitable["bios.bios_revision"])
+
+ if ( string.match(dmitable["system.product_name"], "ESPRIMO P7935") ) then
+ print("Matches")
+ syslinux.run_command("memdisk initrd=/dos/BIOS/FSC-P7935-108.img raw")
+ else
+ print("Does not match")
+ syslinux.run_command("memdisk initrd=/dos/BIOS/FSC-P7935-108.img raw")
+ end
+
+ end
+
+......................................................
+
+
+PCI
+~~~
+
+.pci_getinfo()
+
+Return list of value pairs (device_index, device) of all PCI devices.
+
+.pci_getidlist(filename)
+
+Load a tab separated list of PCI IDs and their description.
+Sample files can be found here: http://pciids.sourceforge.net/
+
+
+_Example_:
+......................................................
+-- get nice output
+printf = function(s,...)
+ return io.write(s:format(...))
+ end
+
+-- get device info
+pciinfo = pci.getinfo()
+
+-- get plain text device description
+pciids = pci.getidlist("/pci.ids")
+
+-- list all pci busses
+for dind,device in pairs(pciinfo) do
+
+ -- search for device description
+ search = string.format("%04x%04x", device['vendor'], device['product'])
+
+ printf(" %04x:%04x:%04x:%04x = ", device['vendor'], device['product'],
+ device['sub_vendor'], device['sub_product'])
+
+ if ( pciids[search] ) then
+ printf("%s\n", pciids[search])
+ else
+ printf("Unknown\n")
+ end
+end
+
+-- print(pciids["8086"])
+-- print(pciids["10543009"])
+-- print(pciids["00700003"])
+-- print(pciids["0070e817"])
+-- print(pciids["1002437a1002437a"])
+......................................................
+
+
+VESA
+~~~~
+
+.getmodes()
+
+Return list of available VESA modes.
+
+_Example_:
+......................................................
+ -- get nice output
+ printf = function(s,...)
+ return io.write(s:format(...))
+ end
+
+ -- list available vesa modes
+ -- only one supported right now, not of much use
+ modes = vesa.getmodes()
+
+ for mind,mode in pairs(modes) do
+ printf("%04x: %dx%dx%d\n", mode['mode'], mode['hres'], mode['vres'], mode['bpp'])
+ end
+......................................................
+
+
+.setmode()
+
+Set (only currently supported) VESA mode.
+
+.load_background(filename)
+
+Load +filename+ from TFTP, and use it as background image.
+
+_Example_:
+......................................................
+ -- get nice output
+ printf = function(s,...)
+ return io.write(s:format(...))
+ end
+
+ -- lets go to graphics land
+ vesa.setmode()
+
+ printf("Hello World! - VESA mode")
+
+ -- some text to display "typing style"
+ textline=[[
+ From syslinux GSOC 2009 home page:
+
+ Finish the Lua engine
+
+ We already have a Lua interpreter integrated with the Syslinux build. However, right now it is not very useful. We need to create a set of bindings to the Syslinux functionality, and have an array of documentation and examples so users can use them.
+
+ This is not a documentation project, but the documentation deliverable will be particularly important for this one, since the intended target is system administrators, not developers.
+ ]]
+
+
+ -- do display loop
+ -- keep in mind: background change will not erase text!
+ while ( true ) do
+
+ vesa.load_background("/background1.jpg")
+
+ syslinux.sleep(1000)
+
+ for i = 1, #textline do
+ local c = textline:sub(i,i)
+ printf("%s", c)
+ syslinux.sleep(200)
+ end
+
+ syslinux.sleep(10000)
+
+......................................................
+
diff --git a/com32/lua/src/Makefile b/com32/lua/src/Makefile
index ac7824a5..eac3b281 100644
--- a/com32/lua/src/Makefile
+++ b/com32/lua/src/Makefile
@@ -21,6 +21,9 @@ include ../../MCONFIG
LIBS = ../../lib/libcom32.a $(LIBGCC)
LNXLIBS =
+# Temporarily allow warnings not being treated as errors
+GCCWARN += -Wno-error
+
MODULES = lua.c32
TESTFILES =
@@ -38,6 +41,11 @@ LIBLUA_OBJS += lstrlib.o loadlib.o linit.o
LIBLUA_OBJS += liolib.o
LIBLUA_OBJS += dmi.o
+LIBLUA_OBJS += pci.o
+LIBLUA_OBJS += vesa.o
+# For function sleep() -- XXX: FIX THIS
+LIBLUA_OBJS += ../../cmenu/libmenu/com32io.o
+
CFLAGS += -DLUA_ANSI
all: $(MODULES) $(TESTFILES)
diff --git a/com32/lua/src/linit.c b/com32/lua/src/linit.c
index e457ee8d..3f15fd05 100644
--- a/com32/lua/src/linit.c
+++ b/com32/lua/src/linit.c
@@ -24,9 +24,11 @@ static const luaL_Reg lualibs[] = {
#if !defined LUA_NUMBER_INTEGRAL
{LUA_MATHLIBNAME, luaopen_math},
#endif
+ {LUA_PCILIBNAME, luaopen_pci},
{LUA_DBLIBNAME, luaopen_debug},
{LUA_DMILIBNAME, luaopen_dmi},
{LUA_SYSLINUXLIBNAME, luaopen_syslinux},
+ {LUA_VESALIBNAME, luaopen_vesa},
{NULL, NULL}
};
diff --git a/com32/lua/src/lualib.h b/com32/lua/src/lualib.h
index 8e220ef1..e169a0f9 100644
--- a/com32/lua/src/lualib.h
+++ b/com32/lua/src/lualib.h
@@ -33,6 +33,9 @@ LUALIB_API int (luaopen_string) (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUALIB_API int (luaopen_math) (lua_State *L);
+#define LUA_PCILIBNAME "pci"
+LUALIB_API int (luaopen_pci) (lua_State *L);
+
#define LUA_DBLIBNAME "debug"
LUALIB_API int (luaopen_debug) (lua_State *L);
@@ -45,6 +48,10 @@ LUALIB_API int (luaopen_syslinux) (lua_State *L);
#define LUA_DMILIBNAME "dmi"
LUALIB_API int (luaopen_dmi) (lua_State *L);
+#define LUA_VESALIBNAME "vesa"
+LUALIB_API int (luaopen_vesa) (lua_State *L);
+
+
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);
diff --git a/com32/lua/src/pci.c b/com32/lua/src/pci.c
new file mode 100644
index 00000000..b9c1605e
--- /dev/null
+++ b/com32/lua/src/pci.c
@@ -0,0 +1,183 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lpcilib_c /* Define the library */
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include <sys/pci.h>
+
+
+static int pci_getinfo(lua_State *L)
+{
+ struct pci_domain *pci_domain;
+ struct pci_device *pci_device;
+ int pci_dev = 1;
+
+ pci_domain = pci_scan();
+
+ lua_newtable(L); /* list of busses */
+
+ for_each_pci_func(pci_device, pci_domain) {
+ lua_pushnumber(L, pci_dev++);
+
+ lua_newtable(L); /* device infos */
+
+ lua_pushstring(L, "bus");
+ lua_pushnumber(L, __pci_bus);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "slot");
+ lua_pushnumber(L, __pci_slot);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "func");
+ lua_pushnumber(L, __pci_func);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "vendor");
+ lua_pushnumber(L, pci_device->vendor);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "product");
+ lua_pushnumber(L, pci_device->product);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "sub_vendor");
+ lua_pushnumber(L, pci_device->sub_vendor);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "sub_product");
+ lua_pushnumber(L, pci_device->sub_product);
+ lua_settable(L,-3);
+
+ lua_settable(L,-3); /* end device infos */
+ }
+
+ return 1;
+}
+
+/* searching the next char that is not a space */
+static char *skipspace(char *p)
+{
+ while (*p && *p <= ' ')
+ p++;
+
+ return p;
+}
+
+/* removing any \n found in a string */
+static void remove_eol(char *string)
+{
+ int j = strlen(string);
+ int i = 0;
+ for(i = 0; i < j; i++) if(string[i] == '\n') string[i] = 0;
+}
+
+
+/* Try to match any pci device to the appropriate kernel module */
+/* it uses the modules.pcimap from the boot device*/
+static int pci_getidlist(lua_State *L)
+{
+ const char *pciidfile;
+ char line[1024];
+ char vendor[255];
+ char vendor_id[5];
+ char product[255];
+ char productvendor[9];
+ char productvendorsub[17];
+ FILE *f;
+
+ if (lua_gettop(L) == 1) {
+ pciidfile = luaL_checkstring(L, 1);
+ } else {
+ pciidfile = "pci.ids";
+ }
+
+ lua_newtable(L); /* list of vendors */
+
+ /* Opening the pci.ids from the boot device*/
+ f=fopen(pciidfile,"r");
+ if (!f)
+ return -1;
+
+ /* for each line we found in the pci.ids*/
+ while ( fgets(line, sizeof line, f) ) {
+ /* Skipping uncessary lines */
+ if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 'C') ||
+ (line[0] == 10))
+ continue;
+
+ /* If the line doesn't start with a tab, it means that's a vendor id */
+ if (line[0] != '\t') {
+
+ /* the 4th first chars are the vendor_id */
+ strlcpy(vendor_id,line,4);
+
+ /* the vendor name is the next field*/
+ vendor_id[4]=0;
+ strlcpy(vendor,skipspace(strstr(line," ")),255);
+ remove_eol(vendor);
+
+ /* ffff is an invalid vendor id */
+ if (strstr(vendor_id,"ffff")) break;
+
+ lua_pushstring(L, vendor_id);
+ lua_pushstring(L, vendor);
+ lua_settable(L,-3);
+
+ /* if we have a tab + a char, it means this is a product id */
+ } else if ((line[0] == '\t') && (line[1] != '\t')) {
+
+ /* the product name the second field */
+ strlcpy(product,skipspace(strstr(line," ")),255);
+ remove_eol(product);
+
+ /* the 4th first chars are the vendor_id */
+ strlcpy(productvendor,vendor_id,4);
+ /* the product id is first field */
+ strlcpy(productvendor+4,&line[1],4);
+ productvendor[8]=0;
+
+ lua_pushstring(L, productvendor);
+ lua_pushstring(L, product);
+ lua_settable(L,-3);
+
+ /* if we have two tabs, it means this is a sub product */
+ } else if ((line[0] == '\t') && (line[1] == '\t')) {
+
+ /* the product name is last field */
+ strlcpy(product,skipspace(strstr(line," ")),255);
+ strlcpy(product,skipspace(strstr(product," ")),255);
+ remove_eol(product);
+
+ strlcpy(productvendorsub, productvendor,8);
+ strlcpy(productvendorsub+8, &line[2],4);
+ strlcpy(productvendorsub+12, &line[7],4);
+ productvendorsub[16]=0;
+
+ lua_pushstring(L, productvendorsub);
+ lua_pushstring(L, product);
+ lua_settable(L,-3);
+
+ }
+ }
+ fclose(f);
+ return(1);
+}
+
+static const luaL_reg pcilib[] = {
+ {"getinfo", pci_getinfo},
+ {"getidlist", pci_getidlist},
+ {NULL, NULL}
+};
+
+/* This defines a function that opens up your library. */
+
+LUALIB_API int luaopen_pci (lua_State *L) {
+ luaL_openlib(L, LUA_PCILIBNAME, pcilib, 0);
+ return 1;
+}
+
diff --git a/com32/lua/src/syslinux.c b/com32/lua/src/syslinux.c
index 91b719eb..be061c4c 100644
--- a/com32/lua/src/syslinux.c
+++ b/com32/lua/src/syslinux.c
@@ -1,30 +1,425 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
#include <stdlib.h>
#include <string.h>
#include <syslinux/boot.h>
-#define lnetlib_c /* Define the library */
+#define lnetlib_c /* Define the library */
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
+#include "syslinux/boot.h"
+#include "syslinux/loadfile.h"
+#include "syslinux/linux.h"
+#include "../../cmenu/libmenu/com32io.h"
+
+int __parse_argv(char ***argv, const char *str);
+
+#define SYSLINUX_FILE "syslinux_file"
+
+typedef struct syslinux_file {
+ char *data;
+ char *name;
+ size_t size;
+} syslinux_file;
+
+/*
+ * Most code taken from:
+ * com32/modules/linux.c
+ */
+
+/* Find the last instance of a particular command line argument
+ (which should include the final =; do not use for boolean arguments) */
+static char *find_argument(char **argv, const char *argument)
+{
+ int la = strlen(argument);
+ char **arg;
+ char *ptr = NULL;
-static int sl_run_command(lua_State *L)
+ for (arg = argv; *arg; arg++) {
+ if (!memcmp(*arg, argument, la))
+ ptr = *arg + la;
+ }
+
+ return ptr;
+}
+
+/* Get a value with a potential suffix (k/m/g/t/p/e) */
+static unsigned long long suffix_number(const char *str)
{
- const char *cmd = luaL_checkstring(L, 1); /* Reads the string parameter */
- syslinux_run_command(cmd);
- return 0;
+ char *ep;
+ unsigned long long v;
+ int shift;
+
+ v = strtoull(str, &ep, 0);
+ switch (*ep | 0x20) {
+ case 'k':
+ shift = 10;
+ break;
+ case 'm':
+ shift = 20;
+ break;
+ case 'g':
+ shift = 30;
+ break;
+ case 't':
+ shift = 40;
+ break;
+ case 'p':
+ shift = 50;
+ break;
+ case 'e':
+ shift = 60;
+ break;
+ default:
+ shift = 0;
+ break;
+ }
+ v <<= shift;
+
+ return v;
}
+/* Truncate to 32 bits, with saturate */
+static inline uint32_t saturate32(unsigned long long v)
+{
+ return (v > 0xffffffff) ? 0xffffffff : (uint32_t) v;
+}
+
+/* Stitch together the command line from a set of argv's */
+static char *make_cmdline(char **argv)
+{
+ char **arg;
+ size_t bytes;
+ char *cmdline, *p;
+
+ bytes = 1; /* Just in case we have a zero-entry cmdline */
+ for (arg = argv; *arg; arg++) {
+ bytes += strlen(*arg) + 1;
+ }
+
+ p = cmdline = malloc(bytes);
+ if (!cmdline)
+ return NULL;
+
+ for (arg = argv; *arg; arg++) {
+ int len = strlen(*arg);
+ memcpy(p, *arg, len);
+ p[len] = ' ';
+ p += len + 1;
+ }
+
+ if (p > cmdline)
+ p--; /* Remove the last space */
+ *p = '\0';
+
+ return cmdline;
+}
+
+static int sl_run_command(lua_State * L)
+{
+ const char *cmd = luaL_checkstring(L, 1); /* Reads the string parameter */
+ syslinux_run_command(cmd);
+ return 0;
+}
+
+/* do default boot */
+static int sl_run_default(lua_State * L)
+{
+ syslinux_run_default();
+ return 0;
+}
+
+/* do local boot */
+static int sl_local_boot(lua_State * L)
+{
+ uint16_t flags = luaL_checkint(L, 1);
+ syslinux_local_boot(flags);
+ return 0;
+}
+
+static int sl_final_cleanup(lua_State * L)
+{
+ uint16_t flags = luaL_checkint(L, 1);
+ syslinux_local_boot(flags);
+ return 0;
+}
+
+/* boot linux kernel and initrd */
+static int sl_boot_linux(lua_State * L)
+{
+ const char *kernel = luaL_checkstring(L, 1);
+ const char *cmdline = luaL_optstring(L, 2, "");
+ char *initrd;
+ void *kernel_data, *file_data;
+ size_t kernel_len, file_len;
+ struct initramfs *initramfs;
+ char *newcmdline;
+ uint32_t mem_limit = luaL_optint(L, 3, 0);
+ uint16_t video_mode = luaL_optint(L, 4, 0);
+// int ret, i;
+ int ret;
+ char **argv, **argp, *arg, *p;
+
+ ret = __parse_argv(&argv, cmdline);
+
+ newcmdline = malloc(strlen(kernel) + 12);
+ if (!newcmdline)
+ printf("Mem alloc failed: cmdline\n");
+
+ strcpy(newcmdline, "BOOT_IMAGE=");
+ strcpy(newcmdline + strlen(newcmdline), kernel);
+ argv[0] = newcmdline;
+ argp = argv;
+
+ /* DEBUG
+ for (i=0; i<ret; i++)
+ printf("%d: %s\n", i, argv[i]);
+ */
+
+ newcmdline = make_cmdline(argp);
+ if (!newcmdline)
+ printf("Creating command line failed!\n");
+
+ /* DEBUG
+ printf("Command line: %s\n", newcmdline);
+ sleep(1000);
+ */
+
+ /* Look for specific command-line arguments we care about */
+ if ((arg = find_argument(argp, "mem=")))
+ mem_limit = saturate32(suffix_number(arg));
+
+ if ((arg = find_argument(argp, "vga="))) {
+ switch (arg[0] | 0x20) {
+ case 'a': /* "ask" */
+ video_mode = 0xfffd;
+ break;
+ case 'e': /* "ext" */
+ video_mode = 0xfffe;
+ break;
+ case 'n': /* "normal" */
+ video_mode = 0xffff;
+ break;
+ default:
+ video_mode = strtoul(arg, NULL, 0);
+ break;
+ }
+ }
+
+ printf("Loading kernel %s...\n", kernel);
+ if (loadfile(kernel, &kernel_data, &kernel_len))
+ printf("failed!\n");
+ else
+ printf("ok\n");
+
+ initramfs = initramfs_init();
+ if (!initramfs)
+ printf("Initializing initrd failed!\n");
+
+ if ((arg = find_argument(argp, "initrd="))) {
+ do {
+ p = strchr(arg, ',');
+ if (p)
+ *p = '\0';
+
+ initrd = arg;
+ printf("Loading initrd %s... ", initrd);
+ if (initramfs_load_archive(initramfs, initrd)) {
+ printf("failed!\n");
+ }
+ printf("ok\n");
+
+ if (p)
+ *p++ = ',';
+ } while ((arg = p));
+ }
+
+ if (!loadfile("/testfile1", &file_data, &file_len)) {
+ if (initramfs_add_file(initramfs, file_data, file_len, file_len,
+ "/testfile1", 0, 0755))
+ printf("Adding extra file failed\n");
+ } else
+ printf("Loading extra file failed\n");
+
+ /* DEBUG
+ sleep(10000);
+ */
+
+ ret = syslinux_boot_linux(kernel_data, kernel_len, initramfs, newcmdline);
+
+ printf("syslinux_boot_linux returned %d\n", ret);
+
+ return 0;
+}
+
+/* sleep for msec milliseconds */
+static int sl_sleep(lua_State * L)
+{
+ unsigned int msec = luaL_checkint(L, 1);
+ sleep(msec);
+ return 0;
+}
+
+static int sl_run_kernel_image(lua_State * L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ const char *cmdline = luaL_checkstring(L, 2);
+ uint32_t ipappend_flags = luaL_checkint(L, 3);
+ uint32_t type = luaL_checkint(L, 4);
+
+ syslinux_run_kernel_image(filename, cmdline, ipappend_flags, type);
+ return 0;
+}
+
+static int sl_loadfile(lua_State * L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ syslinux_file *file;
+
+ void *file_data;
+ size_t file_len;
+
+ if (loadfile(filename, &file_data, &file_len)) {
+ lua_pushstring(L, "Could not load file");
+ lua_error(L);
+ }
+
+ file = malloc(sizeof(syslinux_file));
+ file->name = filename;
+ file->size = file_len;
+ file->data = file_data;
+
+ lua_pushlightuserdata(L, file);
+ luaL_getmetatable(L, SYSLINUX_FILE);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+static int sl_filesize(lua_State * L)
+{
+ const syslinux_file *file = luaL_checkudata(L, 1, SYSLINUX_FILE);
+
+ lua_pushinteger(L, file->size);
+
+ return 1;
+}
+
+static int sl_filename(lua_State * L)
+{
+ const syslinux_file *file = luaL_checkudata(L, 1, SYSLINUX_FILE);
+
+ lua_pushstring(L, file->name);
+
+ return 1;
+}
+
+static int sl_initramfs_init(lua_State * L)
+{
+ struct initramfs *initramfs;
+
+ initramfs = initramfs_init();
+ if (!initramfs)
+ printf("Initializing initrd failed!\n");
+
+ lua_pushlightuserdata(L, initramfs);
+ luaL_getmetatable(L, SYSLINUX_FILE);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+static int sl_initramfs_load_archive(lua_State * L)
+{
+ const struct initramfs *initramfs = luaL_checkudata(L, 1, SYSLINUX_FILE);
+ const char *filename = luaL_checkstring(L, 2);
+
+ if (initramfs_load_archive(initramfs, filename)) {
+ printf("failed!\n");
+ }
+
+ return 0;
+}
+
+static int sl_initramfs_add_file(lua_State * L)
+{
+ const struct initramfs *initramfs = luaL_checkudata(L, 1, SYSLINUX_FILE);
+ const char *filename = luaL_checkstring(L, 2);
+ void *file_data;
+ size_t file_len = 0;
+
+ if (initramfs_add_file(initramfs, file_data, file_len, file_len,
+ "/testfile1", 0, 0755))
+
+ return 0;
+}
+
+static int sl_boot_it(lua_State * L)
+{
+ const syslinux_file *kernel = luaL_checkudata(L, 1, SYSLINUX_FILE);
+ const struct initramfs *initramfs = luaL_checkudata(L, 2, SYSLINUX_FILE);
+ const char *cmdline = luaL_optstring(L, 3, "");
+ uint32_t mem_limit = luaL_optint(L, 4, 0);
+ uint16_t video_mode = luaL_optint(L, 5, 0);
+ int ret;
+
+ ret = syslinux_boot_linux(kernel->data, kernel->size, initramfs, cmdline);
+
+ return 0;
+}
static const luaL_reg syslinuxlib[] = {
- {"run_command", sl_run_command},
- {NULL, NULL}
+ {"run_command", sl_run_command},
+ {"run_default", sl_run_default},
+ {"local_boot", sl_local_boot},
+ {"final_cleanup", sl_final_cleanup},
+ {"boot_linux", sl_boot_linux},
+ {"run_kernel_image", sl_run_kernel_image},
+ {"sleep", sl_sleep},
+ {"loadfile", sl_loadfile},
+ {"filesize", sl_filesize},
+ {"filename", sl_filename},
+ {"initramfs_init", sl_initramfs_init},
+ {"initramfs_load_archive", sl_initramfs_load_archive},
+ {"initramfs_add_file", sl_initramfs_add_file},
+ {"boot_it", sl_boot_it},
+ {NULL, NULL}
};
/* This defines a function that opens up your library. */
-LUALIB_API int luaopen_syslinux (lua_State *L) {
- luaL_openlib(L, LUA_SYSLINUXLIBNAME, syslinuxlib, 0);
- return 1;
-}
+LUALIB_API int luaopen_syslinux(lua_State * L)
+{
+
+ luaL_newmetatable(L, SYSLINUX_FILE);
+ luaL_openlib(L, LUA_SYSLINUXLIBNAME, syslinuxlib, 0);
+ return 1;
+}
diff --git a/com32/lua/src/vesa.c b/com32/lua/src/vesa.c
new file mode 100644
index 00000000..6f34820a
--- /dev/null
+++ b/com32/lua/src/vesa.c
@@ -0,0 +1,148 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "../../include/console.h"
+#include "../../lib/sys/vesa/vesa.h"
+#include "../../lib/sys/vesa/video.h"
+
+int vesacon_load_background(const char *filename);
+
+static int __constfunc is_power_of_2(unsigned int x)
+{
+ return x && !(x & (x-1));
+}
+
+static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi)
+{
+ int i;
+
+ if (!is_power_of_2(mi->win_size) ||
+ !is_power_of_2(mi->win_grain) ||
+ mi->win_grain > mi->win_size)
+ return 0; /* Impossible... */
+
+ for (i = 0; i < 2; i++) {
+ if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i])
+ return 1; /* Usable window */
+ }
+
+ return 0; /* Nope... */
+}
+
+static int vesa_getmodes(lua_State *L)
+{
+ com32sys_t rm;
+ uint16_t mode, bestmode, *mode_ptr;
+ struct vesa_general_info *gi;
+ struct vesa_mode_info *mi;
+ enum vesa_pixel_format bestpxf;
+ int nmode = 1;
+
+ /* Allocate space in the bounce buffer for these structures */
+ gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
+ mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
+
+ memset(&rm, 0, sizeof rm);
+ memset(gi, 0, sizeof *gi);
+
+ gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */
+ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */
+ rm.edi.w[0] = OFFS(gi);
+ rm.es = SEG(gi);
+ __intcall(0x10, &rm, &rm);
+
+ if ( rm.eax.w[0] != 0x004F )
+ return -1; /* Function call failed */
+ if ( gi->signature != VESA_MAGIC )
+ return -2; /* No magic */
+ if ( gi->version < 0x0102 )
+ return -3; /* VESA 1.2+ required */
+
+ lua_newtable(L); /* list of modes */
+
+ /* Copy general info */
+ memcpy(&__vesa_info.gi, gi, sizeof *gi);
+
+ /* Search for a 640x480 mode with a suitable color and memory model... */
+
+ mode_ptr = GET_PTR(gi->video_mode_ptr);
+ bestmode = 0;
+ bestpxf = PXF_NONE;
+
+ while ((mode = *mode_ptr++) != 0xFFFF) {
+ mode &= 0x1FF; /* The rest are attributes of sorts */
+
+ printf("Found mode: 0x%04x (%dx%dx%d)\n", mode, mi->h_res, mi->v_res, mi->bpp);
+
+ memset(mi, 0, sizeof *mi);
+ rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */
+ rm.ecx.w[0] = mode;
+ rm.edi.w[0] = OFFS(mi);
+ rm.es = SEG(mi);
+ __intcall(0x10, &rm, &rm);
+
+ /* Must be a supported mode */
+ if ( rm.eax.w[0] != 0x004f )
+ continue;
+
+ lua_pushnumber(L, nmode++);
+ lua_newtable(L); /* mode info */
+
+ lua_pushstring(L, "mode");
+ lua_pushnumber(L, mode);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "hres");
+ lua_pushnumber(L, mi->h_res);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "vres");
+ lua_pushnumber(L, mi->v_res);
+ lua_settable(L,-3);
+
+ lua_pushstring(L, "bpp");
+ lua_pushnumber(L, mi->bpp);
+ lua_settable(L,-3);
+
+ lua_settable(L, -3); /* add to mode list */
+
+ }
+
+ return 1;
+}
+
+
+static int vesa_setmode(lua_State *L)
+{
+ openconsole(&dev_rawcon_r, &dev_vesaserial_w);
+
+ return 0;
+}
+
+
+static int vesa_load_background(lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+
+ vesacon_load_background(filename);
+
+ return 0;
+}
+
+static const luaL_reg vesalib[] = {
+ {"getmodes", vesa_getmodes},
+ {"setmode", vesa_setmode},
+ {"load_background", vesa_load_background},
+ {NULL, NULL}
+};
+
+/* This defines a function that opens up your library. */
+
+LUALIB_API int luaopen_vesa (lua_State *L) {
+ luaL_openlib(L, LUA_VESALIBNAME, vesalib, 0);
+ return 1;
+}
+
diff --git a/com32/lua/test/pci.lua b/com32/lua/test/pci.lua
new file mode 100644
index 00000000..8d7f7d42
--- /dev/null
+++ b/com32/lua/test/pci.lua
@@ -0,0 +1,34 @@
+-- get nice output
+printf = function(s,...)
+ return io.write(s:format(...))
+ end
+
+-- get device info
+pciinfo = pci.getinfo()
+
+-- get plain text device description
+pciids = pci.getidlist("/pci.ids")
+
+-- list all pci busses
+for dind,device in pairs(pciinfo) do
+
+ -- search for device description
+ search = string.format("%04x%04x", device['vendor'], device['product'])
+
+ printf(" %04x:%04x:%04x:%04x = ", device['vendor'], device['product'],
+ device['sub_vendor'], device['sub_product'])
+
+ if ( pciids[search] ) then
+ printf("%s\n", pciids[search])
+ else
+ printf("Unknown\n")
+ end
+end
+
+-- print(pciids["8086"])
+-- print(pciids["10543009"])
+-- print(pciids["00700003"])
+-- print(pciids["0070e817"])
+-- print(pciids["1002437a1002437a"])
+
+
diff --git a/com32/lua/test/vesa.lua b/com32/lua/test/vesa.lua
new file mode 100644
index 00000000..7f35e5b5
--- /dev/null
+++ b/com32/lua/test/vesa.lua
@@ -0,0 +1,55 @@
+-- get nice output
+printf = function(s,...)
+ return io.write(s:format(...))
+ end
+
+-- list available vesa modes
+-- only one supported right now, not of much use
+modes = vesa.getmodes()
+
+for mind,mode in pairs(modes) do
+ printf("%04x: %dx%dx%d\n", mode['mode'], mode['hres'], mode['vres'], mode['bpp'])
+end
+
+printf("Hello World! - text mode")
+
+-- lets go to graphics land
+vesa.setmode()
+
+printf("Hello World! - VESA mode")
+
+syslinux.sleep(1000)
+
+-- some text to display "typing style"
+textline=[[
+
+From syslinux GSOC 2009 home page:
+
+Finish the Lua engine
+
+We already have a Lua interpreter integrated with the Syslinux build. However, right now it is not very useful. We need to create a set of bindings to the Syslinux functionality, and have an array of documentation and examples so users can use them.
+
+This is not a documentation project, but the documentation deliverable will be particularly important for this one, since the intended target is system administrators, not developers.
+]]
+
+
+-- do display loop
+-- keep in mind: background change will not erase text!
+while ( true ) do
+
+vesa.load_background("/PXE-RRZE_small.jpg")
+
+syslinux.sleep(1000)
+
+for i = 1, #textline do
+ local c = textline:sub(i,i)
+ printf("%s", c)
+ syslinux.sleep(200)
+end
+
+syslinux.sleep(10000)
+
+vesa.load_background("/sample2.jpg")
+syslinux.sleep(10000)
+
+end