From Nathan Whitehorn (nwhitehorn at freebsd dot org):

Add code to generate bootable ISOs on Powermac and CHRP systems.
Synthesize some partition maps (APM and MBR, respectively) pointing
to (a) the whole disk, and (b) relevant El Torito boot images that
have been added by other code. These partition maps are a little
bit funny looking, but they seem to work. FreeBSD has been using
this successfully in their release generation on powerpc, as well
as generating all non-SPARC install media. SPARC support could
probably be added as an extension of this patch.
This commit is contained in:
christos 2011-05-22 21:51:39 +00:00
parent 1742cf8828
commit 0477909eb4
4 changed files with 168 additions and 7 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660.c,v 1.28 2010/11/19 15:47:32 tsutsui Exp $ */
/* $NetBSD: cd9660.c,v 1.29 2011/05/22 21:51:39 christos Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -103,7 +103,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: cd9660.c,v 1.28 2010/11/19 15:47:32 tsutsui Exp $");
__RCSID("$NetBSD: cd9660.c,v 1.29 2011/05/22 21:51:39 christos Exp $");
#endif /* !__lint */
#include <string.h>
@ -215,6 +215,7 @@ cd9660_set_defaults(void)
diskStructure.rr_moved_dir = 0;
diskStructure.archimedes_enabled = 0;
diskStructure.chrp_boot = 0;
diskStructure.include_padding_areas = 1;
@ -399,6 +400,8 @@ cd9660_parse_opts(const char *option, fsinfo_t *fsopts)
diskStructure.rock_ridge_enabled = 1;
else if (CD9660_IS_COMMAND_ARG_DUAL(var, "A", "archimedes"))
diskStructure.archimedes_enabled = 1;
else if (CD9660_IS_COMMAND_ARG(var, "chrp-boot"))
diskStructure.chrp_boot = 1;
else if (CD9660_IS_COMMAND_ARG_DUAL(var, "K", "keep-bad-images"))
diskStructure.keep_bad_images = 1;
else if (CD9660_IS_COMMAND_ARG(var, "allow-deep-trees"))

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660.h,v 1.15 2010/10/27 18:51:34 christos Exp $ */
/* $NetBSD: cd9660.h,v 1.16 2011/05/22 21:51:39 christos Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -286,6 +286,7 @@ typedef struct _iso9660_disk {
cd9660node *rr_moved_dir;
int archimedes_enabled;
int chrp_boot;
/* Spec breaking options */
u_char allow_deep_trees;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd9660_eltorito.c,v 1.14 2010/10/27 18:51:35 christos Exp $ */
/* $NetBSD: cd9660_eltorito.c,v 1.15 2011/05/22 21:51:39 christos Exp $ */
/*
* Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@ -31,12 +31,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <sys/endian.h>
#include "cd9660.h"
#include "cd9660_eltorito.h"
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: cd9660_eltorito.c,v 1.14 2010/10/27 18:51:35 christos Exp $");
__RCSID("$NetBSD: cd9660_eltorito.c,v 1.15 2011/05/22 21:51:39 christos Exp $");
#endif /* !__lint */
#ifdef DEBUG
@ -499,11 +502,81 @@ cd9660_setup_boot_volume_descriptor(volume_descriptor *bvd)
return 1;
}
static int
cd9660_write_mbr_partition_entry(FILE *fd, int idx, off_t sector_start,
off_t nsectors, int type)
{
uint8_t val;
uint32_t lba;
if (fseeko(fd, (off_t)(idx) * 16 + 0x1be, SEEK_SET) == -1)
err(1, "fseeko");
val = 0x80; /* Bootable */
fwrite(&val, sizeof(val), 1, fd);
val = 0xff; /* CHS begin */
fwrite(&val, sizeof(val), 1, fd);
fwrite(&val, sizeof(val), 1, fd);
fwrite(&val, sizeof(val), 1, fd);
val = type; /* Part type */
fwrite(&val, sizeof(val), 1, fd);
val = 0xff; /* CHS end */
fwrite(&val, sizeof(val), 1, fd);
fwrite(&val, sizeof(val), 1, fd);
fwrite(&val, sizeof(val), 1, fd);
/* LBA extent */
lba = htole32(sector_start);
fwrite(&lba, sizeof(lba), 1, fd);
lba = htole32(nsectors);
fwrite(&lba, sizeof(lba), 1, fd);
return 0;
}
static int
cd9660_write_apm_partition_entry(FILE *fd, int idx, 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;
if (fseeko(fd, (off_t)(idx + 1) * sector_size, SEEK_SET) == -1)
err(1, "fseeko");
/* Signature */
apm16 = htobe16(0x504d);
fwrite(&apm16, sizeof(apm16), 1, fd);
apm16 = 0;
fwrite(&apm16, sizeof(apm16), 1, fd);
/* Total number of partitions */
apm32 = htobe32(total_partitions);
fwrite(&apm32, sizeof(apm32), 1, fd);
/* Bounds */
apm32 = htobe32(sector_start);
fwrite(&apm32, sizeof(apm32), 1, fd);
apm32 = htobe32(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;
int mbr_partitions = 0;
/* write boot catalog */
if (fseeko(fd, (off_t)diskStructure.boot_catalog_sector *
@ -535,7 +608,88 @@ 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 (t->system == ET_SYS_PPC)
mbr_partitions++;
}
/* some systems need partition tables as well */
if (mbr_partitions > 0 || diskStructure.chrp_boot) {
uint16_t sig;
fseek(fd, 0x1fe, SEEK_SET);
sig = htole16(0xaa55);
fwrite(&sig, sizeof(sig), 1, fd);
mbr_partitions = 0;
/* Write ISO9660 descriptor, enclosing the whole disk */
if (diskStructure.chrp_boot)
cd9660_write_mbr_partition_entry(fd, mbr_partitions++,
0, diskStructure.totalSectors *
(diskStructure.sectorSize / 512), 0x96);
/* Write all partition entries */
TAILQ_FOREACH(t, &diskStructure.boot_images, image_list) {
if (t->system != ET_SYS_PPC)
continue;
cd9660_write_mbr_partition_entry(fd, mbr_partitions++,
t->sector * (diskStructure.sectorSize / 512),
t->num_sectors * (diskStructure.sectorSize / 512),
0x41 /* PReP Boot */);
}
}
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 = htobe16(0x4552);
fwrite(&apm16, sizeof(apm16), 1, fd);
/* Device block size */
apm16 = htobe16(512);
fwrite(&apm16, sizeof(apm16), 1, fd);
/* Device block count */
apm32 = htobe32(diskStructure.totalSectors *
(diskStructure.sectorSize / 512));
fwrite(&apm32, sizeof(apm32), 1, fd);
/* Device type/id */
apm16 = htobe16(1);
fwrite(&apm16, sizeof(apm16), 1, fd);
fwrite(&apm16, sizeof(apm16), 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, 512, "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 / 512), 512, "ISO9660",
"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 * (diskStructure.sectorSize / 512),
t->num_sectors * (diskStructure.sectorSize / 512),
512, "CD Boot", "Apple_Bootstrap");
}
}
return 0;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: makefs.8,v 1.32 2009/01/20 20:47:25 bjh21 Exp $
.\" $NetBSD: makefs.8,v 1.33 2011/05/22 21:51:39 christos Exp $
.\"
.\" Copyright (c) 2001-2003 Wasabi Systems, Inc.
.\" All rights reserved.
@ -33,7 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 10, 2009
.Dd May 22, 2011
.Dt MAKEFS 8
.Os
.Sh NAME
@ -283,6 +283,9 @@ Use the
extension to encode
.Tn RISC OS
metadata.
.It Sy chrp-boot
Write an MBR partition table to the image to allow older CHRP hardware to
boot.
.It Sy boot-load-segment
Set load segment for the boot image.
.It Sy bootimage