]> git.proxmox.com Git - grub2.git/commitdiff
2009-11-11 Robert Millan <rmh.grub@aybabtu.com>
authorRobert Millan <rmh@aybabtu.com>
Wed, 11 Nov 2009 20:52:04 +0000 (20:52 +0000)
committerRobert Millan <rmh@aybabtu.com>
Wed, 11 Nov 2009 20:52:04 +0000 (20:52 +0000)
        Support for El Torito without floppy emulation.

        * util/mkisofs/eltorito.c: Include `<errno.h>'.
        (init_boot_catalog): Improve error handling.
        (get_torito_desc): Don't use floppy emulation unless requested by
        user. Patch boot information table when requested via
        `-boot-info-table'.
        * util/mkisofs/iso9660.h (struct eltorito_boot_info): New struct.
        * util/mkisofs/mkisofs.c (use_eltorito_emul_floppy)
        (use_boot_info_table): New variables.
        (OPTION_BOOT_INFO_TABLE, OPTION_NO_EMUL_BOOT)
        (OPTION_ELTORITO_EMUL_FLOPPY): New macros.
        (ld_options): Handle `-boot-info-table', `-no-emul-boot' and
        `--eltorito-emul-floppy'.
        (main): Handle `OPTION_BOOT_INFO_TABLE', `OPTION_NO_EMUL_BOOT'
        and `OPTION_ELTORITO_EMUL_FLOPPY'.
        * util/mkisofs/mkisofs.h (use_eltorito_emul_floppy)
        (use_boot_info_table, get_731): New prototypes.
        * util/mkisofs/write.c (get_731): New function.

ChangeLog
util/mkisofs/eltorito.c
util/mkisofs/iso9660.h
util/mkisofs/mkisofs.c
util/mkisofs/mkisofs.h
util/mkisofs/write.c

index 4e868b5b9efa01adc69f89b88bc54801582ef81c..1a15e8d864f19790c5fbb4cd808446962642d2f1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2009-11-11  Robert Millan  <rmh.grub@aybabtu.com>
+
+       Support for El Torito without floppy emulation.
+
+       * util/mkisofs/eltorito.c: Include `<errno.h>'.
+       (init_boot_catalog): Improve error handling.
+       (get_torito_desc): Don't use floppy emulation unless requested by
+       user. Patch boot information table when requested via
+       `-boot-info-table'.
+       * util/mkisofs/iso9660.h (struct eltorito_boot_info): New struct.
+       * util/mkisofs/mkisofs.c (use_eltorito_emul_floppy)
+       (use_boot_info_table): New variables.
+       (OPTION_BOOT_INFO_TABLE, OPTION_NO_EMUL_BOOT)
+       (OPTION_ELTORITO_EMUL_FLOPPY): New macros.
+       (ld_options): Handle `-boot-info-table', `-no-emul-boot' and
+       `--eltorito-emul-floppy'.
+       (main): Handle `OPTION_BOOT_INFO_TABLE', `OPTION_NO_EMUL_BOOT'
+       and `OPTION_ELTORITO_EMUL_FLOPPY'.
+       * util/mkisofs/mkisofs.h (use_eltorito_emul_floppy)
+       (use_boot_info_table, get_731): New prototypes.
+       * util/mkisofs/write.c (get_731): New function.
+
 2009-11-11  Felix Zielcke  <fzielcke@z-51.de>
 
        Fix the generation of the man page.
index e003f2b6780d8100fedd31753d58bd48a5567b45..858aa79dc9936bc624c3578d6b1b95f44efaad85 100644 (file)
@@ -6,9 +6,14 @@
 
    Copyright 1996 RedHat Software, Incorporated
 
+   Copyright (C) 2009  Free Software Foundation, Inc.
+
+   Boot Info Table generation based on code from genisoimage.c
+   (from cdrkit 1.1.9), which was originally licensed under GPLv2+.
+
    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)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,8 +22,8 @@
    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.   */
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 
 static char rcsid[] ="$Id: eltorito.c,v 1.13 1999/03/02 03:41:25 eric Exp $";
@@ -29,6 +34,7 @@ static char rcsid[] ="$Id: eltorito.c,v 1.13 1999/03/02 03:41:25 eric Exp $";
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "config.h"
 #include "mkisofs.h"
@@ -103,12 +109,8 @@ void FDECL1(init_boot_catalog, const char *, path)
      * make it one CD sector long
      */
     bcat = open(bootpath, O_WRONLY | O_CREAT | O_BINARY, S_IROTH | S_IRGRP | S_IRWXU );
-    if (bcat == -1) 
-    {
-       fprintf(stderr, "Error creating boot catalog, exiting...\n");
-       perror("");
-       exit(1);
-    }
+    if (bcat == -1)
+      error (1, errno, "Error creating boot catalog (%s)", bootpath);
     
     buf = (char *) e_malloc( 2048 );
     write(bcat, buf, 2048);
@@ -217,31 +219,35 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
      */
     nsectors = ((de->size + 511) & ~(511))/512;
     fprintf(stderr, "\nSize of boot image is %d sectors -> ", nsectors); 
-    
-    /*
-     * choose size of emulated floppy based on boot image size 
-     */
-    if (nsectors == 2880 ) 
-    {
+
+    if (! use_eltorito_emul_floppy)
+      {
+       default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL;
+       fprintf (stderr, "No emulation\n");
+      }
+    else if (nsectors == 2880 ) 
+      /*
+       * choose size of emulated floppy based on boot image size 
+       */
+      {
        default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
        fprintf(stderr, "Emulating a 1.44 meg floppy\n");
-    }
+      }
     else if (nsectors == 5760 ) 
-    {
+      {
        default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
        fprintf(stderr,"Emulating a 2.88 meg floppy\n");
-    }
+      }
     else if (nsectors == 2400 ) 
-    {
+      {
        default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
        fprintf(stderr,"Emulating a 1.2 meg floppy\n");
-    }
+      }
     else 
-    {
+      {
        fprintf(stderr,"\nError - boot image is not the an allowable size.\n");
        exit(1);
-    }
-    
+      }
     
     /* 
      * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! 
@@ -271,6 +277,53 @@ void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
     write(bootcat, &valid_desc, 32);
     write(bootcat, &default_desc, 32);
     close(bootcat);
+
+    /* If the user has asked for it, patch the boot image */
+    if (use_boot_info_table)
+      {
+       int bootimage;
+       uint32_t bi_checksum;
+       unsigned int total_len;
+       static char csum_buffer[SECTOR_SIZE];
+       int len;
+       struct eltorito_boot_info bi_table;
+       bootimage = open (de->whole_name, O_RDWR | O_BINARY);
+       if (bootimage == -1)
+         error (1, errno, "Error opening boot image file '%s' for update",
+                de->whole_name);
+       /* Compute checksum of boot image, sans 64 bytes */
+       total_len = 0;
+       bi_checksum = 0;
+       while ((len = read (bootimage, csum_buffer, SECTOR_SIZE)) > 0)
+         {
+           if (total_len & 3)
+             error (1, 0, "Odd alignment at non-end-of-file in boot image '%s'",
+                    de->whole_name);
+           if (total_len < 64)
+             memset (csum_buffer, 0, 64 - total_len);
+           if (len < SECTOR_SIZE)
+             memset (csum_buffer + len, 0, SECTOR_SIZE - len);
+           for (i = 0; i < SECTOR_SIZE; i += 4)
+             bi_checksum += get_731 (&csum_buffer[i]);
+           total_len += len;
+         }
+
+       if (total_len != de->size)
+         error (1, 0, "Boot image file '%s' changed underneath us",
+                de->whole_name);
+       /* End of file, set position to byte 8 */
+       lseek (bootimage, (off_t) 8, SEEK_SET);
+       memset (&bi_table, 0, sizeof (bi_table));
+       /* Is it always safe to assume PVD is at session_start+16? */
+       set_731 (bi_table.pvd_addr, session_start + 16);
+       set_731 (bi_table.file_addr, de->starting_block);
+       set_731 (bi_table.file_length, de->size);
+       set_731 (bi_table.file_checksum, bi_checksum);
+
+       write (bootimage, &bi_table, sizeof (bi_table)); /* FIXME: check return value */
+       close (bootimage);
+      }
+
 } /* get_torito_desc(... */
 
 /*
index 65320121def89ffbaa92feb4e38c55d1d416a7b3..3ba0faaac97d1c42669897ca051aa6b79ea8df1d 100644 (file)
@@ -6,9 +6,11 @@
 
    Copyright 1993 Yggdrasil Computing, Incorporated
 
+   Copyright (C) 2009  Free Software Foundation, Inc.
+
    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)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,7 +19,7 @@
    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
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*
@@ -129,6 +131,20 @@ struct eltorito_defaultboot_entry {
         char pad2                       [ISODCL ( 13,   32)];
 };
 
+/* El Torito boot information table */
+struct eltorito_boot_info
+{
+  /* Address of Primary Volume Descriptor.  */
+  char pvd_addr[ISODCL (1, 4)];
+  /* Boot file address.  */
+  char file_addr[ISODCL (5, 8)];
+  /* Boot file length.  */  
+  char file_length[ISODCL (9, 12)];
+  /* Boot file checksum.  */
+  char file_checksum[ISODCL (13, 16)];
+  char dummy[ISODCL (17, 56)];
+};
+
 
 /* We use this to help us look up the parent inode numbers. */
 
index 8497723e68a161805e1450f91571dc10db5b991a..0c89a2d8c4e9f16e21ba43609969fecc16435432 100644 (file)
@@ -89,6 +89,8 @@ int extension_record_size = 0;
 
 /* These variables are associated with command line options */
 int use_eltorito = 0;
+int use_eltorito_emul_floppy = 0;
+int use_boot_info_table = 0;
 int use_RockRidge = 0;
 int use_Joliet = 0;
 int verbose = 1;
@@ -189,6 +191,10 @@ struct ld_option
 #define OPTION_EXPIR_DATE              168
 #define OPTION_EFFEC_DATE              169
 
+#define OPTION_BOOT_INFO_TABLE         170
+#define OPTION_NO_EMUL_BOOT            171
+#define OPTION_ELTORITO_EMUL_FLOPPY    172
+
 static const struct ld_option ld_options[] =
 {
   { {"all-files", no_argument, NULL, 'a'},
@@ -205,6 +211,12 @@ static const struct ld_option ld_options[] =
       'b', "FILE", "Set El Torito boot image name" , ONE_DASH },
   { {"eltorito-catalog", required_argument, NULL, 'c'},
       'c', "FILE", "Set El Torito boot catalog name" , ONE_DASH },
+  { {"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE },
+      '\0', NULL, "Patch Boot Info Table in El Torito boot image" , ONE_DASH },
+  { {"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT },
+      '\0', NULL, "Dummy option for backward compatibility" , ONE_DASH },
+  { {"eltorito-emul-floppy", no_argument, NULL, OPTION_ELTORITO_EMUL_FLOPPY },
+      '\0', NULL, "Enable floppy drive emulation for El Torito" , TWO_DASHES },
   { {"cdwrite-params", required_argument, NULL, 'C'},
       'C', "PARAMS", "Magic parameters from cdrecord" , ONE_DASH },
   { {"omit-period", no_argument, NULL, 'd'},
@@ -716,6 +728,15 @@ int FDECL2(main, int, argc, char **, argv){
                exit(1);
        }
        break;
+      case OPTION_BOOT_INFO_TABLE:
+       use_boot_info_table = 1;
+       break;
+      case OPTION_NO_EMUL_BOOT:
+       fprintf (stderr, "Ignoring -no-emul-boot (no-emulation is the default behaviour)\n");
+       break;
+      case OPTION_ELTORITO_EMUL_FLOPPY:
+       use_eltorito_emul_floppy = 1;
+       break;
       case OPTION_ABSTRACT:
        abstract = optarg;
        if(strlen(abstract) > 37) {
index 52acc72b5cca8e88d192d85c69c73956709c2a2b..79266e08af0af91625a1bf09ed25543ad843adc2 100644 (file)
@@ -291,6 +291,8 @@ extern struct iso_directory_record root_record;
 extern struct iso_directory_record jroot_record;
 
 extern int use_eltorito;
+extern int use_eltorito_emul_floppy;
+extern int use_boot_info_table;
 extern int use_RockRidge;
 extern int use_Joliet;
 extern int rationalize;
@@ -335,6 +337,7 @@ extern void DECL(init_boot_catalog, (const char * path ));
 extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path ));
 
 /* write.c */
+extern int DECL(get_731,(char *));
 extern int DECL(get_733,(char *));
 extern int DECL(isonum_733,(unsigned char *));
 extern void DECL(set_723,(char *, unsigned int));
index 7c45404928312bf17893e77ea54385b8bb2cb6f8..45b630693bd60aaab5bc20351ebd5d1c95b5dfb0 100644 (file)
@@ -111,6 +111,14 @@ void FDECL2(set_732, char *, pnt, unsigned int, i)
      pnt[0] = (i >> 24) &  0xff;
 }
 
+int FDECL1(get_731, char *, p)
+{
+  return ((p[0] & 0xff)
+         | ((p[1] & 0xff) << 8)
+         | ((p[2] & 0xff) << 16)
+         | ((p[3] & 0xff) << 24));
+}
+
 int FDECL1(get_733, char *, p)
 {
      return ((p[0] & 0xff)