]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[image] Add the "imgmem" command
authorMichael Brown <mcb30@ipxe.org>
Wed, 20 Jan 2021 18:08:04 +0000 (18:08 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 22 Jan 2021 18:44:58 +0000 (18:44 +0000)
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>
src/config/config.c
src/config/general.h
src/hci/commands/image_mem_cmd.c [new file with mode: 0644]
src/include/usr/imgmgmt.h
src/usr/imgmgmt.c

index 2ca05dff7d798435c0f9cb06689b4bc873cc01fd..5e7a3ecfdb560c5a2db4f680ee7c4fbe27ae831c 100644 (file)
@@ -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
index 9edf93b5a8a61d73bdf4faffbd030dc1f121dd52..9b21f127132994d968164924a9ec4d38bc697bf9 100644 (file)
@@ -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 (file)
index 0000000..61d5053
--- /dev/null
@@ -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,
+       },
+};
index 806df0bfbcdf67e31009ad5e607fc6d450f32c83..c59cf1a0b778ec55f42cae109b9ebedd72201f6e 100644 (file)
@@ -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 */
index a01d6e291d00dd253e0e5a64fd1d6b588373719d..bf4c745eac7de65caefb8838963e788f004f15b4 100644 (file)
@@ -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;
+}