@ -678,8 +678,10 @@ static bool is_iso_bc_entry_compatible(IsoBcSection *s)
if ( s - > unused | | ! s - > sector_count ) {
return false ;
}
read_iso_sector ( bswap32 ( s - > load_rba ) , magic_sec ,
" Failed to read image sector 0 " ) ;
if ( virtio_read ( bswap32 ( s - > load_rba ) , magic_sec ) ) {
puts ( " Failed to read image sector 0 " ) ;
return false ;
}
/* Checking bytes 8 - 32 for S390 Linux magic */
return ! memcmp ( magic_sec + 8 , linux_s390_magic , 24 ) ;
@ -692,28 +694,35 @@ static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH];
/* Remained directory space in bytes */
static uint32_t dir_rem [ ISO9660_MAX_DIR_DEPTH ] ;
static inline uint32_t iso_get_file_size ( uint32_t load_rba )
static inline long iso_get_file_size ( uint32_t load_rba )
{
IsoVolDesc * vd = ( IsoVolDesc * ) sec ;
IsoDirHdr * cur_record = & vd - > vd . primary . rootdir ;
uint8_t * temp = sec + ISO_SECTOR_SIZE ;
int level = 0 ;
read_iso_sector ( ISO_PRIMARY_VD_SECTOR , sec ,
" Failed to read ISO primary descriptor " ) ;
if ( virtio_read ( ISO_PRIMARY_VD_SECTOR , sec ) ) {
puts ( " Failed to read ISO primary descriptor " ) ;
return - EIO ;
}
sec_loc [ 0 ] = iso_733_to_u32 ( cur_record - > ext_loc ) ;
dir_rem [ 0 ] = 0 ;
sec_offset [ 0 ] = 0 ;
while ( level > = 0 ) {
IPL_assert ( sec_offset [ level ] < = ISO_SECTOR_SIZE ,
" Directory tree structure violation " ) ;
if ( sec_offset [ level ] > ISO_SECTOR_SIZE ) {
puts ( " Directory tree structure violation " ) ;
return - EIO ;
}
cur_record = ( IsoDirHdr * ) ( temp + sec_offset [ level ] ) ;
if ( sec_offset [ level ] = = 0 ) {
read_iso_sector ( sec_loc [ level ] , temp ,
" Failed to read ISO directory " ) ;
if ( virtio_read ( sec_loc [ level ] , temp ) ) {
puts ( " Failed to read ISO directory " ) ;
return - EIO ;
}
if ( dir_rem [ level ] = = 0 ) {
/* Skip self and parent records */
dir_rem [ level ] = iso_733_to_u32 ( cur_record - > data_len ) -
@ -758,8 +767,10 @@ static inline uint32_t iso_get_file_size(uint32_t load_rba)
if ( dir_rem [ level ] = = 0 ) {
/* Nothing remaining */
level - - ;
read_iso_sector ( sec_loc [ level ] , temp ,
" Failed to read ISO directory " ) ;
if ( virtio_read ( sec_loc [ level ] , temp ) ) {
puts ( " Failed to read ISO directory " ) ;
return - EIO ;
}
}
}
@ -774,19 +785,24 @@ static void load_iso_bc_entry(IsoBcSection *load)
* is padded and ISO_SECTOR_SIZE bytes aligned
*/
uint32_t blks_to_load = bswap16 ( s . sector_count ) > > ET_SECTOR_SHIFT ;
uint32_t real_size = iso_get_file_size ( bswap32 ( s . load_rba ) ) ;
long real_size = iso_get_file_size ( bswap32 ( s . load_rba ) ) ;
if ( real_size ) {
if ( real_size > 0 ) {
/* Round up blocks to load */
blks_to_load = ( real_size + ISO_SECTOR_SIZE - 1 ) / ISO_SECTOR_SIZE ;
puts ( " ISO boot image size verified " ) ;
} else {
puts ( " ISO boot image size could not be verified " ) ;
if ( real_size < 0 ) {
return ;
}
}
read_iso_boot_image ( bswap32 ( s . load_rba ) ,
if ( read_iso_boot_image ( bswap32 ( s . load_rba ) ,
( void * ) ( ( uint64_t ) bswap16 ( s . load_segment ) ) ,
blks_to_load ) ;
blks_to_load ) ) {
return ;
}
jump_to_low_kernel ( ) ;
}
@ -809,17 +825,18 @@ static uint32_t find_iso_bc(void)
return bswap32 ( et - > bc_offset ) ;
}
}
read_iso_sector ( block_num + + , sec ,
" Failed to read ISO volume descriptor " ) ;
if ( virtio_read ( block_num + + , sec ) ) {
puts ( " Failed to read ISO volume descriptor " ) ;
return 0 ;
}
}
return 0 ;
}
static IsoBcSection * find_iso_bc_entry ( void )
static IsoBcSection * find_iso_bc_entry ( uint32_t offset )
{
IsoBcEntry * e = ( IsoBcEntry * ) sec ;
uint32_t offset = find_iso_bc ( ) ;
int i ;
unsigned int loadparm = get_loadparm_index ( ) ;
@ -827,11 +844,13 @@ static IsoBcSection *find_iso_bc_entry(void)
return NULL ;
}
read_iso_sector ( offset , sec , " Failed to read El Torito boot catalog " ) ;
if ( virtio_read ( offset , sec ) ) {
puts ( " Failed to read El Torito boot catalog " ) ;
return NULL ;
}
if ( ! is_iso_bc_valid ( e ) ) {
/* The validation entry is mandatory */
panic ( " No valid boot catalog found! \n " ) ;
return NULL ;
}
@ -851,19 +870,25 @@ static IsoBcSection *find_iso_bc_entry(void)
}
}
panic ( " No suitable boot entry found on ISO-9660 media! \n " ) ;
return NULL ;
}
static void ipl_iso_el_torito ( void )
static int ipl_iso_el_torito ( void )
{
IsoBcSection * s = find_iso_bc_entry ( ) ;
uint32_t offset = find_iso_bc ( ) ;
if ( ! offset ) {
return 0 ;
}
IsoBcSection * s = find_iso_bc_entry ( offset ) ;
if ( s ) {
load_iso_bc_entry ( s ) ;
/* no return */
load_iso_bc_entry ( s ) ; /* only return in error */
return - 1 ;
}
puts ( " No suitable boot entry found on ISO-9660 media! " ) ;
return - EIO ;
}
/**
@ -893,7 +918,9 @@ static void zipl_load_vblk(void)
if ( blksize ! = VIRTIO_ISO_BLOCK_SIZE ) {
virtio_assume_iso9660 ( ) ;
}
ipl_iso_el_torito ( ) ;
if ( ipl_iso_el_torito ( ) ) {
return ;
}
}
if ( blksize ! = VIRTIO_DASD_DEFAULT_BLOCK_SIZE ) {
@ -907,7 +934,9 @@ static void zipl_load_vscsi(void)
{
if ( virtio_get_block_size ( ) = = VIRTIO_ISO_BLOCK_SIZE ) {
/* Is it an ISO image in non-CD drive? */
ipl_iso_el_torito ( ) ;
if ( ipl_iso_el_torito ( ) ) {
return ;
}
}
puts ( " Using guessed DASD geometry. " ) ;