static int boot_mips_write(FILE *outfile) { struct directory_entry *boot_file; /* Boot file we need to search for */ unsigned long length = 0; unsigned long extent = 0; int i; struct volume_header vh; unsigned long long iso_size = 0; char *filename = NULL; memset(&vh, 0, sizeof(vh)); iso_size = last_extent * 2048; write_be32(VHMAGIC, (unsigned char *)&vh.vh_magic); /* Values from an IRIX cd */ write_be16(BYTES_PER_SECTOR, (unsigned char *)&vh.vh_dp.dp_secbytes); write_be16(SECTORS_PER_TRACK, (unsigned char *)&vh.vh_dp.dp_secs); write_be32(DP_RESEEK|DP_IGNOREERRORS|DP_TRKFWD, (unsigned char *)&vh.vh_dp.dp_flags); write_be16(1, (unsigned char *)&vh.vh_dp.dp_trks0); write_be16((iso_size + BYTES_PER_SECTOR - 1) / (SECTORS_PER_TRACK * BYTES_PER_SECTOR), (unsigned char *)&vh.vh_dp.dp_cyls); for(i = 0; i < boot_mips_num_files; i++) { boot_file = search_tree_file(root, boot_mips_filename[i]); if (!boot_file) { #ifdef USE_LIBSCHILY comerrno(EX_BAD, "Uh oh, I cant find the MIPS boot file '%s'!\n", boot_mips_filename[i]); #else fprintf(stderr, "Uh oh, I cant find the MIPS boot file '%s'!\n", boot_mips_filename[i]); exit(1); #endif } extent = get_733(boot_file->isorec.extent) * 4; length = ((get_733(boot_file->isorec.size) + 2047) / 2048) * 2048; filename = file_base_name(boot_mips_filename[i]); strncpy((char *)vh.vh_vd[i].vd_name, filename, MIN(VDNAMESIZE, strlen(filename))); write_be32(extent, (unsigned char *)&vh.vh_vd[i].vd_lbn); write_be32(length, (unsigned char *)&vh.vh_vd[i].vd_nbytes); fprintf(stderr, "Found mips boot image %s, using extent %lu (0x%lX), #blocks %lu (0x%lX)\n", filename, extent, extent, length, length); } /* Create volume partition on whole cd iso */ write_be32((iso_size + (BYTES_PER_SECTOR - 1))/ BYTES_PER_SECTOR, (unsigned char *)&vh.vh_pt[10].pt_nblks); write_be32(0, (unsigned char *)&vh.vh_pt[10].pt_firstlbn); write_be32(PTYPE_VOLUME, (unsigned char *)&vh.vh_pt[10].pt_type); /* Create volume header partition, also on WHOLE cd iso */ write_be32((iso_size + (BYTES_PER_SECTOR - 1))/ BYTES_PER_SECTOR, (unsigned char *)&vh.vh_pt[8].pt_nblks); write_be32(0, (unsigned char *)&vh.vh_pt[8].pt_firstlbn); write_be32(PTYPE_VOLHDR, (unsigned char *)&vh.vh_pt[8].pt_type); /* Create checksum */ vh_calc_checksum(&vh); jtwrite(&vh, sizeof(vh), 1, 0, FALSE); xfwrite(&vh, sizeof(vh), 1, outfile, 0, FALSE); last_extent_written++; return 0; }
void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) { int bootcat; int checksum; unsigned char * checksum_ptr; struct directory_entry * de; struct directory_entry * de2; int i; int nsectors; memset(boot_desc, 0, sizeof(*boot_desc)); boot_desc->id[0] = 0; memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID) - 1); boot_desc->version[0] = 1; memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID)); /* * search from root of iso fs to find boot catalog */ de2 = search_tree_file(root, boot_catalog); if (!de2) { fprintf(stderr,"Uh oh, I cant find the boot catalog!\n"); exit(1); } set_731(boot_desc->bootcat_ptr, (unsigned int) get_733(de2->isorec.extent)); /* * now adjust boot catalog * lets find boot image first */ de=search_tree_file(root, boot_image); if (!de) { fprintf(stderr,"Uh oh, I cant find the boot image!\n"); exit(1); } /* * we have the boot image, so write boot catalog information * Next we write out the primary descriptor for the disc */ memset(&valid_desc, 0, sizeof(valid_desc)); valid_desc.headerid[0] = 1; valid_desc.arch[0] = EL_TORITO_ARCH_x86; /* * we'll shove start of publisher id into id field, may get truncated * but who really reads this stuff! */ if (publisher) memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher))); valid_desc.key1[0] = 0x55; valid_desc.key2[0] = 0xAA; /* * compute the checksum */ checksum=0; checksum_ptr = (unsigned char *) &valid_desc; for (i=0; i<sizeof(valid_desc); i+=2) { /* * skip adding in ckecksum word, since we dont have it yet! */ if (i == 28) { continue; } checksum += (unsigned int)checksum_ptr[i]; checksum += ((unsigned int)checksum_ptr[i+1])*256; } /* * now find out the real checksum */ checksum = -checksum; set_721(valid_desc.cksum, (unsigned int) checksum); /* * now make the initial/default entry for boot catalog */ memset(&default_desc, 0, sizeof(default_desc)); default_desc.boot_id[0] = EL_TORITO_BOOTABLE; /* * use default BIOS loadpnt */ set_721(default_desc.loadseg, 0); default_desc.arch[0] = EL_TORITO_ARCH_x86; /* * figure out size of boot image in sectors, for now hard code to * assume 512 bytes/sector on a bootable floppy */ nsectors = ((de->size + 511) & ~(511))/512; #ifdef APPLE_HYB /* NON-HFS change */ if (verbose > 0 ) #endif /* APPLE_HYB */ fprintf(stderr, "\nSize of boot image is %d sectors -> ", nsectors); /* * choose size of emulated floppy based on boot image size */ if (nsectors == 2880 ) { default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP; #ifdef APPLE_HYB /* NON-HFS change */ if (verbose > 0 ) #endif /* APPLE_HYB */ fprintf(stderr, "Emulating a 1.44 meg floppy\n"); } else if (nsectors == 5760 ) { default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP; #ifdef APPLE_HYB /* NON-HFS change */ if (verbose > 0 ) #endif /* APPLE_HYB */ fprintf(stderr,"Emulating a 2.88 meg floppy\n"); } else if (nsectors == 2400 ) { default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP; #ifdef APPLE_HYB /* NON-HFS change */ if (verbose > 0 ) #endif /* APPLE_HYB */ fprintf(stderr,"Emulating a 1.2 meg floppy\n"); } else if (nsectors == 4 ) { default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL; #ifdef APPLE_HYB /* NON-HFS change */ if (verbose > 0 ) #endif /* APPLE_HYB */ fprintf(stderr,"No-emulation CD boot sector\n"); } else { fprintf(stderr,"\nError - boot image is not the an allowable size.\n"); exit(1); } /* * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT, unless it's no-emulation * boot. */ if (default_desc.boot_media[0] != EL_TORITO_MEDIA_NOEMUL) nsectors = 1; set_721(default_desc.nsect, (unsigned int) nsectors ); #ifdef DEBUG_TORITO fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent)); #endif set_731(default_desc.bootoff, (unsigned int) get_733(de->isorec.extent)); /* * now write it to disk */ bootcat = open(de2->whole_name, O_RDWR | O_BINARY); if (bootcat == -1) { fprintf(stderr,"Error opening boot catalog for update.\n"); perror(""); exit(1); } /* * write out */ write(bootcat, &valid_desc, 32); write(bootcat, &default_desc, 32); close(bootcat); } /* get_torito_desc(... */