📄 eltorito.c
字号:
fill_boot_desc(boot_desc_entry, boot_entry) struct eltorito_defaultboot_entry *boot_desc_entry; struct eltorito_boot_entry_info *boot_entry;{ struct directory_entry *de; /* Boot file */ int bootmbr; int i; int nsectors; int geosec; if (!boot_desc_entry || !boot_entry) return; /* now adjust boot catalog lets find boot image first */ de = search_tree_file(root, boot_entry->boot_image); if (!de) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Uh oh, I cant find the boot image '%s' !\n", boot_entry->boot_image);#else fprintf(stderr, "Uh oh, I cant find the boot image '%s' !\n", boot_entry->boot_image); exit(1);#endif } /* now make the initial/default entry for boot catalog */ memset(boot_desc_entry, 0, sizeof(*boot_desc_entry)); boot_desc_entry->boot_id[0] = (char) boot_entry->not_bootable ? EL_TORITO_NOT_BOOTABLE : EL_TORITO_BOOTABLE; /* use default BIOS loadpnt */ set_721(boot_desc_entry->loadseg, boot_entry->load_addr); /* * figure out size of boot image in 512-byte sectors. * However, round up to the nearest integral CD (2048-byte) sector. * This is only used for no-emulation booting. */ nsectors = boot_entry->load_size ? boot_entry->load_size : ((de->size + 2047) / 2048) * 4; fprintf(stderr, "\nSize of boot image is %d sectors -> ", nsectors); if (boot_entry->hard_disk_boot) { /* sanity test hard disk boot image */ boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_HD; fprintf(stderr, "Emulating a hard disk\n"); /* read MBR */ bootmbr = open(de->whole_name, O_RDONLY | O_BINARY); if (bootmbr == -1) {#ifdef USE_LIBSCHILY comerr("Error opening boot image '%s' for read.\n", de->whole_name);#else fprintf(stderr, "Error opening boot image '%s' for read.\n", de->whole_name); perror(""); exit(1);#endif } if (read(bootmbr, &disk_mbr, sizeof(disk_mbr)) != sizeof(disk_mbr)) {#ifdef USE_LIBSCHILY comerr("Error reading MBR from boot image '%s'.\n", de->whole_name);#else fprintf(stderr, "Error reading MBR from boot image '%s'.\n", de->whole_name); exit(1);#endif } close(bootmbr); if (la_to_u_2_byte(disk_mbr.magic) != MBR_MAGIC) {#ifdef USE_LIBSCHILY errmsgno(EX_BAD, "Warning: boot image '%s' MBR is not a boot sector.\n", de->whole_name);#else fprintf(stderr, "Warning: boot image '%s' MBR is not a boot sector.\n", de->whole_name);#endif } /* find partition type */ boot_desc_entry->sys_type[0] = PARTITION_UNUSED; for (i = 0; i < PARTITION_COUNT; ++i) { int s_cyl_sec; int e_cyl_sec; s_cyl_sec = la_to_u_2_byte(disk_mbr.partition[i].s_cyl_sec); e_cyl_sec = la_to_u_2_byte(disk_mbr.partition[i].e_cyl_sec); if (disk_mbr.partition[i].type != PARTITION_UNUSED) { if (boot_desc_entry->sys_type[0] != PARTITION_UNUSED) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Boot image '%s' has multiple partitions.\n", de->whole_name);#else fprintf(stderr, "Boot image '%s' has multiple partitions.\n", de->whole_name); exit(1);#endif } boot_desc_entry->sys_type[0] = disk_mbr.partition[i].type; /* a few simple sanity warnings */ if (!boot_entry->not_bootable && disk_mbr.partition[i].status != PARTITION_ACTIVE) { fprintf(stderr, "Warning: partition not marked active.\n"); } if (MBR_CYLINDER(s_cyl_sec) != 0 || disk_mbr.partition[i].s_head != 1 || MBR_SECTOR(s_cyl_sec != 1)) { fprintf(stderr, "Warning: partition does not start at 0/1/1.\n"); } geosec = (MBR_CYLINDER(e_cyl_sec) + 1) * (disk_mbr.partition[i].e_head + 1) * MBR_SECTOR(e_cyl_sec); if (geosec != nsectors) { fprintf(stderr, "Warning: image size does not match geometry (%d)\n", geosec); }#ifdef DEBUG_TORITO fprintf(stderr, "Partition start %u/%u/%u\n", MBR_CYLINDER(s_cyl_sec), disk_mbr.partition[i].s_head, MBR_SECTOR(s_cyl_sec)); fprintf(stderr, "Partition end %u/%u/%u\n", MBR_CYLINDER(e_cyl_sec), disk_mbr.partition[i].e_head, MBR_SECTOR(e_cyl_sec));#endif } } if (boot_desc_entry->sys_type[0] == PARTITION_UNUSED) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Boot image '%s' has no partitions.\n", de->whole_name);#else fprintf(stderr, "Boot image '%s' has no partitions.\n", de->whole_name); exit(1);#endif }#ifdef DEBUG_TORITO fprintf(stderr, "Partition type %u\n", boot_desc_entry->sys_type[0]);#endif /* load single boot sector, in this case the MBR */ nsectors = 1; } else if (boot_entry->no_emul_boot) { /* * no emulation is a simple image boot of all the sectors * in the boot image */ boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_NOEMUL; fprintf(stderr, "No emulation\n"); } else { /* choose size of emulated floppy based on boot image size */ if (nsectors == 2880) { boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_144FLOP; fprintf(stderr, "Emulating a 1.44 meg floppy\n"); } else if (nsectors == 5760) { boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_288FLOP; fprintf(stderr, "Emulating a 2.88 meg floppy\n"); } else if (nsectors == 2400) { boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_12FLOP; fprintf(stderr, "Emulating a 1.2 meg floppy\n"); } else {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Error - boot image '%s' is not the an allowable size.\n", de->whole_name);#else fprintf(stderr, "Error - boot image '%s' is not the an allowable size.\n", de->whole_name); exit(1);#endif } /* load single boot sector for floppies */ nsectors = 1; } /* fill in boot image details */#ifdef DEBUG_TORITO fprintf(stderr, "Boot %u sectors\n", nsectors); fprintf(stderr, "Extent of boot images is %d\n", get_733(de->isorec.extent));#endif set_721(boot_desc_entry->nsect, (unsigned int) nsectors); set_731(boot_desc_entry->bootoff, (unsigned int) get_733(de->isorec.extent)); /* If the user has asked for it, patch the boot image */ if (boot_entry->boot_info_table) { int bootimage; unsigned int bi_checksum, total_len; static char csum_buffer[SECTOR_SIZE]; int len; struct mkisofs_boot_info bi_table; bootimage = open(de->whole_name, O_RDWR | O_BINARY); if (bootimage == -1) {#ifdef USE_LIBSCHILY comerr( "Error opening boot image file '%s' for update.\n", de->whole_name);#else fprintf(stderr, "Error opening boot image file '%s' for update.\n", de->whole_name); perror(""); exit(1);#endif } /* Compute checksum of boot image, sans 64 bytes */ total_len = 0; bi_checksum = 0; while ((len = read(bootimage, csum_buffer, SECTOR_SIZE)) > 0) { if (total_len & 3) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Odd alignment at non-end-of-file in boot image '%s'.\n", de->whole_name);#else fprintf(stderr, "Odd alignment at non-end-of-file in boot image '%s'.\n", de->whole_name); exit(1);#endif } if (total_len < 64) memset(csum_buffer, 0, 64 - total_len); if (len < SECTOR_SIZE) memset(csum_buffer + len, 0, SECTOR_SIZE-len); for (i = 0; i < SECTOR_SIZE; i += 4) bi_checksum += get_731(&csum_buffer[i]); total_len += len; } if (total_len != de->size) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Boot image file '%s' changed underneath us!\n", de->whole_name);#else fprintf(stderr, "Boot image file '%s' changed underneath us!\n", de->whole_name); exit(1);#endif } /* End of file, set position to byte 8 */ lseek(bootimage, 8, SEEK_SET); memset(&bi_table, 0, sizeof(bi_table)); /* Is it always safe to assume PVD is at session_start+16? */ set_731(bi_table.bi_pvd, session_start + 16); set_731(bi_table.bi_file, de->starting_block); set_731(bi_table.bi_length, de->size); set_731(bi_table.bi_csum, bi_checksum); write(bootimage, &bi_table, sizeof(bi_table)); close(bootimage); }}/* fill_boot_desc(... */voidget_boot_entry(){ if (current_boot_entry) return; current_boot_entry = (struct eltorito_boot_entry_info*) e_malloc(sizeof(struct eltorito_boot_entry_info)); memset(current_boot_entry, 0, sizeof(*current_boot_entry)); if (!first_boot_entry) { first_boot_entry = current_boot_entry; last_boot_entry = current_boot_entry; } else { last_boot_entry->next = current_boot_entry; last_boot_entry = current_boot_entry; }}voidnew_boot_entry(){ current_boot_entry = NULL;}/* * Function to write the EVD for the disc. */static inttvd_write(outfile) FILE *outfile;{ /* check the boot image is not NULL */ if (!boot_image) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "No boot image specified.\n");#else fprintf(stderr, "No boot image specified.\n"); exit(1);#endif } /* Next we write out the boot volume descriptor for the disc */ get_torito_desc(&gboot_desc); xfwrite(&gboot_desc, 1, SECTOR_SIZE, outfile); last_extent_written++; return 0;}struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -