diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-12-31 05:04:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-12-31 05:04:42 +0400 |
commit | 71dc8760ff4de5f365330d1bc571d934deb54af9 (patch) | |
tree | 7346d42a282562a3937d82307012b5857d642ce6 /genisoimage/boot-alpha.c | |
download | cdrkit-71dc8760ff4de5f365330d1bc571d934deb54af9.tar.gz |
Imported Upstream version 1.1.11upstream/1.1.11upstream
Diffstat (limited to 'genisoimage/boot-alpha.c')
-rw-r--r-- | genisoimage/boot-alpha.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/genisoimage/boot-alpha.c b/genisoimage/boot-alpha.c new file mode 100644 index 0000000..cfd4862 --- /dev/null +++ b/genisoimage/boot-alpha.c @@ -0,0 +1,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"}; |