From d3816073d3f110a57cd75f30d47bd06fcb94f601 Mon Sep 17 00:00:00 2001
From: Andreas Loibl <andreas@andreas-loibl.de>
Date: Fri, 17 Feb 2012 00:30:53 +0100
Subject: added hybrid-ISO feature: embedded partiton with ISO offset

---
 config/binary_iso/isoimage.sort         |   7 +-
 config/binary_local-hooks/mkembeddediso |  21 ++++++
 isohybrid-acritox                       | 129 +++++++++++++++++++++++++++++++-
 3 files changed, 150 insertions(+), 7 deletions(-)
 create mode 100755 config/binary_local-hooks/mkembeddediso

diff --git a/config/binary_iso/isoimage.sort b/config/binary_iso/isoimage.sort
index 1495a1d..5ae4594 100644
--- a/config/binary_iso/isoimage.sort
+++ b/config/binary_iso/isoimage.sort
@@ -1,6 +1,7 @@
-binary/boot.catalog +4
-binary/boot.isohybrid +3
-binary/boot.efi.img +2
+binary/boot.catalog +9
+binary/boot.isohybrid +7
+binary/boot.efi.img +5
+binary/boot.iso.img +3
 binary/boot +1
 binary/*/*.squashfs -1
 binary/*.squashfs -1
diff --git a/config/binary_local-hooks/mkembeddediso b/config/binary_local-hooks/mkembeddediso
new file mode 100755
index 0000000..c2e4ce9
--- /dev/null
+++ b/config/binary_local-hooks/mkembeddediso
@@ -0,0 +1,21 @@
+#! /bin/sh
+# mkembeddediso - written by Andreas Loibl <andreas@andreas-loibl.de>
+# 
+# Generate space on the ISO for an offset copy of the ISO file table
+
+case "$LB_BOOTLOADER" in
+grub2|burg)
+	;;
+*)
+	exit 0
+	;;
+esac
+
+
+img=binary/boot.iso.img
+[ "$1" ] && img="$1"
+rm -f "$img"
+
+dd if=/dev/zero bs=512k count=1 of="$img" >/dev/null 2>/dev/null
+
+exit 0
diff --git a/isohybrid-acritox b/isohybrid-acritox
index 6bd7416..60ee8eb 100755
--- a/isohybrid-acritox
+++ b/isohybrid-acritox
@@ -15,9 +15,18 @@ $pm1='504d000000000003000000010000000f4170706c6500000000000000000000000000000000
 $pm2='504d00000000000300000400000005006469736b20696d616765000000000000000000000000000000000000000000004170706c655f4846530000000000000000000000000000000000000000000000000000000000040040000033'; # Apple_HFS
 $pm3='504d00000000000300000001000004004b414e4f5449585f454649000000000000000000000000000000000000000000444f535f4641545f313200000000000000000000000000000000000000000000000000000000040040000033'; # DOS_FAT_12
 
-die "Usage: $0 <isohybrid-bg2.iso> <HFS+-image> <FAT-image-filename>\n" if $#ARGV != 2;
+die "Usage: $0 <isohybrid-bg2.iso> <HFS+-image>\n" if $#ARGV != 1;
 
-($file, $part, $filename) = @ARGV;
+# name of the first file in the ISO
+$first_filename="boot.catalog"; 
+
+# name of the file containing the EFI-FAT-image
+$filename="boot.efi.img";
+
+# name of the file to be used as ISO-offset-destination
+$embiso_filename="boot.iso.img";
+
+($file, $part) = @ARGV;
 open(FILE, "+< $file\0") or die "$0: cannot open $file: $!\n";
 binmode FILE;
 
@@ -39,11 +48,21 @@ seek(PART, 0x400, SEEK_SET) or die "$0: $file: $!\n";
 read(PART, $test, 2) == 2 or die "$0: $file: read error\n";
 die "$part doesn't seem to contain a HFS+ filesystem\n" if($test ne 'H+');
 
-$start = `isoinfo -J -s -l -i "$file" | awk '/$filename/{print \$10}'`;
+$start = int(`isoinfo -R -s -l -i "$file" | awk '/$filename/{print \$10}'`);
 if (!$start) {
     die "$0: $filename: cannot determine position of file\n";
 }
 
+$embiso_start = int(`isoinfo -R -s -l -i "$file" | awk '/$embiso_filename/{print \$10}'`);
+if (!$embiso_start) {
+    die "$0: $embiso_filename: cannot determine position of file\n";
+}
+
+$start_of_files = int(`isoinfo -R -s -l -i "$file" | awk '/$first_filename/{print \$10}'`);
+if (!$start_of_files) {
+    die "$0: $first_filename: cannot determine position of file\n";
+}
+
 # Get the total size of the image
 (@imgstat = stat(FILE)) or die "$0: $file: $!\n";
 $imgsize = $imgstat[7];
@@ -93,6 +112,7 @@ $partsize += $padding;
 
 use integer;
 $lba = $start*4;
+$embiso_lba = $embiso_start*4;
 $psize = $imgsize/512 - $lba;
 
 # Adjust $pm2 (Apple_HFS)
@@ -127,7 +147,7 @@ if ($padding) {
 close(PART);
 
 # Calculate partiton table (MBR)
-$psize = $imgsize/512 - $lba;
+$psize = $embiso_lba - $lba;
 $h = 64; $s = 32;
 $hpc = 32; $spt = 63;
 $bcyl = $lba / ($spt * $hpc);
@@ -151,7 +171,108 @@ $pentry  = 1;
 seek(FILE, 430+16*$pentry, SEEK_SET) or die "$0: $file: $!\n";
 print FILE pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype, $ehead, $esect, $ecyl, $lba, $psize);
 
+$psize = $imgsize/512 - $embiso_lba;
+$bcyl = $embiso_lba / ($spt * $hpc);
+$bhead = ($embiso_lba / $spt) % $hpc;
+$bsect = ($embiso_lba % $spt) + 1;
+$ehead   = $h-1;
+$esect   = $s + ((($cc-1) & 0x300) >> 2);
+$ecyl    = ($cc-1) & 0xff;
+
+$fstype  = 0x83;
+$pentry  = 2;
+
+seek(FILE, 430+16*$pentry, SEEK_SET) or die "$0: $file: $!\n";
+print FILE pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype, $ehead, $esect, $ecyl, $embiso_lba, $psize);
+
+# Done...
+close(FILE);
+
+# Embed a copy of the ISO filesystem into the ISO at the second partition (= start_of_block1)
+print("dd if=$file bs=2048 count=$start_of_files of=$file seek=$embiso_start conv=notrunc\n");
+system("dd if=$file bs=2048 count=$start_of_files of=$file seek=$embiso_start conv=notrunc");
+
+$off = $bs*$embiso_start;
+$diff = $embiso_start;
+
+open(FILE, "+< $file\0") or die "$0: cannot open $file: $!\n";
+binmode FILE;
+
+sub write_val
+{
+	my($offset, $value) = @_;
+	$cur = tell(FILE);
+	$offset += $cur if $offset < 0;
+	printf("byte-offset: 0x%X -> 0x%X\n", $offset, $offset-$diff*$bs);
+	seek(FILE, $offset, SEEK_SET);
+	print FILE $value;
+	seek(FILE, $cur, SEEK_SET);
+}
+
+$off_pvd = $off+0x8000;
+do
+{
+	seek(FILE, $off_pvd, SEEK_SET) or die "$0: $file: $!\n";
+	read(FILE, $voldesc_head, 7) > 0 or die "$0: $file: read error\n";
+	($type, $magic, $version) = unpack("Ca[5]C", $voldesc_head);
+	if($type == 1)
+	{
+		seek(FILE, 0x97, 1);
+		read(FILE, $voldesc, 8) > 0 or die "$0: $file: read error\n";
+		($first_sector, $first_sector_be) = unpack("VN", $voldesc);
+		seek(FILE, $off+$first_sector*$bs, SEEK_SET) or die "$0: $file: $!\n";
+		printf("root-directory entry at 0x%X:\n", tell(FILE));
+		read(FILE, $bytes, 1) > 0 or die "$0: $file: read error\n";
+		$bytes = unpack("C", $bytes) - 1; $sector = 0;
+		do {
+			printf("SUSP entry - %u bytes (0x%X)\n", $bytes+1, $bytes+1);
+			do {
+				$wp = tell(FILE);
+				$bytes -= read(FILE, $voldesc, 32);
+				($ext_sectors, $lba, $lba_be, $size, $size_be, $uu, $namelen)
+					= unpack("CVNVNa[14]C", $voldesc);
+				if($lba > $diff)
+				{
+					printf("LBA 0x%x -> LBA 0x%x\n", $lba, $lba - $diff);
+					write_val($wp+1, pack("VN", $lba - $diff, $lba - $diff));
+				}
+				$namelen++ if $namelen % 2 == 0;
+				$bytes -= read(FILE, $name, $namelen);
+				$filename = unpack("Z*", $name);
+				print("file: $filename\n");
+
+				$bytes -= read(FILE, $sua_head, 4);
+				($sig, $len, $version) = unpack("a[2]CC", $sua_head);
+				$len -= 4;
+				$bytes -= read(FILE, $data, $len);
+				do {
+					$bytes -= read(FILE, $sua_head, 4);
+					($sig, $len, $version) = unpack("a[2]CCa", $sua_head);
+					$len -= 4;
+					$bytes -= read(FILE, $data, $len);
+					if($sig eq "CE")
+					{
+						($sua_block, $uu1, $sua_pos, $uu2, $sua_size, $uu3) = unpack("VNVNVN", $data);
+						printf("CE is at LBA 0x%X -> 0x%x\n", $sua_block);
+					}
+				} while($bytes > 4);
+				$bytes -= read(FILE, $uu, $bytes) if $bytes > 0; # skip bytes (if unaligned)
+				read(FILE, $bytes, 1) > 0 or die "$0: $file: read error\n";
+				$bytes = unpack("C", $bytes) - 1;
+				printf("SUSP Entry - %u bytes (0x%X)\n", $bytes+1, $bytes+1);
+			} while $bytes > 0;
+			$sector++;
+			seek(FILE, $off+$first_sector*$bs+$sector*$bs, SEEK_SET) or die "$0: $file: $!\n";
+			printf("\ndirectory entry at 0x%X:\n", tell(FILE));
+			read(FILE, $bytes, 1) > 0 or break;
+			$bytes = unpack("C", $bytes) - 1;
+		} while $bytes != 0x21 && $bytes != 0;
+	}
+	$off_pvd+=$bs;
+} while $type != 255;
+
 # Done...
 close(FILE);
 
 exit 0;
+
-- 
cgit v1.0