2008-10-19 14:03:13 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2008 Vreixo Formoso
|
2010-04-06 12:41:36 +00:00
|
|
|
* Copyright (c) 2010 Thomas Schmitt
|
2008-10-19 14:03:13 +00:00
|
|
|
*
|
|
|
|
* This file is part of the libisofs project; you can redistribute it and/or
|
2010-01-27 05:48:59 +00:00
|
|
|
* modify it under the terms of the GNU General Public License version 2
|
|
|
|
* or later as published by the Free Software Foundation.
|
|
|
|
* See COPYING file for details.
|
2008-10-19 14:03:13 +00:00
|
|
|
*/
|
|
|
|
|
2010-05-16 08:20:12 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../config.h"
|
|
|
|
#endif
|
|
|
|
|
2010-10-12 10:20:27 +00:00
|
|
|
#include "libisofs.h"
|
2008-10-19 14:03:13 +00:00
|
|
|
#include "system_area.h"
|
|
|
|
#include "eltorito.h"
|
|
|
|
#include "filesrc.h"
|
2010-10-12 18:24:17 +00:00
|
|
|
#include "ecma119_tree.h"
|
|
|
|
#include "image.h"
|
|
|
|
#include "messages.h"
|
2008-10-19 14:03:13 +00:00
|
|
|
|
|
|
|
#include <string.h>
|
2010-04-06 12:41:36 +00:00
|
|
|
#include <stdio.h>
|
2008-10-19 14:03:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a MBR for an isohybrid enabled ISOLINUX boot image.
|
2010-04-06 12:41:36 +00:00
|
|
|
* See libisofs/make_isohybrid_mbr.c
|
|
|
|
* Deprecated.
|
2008-10-19 14:03:13 +00:00
|
|
|
*/
|
|
|
|
int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
|
|
|
|
2010-04-10 16:50:59 +00:00
|
|
|
/*
|
|
|
|
* The New ISOLINUX MBR Producer.
|
|
|
|
* Be cautious with changing parameters. Only few combinations are tested.
|
|
|
|
*
|
|
|
|
*/
|
2010-09-05 10:43:48 +00:00
|
|
|
int make_isolinux_mbr(uint32_t *img_blocks, uint32_t boot_lba,
|
2010-04-10 16:50:59 +00:00
|
|
|
uint32_t mbr_id, int head_count, int sector_count,
|
|
|
|
int part_offset, int part_number, int fs_type,
|
|
|
|
uint8_t *buf, int flag);
|
2010-04-06 12:41:36 +00:00
|
|
|
|
|
|
|
|
2010-09-05 10:43:48 +00:00
|
|
|
/*
|
|
|
|
* @param flag bit0= img_blocks is start address rather than end address:
|
|
|
|
do not subtract 1
|
|
|
|
*/
|
|
|
|
static
|
|
|
|
void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
|
|
|
uint32_t *end_lba, uint32_t *end_sec,
|
|
|
|
uint32_t *end_head, uint32_t *end_cyl, int flag)
|
|
|
|
{
|
|
|
|
uint32_t secs;
|
|
|
|
|
|
|
|
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
|
|
|
if (*img_blocks >= 0x40000000)
|
|
|
|
*img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
|
|
|
if (flag & 1)
|
|
|
|
secs = *end_lba = *img_blocks * 4; /* first valid 512-lba */
|
|
|
|
else
|
|
|
|
secs = *end_lba = *img_blocks * 4 - 1; /* last valid 512-lba */
|
|
|
|
*end_cyl = secs / (sph * hpc);
|
|
|
|
secs -= *end_cyl * sph * hpc;
|
|
|
|
*end_head = secs / sph;
|
|
|
|
*end_sec = secs - *end_head * sph + 1; /* Sector count starts by 1 */
|
|
|
|
if (*end_cyl >= 1024) {
|
|
|
|
*end_cyl = 1023;
|
|
|
|
*end_head = hpc - 1;
|
|
|
|
*end_sec = sph;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-06 12:41:36 +00:00
|
|
|
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
|
|
|
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
|
|
|
"Currently we use first and not last entry. You need to:
|
|
|
|
1) Zero-fill 446-510
|
|
|
|
2) Put 0x55, 0xAA into 510-512
|
|
|
|
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
|
|
|
|
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
|
|
|
|
start in little endian), [LBA end in little endian] at 446-462
|
|
|
|
"
|
|
|
|
|
|
|
|
"C/H/S end" means the CHS address of the last block in the partition.
|
|
|
|
It seems that not "[LBA end in little endian]" but "number of blocks"
|
|
|
|
should go into bytes 458-461. But with a start lba of 1, this is the
|
|
|
|
same number.
|
|
|
|
See also http://en.wikipedia.org/wiki/Master_boot_record
|
2010-09-05 10:43:48 +00:00
|
|
|
|
|
|
|
flag bit0= do not write 0x55, 0xAA to 510,511
|
|
|
|
bit1= do not mark partition as bootable
|
2010-04-06 12:41:36 +00:00
|
|
|
*/
|
2010-04-10 16:50:59 +00:00
|
|
|
static
|
2010-09-05 10:43:48 +00:00
|
|
|
int make_grub_msdos_label(uint32_t img_blocks, uint8_t *buf, int flag)
|
2010-04-06 12:41:36 +00:00
|
|
|
{
|
|
|
|
uint8_t *wpt;
|
2010-09-05 10:43:48 +00:00
|
|
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
2010-04-06 12:41:36 +00:00
|
|
|
int sph = 63, hpc = 255, i;
|
|
|
|
|
2010-09-05 10:43:48 +00:00
|
|
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
|
|
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
2010-04-06 12:41:36 +00:00
|
|
|
|
|
|
|
/* 1) Zero-fill 446-510 */
|
|
|
|
wpt = buf + 446;
|
|
|
|
memset(wpt, 0, 64);
|
|
|
|
|
2010-09-05 10:43:48 +00:00
|
|
|
if (!(flag & 1)) {
|
|
|
|
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
|
|
|
|
buf[510] = 0x55;
|
|
|
|
buf[511] = 0xAA;
|
|
|
|
}
|
|
|
|
if (!(flag & 2)) {
|
|
|
|
/* 3) Put 0x80 (for bootable partition), */
|
|
|
|
*(wpt++) = 0x80;
|
|
|
|
} else {
|
|
|
|
*(wpt++) = 0;
|
|
|
|
}
|
2010-04-06 12:41:36 +00:00
|
|
|
|
|
|
|
/* 0, 2, 0 (C/H/S of the start), */
|
|
|
|
*(wpt++) = 0;
|
|
|
|
*(wpt++) = 2;
|
|
|
|
*(wpt++) = 0;
|
|
|
|
|
|
|
|
/* 0xcd (partition type) */
|
|
|
|
*(wpt++) = 0xcd;
|
|
|
|
|
|
|
|
/* [3 bytes of C/H/S end], */
|
|
|
|
*(wpt++) = end_head;
|
|
|
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
|
|
|
*(wpt++) = end_cyl & 0xff;
|
|
|
|
|
|
|
|
|
|
|
|
/* 0x01, 0x00, 0x00, 0x00 (LBA start in little endian), */
|
|
|
|
*(wpt++) = 0x01;
|
|
|
|
*(wpt++) = 0x00;
|
|
|
|
*(wpt++) = 0x00;
|
|
|
|
*(wpt++) = 0x00;
|
|
|
|
|
|
|
|
/* [LBA end in little endian] */
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
|
|
|
|
|
|
|
/* at 446-462 */
|
|
|
|
if (wpt - buf != 462) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"libisofs: program error in make_grub_msdos_label: \"assert 462\"\n");
|
|
|
|
return ISO_ASSERT_FAILURE;
|
|
|
|
}
|
|
|
|
return ISO_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-10 11:45:37 +00:00
|
|
|
/* @param flag bit0= zeroize partitions entries 2, 3, 4
|
|
|
|
*/
|
2010-09-05 10:43:48 +00:00
|
|
|
static
|
|
|
|
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
|
|
|
int sph_in, int hpc_in, uint8_t *buf, int flag)
|
|
|
|
{
|
|
|
|
uint8_t *wpt;
|
|
|
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
|
|
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
|
|
|
int sph = 63, hpc = 255, i;
|
|
|
|
|
|
|
|
if (sph_in > 0)
|
|
|
|
sph = sph_in;
|
|
|
|
if (hpc_in > 0)
|
|
|
|
hpc = hpc_in;
|
|
|
|
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
|
|
|
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
|
|
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
|
|
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
|
|
|
wpt = buf + 446;
|
|
|
|
|
2010-09-10 11:45:37 +00:00
|
|
|
/* Let pass only legal bootability values */
|
|
|
|
if (*wpt != 0 && *wpt != 0x80)
|
|
|
|
(*wpt) = 0;
|
2010-09-05 10:43:48 +00:00
|
|
|
wpt++;
|
|
|
|
|
|
|
|
/* C/H/S of the start */
|
|
|
|
*(wpt++) = start_head;
|
|
|
|
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
|
|
|
*(wpt++) = end_cyl & 0xff;
|
|
|
|
|
|
|
|
/* (partition type) */
|
|
|
|
wpt++;
|
|
|
|
|
|
|
|
/* 3 bytes of C/H/S end */
|
|
|
|
*(wpt++) = end_head;
|
|
|
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
|
|
|
*(wpt++) = end_cyl & 0xff;
|
|
|
|
|
|
|
|
/* LBA start in little endian */
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
*(wpt++) = (start_lba >> (8 * i)) & 0xff;
|
|
|
|
|
|
|
|
/* Number of sectors in partition, little endian */
|
|
|
|
end_lba = end_lba - start_lba + 1;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
|
|
|
|
|
|
|
if (wpt - buf != 462) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"libisofs: program error in iso_offset_partition_start: \"assert 462\"\n");
|
|
|
|
return ISO_ASSERT_FAILURE;
|
|
|
|
}
|
2010-09-10 11:45:37 +00:00
|
|
|
|
|
|
|
if (flag & 1) /* zeroize the other partition entries */
|
|
|
|
memset(wpt, 0, 3 * 16);
|
|
|
|
|
2010-09-05 10:43:48 +00:00
|
|
|
return ISO_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-12 18:24:17 +00:00
|
|
|
/* This function was implemented according to doc/boot_sectors.txt section
|
|
|
|
"MIPS Volume Header" which was derived by Thomas Schmitt from
|
2010-10-12 10:20:27 +00:00
|
|
|
cdrkit-1.1.10/genisoimage/boot-mips.c by Steve McIntyre which is based
|
|
|
|
on work of Florian Lohoff and Thiemo Seufer who possibly learned from
|
|
|
|
documents of MIPS Computer Systems, Inc. and Silicon Graphics Computer
|
|
|
|
Systems, Inc.
|
|
|
|
This function itself is entirely under copyright (C) 2010 Thomas Schmitt.
|
|
|
|
*/
|
|
|
|
static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
|
|
|
{
|
|
|
|
char *namept, *name_field;
|
|
|
|
uint32_t num_cyl, idx, blocks, num, checksum;
|
|
|
|
off_t image_size;
|
|
|
|
static uint32_t bps = 512, spt = 32;
|
|
|
|
|
2010-10-12 18:24:17 +00:00
|
|
|
#ifdef Libisofs_mips_boot_file_pathS
|
|
|
|
Ecma119Node *ecma_node;
|
|
|
|
IsoNode *node;
|
|
|
|
IsoStream *stream;
|
|
|
|
off_t file_size;
|
|
|
|
uint32_t file_lba;
|
|
|
|
int ret;
|
|
|
|
#endif
|
|
|
|
|
2010-10-13 14:59:18 +00:00
|
|
|
/* Bytes 512 to 32767 may come from image or external file */
|
|
|
|
memset(buf, 0, 512);
|
2010-10-12 10:20:27 +00:00
|
|
|
|
|
|
|
image_size = t->curblock * 2048;
|
|
|
|
|
|
|
|
/* 0 - 3 | 0x0be5a941 | Magic number */
|
|
|
|
iso_msb(buf, 0x0be5a941, 4);
|
|
|
|
|
|
|
|
/* 28 - 29 | num_cyl_l | Number of usable cylinder, lower two bytes */
|
|
|
|
/* >>> Shall i rather orund up ? */
|
|
|
|
num_cyl = image_size / (bps * spt);
|
|
|
|
iso_msb(buf + 28, num_cyl & 0xffff, 2);
|
|
|
|
|
|
|
|
/* 32 - 33 | 1 | Number of tracks per cylinder */
|
|
|
|
iso_msb(buf + 32, 1, 2);
|
|
|
|
|
|
|
|
/* 35 - 35 | num_cyl_h | Number of usable cylinders, high byte */
|
|
|
|
buf[35] = (num_cyl >> 16) & 0xff;
|
|
|
|
|
|
|
|
/* 38 - 39 | 32 | Sectors per track */
|
|
|
|
iso_msb(buf + 38, spt, 2);
|
|
|
|
|
|
|
|
/* 40 - 41 | 512 | Bytes per sector */
|
|
|
|
iso_msb(buf + 40, bps, 2);
|
|
|
|
|
|
|
|
/* 44 - 47 | 0x00000034 | Controller characteristics */
|
|
|
|
iso_msb(buf + 44, 0x00000034, 4);
|
|
|
|
|
|
|
|
/* 72 - 87 | ========== | Volume Directory Entry 1 */
|
|
|
|
/* 72 - 79 | boot_name | Boot file basename */
|
|
|
|
/* 80 - 83 | boot_block | ISO 9660 LBA of boot file * 4 */
|
|
|
|
/* 84 - 87 | boot_bytes | File length in bytes */
|
|
|
|
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
2010-10-12 18:24:17 +00:00
|
|
|
|
|
|
|
#ifdef Libisofs_mips_boot_file_pathS
|
|
|
|
|
|
|
|
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
|
|
|
ret = iso_tree_path_to_node(t->image,
|
|
|
|
t->image->mips_boot_file_paths[idx], &node);
|
|
|
|
if (ret < 0) {
|
|
|
|
iso_msg_submit(t->image->id, ISO_BOOT_MIPS_MISSING, 0,
|
|
|
|
"Cannot find MIPS boot file '%s'",
|
|
|
|
t->image->mips_boot_file_paths[idx]);
|
|
|
|
return ISO_BOOT_MIPS_MISSING;
|
|
|
|
}
|
|
|
|
if (node->type != LIBISO_FILE) {
|
|
|
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
|
|
|
"Designated MIPS boot file is not a data file: '%s'",
|
|
|
|
t->image->mips_boot_file_paths[idx]);
|
|
|
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
|
|
|
}
|
|
|
|
|
|
|
|
namept = (char *) iso_node_get_name(node);
|
|
|
|
name_field = (char *) (buf + (72 + 16 * idx));
|
|
|
|
strncpy(name_field, namept, 8);
|
|
|
|
|
|
|
|
ecma_node= ecma119_search_iso_node(t, node);
|
|
|
|
if (ecma_node != NULL) {
|
|
|
|
if (ecma_node->type != ECMA119_FILE) {
|
|
|
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
|
|
|
"Program error: Ecma119Node of IsoFile is no ECMA119_FILE: '%s'",
|
|
|
|
t->image->mips_boot_file_paths[idx]);
|
|
|
|
return ISO_ASSERT_FAILURE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
|
|
|
"Program error: IsoFile has no Ecma119Node: '%s'",
|
|
|
|
t->image->mips_boot_file_paths[idx]);
|
|
|
|
return ISO_ASSERT_FAILURE;
|
|
|
|
}
|
|
|
|
file_lba = ecma_node->info.file->sections[0].block;
|
|
|
|
|
|
|
|
iso_msb(buf + (72 + 16 * idx) + 8, file_lba * 4, 4);
|
|
|
|
|
|
|
|
stream = iso_file_get_stream((IsoFile *) node);
|
|
|
|
file_size = iso_stream_get_size(stream);
|
|
|
|
|
|
|
|
/* >>> shall i really round up to 2048 ? */
|
|
|
|
iso_msb(buf + (72 + 16 * idx) + 12,
|
|
|
|
((file_size + 2047) / 2048 ) * 2048, 4);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* Libisofs_mips_boot_file_pathS */
|
|
|
|
|
2010-10-12 10:20:27 +00:00
|
|
|
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
|
|
|
|
|
|
|
/* >>> skip non-MIPS boot images */;
|
|
|
|
|
2010-10-12 10:23:16 +00:00
|
|
|
namept = (char *) iso_node_get_name(
|
|
|
|
(IsoNode *) t->catalog->bootimages[idx]->image);
|
2010-10-12 10:20:27 +00:00
|
|
|
name_field = (char *) (buf + (72 + 16 * idx));
|
|
|
|
strncpy(name_field, namept, 8);
|
|
|
|
iso_msb(buf + (72 + 16 * idx) + 8,
|
|
|
|
t->bootsrc[idx]->sections[0].block * 4, 4);
|
|
|
|
|
|
|
|
/* >>> shall i really round up to 2048 ? */
|
|
|
|
iso_msb(buf + (72 + 16 * idx) + 12,
|
|
|
|
((t->bootsrc[idx]->sections[0].size + 2047) / 2048 ) * 2048,
|
|
|
|
4);
|
|
|
|
}
|
|
|
|
|
2010-10-12 18:24:17 +00:00
|
|
|
#endif /* ! Libisofs_mips_boot_file_pathS */
|
|
|
|
|
2010-10-12 10:20:27 +00:00
|
|
|
/* 408 - 411 | part_blks | Number of 512 byte blocks in partition */
|
|
|
|
blocks = (image_size + bps - 1) / bps;
|
|
|
|
iso_msb(buf + 408, blocks, 4);
|
|
|
|
/* 416 - 419 | 0 | Partition is volume header */
|
|
|
|
iso_msb(buf + 416, 0, 4);
|
|
|
|
|
|
|
|
/* 432 - 435 | part_blks | Number of 512 byte blocks in partition */
|
|
|
|
iso_msb(buf + 432, blocks, 4);
|
|
|
|
iso_msb(buf + 444, 6, 4);
|
|
|
|
|
|
|
|
/* 504 - 507 | head_chk | Volume header checksum
|
|
|
|
The two's complement of bytes 0 to 503 read
|
|
|
|
as big endian unsigned 32 bit:
|
|
|
|
sum(32-bit-words) + head_chk == 0
|
|
|
|
*/
|
|
|
|
checksum = 0;
|
|
|
|
for (idx = 0; idx < 504; idx += 4) {
|
|
|
|
num = iso_read_msb(buf + idx, 4);
|
|
|
|
/* Addition modulo a natural number is commutative and associative.
|
|
|
|
Thus the inverse of a sum is the sum of the inverses of the addends.
|
|
|
|
*/
|
|
|
|
checksum -= num;
|
|
|
|
}
|
|
|
|
iso_msb(buf + 504, checksum, 4);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-19 14:03:13 +00:00
|
|
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|
|
|
{
|
2010-10-12 10:20:27 +00:00
|
|
|
int ret, int_img_blocks, sa_type;
|
2010-09-05 10:43:48 +00:00
|
|
|
uint32_t img_blocks;
|
2010-04-06 12:41:36 +00:00
|
|
|
|
2008-10-19 14:03:13 +00:00
|
|
|
if ((t == NULL) || (buf == NULL)) {
|
|
|
|
return ISO_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set buf to 0s */
|
|
|
|
memset(buf, 0, 16 * BLOCK_SIZE);
|
|
|
|
|
2010-10-12 10:20:27 +00:00
|
|
|
sa_type = (t->system_area_options >> 2) & 0x3f;
|
2010-04-06 12:41:36 +00:00
|
|
|
img_blocks = t->curblock;
|
|
|
|
if (t->system_area_data != NULL) {
|
|
|
|
/* Write more or less opaque boot image */
|
|
|
|
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
|
2008-10-19 14:03:13 +00:00
|
|
|
|
2010-10-12 10:20:27 +00:00
|
|
|
} else if (sa_type == 0 && t->catalog != NULL &&
|
2010-04-22 12:04:51 +00:00
|
|
|
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
|
2010-04-06 12:41:36 +00:00
|
|
|
/* Check for isolinux image with magic number of 3.72 and produce
|
|
|
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
|
|
|
*/
|
2010-09-05 10:43:48 +00:00
|
|
|
if (img_blocks < 0x80000000) {
|
|
|
|
int_img_blocks= img_blocks;
|
|
|
|
} else {
|
|
|
|
int_img_blocks= 0x7ffffff0;
|
|
|
|
}
|
2010-04-22 12:04:51 +00:00
|
|
|
ret = make_isohybrid_mbr(t->bootsrc[0]->sections[0].block,
|
2010-09-05 10:43:48 +00:00
|
|
|
&int_img_blocks, (char*)buf, 0);
|
2008-10-19 14:03:13 +00:00
|
|
|
if (ret != 1) {
|
|
|
|
/* error, it should never happen */
|
|
|
|
return ISO_ASSERT_FAILURE;
|
|
|
|
}
|
2010-04-06 12:41:36 +00:00
|
|
|
return ISO_SUCCESS;
|
|
|
|
}
|
2010-10-12 10:20:27 +00:00
|
|
|
if (sa_type == 0 && (t->system_area_options & 1)) {
|
2010-09-05 10:43:48 +00:00
|
|
|
/* Write GRUB protective msdos label, i.e. a simple partition table */
|
2010-04-06 12:41:36 +00:00
|
|
|
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
2010-09-05 10:43:48 +00:00
|
|
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
2010-04-06 12:41:36 +00:00
|
|
|
return ISO_ASSERT_FAILURE;
|
2010-10-12 10:20:27 +00:00
|
|
|
} else if(sa_type == 0 && (t->system_area_options & 2)) {
|
2010-04-10 16:50:59 +00:00
|
|
|
/* Patch externally provided system area as isohybrid MBR */
|
|
|
|
if (t->catalog == NULL || t->system_area_data == NULL) {
|
|
|
|
/* isohybrid makes only sense together with ISOLINUX boot image
|
|
|
|
and externally provided System Area.
|
|
|
|
*/
|
|
|
|
return ISO_ISOLINUX_CANT_PATCH;
|
|
|
|
}
|
2010-04-22 12:04:51 +00:00
|
|
|
ret = make_isolinux_mbr(&img_blocks, t->bootsrc[0]->sections[0].block,
|
2010-04-10 16:50:59 +00:00
|
|
|
(uint32_t) 0, 64, 32, 0, 1, 0x17, buf, 1);
|
|
|
|
if (ret != 1)
|
|
|
|
return ret;
|
2010-10-12 10:20:27 +00:00
|
|
|
} else if(sa_type == 1) {
|
|
|
|
ret = make_mips_volume_header(t, buf, 0);
|
2010-10-12 18:24:17 +00:00
|
|
|
if (ret != ISO_SUCCESS)
|
|
|
|
return ret;
|
2010-10-13 14:59:18 +00:00
|
|
|
} else if(t->partition_offset > 0 && sa_type == 0) {
|
2010-09-05 10:43:48 +00:00
|
|
|
/* Write a simple partition table. */
|
|
|
|
ret = make_grub_msdos_label(img_blocks, buf, 2);
|
|
|
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
|
|
|
return ISO_ASSERT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2010-10-13 14:59:18 +00:00
|
|
|
if (t->partition_offset > 0 && sa_type == 0) {
|
2010-09-11 11:25:51 +00:00
|
|
|
/* Adjust partition table to partition offset */
|
2010-09-05 10:43:48 +00:00
|
|
|
img_blocks = t->curblock; /* value might be altered */
|
|
|
|
ret = iso_offset_partition_start(img_blocks, t->partition_offset,
|
|
|
|
t->partition_secs_per_head,
|
2010-09-10 11:45:37 +00:00
|
|
|
t->partition_heads_per_cyl, buf, 1);
|
2010-09-05 10:43:48 +00:00
|
|
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
|
|
|
return ISO_ASSERT_FAILURE;
|
2008-10-19 14:03:13 +00:00
|
|
|
}
|
2010-09-05 10:43:48 +00:00
|
|
|
|
2008-10-19 14:03:13 +00:00
|
|
|
return ISO_SUCCESS;
|
|
|
|
}
|