[syslinux] [PATCH] poweroff COM32 module

Sebastian Herbszt herbszt at gmx.de
Sun Feb 10 10:30:51 PST 2013


This module is able to power off a system via APM.
It replaces the poweroff COMBOOT module.

Signed-off-by: Sebastian Herbszt <herbszt at gmx.de>
---
 com32/modules/Makefile   |    2 +-
 com32/modules/poweroff.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 1 deletions(-)
 create mode 100644 com32/modules/poweroff.c

diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 628fa5d..1998a0e 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -25,7 +25,7 @@ MODULES	  = config.c32 ethersel.c32 dmitest.c32 cpuidtest.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
+	    hexdump.c32 poweroff.c32
 
 TESTFILES =
 
diff --git a/com32/modules/poweroff.c b/com32/modules/poweroff.c
new file mode 100644
index 0000000..8cec483
--- /dev/null
+++ b/com32/modules/poweroff.c
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2013 Sebastian Herbszt - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * poweroff.c
+ *
+ * APM poweroff module
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <com32.h>
+
+int main()
+{
+	com32sys_t inregs, outregs;
+
+	memset(&inregs, 0, sizeof inregs);
+
+	inregs.eax.l = 0x5300; /* APM Installation Check (00h) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM not present.\n");
+		return 1;
+	}
+
+	if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */
+		printf("APM not present.\n");
+		return 1;
+	}
+
+	if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */
+		printf("Power management disabled.\n");
+		return 1;
+	}
+
+	inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	__intcall(0x15, &inregs, &outregs);
+   
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM RM interface connect failed.\n");
+		return 1;
+	}
+
+	inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	inregs.ecx.l = 0x101; /* APM Driver version 1.1 */
+	__intcall(0x15, &inregs, &outregs);
+   
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	inregs.eax.l = 0x5307; /* Set Power State (07h) */
+	inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */
+	inregs.ecx.l = 3; /* Power state off */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("Power off failed.\n");
+		return 1;
+	}
+
+	return 0;
+}
-- 
1.7.3.4




More information about the Syslinux mailing list