diff options
Diffstat (limited to 'src/core/image.c')
| -rw-r--r-- | src/core/image.c | 182 |
1 files changed, 88 insertions, 94 deletions
diff --git a/src/core/image.c b/src/core/image.c index ec4b46106..cb9615311 100644 --- a/src/core/image.c +++ b/src/core/image.c @@ -32,7 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** @file * - * Executable/loadable images + * Executable images * */ @@ -40,7 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); struct list_head images = LIST_HEAD_INIT ( images ); /** - * Free executable/loadable image + * Free executable image * * @v refcnt Reference counter */ @@ -52,13 +52,13 @@ static void free_image ( struct refcnt *refcnt ) { ufree ( image->data ); image_put ( image->replacement ); free ( image ); - DBGC ( image, "IMAGE %p freed\n", image ); + DBGC ( image, "IMAGE %s freed\n", image->name ); } /** - * Allocate executable/loadable image + * Allocate executable image * - * @ret image Executable/loadable image + * @ret image Executable image */ struct image * alloc_image ( void ) { struct image *image; @@ -75,12 +75,11 @@ struct image * alloc_image ( void ) { * * @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 ) { +void image_set_uri ( struct image *image, struct uri *uri ) { const char *path = uri->path; /* Replace URI reference */ @@ -90,8 +89,6 @@ int image_set_uri ( struct image *image, struct uri *uri ) { /* Set name if none already specified */ if ( path && ( ! image->name[0] ) ) image_set_name ( image, basename ( ( char * ) path ) ); - - return 0; } /** @@ -110,9 +107,9 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) { } /** - * Register executable/loadable image + * Register executable image * - * @v image Executable/loadable image + * @v image Executable image * @ret rc Return status code */ int register_image ( struct image *image ) { @@ -127,20 +124,20 @@ int register_image ( struct image *image ) { /* Add to image list */ image_get ( image ); list_add_tail ( &image->list, &images ); - DBGC ( image, "IMAGE %p at [%lx,%lx) registered as %s\n", - image, user_to_phys ( image->data, 0 ), - user_to_phys ( image->data, image->len ), image->name ); + DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n", + image->name, user_to_phys ( image->data, 0 ), + user_to_phys ( image->data, image->len ) ); return 0; } /** - * Unregister executable/loadable image + * Unregister executable image * - * @v image Executable/loadable image + * @v image Executable image */ void unregister_image ( struct image *image ) { - DBGC ( image, "IMAGE %p unregistered\n", image ); + DBGC ( image, "IMAGE %s unregistered\n", image->name ); list_del ( &image->list ); image_put ( image ); } @@ -149,7 +146,7 @@ void unregister_image ( struct image *image ) { * Find image by name * * @v name Image name - * @ret image Executable/loadable image, or NULL + * @ret image Executable image, or NULL */ struct image * find_image ( const char *name ) { struct image *image; @@ -163,75 +160,39 @@ struct image * find_image ( const char *name ) { } /** - * Load executable/loadable image into memory - * - * @v image Executable/loadable image - * @v type Executable/loadable image type - * @ret rc Return status code - */ -static int image_load_type ( struct image *image, struct image_type *type ) { - int rc; - - /* Check image is actually loadable */ - if ( ! type->load ) - return -ENOEXEC; - - /* Try the image loader */ - if ( ( rc = type->load ( image ) ) != 0 ) { - DBGC ( image, "IMAGE %p could not load as %s: %s\n", - image, type->name, strerror ( rc ) ); - return rc; - } - - /* Flag as loaded */ - image->flags |= IMAGE_LOADED; - return 0; -} - -/** - * Load executable/loadable image into memory - * - * @v image Executable/loadable image - * @ret rc Return status code - */ -int image_load ( struct image *image ) { - - assert ( image->type != NULL ); - - return image_load_type ( image, image->type ); -} - -/** - * Autodetect image type and load executable/loadable image into memory + * Determine image type * - * @v image Executable/loadable image + * @v image Executable image * @ret rc Return status code */ -int image_autoload ( struct image *image ) { +int image_probe ( struct image *image ) { struct image_type *type; int rc; - /* If image already has a type, use it */ + /* Succeed if we already have a type */ if ( image->type ) - return image_load ( image ); + return 0; - /* Otherwise probe for a suitable type */ + /* Try each type in turn */ for_each_table_entry ( type, IMAGE_TYPES ) { - DBGC ( image, "IMAGE %p trying type %s\n", image, type->name ); - rc = image_load_type ( image, type ); - if ( image->type == NULL ) - continue; - return rc; + if ( ( rc = type->probe ( image ) ) == 0 ) { + image->type = type; + DBGC ( image, "IMAGE %s is %s\n", + image->name, type->name ); + return 0; + } + DBGC ( image, "IMAGE %s is not %s: %s\n", image->name, + type->name, strerror ( rc ) ); } - DBGC ( image, "IMAGE %p format not recognised\n", image ); + DBGC ( image, "IMAGE %s format not recognised\n", image->name ); return -ENOEXEC; } /** - * Execute loaded image + * Execute image * - * @v image Loaded image + * @v image Executable image * @ret rc Return status code */ int image_exec ( struct image *image ) { @@ -239,18 +200,9 @@ int image_exec ( struct image *image ) { struct uri *old_cwuri; int rc; - /* Image must be loaded first */ - if ( ! ( image->flags & IMAGE_LOADED ) ) { - DBGC ( image, "IMAGE %p could not execute: not loaded\n", - image ); - return -ENOTTY; - } - - assert ( image->type != NULL ); - - /* Check that image is actually executable */ - if ( ! image->type->exec ) - return -ENOEXEC; + /* Check that this image can be executed */ + if ( ( rc = image_probe ( image ) ) != 0 ) + return rc; /* Switch current working directory to be that of the image itself */ old_cwuri = uri_get ( cwuri ); @@ -264,8 +216,8 @@ int image_exec ( struct image *image ) { /* Try executing the image */ if ( ( rc = image->type->exec ( image ) ) != 0 ) { - DBGC ( image, "IMAGE %p could not execute: %s\n", - image, strerror ( rc ) ); + DBGC ( image, "IMAGE %s could not execute: %s\n", + image->name, strerror ( rc ) ); /* Do not return yet; we still have clean-up to do */ } @@ -283,8 +235,8 @@ int image_exec ( struct image *image ) { /* Tail-recurse into replacement image, if one exists */ if ( replacement ) { - DBGC ( image, "IMAGE %p replacing self with IMAGE %p\n", - image, replacement ); + DBGC ( image, "IMAGE %s replacing self with IMAGE %s\n", + image->name, replacement->name ); if ( ( rc = image_exec ( replacement ) ) != 0 ) return rc; } @@ -293,33 +245,75 @@ int image_exec ( struct image *image ) { } /** - * Register and autoload an image + * Select image for execution * - * @v image Image + * @v image Executable image * @ret rc Return status code */ -int register_and_autoload_image ( struct image *image ) { +int image_select ( struct image *image ) { + struct image *tmp; + int rc; + + /* Unselect all other images */ + for_each_image ( tmp ) + tmp->flags &= ~IMAGE_SELECTED; + + /* Check that this image can be executed */ + if ( ( rc = image_probe ( image ) ) != 0 ) + return rc; + + /* Mark image as selected */ + image->flags |= IMAGE_SELECTED; + + return 0; +} + +/** + * Find selected image + * + * @ret image Executable image, or NULL + */ +struct image * image_find_selected ( void ) { + struct image *image; + + for_each_image ( image ) { + if ( image->flags & IMAGE_SELECTED ) + return image; + } + return NULL; +} + +/** + * Register and select an image + * + * @v image Executable image + * @ret rc Return status code + */ +int register_and_select_image ( struct image *image ) { int rc; if ( ( rc = register_image ( image ) ) != 0 ) return rc; - if ( ( rc = image_autoload ( image ) ) != 0 ) + if ( ( rc = image_probe ( image ) ) != 0 ) + return rc; + + if ( ( rc = image_select ( image ) ) != 0 ) return rc; return 0; } /** - * Register and autoexec an image + * Register and boot an image * * @v image Image * @ret rc Return status code */ -int register_and_autoexec_image ( struct image *image ) { +int register_and_boot_image ( struct image *image ) { int rc; - if ( ( rc = register_and_autoload_image ( image ) ) != 0 ) + if ( ( rc = register_and_select_image ( image ) ) != 0 ) return rc; if ( ( rc = image_exec ( image ) ) != 0 ) |
