aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2021-01-20 18:08:04 +0000
committerMichael Brown <mcb30@ipxe.org>2021-01-22 18:44:58 +0000
commitb99477b3fa6d4063314a313f62b7ae784bcbe710 (patch)
tree91c8cdc57cac2de558278c81628d9ea7ed02b6ba
parent99ac69b8a9a48207913e98ac6b357c029b0eef81 (diff)
downloadipxe-b99477b3fa6d4063314a313f62b7ae784bcbe710.zip
ipxe-b99477b3fa6d4063314a313f62b7ae784bcbe710.tar.gz
ipxe-b99477b3fa6d4063314a313f62b7ae784bcbe710.tar.bz2
[image] Add the "imgmem" command
Provide the "imgmem" command to create an image from an existing block of memory, for debugging purposes only. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/config/config.c3
-rw-r--r--src/config/general.h1
-rw-r--r--src/hci/commands/image_mem_cmd.c98
-rw-r--r--src/include/usr/imgmgmt.h2
-rw-r--r--src/usr/imgmgmt.c44
5 files changed, 148 insertions, 0 deletions
diff --git a/src/config/config.c b/src/config/config.c
index 2ca05df..5e7a3ec 100644
--- a/src/config/config.c
+++ b/src/config/config.c
@@ -281,6 +281,9 @@ REQUIRE_OBJECT ( ntp_cmd );
#ifdef CERT_CMD
REQUIRE_OBJECT ( cert_cmd );
#endif
+#ifdef IMAGE_MEM_CMD
+REQUIRE_OBJECT ( image_mem_cmd );
+#endif
/*
* Drag in miscellaneous objects
diff --git a/src/config/general.h b/src/config/general.h
index 9edf93b..9b21f12 100644
--- a/src/config/general.h
+++ b/src/config/general.h
@@ -155,6 +155,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#define PROFSTAT_CMD /* Profiling commands */
//#define NTP_CMD /* NTP commands */
//#define CERT_CMD /* Certificate management commands */
+//#define IMAGE_MEM_CMD /* Read memory command */
/*
* ROM-specific options
diff --git a/src/hci/commands/image_mem_cmd.c b/src/hci/commands/image_mem_cmd.c
new file mode 100644
index 0000000..61d5053
--- /dev/null
+++ b/src/hci/commands/image_mem_cmd.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * 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; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/imgmgmt.h>
+
+/** @file
+ *
+ * Read memory command
+ *
+ */
+
+/** "imgmem" options */
+struct imgmem_options {
+ /** Image name */
+ char *name;
+};
+
+/** "imgmem" option list */
+static struct option_descriptor imgmem_opts[] = {
+ OPTION_DESC ( "name", 'n', required_argument,
+ struct imgmem_options, name, parse_string ),
+};
+
+/** "imgmem" command descriptor */
+static struct command_descriptor imgmem_cmd =
+ COMMAND_DESC ( struct imgmem_options, imgmem_opts, 2, 2,
+ "<address> <length>" );
+
+/**
+ * The "imgmem" command
+ *
+ * @v argc Argument count
+ * @v argv Argument list
+ * @ret rc Return status code
+ */
+static int imgmem_exec ( int argc, char **argv ) {
+ struct imgmem_options opts;
+ struct image *image;
+ unsigned int data;
+ unsigned int len;
+ int rc;
+
+ /* Parse options */
+ if ( ( rc = parse_options ( argc, argv, &imgmem_cmd, &opts ) ) != 0 )
+ return rc;
+
+ /* Use start address as name if none specified */
+ if ( ! opts.name )
+ opts.name = argv[optind];
+
+ /* Parse address */
+ if ( ( rc = parse_integer ( argv[optind++], &data ) ) != 0 )
+ return rc;
+
+ /* Parse length */
+ if ( ( rc = parse_integer ( argv[optind++], &len ) ) != 0 )
+ return rc;
+
+ /* Create image */
+ if ( ( rc = imgmem ( phys_to_user ( data ), len, opts.name,
+ &image ) ) != 0 )
+ return rc;
+
+ return 0;
+}
+
+/** Read memory command */
+struct command imgmem_commands[] __command = {
+ {
+ .name = "imgmem",
+ .exec = imgmem_exec,
+ },
+};
diff --git a/src/include/usr/imgmgmt.h b/src/include/usr/imgmgmt.h
index 806df0b..c59cf1a 100644
--- a/src/include/usr/imgmgmt.h
+++ b/src/include/usr/imgmgmt.h
@@ -18,5 +18,7 @@ extern int imgdownload_string ( const char *uri_string, unsigned long timeout,
extern int imgacquire ( const char *name, unsigned long timeout,
struct image **image );
extern void imgstat ( struct image *image );
+extern int imgmem ( userptr_t data, size_t len, const char *name,
+ struct image **image );
#endif /* _USR_IMGMGMT_H */
diff --git a/src/usr/imgmgmt.c b/src/usr/imgmgmt.c
index a01d6e2..bf4c745 100644
--- a/src/usr/imgmgmt.c
+++ b/src/usr/imgmgmt.c
@@ -169,3 +169,47 @@ void imgstat ( struct image *image ) {
printf ( " \"%s\"", image->cmdline );
printf ( "\n" );
}
+
+/**
+ * Create image from block of memory
+ *
+ * @v data Image data
+ * @v len Length
+ * @v name Name
+ * @v image Image to fill in
+ * @ret rc Return status code
+ */
+int imgmem ( userptr_t data, size_t len, const char *name,
+ struct image **image ) {
+ int rc;
+
+ /* Allocate image */
+ *image = alloc_image ( NULL );
+ if ( ! *image ) {
+ rc = -ENOMEM;
+ goto err_alloc_image;
+ }
+
+ /* Set name */
+ if ( ( rc = image_set_name ( *image, name ) ) != 0 )
+ goto err_set_name;
+
+ /* Set data */
+ if ( ( rc = image_set_data ( *image, data, len ) ) != 0 ) {
+ printf ( "Could not set image data: %s\n", strerror ( rc ) );
+ goto err_set_data;
+ }
+
+ /* Register image */
+ if ( ( rc = register_image ( *image ) ) != 0 ) {
+ printf ( "Could not register image: %s\n", strerror ( rc ) );
+ goto err_register_image;
+ }
+
+ err_register_image:
+ err_set_data:
+ err_set_name:
+ image_put ( *image );
+ err_alloc_image:
+ return rc;
+}