#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. | |
Definition in file eltorito.c.
| #define ISO9660_BLKSIZE 2048 |
Definition at line 40 of file eltorito.c.
Referenced by eltorito_exec(), eltorito_load_disk(), eltorito_read_catalog(), and eltorito_read_voldesc().
| #define ELTORITO_VOL_DESC_OFFSET ( 17 * ISO9660_BLKSIZE ) |
| #define ELTORITO_BOOTABLE 0x88 |
Boot indicator for a bootable ISO image.
Definition at line 106 of file eltorito.c.
Referenced by eltorito_read_catalog().
| enum eltorito_media_type |
El Torito media types.
Definition at line 109 of file eltorito.c.
00109 { 00110 /** No emulation */ 00111 ELTORITO_NO_EMULATION = 0, 00112 };
| 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.
| data | Data to checksum | |
| len | Length (in bytes, must be even) |
| 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.
| 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.
| image | El Torito file |
| 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.
| image | El Torito file | |
| catalog_offset | Offset of Boot Catalog |
| 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.
| image | El Torito file | |
| boot_entry | El Torito boot entry |
| 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.
| image | El Torito file |
| 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 }
1.5.7.1