[syslinux] [PATCH 0/1] EFI access from Com32 modules
Patrick Masotta
masottaus at yahoo.com
Sat Mar 14 04:23:26 PDT 2015
This patch adds to Com32 modules the capabilities of accessing the EFI environment
The idea is simple, the EFI parameters "image" and "table" received by syslinux.efi's
efi_main() are stored in the "firmware" structure, next they are retrieved from the Com32
module which is linked against the gnu-efi static library. The Com32 module can use the EFI
environment after calling InitializeLib(image, systab);
With this patch coding i.e. pxechn.c32 able to run on EFI environments should be a trivial job.
It was tested on VMware BIOS/EFI clients and HP Elitebook EFI/BIOS notebooks,
Feedback appreciated.
Best,
Patrick
Signed-off-by: Patrick Masotta <masottaus at yahoo.com>
---
diff -uprN a/com32/include/syslinux/firmware.h b/com32/include/syslinux/firmware.h
--- a/com32/include/syslinux/firmware.h 2014-10-06 10:27:44.000000000 -0600
+++ b/com32/include/syslinux/firmware.h 2015-03-13 12:59:12.147356419 -0600
@@ -62,6 +62,8 @@ struct firmware {
struct setup_data *, char *);
struct vesa_ops *vesa;
struct mem_ops *mem;
+ void* image;
+ void** table;
};
extern struct firmware *firmware;
diff -uprN a/com32/modules/elf_bios_efi.c b/com32/modules/elf_bios_efi.c
--- a/com32/modules/elf_bios_efi.c 1969-12-31 17:00:00.000000000 -0700
+++ b/com32/modules/elf_bios_efi.c 2015-03-13 14:43:18.266718706 -0600
@@ -0,0 +1,116 @@
+/*
+ * Demo module showing EFI access from a com32 module
+ * by Patrick Masotta (Serva) (c) 2015
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <consoles.h>
+#include <console.h>
+#include <errno.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdint.h>
+#include <syslinux/pxe.h>
+#include <sys/gpxe.h>
+#include <unistd.h>
+#include <getkey.h>
+#include <dhcp.h>
+#include <limits.h>
+
+#ifndef __FIRMWARE_BIOS__
+
+#include <syslinux/firmware.h>
+#include "../../efi/efi.h"
+
+#endif
+
+
+
+#ifdef __FIRMWARE_BIOS__
+
+int pressanykey(void) {
+ int inc;
+
+ printf("Press any key to continue. ");
+ inc = KEY_NONE;
+ while (inc == KEY_NONE)
+ inc = get_key(stdin, 6000);
+ puts("");
+ return inc;
+}
+
+int doTheJob(void)
+{
+
+ printf("This Com32 instance of elf_bios_efi.c32 is running on a BIOS environment\n");
+ pressanykey();
+
+ return 0;
+}
+
+#else
+
+char efi_getchar(char *hi)
+{
+ SIMPLE_INPUT_INTERFACE *in = ST->ConIn;
+ EFI_INPUT_KEY key;
+ EFI_STATUS status;
+
+
+ status = WaitForSingleEvent(in->WaitForKey, 0); // 0=> no timeout
+ status = uefi_call_wrapper(in->ReadKeyStroke, 2, in, &key); // get the char
+
+ if (!key.ScanCode)
+ return (char)key.UnicodeChar;
+
+ /*
+ * We currently only handle scan codes that fit in 8 bits.
+ */
+ if(hi)
+ *hi = (char)key.ScanCode;
+
+ return 0;
+
+}
+
+EFI_HANDLE image = NULL;
+EFI_SYSTEM_TABLE* systab = NULL;
+
+int doTheJob(void)
+{
+
+
+ image = (EFI_HANDLE) firmware->image;
+ systab = (EFI_SYSTEM_TABLE*) firmware->table;
+
+ InitializeLib(image, systab);
+
+ //Clear screen
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ Print(L"This Com32 instance of elf_bios_efi.c32 is running on an EFI environment\nPress any key to continue...");
+ efi_getchar(NULL);
+
+ return 0;
+}
+
+
+#endif
+
+
+
+
+int main(int argc, char *argv[])
+{
+
+
+ return doTheJob();
+
+
+}
diff -uprN a/com32/modules/Makefile b/com32/modules/Makefile
--- a/com32/modules/Makefile 2014-10-06 10:27:44.000000000 -0600
+++ b/com32/modules/Makefile 2015-03-13 13:37:44.416274394 -0600
@@ -18,13 +18,17 @@
VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
+ifneq "$(FIRMWARE)" "BIOS"
+include $(MAKEDIR)/elf_efi.mk
+endif
+
MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
disk.c32 pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 \
meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \
ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \
whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 \
- hexdump.c32 poweroff.c32 cptime.c32 debug.c32
+ hexdump.c32 poweroff.c32 cptime.c32 debug.c32 elf_bios_efi.c32
TESTFILES =
diff -uprN a/efi/build-gnu-efi.sh b/efi/build-gnu-efi.sh
--- a/efi/build-gnu-efi.sh 2014-10-06 10:27:44.000000000 -0600
+++ b/efi/build-gnu-efi.sh 2015-03-13 13:07:51.577939127 -0600
@@ -21,23 +21,23 @@ fi
ARCH="$1"
objdir="$(readlink -f $2)"
-if [ ! -e ../version.h ]; then
- printf "build-gnu-efi.sh: Cannot be run outside Syslinux object tree\n"
- pwd
- exit 1
-fi
-
-(
- cd ../..
- git submodule update --init
-)
+#if [ ! -e ../version.h ]; then
+# printf "build-gnu-efi.sh: Cannot be run outside Syslinux object tree\n"
+# pwd
+# exit 1
+#fi
+#
+#(
+# cd ../..
+# git submodule update --init
+#)
mkdir -p "$objdir/gnu-efi"
cd "$objdir/gnu-efi"
-EFIDIR="$(readlink -f "$objdir/../gnu-efi/gnu-efi-3.0")"
+EFIDIR="$(readlink -f "$topdir/gnu-efi/gnu-efi-3.0")"
make SRCDIR="$EFIDIR" TOPDIR="$EFIDIR" -f "$EFIDIR/Makefile" ARCH=$ARCH
make SRCDIR="$EFIDIR" TOPDIR="$EFIDIR" -f "$EFIDIR/Makefile" ARCH=$ARCH PREFIX="$objdir" install
-cd "$objdir/efi"
+cd "$objdir"
diff -uprN a/efi/check-gnu-efi.sh b/efi/check-gnu-efi.sh
--- a/efi/check-gnu-efi.sh 2014-10-06 10:27:44.000000000 -0600
+++ b/efi/check-gnu-efi.sh 2015-03-13 13:11:01.575274084 -0600
@@ -25,7 +25,8 @@ if [ ! \( -f "$objdir/include/efi/$ARCH/
# Syslinux disables built-in implicit rules.
export MAKEFLAGS=
- ../../efi/build-gnu-efi.sh $ARCH "$objdir" > /dev/null 2>&1
+ $topdir/efi/build-gnu-efi.sh $ARCH "$objdir"
+
if [ $? -ne 0 ]; then
printf "Failed to build gnu-efi. "
printf "Execute the following command for full details: \n\n"
diff -uprN a/efi/clean-gnu-efi.sh b/efi/clean-gnu-efi.sh
--- a/efi/clean-gnu-efi.sh 2014-10-06 10:27:44.000000000 -0600
+++ b/efi/clean-gnu-efi.sh 2015-03-13 13:11:33.200161911 -0600
@@ -21,10 +21,10 @@ fi
ARCH="$1"
objdir=$(readlink -f "$2")
-(
- cd ../..
- git submodule update --init
-)
+#(
+# cd ../..
+# git submodule update --init
+#)
if [ -d "$objdir/gnu-efi" ];then
cd "$objdir/gnu-efi"
diff -uprN a/efi/main.c b/efi/main.c
--- a/efi/main.c 2014-10-06 10:27:44.000000000 -0600
+++ b/efi/main.c 2015-03-13 12:56:38.747049818 -0600
@@ -1202,6 +1202,8 @@ struct firmware efi_fw = {
.boot_linux = efi_boot_linux,
.vesa = &efi_vesa_ops,
.mem = &efi_mem_ops,
+ .image = NULL,
+ .table = NULL
};
static inline void syslinux_register_efi(void)
@@ -1265,6 +1267,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EF
InitializeLib(image, table);
image_handle = image;
+ efi_fw.image = (void*) image;
+ efi_fw.table = (void**) table;
syslinux_register_efi();
efi_console_save();
diff -uprN a/mk/elf_efi.mk b/mk/elf_efi.mk
--- a/mk/elf_efi.mk 1969-12-31 17:00:00.000000000 -0700
+++ b/mk/elf_efi.mk 2015-03-13 13:03:27.630529153 -0600
@@ -0,0 +1,76 @@
+#/*
+# * EFI access from a com32 module by Patrick Masotta (Serva) (c) 2015
+# */
+
+
+com32 = $(topdir)/com32
+core = $(topdir)/core
+
+# Support IA32 and x86_64 platforms with one build
+# Set up architecture specifics; for cross compilation, set ARCH as apt
+# gnuefi sets up architecture specifics in ia32 or x86_64 sub directories
+# set up the LIBDIR and EFIINC for building for the appropriate architecture
+
+GCCOPT := $(call gcc_ok,-fno-stack-protector,)
+
+EFIINC = $(objdir)/include/efi
+LIBDIR = $(objdir)/lib
+
+ifeq ($(ARCH),i386)
+ ARCHOPT = -m32 -march=i386
+ EFI_SUBARCH = ia32
+endif
+ifeq ($(ARCH),x86_64)
+ ARCHOPT = -m64 -march=x86-64
+ EFI_SUBARCH = $(ARCH)
+endif
+
+
+
+CFLAGS := $(CFLAGS)
+CFLAGS += -I$(EFIINC) -I$(EFIINC)/$(EFI_SUBARCH) \
+ -DEFI_FUNCTION_WRAPPER -fPIC -fshort-wchar -ffreestanding \
+ -Wall \
+ -I$(core)/ $(ARCHOPT) \
+ -I$(com32)/lib/ -I$(com32)/libutil/include -std=gnu99 \
+ -DELF_DEBUG -DSYSLINUX_EFI -I$(objdir) \
+ $(GCCWARN) -D__COM32__ -D__FIRMWARE_$(FIRMWARE)__ -mno-red-zone \
+ -Wno-unused-parameter $(GCCOPT)
+
+
+
+
+## granular test pat
+LDFLAGS += -Bsymbolic -pie -nostdlib -znocombreloc \
+ -L$(LIBDIR) -m elf_$(ARCH) -E
+#
+#
+SFLAGS += $(GCCOPT) $(GCCWARN) $(ARCHOPT) \
+ -fomit-frame-pointer -D__COM32__ -D__FIRMWARE_$(FIRMWARE)__ \
+ -nostdinc -iwithprefix include \
+ -I$(com32)/libutil/include -I$(com32)/include -I$(com32)/include/sys $(GPLINCLUDE)
+
+
+
+
+LIBEFI = $(objdir)/lib/libefi.a
+
+$(LIBEFI):
+ @echo Building gnu-efi for $(EFI_SUBARCH)
+ $(topdir)/efi/check-gnu-efi.sh $(EFI_SUBARCH) $(objdir)
+
+
+
+%.o: %.S # Cancel old rule
+
+%.o: %.c
+
+.PRECIOUS: %.o
+%.o: %.S $(LIBEFI)
+ $(CC) $(SFLAGS) -c -o $@ $<
+
+.PRECIOUS: %.o
+%.o: %.c $(LIBEFI)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+
More information about the Syslinux
mailing list