eltorito.c File Reference

El Torito bootable ISO image format. More...

#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <realmode.h>
#include <bootsector.h>
#include <int13.h>
#include <gpxe/uaccess.h>
#include <gpxe/image.h>
#include <gpxe/segment.h>
#include <gpxe/ramdisk.h>
#include <gpxe/init.h>

Go to the source code of this file.

Data Structures

struct  eltorito_vol_desc
 An El Torito Boot Record Volume Descriptor. More...
struct  eltorito_validation_entry
 An El Torito Boot Catalog Validation Entry. More...
struct  eltorito_boot_entry
 A bootable entry in the El Torito Boot Catalog. More...

Defines

#define ISO9660_BLKSIZE   2048
#define ELTORITO_VOL_DESC_OFFSET   ( 17 * ISO9660_BLKSIZE )
#define ELTORITO_BOOTABLE   0x88
 Boot indicator for a bootable ISO image.

Enumerations

enum  eltorito_media_type { ELTORITO_NO_EMULATION = 0 }
 El Torito media types. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER)
struct image_type
eltorito_image_type 
__image_type (PROBE_NORMAL)
 El Torito image type.
static unsigned int word_checksum (void *data, size_t len)
 Calculate 16-bit word checksum.
static int eltorito_exec (struct image *image)
 Execute El Torito image.
static int eltorito_read_voldesc (struct image *image, unsigned long *catalog_offset)
 Read and verify El Torito Boot Record Volume Descriptor.
static int eltorito_read_catalog (struct image *image, unsigned long catalog_offset, struct eltorito_boot_entry *boot_entry)
 Read and verify El Torito Boot Catalog.
static int eltorito_load_disk (struct image *image, struct eltorito_boot_entry *boot_entry)
 Load El Torito virtual disk image into memory.
static int eltorito_load (struct image *image)
 Load El Torito image into memory.


Detailed Description

El Torito bootable ISO image format.

Definition in file eltorito.c.


Define Documentation

#define ISO9660_BLKSIZE   2048

#define ELTORITO_VOL_DESC_OFFSET   ( 17 * ISO9660_BLKSIZE )

Definition at line 41 of file eltorito.c.

Referenced by eltorito_read_voldesc().

#define ELTORITO_BOOTABLE   0x88

Boot indicator for a bootable ISO image.

Definition at line 106 of file eltorito.c.

Referenced by eltorito_read_catalog().


Enumeration Type Documentation

El Torito media types.

Enumerator:
ELTORITO_NO_EMULATION  No emulation.

Definition at line 109 of file eltorito.c.

00109                          {
00110         /** No emulation */
00111         ELTORITO_NO_EMULATION = 0,
00112 };


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

struct image_type eltorito_image_type __image_type ( PROBE_NORMAL   )  [read]

El Torito image type.

static unsigned int word_checksum ( void *  data,
size_t  len 
) [static]

Calculate 16-bit word checksum.

Parameters:
data Data to checksum
len Length (in bytes, must be even)
Return values:
sum Checksum

Definition at line 123 of file eltorito.c.

Referenced by eltorito_read_catalog().

00123                                                              {
00124         uint16_t *words;
00125         uint16_t sum = 0;
00126 
00127         for ( words = data ; len ; words++, len -= 2 ) {
00128                 sum += *words;
00129         }
00130         return sum;
00131 }

static int eltorito_exec ( struct image image  )  [static]

Execute El Torito image.

Parameters:
image El Torito image
Return values:
rc Return status code

Definition at line 139 of file eltorito.c.

References ramdisk::blockdev, int13_drive::blockdev, call_bootsector(), image::data, DBGC, int13_drive::drive, ECANCELED, init_ramdisk(), ISO9660_BLKSIZE, image::len, memset(), image::priv, register_int13_drive(), strerror(), image::ul, and unregister_int13_drive().

