[syslinux:master] memdiskfind: utility to find an mBFT and output phram parameters

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Mon Jun 21 17:33:07 PDT 2010


Commit-ID:  1d0c49827da98d852d42fadd56b073ad3d3f1faa
Gitweb:     http://syslinux.zytor.com/commit/1d0c49827da98d852d42fadd56b073ad3d3f1faa
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Mon, 21 Jun 2010 17:29:51 -0700
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Mon, 21 Jun 2010 17:29:51 -0700

memdiskfind: utility to find an mBFT and output phram parameters

A trivial Linux utility to search for mBFT and output its parameters
in a form which can be used as input to the phram Linux kernel module.

Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>


---
 utils/Makefile      |    5 ++-
 utils/memdiskfind.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 1 deletions(-)

diff --git a/utils/Makefile b/utils/Makefile
index 43552d8..455eb82 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -20,7 +20,7 @@ include $(topdir)/MCONFIG
 CFLAGS   = $(GCCWARN) -Os -fomit-frame-pointer -D_FILE_OFFSET_BITS=64
 LDFLAGS  = -O2 -s
 
-TARGETS	 = mkdiskimage isohybrid gethostip
+TARGETS	 = mkdiskimage isohybrid gethostip memdiskfind
 TARGETS += isohybrid.pl  # about to be obsoleted
 ASIS     = keytab-lilo lss16toppm md5pass ppmtolss16 sha1pass syslinux2ansi \
 	   pxelinux-options
@@ -52,6 +52,9 @@ isohybrid: isohybrid.o isohdpfx.o
 gethostip: gethostip.o
 	$(CC) $(LDFLAGS) -o $@ $^
 
+memdiskfind: memdiskfind.o
+	$(CC) $(LDFLAGS) -o $@ $^
+
 tidy dist:
 	rm -f *.o .*.d isohdpfx.c
 
diff --git a/utils/memdiskfind.c b/utils/memdiskfind.c
new file mode 100644
index 0000000..331bfb3
--- /dev/null
+++ b/utils/memdiskfind.c
@@ -0,0 +1,119 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memdiskfind.c
+ *
+ * Simple utility to search for a MEMDISK instance and output the parameters
+ * needed to use the "phram" driver in Linux to map it.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include "../memdisk/mstructs.h"
+
+#define MBFT_MIN_LENGTH	(36+4+26)
+
+static bool valid_mbft(const struct mBFT *mbft, size_t space)
+{
+    uint8_t csum;
+    size_t i;
+
+    if (memcmp(mbft->acpi.signature, "mBFT", 4))
+	return false;
+
+    if (mbft->acpi.length < MBFT_MIN_LENGTH)
+	return false;
+
+    if (mbft->acpi.length > space)
+	return false;
+
+    if ((size_t)mbft->acpi.length != (size_t)mbft->mdi.bytes + 36+4)
+	return false;
+
+    csum = 0;
+    for (i = 0; i < mbft->acpi.length; i++)
+	csum += ((const uint8_t *)mbft)[i];
+
+    if (csum)
+	return false;
+
+    return true;
+}
+
+static void output_params(const struct mBFT *mbft)
+{
+    printf("%u,%u\n", mbft->mdi.diskbuf, mbft->mdi.disksize);
+}
+
+int main(int argc, char *argv[])
+{
+    const char *map;
+    int memfd;
+    uint16_t fbm;
+    const char *ptr, *end;
+    size_t page = sysconf(_SC_PAGESIZE);
+    size_t mapbase, maplen;
+    int err = 1;
+
+    (void)argc;
+
+    memfd = open("/dev/mem", O_RDONLY);
+    if (memfd < 0) {
+	fprintf(stderr, "%s: cannot open /dev/mem: %s\n",
+		argv[0], strerror(errno));
+	return 2;
+    }
+
+    map = mmap(NULL, page, PROT_READ, MAP_SHARED, memfd, 0);
+    if (map == MAP_FAILED) {
+	fprintf(stderr, "%s: cannot map page 0: %s\n",
+		argv[0], strerror(errno));
+	return 2;
+    }
+
+    fbm = *(uint16_t *)(map + 0x413);
+
+    munmap((void *)map, 4096);
+
+    mapbase = (fbm << 10) & ~(page - 1);
+    maplen  = 0xa0000 - mapbase;
+    map = mmap(NULL, maplen, PROT_READ, MAP_SHARED, memfd, mapbase);
+    if (map == MAP_FAILED) {
+	fprintf(stderr, "%s: cannot map base memory: %s\n",
+		argv[0], strerror(errno));
+	exit(1);
+    }
+
+    ptr = map + ((fbm << 10) & (page - 1));
+    end = map + (0xa0000 - mapbase);
+    while (ptr < end) {
+	if (valid_mbft((const struct mBFT *)ptr, end-ptr)) {
+	    output_params((const struct mBFT *)ptr);
+	    err = 0;
+	    break;
+	}
+	ptr += 16;
+    }
+
+    munmap((void *)map, maplen);
+
+    return err;
+}



More information about the Syslinux-commits mailing list