aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Whitehorn <nwhitehorn@FreeBSD.org>2011-05-03 15:12:01 +0000
committerNathan Whitehorn <nwhitehorn@FreeBSD.org>2011-05-03 15:12:01 +0000
commitb3fa6d2cf1eea1b02acc2bee3b61d71fb9afe5ec (patch)
tree06cd023991d718634a951391ab99f7ba4db48af0
parent20ff6c114f4431e32ec0ff53ba81e420bd4e86a5 (diff)
downloadsrc-b3fa6d2cf1eea1b02acc2bee3b61d71fb9afe5ec.tar.gz
src-b3fa6d2cf1eea1b02acc2bee3b61d71fb9afe5ec.zip
Add support for synthesizing an APM partition map to map Mac PowerPC
bootstrap partitions from the ISO9660 boot catalog. This preserves OS X's ability to mount the CD, while allowing us a way to provide HFS-ified bootstrap code for Open Firmware.
Notes
Notes: svn path=/head/; revision=221387
-rw-r--r--usr.sbin/makefs/cd9660/cd9660_eltorito.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/usr.sbin/makefs/cd9660/cd9660_eltorito.c b/usr.sbin/makefs/cd9660/cd9660_eltorito.c
index 055451d1800c..f0c8b2d4b18f 100644
--- a/usr.sbin/makefs/cd9660/cd9660_eltorito.c
+++ b/usr.sbin/makefs/cd9660/cd9660_eltorito.c
@@ -31,6 +31,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
+
+#include <netinet/in.h>
+
#include "cd9660.h"
#include "cd9660_eltorito.h"
@@ -497,11 +500,43 @@ cd9660_setup_boot_volume_descriptor(volume_descriptor *bvd)
return 1;
}
+static int
+cd9660_write_apm_partition_entry(FILE *fd, int index, int total_partitions,
+ off_t sector_start, off_t nsectors, off_t sector_size,
+ const char *part_name, const char *part_type) {
+ uint32_t apm32;
+ uint16_t apm16;
+
+ fseeko(fd, (off_t)(index + 1) * sector_size, SEEK_SET);
+
+ /* Signature */
+ apm16 = htons(0x504d);
+ fwrite(&apm16, sizeof(apm16), 1, fd);
+ apm16 = 0;
+ fwrite(&apm16, sizeof(apm16), 1, fd);
+
+ /* Total number of partitions */
+ apm32 = htonl(total_partitions);
+ fwrite(&apm32, sizeof(apm32), 1, fd);
+ /* Bounds */
+ apm32 = htonl(sector_start);
+ fwrite(&apm32, sizeof(apm32), 1, fd);
+ apm32 = htonl(nsectors);
+ fwrite(&apm32, sizeof(apm32), 1, fd);
+
+ fwrite(part_name, strlen(part_name) + 1, 1, fd);
+ fseek(fd, 32 - strlen(part_name) - 1, SEEK_CUR);
+ fwrite(part_type, strlen(part_type) + 1, 1, fd);
+
+ return 0;
+}
+
int
cd9660_write_boot(FILE *fd)
{
struct boot_catalog_entry *e;
struct cd9660_boot_image *t;
+ int apm_partitions = 0;
/* write boot catalog */
if (fseeko(fd, (off_t)diskStructure.boot_catalog_sector *
@@ -533,7 +568,51 @@ cd9660_write_boot(FILE *fd)
t->filename, t->sector);
}
cd9660_copy_file(fd, t->sector, t->filename);
+
+ if (t->system == ET_SYS_MAC)
+ apm_partitions++;
+ }
+
+ if (apm_partitions > 0) {
+ /* Write DDR and global APM info */
+ uint32_t apm32;
+ uint16_t apm16;
+ int total_parts;
+
+ fseek(fd, 0, SEEK_SET);
+ apm16 = htons(0x4552);
+ fwrite(&apm16, sizeof(apm16), 1, fd);
+ apm16 = htons(diskStructure.sectorSize);
+ fwrite(&apm16, sizeof(apm16), 1, fd);
+ apm32 = htonl(diskStructure.totalSectors);
+ fwrite(&apm32, sizeof(apm32), 1, fd);
+
+ /* Count total needed entries */
+ total_parts = 2 + apm_partitions; /* Self + ISO9660 */
+
+ /* Write self-descriptor */
+ cd9660_write_apm_partition_entry(fd, 0,
+ total_parts, 1, total_parts, diskStructure.sectorSize,
+ "Apple", "Apple_partition_map");
+
+ /* Write ISO9660 descriptor, enclosing the whole disk */
+ cd9660_write_apm_partition_entry(fd, 1,
+ total_parts, 0, diskStructure.totalSectors,
+ diskStructure.sectorSize, "", "CD_ROM_Mode_1");
+
+ /* Write all partition entries */
+ apm_partitions = 0;
+ TAILQ_FOREACH(t, &diskStructure.boot_images, image_list) {
+ if (t->system != ET_SYS_MAC)
+ continue;
+
+ cd9660_write_apm_partition_entry(fd,
+ 2 + apm_partitions++, total_parts,
+ t->sector, t->num_sectors, diskStructure.sectorSize,
+ "CD Boot", "Apple_Bootstrap");
+ }
}
return 0;
}
+