00139                                                  {
00140         struct ramdisk ramdisk;
00141         struct int13_drive int13_drive;
00142         unsigned int load_segment = image->priv.ul;
00143         unsigned int load_offset = ( load_segment ? 0 : 0x7c00 );
00144         int rc;
00145 
00146         memset ( &ramdisk, 0, sizeof ( ramdisk ) );
00147         init_ramdisk ( &ramdisk, image->data, image->len, ISO9660_BLKSIZE );
00148         
00149         memset ( &int13_drive, 0, sizeof ( int13_drive ) );
00150         int13_drive.blockdev = &ramdisk.blockdev;
00151         register_int13_drive ( &int13_drive );
00152 
00153         if ( ( rc = call_bootsector ( load_segment, load_offset, 
00154                                       int13_drive.drive ) ) != 0 ) {
00155                 DBGC ( image, "ElTorito %p boot failed: %s\n",
00156                        image, strerror ( rc ) );
00157                 goto err;
00158         }
00159         
00160         rc = -ECANCELED; /* -EIMPOSSIBLE */
00161  err:
00162         unregister_int13_drive ( &int13_drive );
00163         return rc;
00164 }

static int eltorito_read_voldesc ( struct image image,
unsigned long *  catalog_offset 
) [static]

Read and verify El Torito Boot Record Volume Descriptor.

Parameters:
image El Torito file
Return values:
catalog_offset Offset of Boot Catalog
rc Return status code

Definition at line 173 of file eltorito.c.

References copy_from_user(), image::data, DBGC, ELTORITO_VOL_DESC_OFFSET, ENOEXEC, ISO9660_BLKSIZE, image::len, memcmp(), offsetof, eltorito_vol_desc::record_indicator, and eltorito_vol_desc::sector.

Referenced by eltorito_load().

00174                                                                    {
00175         static const struct eltorito_vol_desc vol_desc_signature = {
00176                 .record_indicator = 0,
00177                 .iso9660_id = "CD001",
00178                 .version = 1,
00179                 .system_indicator = "EL TORITO SPECIFICATION",
00180         };
00181         struct eltorito_vol_desc vol_desc;
00182 
00183         /* Sanity check */
00184         if ( image->len < ( ELTORITO_VOL_DESC_OFFSET + ISO9660_BLKSIZE ) ) {
00185                 DBGC ( image, "ElTorito %p too short\n", image );
00186                 return -ENOEXEC;
00187         }
00188 
00189         /* Read and verify Boot Record Volume Descriptor */
00190         copy_from_user ( &vol_desc, image->data, ELTORITO_VOL_DESC_OFFSET,
00191                          sizeof ( vol_desc ) );
00192         if ( memcmp ( &vol_desc, &vol_desc_signature,
00193                       offsetof ( typeof ( vol_desc ), sector ) ) != 0 ) {
00194                 DBGC ( image, "ElTorito %p invalid Boot Record Volume "
00195                        "Descriptor\n", image );
00196                 return -ENOEXEC;
00197         }
00198         *catalog_offset = ( vol_desc.sector * ISO9660_BLKSIZE );
00199 
00200         DBGC ( image, "ElTorito %p boot catalog at offset %#lx\n",
00201                image, *catalog_offset );
00202 
00203         return 0;
00204 }

static int eltorito_read_catalog ( struct image image,
unsigned long  catalog_offset,
struct eltorito_boot_entry boot_entry 
) [static]

Read and verify El Torito Boot Catalog.

Parameters:
image El Torito file
catalog_offset Offset of Boot Catalog
Return values:
boot_entry El Torito boot entry
rc Return status code

Definition at line 214 of file eltorito.c.

References copy_from_user(), image::data, DBGC, ELTORITO_BOOTABLE, ELTORITO_NO_EMULATION, ENOEXEC, ENOTSUP, eltorito_boot_entry::indicator, ISO9660_BLKSIZE, image::len, eltorito_boot_entry::load_segment, eltorito_boot_entry::media_type, and word_checksum().

Referenced by eltorito_load().

