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
-------

Modules must be explicitly loaded into the namespace
before use, for example:
......................................................
syslinux = require ("syslinux")
......................................................

SYSLINUX
~~~~~~~~

.syslinux.version()

Returns version string

.syslinux.derivative()

Returns running Syslinux's derivative (ISOLINUX, PXELINUX or SYSLINUX).
See com32/lua/test/syslinux-derivative.lua for an example.

.syslinux.sleep(s)

Sleep for +s+ seconds

.syslinux.msleep(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(20)
	
......................................................



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(1)
	
	for i = 1, #textline do
	    local c = textline:sub(i,i)
	    printf("%s", c)
	    syslinux.msleep(200)
	end
	
	syslinux.sleep(10)

......................................................

