Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow images to hold references to the originating URI.
Some shuffling around of the image management code; this needs tidying up.
  • Loading branch information
Michael Brown committed Aug 2, 2007
1 parent 9fd6a04 commit d4947c0
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 69 deletions.
2 changes: 1 addition & 1 deletion src/arch/i386/image/bzimage.c
Expand Up @@ -190,7 +190,7 @@ static size_t bzimage_load_initrd ( struct image *image,
return 0;

/* Create cpio header before non-prebuilt images */
if ( filename[0] ) {
if ( filename && filename[0] ) {
size_t name_len = ( strlen ( filename ) + 1 );

DBGC ( image, "bzImage %p inserting initrd %p as %s\n",
Expand Down
9 changes: 7 additions & 2 deletions src/arch/i386/image/multiboot.c
Expand Up @@ -135,6 +135,7 @@ multiboot_build_module_list ( struct image *image,
unsigned int insert;
physaddr_t start;
physaddr_t end;
char *cmdline;
unsigned int i;

/* Add each image as a multiboot module */
Expand Down Expand Up @@ -169,7 +170,9 @@ multiboot_build_module_list ( struct image *image,
( ( count - insert ) * sizeof ( *module ) ));
module->mod_start = start;
module->mod_end = end;
module->string = virt_to_phys ( module_image->cmdline);
cmdline = ( module_image->cmdline ?
module_image->cmdline : "" );
module->string = virt_to_phys ( cmdline );
module->reserved = 0;

/* We promise to page-align modules */
Expand Down Expand Up @@ -222,14 +225,16 @@ static struct multiboot_module __bss16_array ( mbmodules, [MAX_MODULES] );
*/
static int multiboot_exec ( struct image *image ) {
physaddr_t entry = image->priv.phys;
char *cmdline;

/* Populate multiboot information structure */
memset ( &mbinfo, 0, sizeof ( mbinfo ) );
mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP |
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
multiboot_build_memmap ( image, &mbinfo, mbmemmap,
( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
mbinfo.cmdline = virt_to_phys ( image->cmdline );
cmdline = ( image->cmdline ? image->cmdline : "" );
mbinfo.cmdline = virt_to_phys ( cmdline );
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
( sizeof(mbmodules) / sizeof(mbmodules[0]) ) );
mbinfo.mods_addr = virt_to_phys ( mbmodules );
Expand Down
78 changes: 78 additions & 0 deletions src/core/image.c
Expand Up @@ -22,8 +22,10 @@
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <libgen.h>
#include <gpxe/list.h>
#include <gpxe/umalloc.h>
#include <gpxe/uri.h>
#include <gpxe/image.h>

/** @file
Expand All @@ -49,6 +51,7 @@ static struct image_type image_types_end[0]
static void free_image ( struct refcnt *refcnt ) {
struct image *image = container_of ( refcnt, struct image, refcnt );

uri_put ( image->uri );
ufree ( image->data );
free ( image );
DBGC ( image, "IMAGE %p freed\n", image );
Expand All @@ -69,6 +72,45 @@ struct image * alloc_image ( void ) {
return image;
}

/**
* Set image URI
*
* @v image Image
* @v URI New image URI
* @ret rc Return status code
*
* If no name is set, the name will be updated to the base name of the
* URI path (if any).
*/
int image_set_uri ( struct image *image, struct uri *uri ) {
const char *path = uri->path;

/* Replace URI reference */
uri_put ( image->uri );
image->uri = uri_get ( uri );

/* Set name if none already specified */
if ( path && ( ! image->name[0] ) )
image_set_name ( image, basename ( ( char * ) path ) );

return 0;
}

/**
* Set image command line
*
* @v image Image
* @v cmdline New image command line
* @ret rc Return status code
*/
int image_set_cmdline ( struct image *image, const char *cmdline ) {
free ( image->cmdline );
image->cmdline = strdup ( cmdline );
if ( ! image->cmdline )
return -ENOMEM;
return 0;
}

/**
* Register executable/loadable image
*
Expand Down Expand Up @@ -220,3 +262,39 @@ int image_exec ( struct image *image ) {
/* Well, some formats might return... */
return 0;
}

/**
* Register and autoload an image
*
* @v image Image
* @ret rc Return status code
*/
int register_and_autoload_image ( struct image *image ) {
int rc;

if ( ( rc = register_image ( image ) ) != 0 )
return rc;

if ( ( rc = image_autoload ( image ) ) != 0 )
return rc;

return 0;
}

/**
* Register and autoexec an image
*
* @v image Image
* @ret rc Return status code
*/
int register_and_autoexec_image ( struct image *image ) {
int rc;

if ( ( rc = register_and_autoload_image ( image ) ) != 0 )
return rc;

if ( ( rc = image_exec ( image ) ) != 0 )
return rc;

return 0;
}
83 changes: 59 additions & 24 deletions src/hci/commands/image_cmd.c
Expand Up @@ -33,41 +33,51 @@
*
*/

/**
* Print image description
*
*/
enum image_action {
IMG_FETCH = 0,
IMG_LOAD,
IMG_EXEC,
};

/**
* Fill in image command line
*
* @v image Image
* @v nargs Argument count
* @v args Argument list
* @ret rc Return status code
*/
static void imgfill_cmdline ( struct image *image, unsigned int nargs,
char **args ) {
static int imgfill_cmdline ( struct image *image, unsigned int nargs,
char **args ) {
char buf[256];
size_t used = 0;

image->cmdline[0] = '\0';
while ( ( used < sizeof ( image->cmdline ) ) && nargs-- ) {
used += snprintf ( &image->cmdline[used],
( sizeof ( image->cmdline ) - used ),
"%s%s", ( used ? " " : "" ), *(args++) );
memset ( buf, 0, sizeof ( buf ) );
while ( ( used < sizeof ( buf ) ) && nargs-- ) {
used += snprintf ( &buf[used], ( sizeof ( buf ) - used ),
" %s", *(args++) );
}

return image_set_cmdline ( image, &buf[1] );
}

/**
* "imgfetch"/"module"/"kernel" command syntax message
*
* @v argv Argument list
*/
static void imgfetch_core_syntax ( char **argv, int load ) {
static void imgfetch_core_syntax ( char **argv, enum image_action action ) {
static const char *actions[] = {
[IMG_FETCH] = "Fetch",
[IMG_LOAD] = "Fetch and load",
[IMG_EXEC] = "Fetch and execute",
};

printf ( "Usage:\n"
" %s [-n|--name <name>] filename [arguments...]\n"
"\n"
"%s executable/loadable image\n",
argv[0], ( load ? "Fetch and load" : "Fetch" ) );
argv[0], actions[action] );
}

/**
Expand All @@ -79,7 +89,8 @@ static void imgfetch_core_syntax ( char **argv, int load ) {
* @v argv Argument list
* @ret rc Return status code
*/
static int imgfetch_core_exec ( struct image_type *image_type, int load,
static int imgfetch_core_exec ( struct image_type *image_type,
enum image_action action,
int argc, char **argv ) {
static struct option longopts[] = {
{ "help", 0, NULL, 'h' },
Expand All @@ -89,6 +100,7 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
struct image *image;
const char *name = NULL;
char *filename;
int ( * image_register ) ( struct image *image );
int c;
int rc;

Expand All @@ -104,14 +116,14 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
/* Display help text */
default:
/* Unrecognised/invalid option */
imgfetch_core_syntax ( argv, load );
imgfetch_core_syntax ( argv, action );
return -EINVAL;
}
}

/* Need at least a filename remaining after the options */
if ( optind == argc ) {
imgfetch_core_syntax ( argv, load );
imgfetch_core_syntax ( argv, action );
return -EINVAL;
}
filename = argv[optind++];
Expand All @@ -126,17 +138,35 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
}

/* Fill in image name */
if ( name )
strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
if ( name ) {
if ( ( rc = image_set_name ( image, name ) ) != 0 )
return rc;
}

/* Set image type (if specified) */
image->type = image_type;

/* Fill in command line */
imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
&argv[optind] ) ) != 0 )
return rc;

/* Fetch the image */
if ( ( rc = imgfetch ( image, filename, load ) ) != 0 ) {
switch ( action ) {
case IMG_FETCH:
image_register = register_image;
break;
case IMG_LOAD:
image_register = register_and_autoload_image;
break;
case IMG_EXEC:
image_register = register_and_autoexec_image;
break;
default:
assert ( 0 );
return -EINVAL;
}
if ( ( rc = imgfetch ( image, filename, image_register ) ) != 0 ) {
printf ( "Could not fetch %s: %s\n", name, strerror ( rc ) );
image_put ( image );
return rc;
Expand All @@ -156,7 +186,8 @@ static int imgfetch_core_exec ( struct image_type *image_type, int load,
static int imgfetch_exec ( int argc, char **argv ) {
int rc;

if ( ( rc = imgfetch_core_exec ( NULL, 0, argc, argv ) ) != 0 )
if ( ( rc = imgfetch_core_exec ( NULL, IMG_FETCH,
argc, argv ) ) != 0 )
return rc;

return 0;
Expand All @@ -172,7 +203,7 @@ static int imgfetch_exec ( int argc, char **argv ) {
static int kernel_exec ( int argc, char **argv ) {
int rc;

if ( ( rc = imgfetch_core_exec ( NULL, 1, argc, argv ) ) != 0 )
if ( ( rc = imgfetch_core_exec ( NULL, IMG_LOAD, argc, argv ) ) != 0 )
return rc;

return 0;
Expand All @@ -188,7 +219,7 @@ static int kernel_exec ( int argc, char **argv ) {
static int initrd_exec ( int argc, char **argv ) {
int rc;

if ( ( rc = imgfetch_core_exec ( &initrd_image_type, 0,
if ( ( rc = imgfetch_core_exec ( &initrd_image_type, IMG_FETCH,
argc, argv ) ) != 0 )
return rc;

Expand Down Expand Up @@ -286,6 +317,7 @@ static int imgargs_exec ( int argc, char **argv ) {
struct image *image;
const char *name;
int c;
int rc;

/* Parse options */
while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
Expand All @@ -312,7 +344,10 @@ static int imgargs_exec ( int argc, char **argv ) {
printf ( "No such image: %s\n", name );
return 1;
}
imgfill_cmdline ( image, ( argc - optind ), &argv[optind] );
if ( ( rc = imgfill_cmdline ( image, ( argc - optind ),
&argv[optind] ) ) != 0 )
return rc;


return 0;
}
Expand Down

0 comments on commit d4947c0

Please sign in to comment.