00216                                                                             {
00217         struct eltorito_validation_entry validation_entry;
00218 
00219         /* Sanity check */
00220         if ( image->len < ( catalog_offset + ISO9660_BLKSIZE ) ) {
00221                 DBGC ( image, "ElTorito %p bad boot catalog offset %#lx\n",
00222                        image, catalog_offset );
00223                 return -ENOEXEC;
00224         }
00225 
00226         /* Read and verify the Validation Entry of the Boot Catalog */
00227         copy_from_user ( &validation_entry, image->data, catalog_offset,
00228                          sizeof ( validation_entry ) );
00229         if ( word_checksum ( &validation_entry,
00230                              sizeof ( validation_entry ) ) != 0 ) {
00231                 DBGC ( image, "ElTorito %p bad Validation Entry checksum\n",
00232                        image );
00233                 return -ENOEXEC;
00234         }
00235 
00236         /* Read and verify the Initial/Default entry */
00237         copy_from_user ( boot_entry, image->data,
00238                          ( catalog_offset + sizeof ( validation_entry ) ),
00239                          sizeof ( *boot_entry ) );
00240         if ( boot_entry->indicator != ELTORITO_BOOTABLE ) {
00241                 DBGC ( image, "ElTorito %p not bootable\n", image );
00242                 return -ENOEXEC;
00243         }
00244         if ( boot_entry->media_type != ELTORITO_NO_EMULATION ) {
00245                 DBGC ( image, "ElTorito %p cannot support media type %d\n",
00246                        image, boot_entry->media_type );
00247                 return -ENOTSUP;
00248         }
00249 
00250         DBGC ( image, "ElTorito %p media type %d segment %04x\n",
00251                image, boot_entry->media_type, boot_entry->load_segment );
00252 
00253         return 0;
00254 }

static int eltorito_load_disk ( struct image image,
struct eltorito_boot_entry boot_entry 
) [static]

Load El Torito virtual disk image into memory.

Parameters:
image El Torito file
boot_entry El Torito boot entry
Return values:
rc Return status code

Definition at line 263 of file eltorito.c.

References image::data, DBGC, ENOEXEC, ISO9660_BLKSIZE, image::len, eltorito_boot_entry::length, eltorito_boot_entry::load_segment, memcpy_user(), prep_segment(), real_to_user(), eltorito_boot_entry::start, and strerror().

Referenced by eltorito_load().

00264                                                                          {
00265         unsigned long start = ( boot_entry->start * ISO9660_BLKSIZE );
00266         unsigned long length = ( boot_entry->length * ISO9660_BLKSIZE );
00267         unsigned int load_segment;
00268         userptr_t buffer;
00269         int rc;
00270 
00271         /* Sanity check */
00272         if ( image->len < ( start + length ) ) {
00273                 DBGC ( image, "ElTorito %p virtual disk lies outside image\n",
00274                        image );
00275                 return -ENOEXEC;
00276         }
00277         DBGC ( image, "ElTorito %p virtual disk at %#lx+%#lx\n",
00278                image, start, length );
00279 
00280         /* Calculate load address */
00281         load_segment = boot_entry->load_segment;
00282         buffer = real_to_user ( load_segment, ( load_segment ? 0 : 0x7c00 ) );
00283 
00284         /* Verify and prepare segment */
00285         if ( ( rc = prep_segment ( buffer, length, length ) ) != 0 ) {
00286                 DBGC ( image, "ElTorito %p could not prepare segment: %s\n",
00287                        image, strerror ( rc ) );
00288                 return rc;
00289         }
00290 
00291         /* Copy image to segment */
00292         memcpy_user ( buffer, 0, image->data, start, length );
00293 
00294         return 0;
00295 }

static int eltorito_load ( struct image image  )  [static]

Load El Torito image into memory.

Parameters:
image El Torito file
Return values:
rc Return status code

Definition at line 303 of file eltorito.c.

References eltorito_load_disk(), eltorito_read_catalog(), eltorito_read_voldesc(), eltorito_boot_entry::load_segment, image::priv, image::type, and image::ul.

00303                                                  {
00304         struct eltorito_boot_entry boot_entry;
00305         unsigned long bootcat_offset;
00306         int rc;
00307 
00308         /* Read Boot Record Volume Descriptor, if present */
00309         if ( ( rc = eltorito_read_voldesc ( image, &bootcat_offset ) ) != 0 )
00310                 return rc;
00311 
00312         /* This is an El Torito image, valid or otherwise */
00313         if ( ! image->type )
00314                 image->type = &eltorito_image_type;
00315 
00316         /* Read Boot Catalog */
00317         if ( ( rc = eltorito_read_catalog ( image, bootcat_offset,
00318                                             &boot_entry ) ) != 0 )
00319                 return rc;
00320 
00321         /* Load Virtual Disk image */
00322         if ( ( rc = eltorito_load_disk ( image, &boot_entry ) ) != 0 )
00323                 return rc;
00324 
00325         /* Record load segment in image private data field */
00326         image->priv.ul = boot_entry.load_segment;
00327 
00328         return 0;
00329 }


Generated on Tue Apr 6 20:01:12 2010 for gPXE by  doxygen 1.5.7.1