1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
* This file has been modified for the cdrkit suite.
*
* The behaviour and appearence of the program code below can differ to a major
* extent from the version distributed by the original author(s).
*
* For details, see Changelog file distributed with the cdrkit package. If you
* received this file from another source then ask the distributing person for
* a log of modifications.
*
*/
/*
* Program boot-alpha.c - Handle Linux alpha boot extensions to iso9660.
*
* Written by Steve McIntyre <steve@einval.com> June 2004
*
* Heavily inspired by isomarkboot by David Mosberger in 1996.
*
* Copyright 2004 Steve McIntyre
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <mconfig.h>
#include "genisoimage.h"
#include <fctldefs.h>
#include <utypes.h>
#include <intcvt.h>
#include "match.h"
#include "diskmbr.h"
#include "bootinfo.h"
#include <schily.h>
#include "endianconv.h"
int add_boot_alpha_filename(char *filename);
static int boot_alpha_write(FILE *outfile);
static int boot_alpha_hppa_write(FILE *outfile);
static char *boot_file_name = NULL;
unsigned long long alpha_hppa_boot_sector[256]; /* One (ISO) sector */
int boot_sector_initialized = 0;
#define BOOT_STRING "Linux/Alpha aboot for ISO filesystem."
/* Simple function: store the filename to be used later when we need
to find the boot file */
extern int add_boot_alpha_filename(char *filename)
{
boot_file_name = filename;
return 0;
}
static int boot_alpha_write(FILE *outfile)
{
struct directory_entry *boot_file; /* Boot file we need to search for */
unsigned long length = 0;
unsigned long extent = 0;
if (!boot_sector_initialized) {
memset(alpha_hppa_boot_sector, 0, sizeof(alpha_hppa_boot_sector));
boot_sector_initialized = 1;
}
/* Write the text header into the boot sector */
strcpy((char *)alpha_hppa_boot_sector, BOOT_STRING);
/* Find the dir entry for the boot file by walking our file list */
boot_file = search_tree_file(root, boot_file_name);
if (!boot_file) {
#ifdef USE_LIBSCHILY
comerrno(EX_BAD, "Uh oh, I cant find the Alpha boot file '%s'!\n",
boot_file_name);
#else
fprintf(stderr, "Uh oh, I cant find the Alpha boot file '%s'!\n",
boot_file_name);
exit(1);
#endif
}
/* Grab the ISO start sector and length from the dir entry. ISO
uses 2048-byte sectors, but we convert to 512-byte sectors here
for the sake of the firmware */
extent = get_733(boot_file->isorec.extent);
extent *= 4;
length = get_733(boot_file->isorec.size);
length /= 512; /* I'm sure we should take account of any overlap
here, but I'm copying what isomarkboot
does. Maybe the boot files are specified to be
exact multiples of 512 bytes? */
fprintf(stderr, "Found alpha boot image %s: using extent %lu, #blocks %lu\n",
boot_file_name, extent, length);
/* Now write those values into the appropriate area of the boot
sector in LITTLE ENDIAN format. */
write_le64(length, (unsigned char *)&alpha_hppa_boot_sector[60]);
write_le64(extent, (unsigned char *)&alpha_hppa_boot_sector[61]);
return 0;
}
static int boot_alpha_hppa_write(FILE *outfile)
{
unsigned long long sum = 0;
int i = 0;
/* Now generate a checksum of the first 504 bytes of the boot
sector and place it in alpha_hppa_boot_sector[63]. Isomarkboot currently
gets this wrong and will not work on big-endian systems! */
for (i = 0; i < 63; i++)
sum += read_le64((unsigned char *)&alpha_hppa_boot_sector[i]);
write_le64(sum, (unsigned char *)&alpha_hppa_boot_sector[63]);
jtwrite(alpha_hppa_boot_sector, sizeof(alpha_hppa_boot_sector), 1, 0, FALSE);
xfwrite(alpha_hppa_boot_sector, sizeof(alpha_hppa_boot_sector), 1, outfile, 0, FALSE);
last_extent_written++;
return 0;
}
struct output_fragment alphaboot_desc = {NULL, NULL, NULL, boot_alpha_write, "alpha boot block"};
struct output_fragment alpha_hppa_boot_desc = {NULL, oneblock_size, NULL, boot_alpha_hppa_write, "alpha/hppa boot block"};
|