diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-07-05 14:23:50 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-07-05 14:23:50 -0700 |
commit | 7072cf57e5f43449223c1fe75aebcbf82659e515 (patch) | |
tree | ddb56c4504a5f5f0c38e9dc71e9a707932d21d85 | |
parent | 9a332c5f03c9f9cc81f6c247c6d248a715f6eabb (diff) | |
parent | 6841745fa86a45405de9bdd0e453f4abb26398b7 (diff) | |
download | syslinux-7072cf57e5f43449223c1fe75aebcbf82659e515.tar.gz |
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.asc | 273 | ||||
-rw-r--r-- | com32/lua/src/Makefile | 8 | ||||
-rw-r--r-- | com32/lua/src/linit.c | 2 | ||||
-rw-r--r-- | com32/lua/src/lualib.h | 7 | ||||
-rw-r--r-- | com32/lua/src/pci.c | 183 | ||||
-rw-r--r-- | com32/lua/src/syslinux.c | 417 | ||||
-rw-r--r-- | com32/lua/src/vesa.c | 148 | ||||
-rw-r--r-- | com32/lua/test/pci.lua | 34 | ||||
-rw-r--r-- | com32/lua/test/vesa.lua | 55 |
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 |