From d02d8642b98e8f065dd37e1c1a42b3b6c8daef85 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 23 Sep 2010 13:56:22 +0000 Subject: [PATCH] Explaining the partition offset feature --- Makefile.am | 1 + doc/partition_offset.wiki | 159 +++++++++++++++++++++++++++++ xorriso/make_xorriso_standalone.sh | 4 +- xorriso/xorriso_timestamp.h | 2 +- 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 doc/partition_offset.wiki diff --git a/Makefile.am b/Makefile.am index 405ac582..3e5fd8c0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -228,6 +228,7 @@ EXTRA_DIST = \ version.h.in \ doc/comments \ doc/doxygen.conf.in \ + doc/partition_offset.wiki \ README \ AUTHORS \ CONTRIBUTORS \ diff --git a/doc/partition_offset.wiki b/doc/partition_offset.wiki new file mode 100644 index 00000000..2056c324 --- /dev/null +++ b/doc/partition_offset.wiki @@ -0,0 +1,159 @@ + +The partition offset feature of libisofs can produce ISO 9660 images which bear +a quite conventional partition table if copied onto a USB stick. The first +partition marks the size of the ISO image but starts at a non-zero address. +Thus it marks a small part of the device as unclaimed by partitions and +available for storing boot loader code. + +Nevertheless the USB stick is mountable via its overall device file as well as +via the partition device file. E.g. on GNU/Linux: /dev/sdb and /dev/sdb1. +This is achieved by two distinct sets of meta-data which refer to the same +file content. + +The dual-mount feature supports Rock Ridge and eventually Joliet too. +It is capable of multi-session. + +Currently only offset 32 kB seems to make sense. Smaller offsets are prohibited +by fundamental assumptions of libisofs and libisoburn. Larger offsets would +extend the unclaimed area into vital blocks of the ISO image. + +-------------------------------------------------------------------------- + +Example: + +Testing mountability and ISOLINUX bootability from USB stick and CD. + +Overview: + +The test image was derived from one year old RIPLinux-9.3-non-X.iso which +has an isohybrid MBR. Syslinux version seems to be 3.82. That MBR and the file +tree from the mounted RIPLinux image was used to build a new ISO image +with 16 * 2kB partition offset. Isohybrid MBR patching was done by xorriso. + +Details: + +The first 32 kB of an ISO 9660 image are called System Area and may host any +byte pattern. In the case of RIPLinux-9.3-non-X.iso only the first 512 bytes +are non-zero. But to avoid any assumptions, all 32 kB get copied here. +{{{ + dd if=RIPLinux-9.3-non-X.iso bs=1K count=32 of=RIPLinux-9.3-non-X.sysarea +}}} +The files of the image are made accessible for reading +{{{ + mount -o loop RIPLinux-9.3-non-X.iso /mnt +}}} + +A new ISO image gets composed. The first three lines of arguments are taken +from the prescriptions of ISOLINUX wiki and adapted to the names used in +RIPLinux-9.3-non-X.iso. +Option -isohybrid-mbr imports the copied System Area and patches the MBR +according to rules published by hpa on Syslinux mailing list. +Option -partition_offset 16 causes the first partition to start at 2 kB block +number 16. It also prepares the image to be mountable by this partition, too. +{{{ + xorriso -as mkisofs \ + -o new_image.iso \ + -b boot/isolinux/isolinux.bin -c boot/boot.cat \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -isohybrid-mbr RIPLinux-9.3-non-X.sysarea \ + -partition_offset 16 \ + /mnt +}}} +The image was copied onto a USB stick +{{{ + dd if=new_image.iso of=/dev/sdc +}}} +and plugged into a Debian system. +{{{ + fdisk -lu /dev/sdb +}}} +yields +{{{ + Device Boot Start End Blocks Id System +/dev/sdb1 * 64 119215 59576 17 Hidden HPFS/NTFS +}}} + +I can mount /dev/sdb and /dev/sdb1 alike: +{{{ + mount /dev/sdb1 /mnt1 + mount -o loop /dev/sdb /mnt +}}} +-o loop avoids failure with "mount: /dev/sdb already mounted or /mnt busy". +A comparison by +{{{ + diff -r /mnt /mnt1 +}}} +reports no difference. +Human readable files look ok. +Test-reading all content by +{{{ + tar cf - /mnt | wc +}}} +yields a reasonable byte count of 60743680 and no errors. + +The machine boots RIPLinux from this USB stick with no visible problems. +It can then mount /dev/sdb as well as /dev/sdb1. +The ISO image boots from CD too. + +Mounting the partition can be simulated with an image file on hard disk by +cutting off the first partition_offset blocks of 2 KB: +{{{ + dd if=new_image.iso of=partition_image.iso bs=2048 skip=16 + mount -o loop partition_image.iso /mnt1 +}}} + +-------------------------------------------------------------------------- + +Open questions: + +- Shall the partition of an isohybrid image be marked bootable ? + Currently xorriso keeps the 0x80 mark of an eventually imported MBR +resp. the 0x80 mark which xorriso eventually sets by its own MBR +preparations. + - If not to be marked bootable: + What equipment would the partition need to justify having the mark ? + +- I am still puzzled by the cylinder-head-sector ambiguity. How does a reader +of the partition table determine the numbers for heads/cylinder and +sectors/head ? +fdisk tells about my /dev/sdb +{{{ + 105 heads, 17 sectors/track, 2193 cylinders, total 3915776 sectors +}}} +My partiton table rather was computed with 255 heads/cylinder, 63 sectors/head +Debian does not mind the difference. (It uses the 32 bit LBAs, i assume.) + +------------------------------------------------------------------------ + +Application: + +The partition offset feature can be controlled by libisofs API call +{{{ +int iso_write_opts_set_part_offset(IsoWriteOpts *opts, + uint32_t block_offset_2k, + int secs_512_per_head, + int heads_per_cyl); +}}} +resp. by libisoburn calls +{{{ +int isoburn_igopt_set_part_offset(struct isoburn_imgen_opts *opts, + uint32_t block_offset_2k, + int secs_512_per_head, int heads_per_cyl); + +int isoburn_igopt_get_part_offset(struct isoburn_imgen_opts *opts, + uint32_t *block_offset_2k, + int *secs_512_per_head, int *heads_per_cyl); +}}} +resp. by xorriso options +{{{ + -boot_image any partition_offset=(2kb_block_adr) + -boot_image any partition_sec_hd=(number) + -boot_image any partition_hd_cyl=(number) + -as mkisofs ... -partition_offset (2kb_block_adr) ... +}}} + +As stated above, an offset larger than 16 would expose vital parts of the +ISO image as unclaimed space. Values smaller than 16 are not accepted. +So use either an offset of 16 blocks or keep the feature disabled by +offset 0. + diff --git a/xorriso/make_xorriso_standalone.sh b/xorriso/make_xorriso_standalone.sh index 192330b6..facc12f8 100755 --- a/xorriso/make_xorriso_standalone.sh +++ b/xorriso/make_xorriso_standalone.sh @@ -204,6 +204,9 @@ copy_files xorriso/xorriso_buildstamp_none.h \ copy_files xorriso/xorriso_buildstamp_none.h \ "$lone_dir"/xorriso/xorriso_buildstamp_none.h +create_dir "$lone_dir"/doc +copy_files doc/partition_offset.wiki "$lone_dir"/doc + create_dir "$lone_dir"/test copy_files \ test/compare_file.c \ @@ -214,7 +217,6 @@ copy_files \ create_dir "$lone_dir"/libisofs create_dir "$lone_dir"/libisofs/filters -create_dir "$lone_dir"/doc goto_dir "$current_dir"/nglibisofs-develop copy_files libisofs/*.[ch] "$lone_dir"/libisofs copy_files libisofs/filters/*.[ch] "$lone_dir"/libisofs/filters diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 7e622e77..a238eb47 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2010.09.21.150325" +#define Xorriso_timestamP "2010.09.23.135551"