Compare commits
32 Commits
release-0.
...
release-0.
Author | SHA1 | Date | |
---|---|---|---|
fce35ac718 | |||
01518896f9 | |||
caf90e35f5 | |||
1f486fd78b | |||
b58d1e28ef | |||
ebb5937568 | |||
ef444fb29c | |||
1ccbaa302c | |||
0d35100eb0 | |||
48316af1d9 | |||
a75fb9a894 | |||
a0ba4b976c | |||
870280a018 | |||
f33df0ef29 | |||
2a087f6f39 | |||
b07d3ab0c3 | |||
f12df92600 | |||
8a75d35c46 | |||
bb28c69cae | |||
25068a4de2 | |||
d2094a0d80 | |||
16dcf4a29c | |||
69a25c9734 | |||
a387a8b06a | |||
a9af97733e | |||
c30674095b | |||
be838b6940 | |||
b0c79a9a1e | |||
8725baa55f | |||
59ab73c57f | |||
7386596bfa | |||
4833ef23e5 |
32
ChangeLog
32
ChangeLog
@ -1,3 +1,32 @@
|
||||
bzr branch lp:libisofs/for-libisoburn (to become libisofs-0.6.40.tar.gz)
|
||||
===============================================================================
|
||||
- no novelties yet -
|
||||
|
||||
libisofs-0.6.38.tar.gz Sat Oct 23 2010
|
||||
===============================================================================
|
||||
* New API calls iso_write_opts_attach_jte() and iso_write_opts_detach_jte()
|
||||
allow to use of libjte for jigdo production.
|
||||
* New API call iso_write_opts_set_tail_blocks() for tail padding inside
|
||||
ISO image.
|
||||
* New API call iso_image_generator_is_running() to learn when the write thread
|
||||
is done.
|
||||
* New API calls iso_image_add_mips_boot_file(),
|
||||
iso_image_get_mips_boot_files(), iso_image_give_up_mips_boot().
|
||||
* New API call iso_write_opts_set_partition_img() for appending e.g. a small
|
||||
empty FAT12 filesystem which may be used on USB stick.
|
||||
|
||||
libisofs-0.6.36.tar.gz Wed Sep 15 2010
|
||||
===============================================================================
|
||||
* New API function iso_write_opts_set_part_offset() controls creation of
|
||||
an MBR with a first partiton table entry that bears non-zero start address.
|
||||
A second set of volume descriptors and directory tree+tables gets created
|
||||
which can be used to mount the image at the partition start.
|
||||
* Hiding all non-API symbols from the linker by use of --version-script
|
||||
* Automatic C++ detection in libisofs.h by using macro __cplusplus
|
||||
* Corrected several memory leaks and potential NULL pointer evaluations
|
||||
in case of memory shortage.
|
||||
* Now with history of release notes in ./ChangeLog file.
|
||||
|
||||
libisofs-0.6.34.tar.gz Tue Jun 29 2010
|
||||
===============================================================================
|
||||
* New API call iso_image_set_boot_catalog_hidden()
|
||||
@ -193,4 +222,5 @@ libisofs-0.2.4.tar.gz Jan 03 2007
|
||||
libisofs-0.2.3.tar.gz Sat Dec 02 2006
|
||||
===============================================================================
|
||||
* Bugfix release, with some improvements for freebsd support.
|
||||
* Requires libburn to compile.
|
||||
* Requires libburn to compile.
|
||||
|
||||
|
@ -16,7 +16,9 @@ libisofs_libisofs_la_LDFLAGS = \
|
||||
|
||||
# Eventually enabling system adapters for ACL and EA.
|
||||
# ts A90409: Eventually enabling use of zlib.
|
||||
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF)
|
||||
# ts B00927: Eventually enabling use of libjte (Jigdo Template Extraction)
|
||||
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF) \
|
||||
$(LIBJTE_DEF)
|
||||
|
||||
# ts A90114 : added aaip_0_2.*
|
||||
|
||||
@ -80,6 +82,8 @@ libisofs_libisofs_la_LIBADD= \
|
||||
libinclude_HEADERS = \
|
||||
libisofs/libisofs.h
|
||||
|
||||
install-exec-hook:
|
||||
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
|
||||
|
||||
## ========================================================================= ##
|
||||
|
||||
|
40
README
40
README
@ -37,7 +37,25 @@ and execute
|
||||
To make the libraries accessible for running resp. developing applications
|
||||
make install
|
||||
|
||||
See INSTALL file for further details.
|
||||
On GNU/Linux it will try to run program ldconfig with the library installation
|
||||
directory as only argument. Failure to do so will not abort installation.
|
||||
One may disable ldconfig by ./configure option --disable-ldconfig-at-install .
|
||||
|
||||
By use of a version script, the libisofs.so library exposes no other function
|
||||
names but those of the API definitions in <libisofs/libisofs.h>.
|
||||
If -Wl,--version-script=... makes problems with the local compiler, then
|
||||
disable this encapsulation feature by
|
||||
./configure --disable-versioned-libs
|
||||
make clean ; make
|
||||
|
||||
The ./configure script checks for the availability of supporting libraries.
|
||||
If found, they will become mandatory for the emerging libisofs.so and all
|
||||
applications which use it. This dependency can be avoided by configure options
|
||||
--disable-libacl avoid use of ACL functions like acl_to_text()
|
||||
--disable-xattr avoid use of xattr functions like listxattr()
|
||||
--disable-zlib avoid use of zlib functions like compress2()
|
||||
|
||||
See INSTALL file for general options of ./configure.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@ -113,7 +131,6 @@ a) Images with unsupported features, such as:
|
||||
- UDF.
|
||||
- HSF/HFS+ or other Mac extensions.
|
||||
- ECMA-119 Extended attributes.
|
||||
- Non El-Torito boot info.
|
||||
- ...
|
||||
In all these cases, the resulting new image (or new session) could lack some
|
||||
features of the original image. Nevertheless, the ECMA-119 System Area with
|
||||
@ -122,22 +139,9 @@ a) Images with unsupported features, such as:
|
||||
or modify the image. Others remain undetected. Images created with libisofs
|
||||
do not have this problems.
|
||||
|
||||
b) Bootable El-Torito images may have several problems, that result in a new
|
||||
image that is not bootable, or that boots from an outdated session. In many
|
||||
cases it is recommended to add boot info again in the new session.
|
||||
|
||||
- isolinux images won't be bootable after a modify. This is because
|
||||
isolinux images need to have hardcoded the root dir lba in their boot
|
||||
information table.
|
||||
libisofs makes an educated guess at load time whether a boot image
|
||||
contains such a table. Its outcome can be inquired by call
|
||||
el_torito_seems_boot_info_table().
|
||||
If one knows to have isolinux or GRUB El-Torito-bootable images, or if
|
||||
a boot information table seems to exist, it is advised to apply the
|
||||
el_torito_patch_isolinux_image() function.
|
||||
Most boot images are highly dependent of the image contents, so if the
|
||||
user moves or removes some files on image it is possible they won't boot
|
||||
anymore.
|
||||
b) Bootable El-Torito images may have problems, that result in a new image that
|
||||
is not bootable, or that boots from an outdated session. In some cases it
|
||||
might be necessary to add boot info again in a new first session.
|
||||
- There is no safe way to modify hidden boot images, as the size of the
|
||||
boot image can't be figured out.
|
||||
|
||||
|
@ -16,10 +16,12 @@ AC_DEFUN([TARGET_SHIZZLE],
|
||||
|
||||
AC_MSG_CHECKING([target operating system])
|
||||
|
||||
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
||||
case $target in
|
||||
*-*-linux*)
|
||||
ARCH=linux
|
||||
LIBBURN_ARCH_LIBS=
|
||||
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
||||
;;
|
||||
*-*-freebsd*)
|
||||
ARCH=freebsd
|
||||
|
35
configure.ac
35
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [0.6.36], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [0.6.38], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -40,7 +40,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
LIBISOFS_MAJOR_VERSION=0
|
||||
LIBISOFS_MINOR_VERSION=6
|
||||
LIBISOFS_MICRO_VERSION=36
|
||||
LIBISOFS_MICRO_VERSION=38
|
||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||
|
||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||
@ -50,10 +50,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||
# 2010.09.15 development jump has not yet happened
|
||||
# SONAME = 38 - 32 = 6 . Library name = libisofs.6.32.0
|
||||
LT_CURRENT=38
|
||||
LT_AGE=32
|
||||
# 2010.10.23 development jump has not yet happened
|
||||
# SONAME = 40 - 34 = 6 . Library name = libisofs.6.34.0
|
||||
LT_CURRENT=40
|
||||
LT_AGE=34
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
@ -205,6 +205,18 @@ else
|
||||
fi
|
||||
AC_SUBST(ZLIB_DEF)
|
||||
|
||||
dnl ts B00927
|
||||
AC_ARG_ENABLE(libjte,
|
||||
[ --enable-libjte Enable use of libjte by libisofs, default=yes],
|
||||
, enable_libjte=yes)
|
||||
if test "x$enable_libjte" = xyes; then
|
||||
LIBJTE_DEF="-DLibisofs_with_libjtE"
|
||||
AC_CHECK_HEADER(libjte/libjte.h, AC_CHECK_LIB(jte, libjte_new, , LIBJTE_DEF= ), LIBJTE_DEF= )
|
||||
else
|
||||
LIBJTE_DEF=
|
||||
fi
|
||||
AC_SUBST(LIBJTE_DEF)
|
||||
|
||||
# Library versioning normally serves a complex purpose.
|
||||
# Since libisofs obeys strict ABI backward compatibility, it needs only the
|
||||
# simple feature to declare function names "global:" or "local:". Only the
|
||||
@ -225,6 +237,17 @@ else
|
||||
echo "disabled strict symbol encapsulation"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(ldconfig-at-install,
|
||||
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
|
||||
, ldconfig_at_install=yes)
|
||||
if test x$ldconfig_at_install = xyes; then
|
||||
dummy=dummy
|
||||
else
|
||||
LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'"
|
||||
echo "disabled run of ldconfig during installation on GNU/Linux"
|
||||
fi
|
||||
AC_SUBST(LIBBURNIA_LDCONFIG_CMD)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/doxygen.conf
|
||||
|
662
doc/boot_sectors.txt
Normal file
662
doc/boot_sectors.txt
Normal file
@ -0,0 +1,662 @@
|
||||
|
||||
|
||||
|
||||
Collection of Boot Sector Formats for ISO 9660 Images
|
||||
|
||||
|
||||
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||
|
||||
This information is collected from various sources. Some is backed by
|
||||
specifications, some is just rumor which happens to work (maybe not even that).
|
||||
|
||||
|
||||
Content
|
||||
|
||||
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
|
||||
|
||||
MBR, for PC-BIOS x86 from (pseudo-) hard disk
|
||||
- SYSLINUX isohybrid MBR
|
||||
- GRUB2 grub-mkrescue MBR.
|
||||
|
||||
MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
||||
|
||||
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
EL Torito CD booting
|
||||
for PC-BIOS x86, PowerPC, (old) Mac, EFI
|
||||
|
||||
Sources:
|
||||
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
||||
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
||||
libisofs/eltorito.[ch] by Vreixo Formoso.
|
||||
man mkisofs by Joerg Schilling.
|
||||
|
||||
|
||||
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
|
||||
with arbitrary content. This prescription is obeyed by PC-BIOS systems only
|
||||
if the ISO 9660 image is presented on CD, DVD or BD media.
|
||||
In this case the El Torito Boot record is the starting point of booting.
|
||||
|
||||
The Boot Record is a ECMA-119 Volume Descriptor which is eventually located
|
||||
at 2 kB block number 17 (decimal). Its content points to the location of the
|
||||
Boot Catalog.
|
||||
The format is described in part by ECMA-119 8.2 "Boot Record" and further
|
||||
specified by El Torito figure 7.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 0 | 0 | Volume Descriptor Type. 0= Boot record
|
||||
1 - 5 | "CD001" | Standard Identifier
|
||||
6 - 6 | 1 | Volume Descriptor Version
|
||||
7 - 38 | el_torito | Boot System Identifier
|
||||
39 - 70 | 0 | Boot Identifier
|
||||
| |
|
||||
71 -2047 | ========== | Boot System Use
|
||||
| |
|
||||
71 - 74 | cataloglba | The 2 kB block number of the Boot Catalog
|
||||
| | as little-endian 32 bit number.
|
||||
| |
|
||||
75 -2047 | 0 | Unused
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
el_torito is the constant string "EL TORITO SPECIFICATION" padded by 9 zeros.
|
||||
cataloglba has to be provided by the file system generator.
|
||||
|
||||
|
||||
The Boot Catalog lists the available boot images which may be prepared for
|
||||
multiple system architectures, called "platforms".
|
||||
It consists of one or more 2 kB blocks. The content is a sequence of fixed
|
||||
format entries, 32 bytes each.
|
||||
The entries are grouped in sections, which assign the entries to a particular
|
||||
system architecture. The booting system will then choose an entry from an
|
||||
appropriate section.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 31 | ========== | Validation Entry
|
||||
| | begins the first section, specifies an architecture
|
||||
32 - 63 | ========== | Initial/Default Entry
|
||||
| | points to a boot image for given architecture
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
Optional:
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
64 - 95 | ========== | Section Header entry
|
||||
| | begins new section, specifies an architecture
|
||||
96 - 127 | ========== | Section Entry
|
||||
| | points to a boot image for given architecture
|
||||
... | .......... | Optional more Section Entries
|
||||
... | .......... | Optional more Section Headers and their Section
|
||||
| | Entries
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
An architecture is refered by a Platform Id number.
|
||||
Defined by El Torito are:
|
||||
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
||||
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
||||
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
|
||||
Further in use by GRUB2 is:
|
||||
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
|
||||
Intel ia64 Itanium and possibly with newer Apple machines.
|
||||
|
||||
Words resp. numbers are represented are little-endian.
|
||||
|
||||
Validation Entry:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 0 | 1 | Header Id
|
||||
| |
|
||||
1 - 1 | platform_id| Platform Id. One of: 0, 1, 2, 0xef. See above.
|
||||
| |
|
||||
2 - 3 | 0 | Reserved
|
||||
4 - 27 | manuf_dev | ID string identifies the manufacturer/developer
|
||||
| | (no non-zero examples known yet)
|
||||
| |
|
||||
28 - 29 | checksum | Checksum Word for the Validation Entry.
|
||||
| | The sum of all words in the entry has to be 0.
|
||||
| |
|
||||
30 - 30 | 0x55 |
|
||||
31 - 31 | 0xaa |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
Initial/Default Entry:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 0 | boot_indct | Boot Indicator: 0x88 = bootable, 0x00 = not bootable
|
||||
| |
|
||||
1 - 1 | boot_media | Boot Media Type (i.e. media emulated by boot image):
|
||||
| | 0= no emulation , 1= 1.2 MB diskette, 2=1.44 MB,
|
||||
| | 3= 2.88 MB , 4= hard disk
|
||||
| | (About everybody uses 0 = no emulation)
|
||||
| |
|
||||
2 - 3 | load_seg | Load Segment. (meaning unclear)
|
||||
| | "If this value is 0 the system will use the
|
||||
| | traditional segment of 7C0."
|
||||
| | libisofs default is 0
|
||||
| |
|
||||
4 - 4 | sys_type | System Type.
|
||||
| | "Must be a copy of byte 5 from the partition table
|
||||
| | found in the boot image."
|
||||
| | libisofs reads the start the boot image as MBR
|
||||
| | if boot_media == 4. This emulated MBR has a
|
||||
| | partition table from where a byte gets copied.
|
||||
| | Else this byte is 0.
|
||||
| |
|
||||
5 - 5 | 0 | Unused
|
||||
| |
|
||||
6 - 7 | sec_count | Sector Count.
|
||||
| | "the number of virtual/emulated sectors the system
|
||||
| | will store at Load Segment during the initial boot
|
||||
| | procedure."
|
||||
| | libisofs stores 1 for emulated boot_media and
|
||||
| | 0 for boot_media == 0.
|
||||
| |
|
||||
8 - 11 | load_rba | Load RBA. The 2 kB block address where the boot
|
||||
| | image file content is located in the ISO 9660 image.
|
||||
| |
|
||||
12 - 31 | 0 | Unused
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
Section Header Entry:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 0 | head_ind | Header Indicator: 0x90 = more headers follow
|
||||
| | 0x91 = final header, last section
|
||||
| |
|
||||
1 - 1 | platform_id| Platform Id. One of: 0, 1, 2, 0xef. See above.
|
||||
| |
|
||||
2 - 3 | num_entries| Number of entries to follow in this section
|
||||
| |
|
||||
4 - 31 | | ID string identifies the manufacturer/developer
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
Section Entry:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 0 | boot_indct | Boot Indicator: 0x88 = bootable, 0x00 = not bootable
|
||||
| |
|
||||
1 - 1 | boot_media | Boot Media Type (i.e. media emulated by boot image):
|
||||
| | Bit 0 to 3 govern emulation
|
||||
| | 0= no emulation , 1= 1.2 MB diskette, 2=1.44 MB,
|
||||
| | 3= 2.88 MB , 4= hard disk
|
||||
| | (About everybody uses 0 = no emulation)
|
||||
| | Bit 4 is reserved and must be 0
|
||||
| | Bit 5 "Continuation entry follows" (meaning unclear)
|
||||
| | Might be the indicator for Extension Entries,
|
||||
| | which are not described here.
|
||||
| | Bit 6 "Image contains an ATAPI driver"
|
||||
| | Bit 7 "Image contains SCSI drivers"
|
||||
| |
|
||||
2 - 3 | load_seg | Load Segment. (meaning unclear)
|
||||
| | See above Initial/Default Entry
|
||||
| | libisofs default is 0.
|
||||
4 - 4 | sys_type | System Type.
|
||||
| | See above Initial/Default Entry
|
||||
| | 0 if not emulation == 4.
|
||||
5 - 5 | 0 | Unused
|
||||
| |
|
||||
6 - 7 | sec_count | Sector Count.
|
||||
| | See above Initial/Default Entry
|
||||
| | libisofs stores 1 for emulated boot_media and
|
||||
| | 0 for boot_media == 0.
|
||||
| |
|
||||
8 - 11 | load_rba | Load RBA. The 2 kB block address where the boot
|
||||
| | image file content is located in the ISO 9660 image.
|
||||
| |
|
||||
12 - 31 | sel_crit | "Vendor unique selection criteria."
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
The boot image file content is mostly opaque to the ISO 9660 image generator.
|
||||
Nevertheless there is a tradition named "Boot Info Table" which prescribes
|
||||
to write information into byte fields of the boot image file content.
|
||||
There are no general means known how a producer of ISO 9660 images could
|
||||
detect the need for Boot Info Table production.
|
||||
It rather needs a hint from the user who has to know whether the boot image
|
||||
expects a Boot Info Table.
|
||||
The Boot Info Table begins at byte 8 of the boot image content.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor
|
||||
| | This is the session start LBA + 16.
|
||||
| |
|
||||
12 - 15 | file_lba | Block address of the start of the boot image file
|
||||
| | content.
|
||||
| |
|
||||
16 - 19 | file_len | Number of bytes in boot image file content.
|
||||
| |
|
||||
20 - 23 | checksum | Little-endian: The sum of all 32-bit words of the
|
||||
| | file content from byte 64 to file end.
|
||||
| |
|
||||
24 - 63 | 0 | Reserved
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
MBR
|
||||
for PC-BIOS x86 from (pseudo-) hard disk
|
||||
|
||||
Sources:
|
||||
http://en.wikipedia.org/wiki/Master_boot_record
|
||||
Mailing list conversations with H. Peter Anvin and Vladimir Serbinenko.
|
||||
|
||||
|
||||
The candidates for MBR booting will normally use El Torito rather than MBR
|
||||
if the ISO image is presented on CD, DVD, or BD media.
|
||||
The eventual MBR comes into effect it the image is on a media that is
|
||||
interpreted by the BIOS as some kind of hard disk. Usually real hard disks,
|
||||
floppy disks, USB sticks, memory cards.
|
||||
|
||||
An important part of an MBR is the DOS style partition table. It describes up
|
||||
to four primary partitions. There are two formats used for block address:
|
||||
Cylinder/Head/Sector (C/H/S) and Logical Block Address (LBA). Both are based
|
||||
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
|
||||
|
||||
For C/H/S, the sector address is broken up into whole cylinders, remaining
|
||||
heads, and remaining sectors + 1. The nomenclature seems to stem from antique
|
||||
drum storage.
|
||||
There are two parameters, sectors_per_head and heads_per_cylinder which are not
|
||||
stored in the MBR. So it is more or less arbitray how to convert a LBA into
|
||||
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
|
||||
may use sectors_per_head = 63 , heads_per_cylinder = 255.
|
||||
|
||||
|
||||
Words are composed little-endian style.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 439 | = opaque = | Code Area filled with bytes for some boot system,
|
||||
| | typically machine code.
|
||||
| |
|
||||
440 - 443 | disk_sgntr | Disc signature, an individual disk id of obscure
|
||||
| | usability.
|
||||
| | (The Code Area might extend up to this field.)
|
||||
| |
|
||||
444 - 445 | 0 | "usually nulls"
|
||||
| | (The Code Area might extend up to this field.)
|
||||
| |
|
||||
446 - 461 | ========== | Partition Table Entry for partition 1
|
||||
| |
|
||||
446 - 446 | status | Governs bootability:
|
||||
| | 0x80 = bootable/active , 0x00 non-bootable/inactive
|
||||
| |
|
||||
447 - 449 | ========== | C/H/S address of partition start
|
||||
447 - 447 | start_head | Heads part of start address.
|
||||
448 - 448 | start_c_s | Bits 0 to 5 : Sectors part of start address.
|
||||
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
||||
449 - 449 | start_cyl | Lower 8 bits of cylinders part of start address
|
||||
| |
|
||||
450 - 450 | part_type | Partition type indicates the purpose or kind of
|
||||
| | filesystem in the partition.
|
||||
| |
|
||||
451 - 453 | ========== | C/H/S address of last absolute sector in partition
|
||||
451 - 451 | end_head | Heads part of end address.
|
||||
452 - 452 | end_c_s | Bits 0 to 5 : Sectors part of end address.
|
||||
| Values: 1 to 63, not 0.
|
||||
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
||||
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
|
||||
| |
|
||||
454 - 457 | start_lba | LBA of first absolute sector in partiton.
|
||||
| | Block size is 512. Counting starts at 0.
|
||||
| |
|
||||
458 - 461 | num_blocks | Number of sectors in partition.
|
||||
| |
|
||||
462 - 477 | ========== | Partition Table Entry for partition 2
|
||||
| part_entr2 | 16 bytes. Format as with partition 1.
|
||||
| | All 0 means that partition is unused/undefined.
|
||||
| |
|
||||
478 - 493 | ========== | Partition Table Entry for partition 3
|
||||
| part_entr3 | 16 bytes. See above.
|
||||
| |
|
||||
494 - 509 | ========== | Partition Table Entry for partition 4
|
||||
| part_entr4 | 16 bytes. See above.
|
||||
| |
|
||||
510 - 510 | 0x55 | MBR signature
|
||||
511 - 511 | 0xaa | MBR signature
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
By tradition the MBR itself and possibly more blocks are not claimed by any
|
||||
partition. But starting the first partition at a non-zero block address causes
|
||||
on Linux a partition device file (e.g. /dev/sdb1) which cannot be used to mount
|
||||
the ISO filesystem.
|
||||
|
||||
libisofs is able to produce a second set of trees and meta data which is
|
||||
suitable for being mounted at start block 16 (ISO) resp. 64 (MBR).
|
||||
See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
|
||||
and http://libburnia-project.org/wiki/PartitionOffset for examples with
|
||||
program xorriso.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
SYSLINUX Isohybrid MBR
|
||||
|
||||
Sources:
|
||||
syslinux-3.72/utils/isohybrid , a perl script by H. Peter Anvin = hpa.
|
||||
Mailing list conversations with hpa.
|
||||
|
||||
|
||||
An isohybrid MBR directs the booting BIOS to an ISOLINUX boot image which
|
||||
is also the target of an El Torito boot catalog entry.
|
||||
For that purpose one has to take an MBR template and has to set a few bytes
|
||||
to values which sufficiently describe the ISO image and the boot image file.
|
||||
|
||||
Words are composed little-endian style.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 431 | = opaque = | Syslinux machine code provided by MBR template
|
||||
| |
|
||||
432 - 439 | hd_bootlba | Address of the ISOLINUX boot image file in the
|
||||
| | ISO image. Counted in 512 byte blocks.
|
||||
| |
|
||||
440 - 443 | mbr_id | Random number
|
||||
444 - 445 | 0 | Padding
|
||||
| |
|
||||
446 - 509 | ========== | Partition table
|
||||
| |
|
||||
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
||||
| | starting at LBA 0. I.e. contrary to tradition.
|
||||
| | See above for partition table entry format.
|
||||
| |
|
||||
462 - 509 | 0 | Unused partition entries 2 to 4
|
||||
510 - 511 | 0xaa55 | MBR signature
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
hpa about MBR templates and partition table filesystem types:
|
||||
|
||||
"[MBR templates] are available in the Syslinux build tree under the names:
|
||||
mbr/isohdp[fp]x*.bin
|
||||
The default probably should be mbr/isohdppx.bin, but it's ultimately up
|
||||
to the user.
|
||||
[...]
|
||||
Note: the filesystem type is largely arbitrary, in theory it can be any
|
||||
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
|
||||
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
|
||||
"
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
GRUB2 grub-mkrescue MBR
|
||||
|
||||
Sources:
|
||||
Mailing list conversations with Vladimir Serbinenko.
|
||||
|
||||
|
||||
The MBR file that is used with GRUB2 script grub-mkrescue needs only a
|
||||
partition table entry which describes the image size.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template
|
||||
| |
|
||||
446 - 509 | ========== | Partition table
|
||||
| |
|
||||
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
||||
| | Peculiar is the start offset of 1 block.
|
||||
| | This prevents mounting of the partition.
|
||||
| | See above for partition table entry format.
|
||||
| |
|
||||
462 - 509 | 0 | Unused partition entries 2 to 4
|
||||
510 - 511 | 0xaa55 | MBR signature
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
Vladimir Serbinenko about the partition table entry:
|
||||
"Currently we use first and not last entry. You need to:
|
||||
1) Zero-fill 446-510
|
||||
2) Put 0x55, 0xAA into 510-512
|
||||
3) Put 0x80 (for bootable partition), 0, 2, 0 (C/H/S of the start), 0xcd
|
||||
(partition type), [3 bytes of C/H/S end], 0x01, 0x00, 0x00, 0x00 (LBA
|
||||
start in little endian), [LBA end in little endian] at 446-462
|
||||
"
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
MIPS Volume Header
|
||||
for MIPS Big Endian, e.g. SGI Indigo2
|
||||
|
||||
Sources:
|
||||
cdrkit-1.1.10/genisoimage/boot-mips.c
|
||||
by Steve McIntyre <steve@einval.com>
|
||||
which refers to
|
||||
genisovh by Florian Lohoff <flo@rfc822.org>
|
||||
and Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
who seem to have learned parameter settings from IRIX CD media
|
||||
There are traces in the web which relate this to specs by
|
||||
MIPS Computer Systems, Inc. , 1985
|
||||
Silicon Graphics Computer Systems, Inc. , 2000
|
||||
|
||||
|
||||
The first 512 bytes of the media constitute the Volume Header.
|
||||
Words are composed big-endian style.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 3 | 0x0be5a941 | Magic number
|
||||
4 - 5 | 0 | Root partition number
|
||||
6 - 7 | 0 | Swap partition number
|
||||
8 - 23 | 0 | Name of file to boot (unclear what this means)
|
||||
| |
|
||||
24 - 71 | ========== | Device Parameters
|
||||
| |
|
||||
24 - 24 | 0 | Spiral addressing skew (unclear what this means)
|
||||
25 - 25 | 0 | Words of 0 before header
|
||||
26 - 26 | 0 | Words of 0 between hdr and data
|
||||
27 - 27 | 0 | Spare sectors per cylinder
|
||||
28 - 29 | num_cyl_l | Number of usable cylinder, lower two bytes
|
||||
| | ((iso_size + BYTES_PER_SECTOR - 1) /
|
||||
| | (SECTORS_PER_TRACK * BYTES_PER_SECTOR)) & 0xffff
|
||||
30 - 31 | 0 | Starting head of volume 0
|
||||
32 - 33 | 1 | Number of tracks per cylinder
|
||||
34 - 34 | 0 | Depth of CTQ queue (unclear what this means)
|
||||
35 - 35 | num_cyl_h | Number of usable cylinders, high byte
|
||||
| | ((iso_size + BYTES_PER_SECTOR - 1) /
|
||||
| | (SECTORS_PER_TRACK * BYTES_PER_SECTOR)) >> 16
|
||||
36 - 37 | 0 | unused
|
||||
38 - 39 | 32 | SECTORS_PER_TRACK
|
||||
40 - 41 | 512 | BYTES_PER_SECTOR
|
||||
42 - 43 | 0 | Sector interleave (unclear what this means)
|
||||
44 - 47 | 0x00000034 | Controller characteristics composed from
|
||||
| | DP_RESEEK 0x00000020 /* recalibrate as last resort */
|
||||
| | DP_IGNOREERRORS 0x00000010
|
||||
| | /* transfer data regardless of errors */
|
||||
| | DP_TRKFWD 0x00000004
|
||||
| | /* forward to replacement track */
|
||||
48 - 51 | 0 | Bytes/sec for kernel stats
|
||||
52 - 55 | 0 | Max num retries on data error
|
||||
56 - 59 | 0 | ms per word to xfer, for iostat
|
||||
60 - 71 | 0 | 6 parameter words for xylogics controllers
|
||||
| |
|
||||
72 - 311 | ========== | Volume Directory with 15 entries of 16 bytes each
|
||||
| |
|
||||
72 - 87 | ========== | Volume Directory Entry 1
|
||||
72 - 79 | boot_name | Boot file basename, eventually padded by 0 to lenght 8
|
||||
80 - 83 | boot_block | ISO 9660 LBA of boot file * 4, i.e. in blocks of 512
|
||||
84 - 87 | boot_bytes | File length in bytes
|
||||
| |
|
||||
88 - 311 | see above | Volume Directory Entries 2 to 15
|
||||
| |
|
||||
312 - 504 | ========== | Partition Table with 16 entries of 12 bytes each
|
||||
| |
|
||||
312 - 407 | 0 | Unused partition entries 1 to 8
|
||||
| |
|
||||
408 - 419 | ========== | Partition Table Entry 9 for Volume Header
|
||||
408 - 411 | part_blks | Number of 512 byte blocks in partition
|
||||
| |(iso_size + (BYTES_PER_SECTOR - 1)) / BYTES_PER_SECTOR
|
||||
412 - 415 | 0 | Start block of partition
|
||||
416 - 419 | 0 | PTYPE_VOLHDR = Partition is volume header
|
||||
| |
|
||||
420 - 431 | 0 | Unused partition entry 10
|
||||
| |
|
||||
432 - 443 | ========== | Partition Table Entry 11 for Volume
|
||||
432 - 435 | part_blks | Number of 512 byte blocks in partition
|
||||
| |(iso_size + (BYTES_PER_SECTOR - 1)) / BYTES_PER_SECTOR
|
||||
436 - 439 | 0 | Start block of partition
|
||||
440 - 443 | 6 | PTYPE_VOLUME = Partition is entire volume
|
||||
| |
|
||||
444 - 503 | 0 | Unused partition entries 12 to 16
|
||||
| |
|
||||
504 - 507 | head_chk | Volume header checksum
|
||||
| | The two's complement of bytes 0 to 503 read as big
|
||||
| | endian unsigned 32 bit: sum(words) + head_chk == 0
|
||||
| |
|
||||
508 - 511 | 0 | Volume header end padding
|
||||
| |
|
||||
up to 2048 | 0 | ISO 9660 Block end padding
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
Test image produced by
|
||||
genisoimage -o /u/test/mips_boot.iso -mips-boot checksum.c jte
|
||||
which reports
|
||||
Found mips boot image checksum.c, using extent 636 (0x27C), #blocks 14336 (0x3800)
|
||||
|
||||
xorriso reports as 2048 byte LBA of the boot image dummy file
|
||||
File data lba: 0 , 159 , 7 , 14330 , '/CHECKSUM.C'
|
||||
|
||||
First 512 bytes in hex:
|
||||
0 : 0b e5 a9 41 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
16 : 00 00 00 00 00 00 00 00 00 00 00 00 00 51 00 00
|
||||
32 : 00 01 00 00 00 00 00 20 02 00 00 00 00 00 00 34
|
||||
48 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
64 : 00 00 00 00 00 00 00 00 63 68 65 63 6b 73 75 6d
|
||||
80 : 00 00 02 7c 00 00 38 00 00 00 00 00 00 00 00 00
|
||||
... 0 ...
|
||||
400 : 00 00 00 00 00 00 00 00 00 00 0a 28 00 00 00 00
|
||||
416 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
432 : 00 00 0a 28 00 00 00 00 00 00 00 06 00 00 00 00
|
||||
... 0 ...
|
||||
496 : 00 00 00 00 00 00 00 00 22 ec 2c c9 00 00 00 00
|
||||
|
||||
The 32 bit two's complement of bytes 0 to 503 is 0x22ec2cc9.
|
||||
|
||||
In decimal:
|
||||
0 : 11 229 169 65 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
16 : 0 0 0 0 0 0 0 0 0 0 0 0 0 81 0 0
|
||||
32 : 0 1 0 0 0 0 0 32 2 0 0 0 0 0 0 52
|
||||
48 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
64 : 0 0 0 0 0 0 0 0 99 104 101 99 107 115 117 109
|
||||
80 : 0 0 2 124 0 0 56 0 0 0 0 0 0 0 0 0
|
||||
... 0 ...
|
||||
400 : 0 0 0 0 0 0 0 0 0 0 10 40 0 0 0 0
|
||||
416 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
432 : 0 0 10 40 0 0 0 0 0 0 0 6 0 0 0 0
|
||||
... 0 ...
|
||||
496 : 0 0 0 0 0 0 0 0 34 236 44 201 0 0 0 0
|
||||
|
||||
Cleartext part:
|
||||
64 : c h e c k s u m
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
DEC Boot Block
|
||||
for MIPS Little Endian , e.g. DECstation
|
||||
|
||||
Sources:
|
||||
cdrkit-1.1.10/genisoimage/boot-mipsel.c
|
||||
by Steve McIntyre <steve@einval.com>
|
||||
which refers to
|
||||
delo by Florian Lohoff <flo@rfc822.org>
|
||||
and Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
cdrkit-1.1.10/include/glibc_elf.h
|
||||
by Steve McIntyre
|
||||
which is based on
|
||||
<elf.h> from GNUC C Library by Free Software Foundation, Inc.
|
||||
|
||||
|
||||
There seems to be only one boot file possible.
|
||||
Some information needs to be read out of the ELF headers of this boot file.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 7 | 0 | Padding
|
||||
| |
|
||||
8 - 11 | 0x0002757a | Magic number
|
||||
| |
|
||||
12 - 15 | 1 | Mode /* 0: Single extent, 1: Multi extent boot */
|
||||
| |
|
||||
16 - 19 | load_adr | Load address /* Load below kernel */
|
||||
| | Stems from ELF header of boot file.
|
||||
| | See below Elf32_Phdr field p_vaddr.
|
||||
| |
|
||||
20 - 23 | exec_adr | Execution address /* And exec there */
|
||||
| | Stems from ELF header of boot file.
|
||||
| | See below Elf32_Ehdr field e_entry.
|
||||
| |
|
||||
24 - 31 | ========== | Boot Map Entry 1
|
||||
| |
|
||||
24 - 27 | seg_size | Segment size in file. Blocks of 512 bytes.
|
||||
| | Stems from ELF header of boot file.
|
||||
| | (Elf32_Phdr field p_filesz + 511) / 512;
|
||||
| |
|
||||
28 - 31 | seg_start | Segment file offset. Blocks 512 bytes.
|
||||
| | ISO 9660 LBA of boot file * 4 plus offset
|
||||
| | + offset which stems from ELF header of boot file:
|
||||
| | (Elf32_Phdr field p_offset + 511) / 512;
|
||||
| |
|
||||
32 - 431 | ========== | Boot Map Entries 2 to 51
|
||||
| 0 |
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
Elf32_Ehdr gets loaded from boot file byte address 0:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 23 | | ( Magic number, file information )
|
||||
| |
|
||||
24 - 27 | e_entry | /* Entry point virtual address */
|
||||
| = exec_adr | Needed for exec_adr
|
||||
| |
|
||||
28 - 31 | e_phoff | /* Program header table file offset */
|
||||
| | Byte address of Elf32_Phdr
|
||||
| |
|
||||
|
||||
Elf32_Phdr gets loaded from boot file byte_address Elf32_Ehdr.e_phoff :
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 3 | | ( Segment type )
|
||||
| |
|
||||
4 - 7 | p_offset | /* Segment file offset */
|
||||
|-> seg_start| Needed for seg_start
|
||||
| |
|
||||
8 - 11 | p_vaddr | /* Segment virtual address */
|
||||
| =load_adr | Needed for load_adr
|
||||
| |
|
||||
12 - 15 | | (Segment physical address)
|
||||
| |
|
||||
16 - 19 | p_filesz | /* Segment size in file */
|
||||
|-> seg_size | Needed for seg_size
|
||||
| |
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
>>> ??? HP-PA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
>>> ??? DEC Alpha
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -295,9 +295,9 @@ ex:;
|
||||
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
||||
if(d_acl_text != NULL)
|
||||
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
||||
if(list != NULL)
|
||||
free(list);
|
||||
if(ret <= 0 || (flag & (1 << 15))) {
|
||||
if(list != NULL)
|
||||
free(list);
|
||||
if(*names != NULL) {
|
||||
for(i= 0; i < *num_attrs; i++)
|
||||
free((*names)[i]);
|
||||
|
@ -41,6 +41,20 @@
|
||||
#include <langinfo.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef Xorriso_standalonE
|
||||
|
||||
#ifdef Xorriso_with_libjtE
|
||||
#include "../libjte/libjte.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
#include <libjte/libjte.h>
|
||||
#endif
|
||||
|
||||
#endif /* ! Xorriso_standalonE */
|
||||
|
||||
/*
|
||||
* TODO #00011 : guard against bad path table usage with more than 65535 dirs
|
||||
* image with more than 65535 directories have path_table related problems
|
||||
@ -55,6 +69,12 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
|
||||
if (t == NULL)
|
||||
return;
|
||||
|
||||
if (t->refcount > 1) {
|
||||
t->refcount--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (t->root != NULL)
|
||||
ecma119_node_free(t->root);
|
||||
if (t->image != NULL)
|
||||
@ -87,10 +107,34 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
free(t->writers);
|
||||
if (t->partition_root != NULL)
|
||||
ecma119_node_free(t->partition_root);
|
||||
t->partition_root = NULL;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (t->appended_partitions[i] != NULL)
|
||||
free(t->appended_partitions[i]);
|
||||
|
||||
free(t);
|
||||
}
|
||||
|
||||
static int show_chunk_to_jte(Ecma119Image *target, char *buf, int count)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
int ret;
|
||||
|
||||
if (target->libjte_handle == NULL)
|
||||
return ISO_SUCCESS;
|
||||
ret = libjte_show_data_chunk(target->libjte_handle, buf, count, 1);
|
||||
if (ret <= 0) {
|
||||
iso_libjte_forward_msgs(target->libjte_handle,
|
||||
target->image->id, ISO_LIBJTE_FILE_FAILED, 0);
|
||||
return ISO_LIBJTE_FILE_FAILED;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we should add version number ";" to the given node name.
|
||||
*/
|
||||
@ -896,7 +940,7 @@ int ecma119_writer_create(Ecma119Image *target)
|
||||
|
||||
/** compute how many padding bytes are needed */
|
||||
static
|
||||
int pad_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
int mspad_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *target;
|
||||
uint32_t min_size;
|
||||
@ -907,24 +951,25 @@ int pad_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
target = writer->target;
|
||||
min_size = 32 + target->partition_offset;
|
||||
if (target->curblock < min_size) {
|
||||
target->pad_blocks = min_size - target->curblock;
|
||||
target->mspad_blocks = min_size - target->curblock;
|
||||
target->curblock = min_size;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int pad_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
int mspad_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
/* nothing to do */
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int pad_writer_write_data(IsoImageWriter *writer)
|
||||
int mspad_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
uint32_t pad[BLOCK_SIZE];
|
||||
uint8_t pad[BLOCK_SIZE];
|
||||
size_t i;
|
||||
|
||||
if (writer == NULL) {
|
||||
@ -932,12 +977,12 @@ int pad_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
t = writer->target;
|
||||
|
||||
if (t->pad_blocks == 0) {
|
||||
if (t->mspad_blocks == 0) {
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
memset(pad, 0, BLOCK_SIZE);
|
||||
for (i = 0; i < t->pad_blocks; ++i) {
|
||||
for (i = 0; i < t->mspad_blocks; ++i) {
|
||||
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -948,14 +993,14 @@ int pad_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
static
|
||||
int pad_writer_free_data(IsoImageWriter *writer)
|
||||
int mspad_writer_free_data(IsoImageWriter *writer)
|
||||
{
|
||||
/* nothing to do */
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int pad_writer_create(Ecma119Image *target)
|
||||
int mspad_writer_create(Ecma119Image *target)
|
||||
{
|
||||
IsoImageWriter *writer;
|
||||
|
||||
@ -964,10 +1009,10 @@ int pad_writer_create(Ecma119Image *target)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
writer->compute_data_blocks = pad_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = pad_writer_write_vol_desc;
|
||||
writer->write_data = pad_writer_write_data;
|
||||
writer->free_data = pad_writer_free_data;
|
||||
writer->compute_data_blocks = mspad_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = mspad_writer_write_vol_desc;
|
||||
writer->write_data = mspad_writer_write_data;
|
||||
writer->free_data = mspad_writer_free_data;
|
||||
writer->data = NULL;
|
||||
writer->target = target;
|
||||
|
||||
@ -976,6 +1021,100 @@ int pad_writer_create(Ecma119Image *target)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/** ----- Zero padding writer ----- */
|
||||
|
||||
struct iso_zero_writer_data_struct {
|
||||
uint32_t num_blocks;
|
||||
};
|
||||
|
||||
static
|
||||
int zero_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *target;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
|
||||
if (writer == NULL)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
target = writer->target;
|
||||
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||
target->curblock += data->num_blocks;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int zero_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
/* nothing to do */
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int zero_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
uint8_t pad[BLOCK_SIZE];
|
||||
size_t i;
|
||||
|
||||
if (writer == NULL)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
t = writer->target;
|
||||
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||
|
||||
if (data->num_blocks == 0)
|
||||
return ISO_SUCCESS;
|
||||
memset(pad, 0, BLOCK_SIZE);
|
||||
for (i = 0; i < data->num_blocks; ++i) {
|
||||
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int zero_writer_free_data(IsoImageWriter *writer)
|
||||
{
|
||||
if (writer == NULL)
|
||||
return ISO_SUCCESS;
|
||||
if (writer->data == NULL)
|
||||
return ISO_SUCCESS;
|
||||
free(writer->data);
|
||||
writer->data = NULL;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks)
|
||||
{
|
||||
IsoImageWriter *writer;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
|
||||
writer = malloc(sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
data = calloc(1, sizeof(struct iso_zero_writer_data_struct));
|
||||
if (data == NULL) {
|
||||
free(writer);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
data->num_blocks = num_blocks;
|
||||
|
||||
writer->compute_data_blocks = zero_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = zero_writer_write_vol_desc;
|
||||
writer->write_data = zero_writer_write_data;
|
||||
writer->free_data = zero_writer_free_data;
|
||||
writer->data = data;
|
||||
writer->target = target;
|
||||
|
||||
/* add this writer to image */
|
||||
target->writers[target->nwriters++] = writer;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
||||
{
|
||||
@ -1069,7 +1208,7 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||
if (target->partition_offset <= 0)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
/* Write padding up to target->partition_offset + 16 */
|
||||
/* Write multi-session padding up to target->partition_offset + 16 */
|
||||
memset(buf, 0, 2048);
|
||||
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
|
||||
res = iso_write(target, buf, BLOCK_SIZE);
|
||||
@ -1136,6 +1275,62 @@ int write_head_part(Ecma119Image *target, int flag)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Eventually end Jigdo Template Extraction */
|
||||
static int finish_libjte(Ecma119Image *target)
|
||||
{
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
int ret;
|
||||
|
||||
if (target->libjte_handle != NULL) {
|
||||
ret = libjte_write_footer(target->libjte_handle);
|
||||
if (ret <= 0) {
|
||||
iso_libjte_forward_msgs(target->libjte_handle,
|
||||
target->image->id, ISO_LIBJTE_END_FAILED, 0);
|
||||
return ISO_LIBJTE_END_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||
uint32_t blocks, int flag)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
uint32_t i;
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
int ret;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL)
|
||||
return ISO_BAD_PARTITION_FILE;
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
if (fp != NULL) {
|
||||
ret = fread(buf, 1, BLOCK_SIZE, fp);
|
||||
if (ret != BLOCK_SIZE) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
}
|
||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void *write_function(void *arg)
|
||||
{
|
||||
@ -1162,11 +1357,32 @@ void *write_function(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
/* Append partition data */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (target->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
res = write_mbr_partition_file(target, target->appended_partitions[i],
|
||||
target->appended_part_size[i], 0);
|
||||
if (res < 0)
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
|
||||
/* Transplant checksum buffer from Ecma119Image to IsoImage */
|
||||
transplant_checksum_buffer(target, 0);
|
||||
|
||||
iso_ring_buffer_writer_close(target->buffer, 0);
|
||||
|
||||
res = finish_libjte(target);
|
||||
if (res <= 0)
|
||||
goto write_error;
|
||||
|
||||
target->image->generator_is_running = 0;
|
||||
|
||||
/* Give up reference claim made in ecma119_image_new().
|
||||
Eventually free target */
|
||||
ecma119_image_free(target);
|
||||
|
||||
#ifdef Libisofs_with_pthread_exiT
|
||||
pthread_exit(NULL);
|
||||
#else
|
||||
@ -1174,6 +1390,8 @@ void *write_function(void *arg)
|
||||
#endif
|
||||
|
||||
write_error: ;
|
||||
if (res != ISO_LIBJTE_END_FAILED)
|
||||
finish_libjte(target);
|
||||
target->eff_partition_offset = 0;
|
||||
if (res == ISO_CANCELED) {
|
||||
/* canceled */
|
||||
@ -1190,6 +1408,12 @@ void *write_function(void *arg)
|
||||
/* Invalidate the transplanted checksum buffer in IsoImage */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
|
||||
target->image->generator_is_running = 0;
|
||||
|
||||
/* Give up reference claim made in ecma119_image_new().
|
||||
Eventually free target */
|
||||
ecma119_image_free(target);
|
||||
|
||||
#ifdef Libisofs_with_pthread_exiT
|
||||
pthread_exit(NULL);
|
||||
#else
|
||||
@ -1292,7 +1516,6 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
{
|
||||
@ -1304,11 +1527,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
char *system_area = NULL;
|
||||
int write_count = 0, write_count_mem;
|
||||
|
||||
|
||||
/* 1. Allocate target and copy opts there */
|
||||
target = calloc(1, sizeof(Ecma119Image));
|
||||
if (target == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
/* This reference will be transfered to the burn_source and released by
|
||||
bs_free_data.
|
||||
*/
|
||||
target->refcount = 1;
|
||||
|
||||
/* create the tree for file caching */
|
||||
ret = iso_rbtree_new(iso_file_src_cmp, &(target->files));
|
||||
@ -1384,7 +1612,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
} else if (src->system_area_data != NULL) {
|
||||
system_area = src->system_area_data;
|
||||
system_area_options = src->system_area_options;
|
||||
} else {
|
||||
system_area_options = opts->system_area_options & 0xfc;
|
||||
}
|
||||
if ((system_area_options & 0xfc) != 0)
|
||||
for (i = 0; i < 4; i++)
|
||||
if (opts->appended_partitions[i] != NULL)
|
||||
return ISO_NON_MBR_SYS_AREA;
|
||||
|
||||
target->system_area_data = NULL;
|
||||
if (system_area != NULL) {
|
||||
target->system_area_data = calloc(32768, 1);
|
||||
@ -1405,6 +1640,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->partition_offset = opts->partition_offset;
|
||||
target->partition_secs_per_head = opts->partition_secs_per_head;
|
||||
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
||||
if (target->partition_secs_per_head == 0)
|
||||
target->partition_secs_per_head = 63;
|
||||
if (target->partition_heads_per_cyl == 0)
|
||||
target->partition_heads_per_cyl = 255;
|
||||
target->eff_partition_offset = 0;
|
||||
target->partition_root = NULL;
|
||||
target->partition_l_table_pos = 0;
|
||||
@ -1412,7 +1651,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->j_part_root = NULL;
|
||||
target->j_part_l_path_table_pos = 0;
|
||||
target->j_part_m_path_table_pos = 0;
|
||||
|
||||
target->input_charset = strdup(iso_get_local_charset(0));
|
||||
if (target->input_charset == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
@ -1446,6 +1684,42 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->checksum_range_size = 0;
|
||||
target->opts_overwrite = NULL;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
/* Eventually start Jigdo Template Extraction */
|
||||
target->libjte_handle = NULL;
|
||||
if (opts->libjte_handle != NULL) {
|
||||
target->libjte_handle = opts->libjte_handle;
|
||||
ret = libjte_write_header(target->libjte_handle);
|
||||
if (ret <= 0) {
|
||||
iso_libjte_forward_msgs(target->libjte_handle,
|
||||
target->image->id, ISO_LIBJTE_START_FAILED, 0);
|
||||
ret = ISO_LIBJTE_START_FAILED;
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
target->tail_blocks = opts->tail_blocks;
|
||||
|
||||
target->mipsel_e_entry = 0;
|
||||
target->mipsel_p_offset = 0;
|
||||
target->mipsel_p_vaddr = 0;
|
||||
target->mipsel_p_filesz = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (opts->appended_partitions[i] != NULL) {
|
||||
target->appended_partitions[i] =
|
||||
strdup(opts->appended_partitions[i]);
|
||||
if (target->appended_partitions[i] == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
target->appended_part_types[i] = opts->appended_part_types[i];
|
||||
}
|
||||
target->appended_part_start[i] = target->appended_part_size[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 2. Based on those options, create needed writers: iso, joliet...
|
||||
* Each writer inits its structures and stores needed info into
|
||||
@ -1464,7 +1738,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
}
|
||||
|
||||
/* the number of writers is dependent of the extensions */
|
||||
nwriters = 1 + 1 + 1; /* ECMA-119 + padding + files */
|
||||
nwriters = 1 + 1 + 1; /* ECMA-119 + multi-session padding + files */
|
||||
|
||||
if (target->eltorito) {
|
||||
nwriters++;
|
||||
@ -1475,7 +1749,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (target->iso1999) {
|
||||
nwriters++;
|
||||
}
|
||||
|
||||
if (target->tail_blocks > 0)
|
||||
nwriters++;
|
||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||
nwriters++;
|
||||
image_checksums_mad = 1; /* from here on the loaded checksums are
|
||||
@ -1538,7 +1813,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
* Create the writer for possible padding to ensure that in case of image
|
||||
* growing we can safely overwrite the first 64 KiB of image.
|
||||
*/
|
||||
ret = pad_writer_create(target);
|
||||
ret = mspad_writer_create(target);
|
||||
if (ret < 0) {
|
||||
goto target_cleanup;
|
||||
}
|
||||
@ -1549,6 +1824,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
goto target_cleanup;
|
||||
}
|
||||
file_src_writer_index = target->nwriters - 1;
|
||||
|
||||
|
||||
/* IMPORTANT: This must be the last writer before the checksum writer */
|
||||
if (target->tail_blocks > 0) {
|
||||
ret = zero_writer_create(target, target->tail_blocks);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||
ret = checksum_writer_create(target);
|
||||
if (ret < 0)
|
||||
@ -1597,12 +1881,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
IsoImageWriter *writer = target->writers[i];
|
||||
|
||||
#define Libisofs_patch_ticket_145 yes
|
||||
#ifdef Libisofs_patch_ticket_145
|
||||
/* Delaying boot image patching until new LBA is known */
|
||||
if (i == el_torito_writer_index)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* Exposing address of data start to IsoWriteOpts */
|
||||
if (i == file_src_writer_index) {
|
||||
@ -1614,8 +1895,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
#ifdef Libisofs_patch_ticket_145
|
||||
/* Now perform delayed image patching */
|
||||
|
||||
/* Now perform delayed image patching and System Area preparations */
|
||||
if (el_torito_writer_index >= 0) {
|
||||
IsoImageWriter *writer = target->writers[el_torito_writer_index];
|
||||
ret = writer->compute_data_blocks(writer);
|
||||
@ -1623,7 +1904,23 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
#endif /* Libisofs_patch_ticket_145 */
|
||||
if (((target->system_area_options & 0xfc) >> 2) == 2) {
|
||||
ret = iso_read_mipsel_elf(target, 0);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* The volume space size is just the size of the last session, in
|
||||
* case of ms images.
|
||||
*/
|
||||
target->vol_space_size = target->curblock - target->ms_block;
|
||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||
|
||||
/* Add sizes of eventually appended partitions */
|
||||
ret = iso_compute_append_partitions(target, 0);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
/* create the ring buffer */
|
||||
if (opts->overwrite != NULL &&
|
||||
@ -1718,13 +2015,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The volume space size is just the size of the last session, in
|
||||
* case of ms images.
|
||||
*/
|
||||
/* This was possibly altered by above overwrite buffer production */
|
||||
target->vol_space_size = target->curblock - target->ms_block;
|
||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||
|
||||
|
||||
/* 4. Create and start writing thread */
|
||||
if (target->md5_session_checksum) {
|
||||
@ -1744,9 +2036,24 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
pthread_attr_init(&(target->th_attr));
|
||||
pthread_attr_setdetachstate(&(target->th_attr), PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
/* To avoid race conditions with the caller, this mark must be set
|
||||
before the thread starts. So the caller can rely on a value of 0
|
||||
really meaning that the write has ended, and not that it might not have
|
||||
begun yet.
|
||||
In normal processing, the value will be changed to 0 at the end of
|
||||
write_function().
|
||||
*/
|
||||
target->image->generator_is_running = 1;
|
||||
|
||||
|
||||
/* Claim that target may not get destroyed by bs_free_data() before
|
||||
write_function() is done with it */
|
||||
target->refcount++;
|
||||
|
||||
ret = pthread_create(&(target->wthread), &(target->th_attr),
|
||||
write_function, (void *) target);
|
||||
if (ret != 0) {
|
||||
target->refcount--;
|
||||
iso_msg_submit(target->image->id, ISO_THREAD_ERROR, 0,
|
||||
"Cannot create writer thread");
|
||||
ret = ISO_THREAD_ERROR;
|
||||
@ -1766,6 +2073,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target_cleanup: ;
|
||||
if(image_checksums_mad) /* No checksums is better than mad checksums */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
target->image->generator_is_running = 0;
|
||||
ecma119_image_free(target);
|
||||
return ret;
|
||||
}
|
||||
@ -1816,7 +2124,7 @@ static void bs_free_data(struct burn_source *bs)
|
||||
iso_ring_buffer_get_times_full(target->buffer),
|
||||
iso_ring_buffer_get_times_empty(target->buffer));
|
||||
|
||||
/* now we can safety free target */
|
||||
/* The reference to target was inherited from ecma119_image_new() */
|
||||
ecma119_image_free(target);
|
||||
}
|
||||
|
||||
@ -1910,6 +2218,11 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
||||
target->checksum_counter += count;
|
||||
iso_md5_compute(target->checksum_ctx, (char *) buf, (int) count);
|
||||
}
|
||||
|
||||
ret = show_chunk_to_jte(target, buf, count);
|
||||
if (ret != ISO_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* total size is 0 when writing the overwrite buffer */
|
||||
if (ret > 0 && (target->total_size != (off_t) 0)){
|
||||
unsigned int kbw, kbt;
|
||||
@ -1933,6 +2246,7 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
||||
|
||||
int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
{
|
||||
int i;
|
||||
IsoWriteOpts *wopts;
|
||||
|
||||
if (opts == NULL) {
|
||||
@ -1987,19 +2301,32 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->partition_secs_per_head = 0;
|
||||
wopts->partition_heads_per_cyl = 0;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
wopts->libjte_handle = NULL;
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
wopts->tail_blocks = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
wopts->appended_partitions[i] = NULL;
|
||||
|
||||
*opts = wopts;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
void iso_write_opts_free(IsoWriteOpts *opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (opts == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(opts->output_charset);
|
||||
if(opts->system_area_data != NULL)
|
||||
if (opts->system_area_data != NULL)
|
||||
free(opts->system_area_data);
|
||||
for (i = 0; i < 4; i++)
|
||||
if (opts->appended_partitions[i] != NULL)
|
||||
free(opts->appended_partitions[i]);
|
||||
|
||||
free(opts);
|
||||
}
|
||||
|
||||
@ -2375,9 +2702,24 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
||||
|
||||
/*
|
||||
* @param data Either NULL or 32 kB of data. Do not submit less bytes !
|
||||
* @param options bit0 = apply GRUB protective msdos label
|
||||
* @param options
|
||||
* Can cause manipulations of submitted data before they get written:
|
||||
* bit0= apply a --protective-msdos-label as of grub-mkisofs.
|
||||
* This means to patch bytes 446 to 512 of the system area so
|
||||
* that one partition is defined which begins at the second
|
||||
* 512-byte block of the image and ends where the image ends.
|
||||
* This works with and without system_area_data.
|
||||
* bit1= apply isohybrid MBR patching to the system area.
|
||||
* This works only with system area data from SYSLINUX plus an
|
||||
* ISOLINUX boot image (see iso_image_set_boot_image()) and
|
||||
* only if not bit0 is set.
|
||||
* bit2-7= System area type
|
||||
* 0= PC-BIOS DOS MBR
|
||||
* 1= MIPS Big Endian Volume Header
|
||||
* @param flag bit0 = invalidate any attached system area data
|
||||
* same as data == NULL
|
||||
* bit1 = keep data unaltered
|
||||
* bit2 = keep options unaltered
|
||||
*/
|
||||
int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||
int options, int flag)
|
||||
@ -2395,7 +2737,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
||||
memcpy(opts->system_area_data, data, 32768);
|
||||
}
|
||||
if (!(flag & 4))
|
||||
opts->system_area_options = options & 3;
|
||||
opts->system_area_options = options & 0xff;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2424,4 +2766,56 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||
opts->partition_heads_per_cyl = heads_per_cyl;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int iso_write_opts_attach_jte(IsoWriteOpts *opts, void *libjte_handle)
|
||||
{
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
opts->libjte_handle = libjte_handle;
|
||||
return ISO_SUCCESS;
|
||||
|
||||
#else
|
||||
|
||||
return ISO_LIBJTE_NOT_ENABLED;
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
}
|
||||
|
||||
int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle)
|
||||
{
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
if (*libjte_handle != NULL)
|
||||
*libjte_handle = opts->libjte_handle;
|
||||
opts->libjte_handle = NULL;
|
||||
return ISO_SUCCESS;
|
||||
|
||||
#else
|
||||
|
||||
return ISO_LIBJTE_NOT_ENABLED;
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
}
|
||||
|
||||
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
|
||||
{
|
||||
opts->tail_blocks = num_blocks;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||
uint8_t partition_type, char *image_path, int flag)
|
||||
{
|
||||
if (partition_number < 1 || partition_number > 4)
|
||||
return ISO_BAD_PARTITION_NO;
|
||||
|
||||
if (opts->appended_partitions[partition_number - 1] != NULL)
|
||||
free(opts->appended_partitions[partition_number - 1]);
|
||||
opts->appended_partitions[partition_number - 1] = strdup(image_path);
|
||||
if (opts->appended_partitions[partition_number - 1] == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
opts->appended_part_types[partition_number - 1] = partition_type;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -324,6 +324,21 @@ struct iso_write_opts {
|
||||
/* 1 to 255, 0= disabled/default */
|
||||
int partition_heads_per_cyl;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
/* Parameters and state of Jigdo Template Export environment.
|
||||
*/
|
||||
struct libjte_env *libjte_handle;
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
/* A trailing padding of zero bytes which belongs to the image
|
||||
*/
|
||||
uint32_t tail_blocks;
|
||||
|
||||
/* Eventual disk file paths of prepared images which shall be appended
|
||||
after the ISO image and described by partiton table entries in a MBR
|
||||
*/
|
||||
char *appended_partitions[4];
|
||||
uint8_t appended_part_types[4];
|
||||
};
|
||||
|
||||
typedef struct ecma119_image Ecma119Image;
|
||||
@ -335,6 +350,8 @@ typedef struct Iso_Image_Writer IsoImageWriter;
|
||||
|
||||
struct ecma119_image
|
||||
{
|
||||
int refcount;
|
||||
|
||||
IsoImage *image;
|
||||
Ecma119Node *root;
|
||||
|
||||
@ -469,14 +486,19 @@ struct ecma119_image
|
||||
*/
|
||||
char *system_area_data;
|
||||
/*
|
||||
* bit0= make bytes 446 - 512 of the system area a partition
|
||||
* bit0= Only with PC-BIOS DOS MBR
|
||||
* Make bytes 446 - 512 of the system area a partition
|
||||
* table which reserves partition 1 from byte 63*512 to the
|
||||
* end of the ISO image. Assumed are 63 secs/hed, 255 head/cyl.
|
||||
* (GRUB protective msdos label.)
|
||||
* This works with and without system_area_data.
|
||||
* bit1= apply isohybrid MBR patching to the system area.
|
||||
* bit1= Only with PC-BIOS DOS MBR
|
||||
* Apply isohybrid MBR patching to the system area.
|
||||
* This works only with system_area_data plus ISOLINUX boot image
|
||||
* and only if not bit0 is set.
|
||||
* bit2-7= System area type
|
||||
* 0= DOS MBR
|
||||
* 1= MIPS Big Endian Volume Header
|
||||
*/
|
||||
int system_area_options;
|
||||
|
||||
@ -493,7 +515,7 @@ struct ecma119_image
|
||||
* file data is written in the first 64 KiB, that are the bytes we usually
|
||||
* overwrite.
|
||||
*/
|
||||
uint32_t pad_blocks;
|
||||
uint32_t mspad_blocks;
|
||||
|
||||
size_t nwriters;
|
||||
IsoImageWriter **writers;
|
||||
@ -567,6 +589,24 @@ struct ecma119_image
|
||||
uint32_t j_part_l_path_table_pos;
|
||||
uint32_t j_part_m_path_table_pos;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
struct libjte_env *libjte_handle;
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
uint32_t tail_blocks;
|
||||
|
||||
/* Memorized ELF parameters from MIPS Little Endian boot file */
|
||||
uint32_t mipsel_e_entry;
|
||||
uint32_t mipsel_p_offset;
|
||||
uint32_t mipsel_p_vaddr;
|
||||
uint32_t mipsel_p_filesz;
|
||||
|
||||
char *appended_partitions[4];
|
||||
uint8_t appended_part_types[4];
|
||||
/* Counted in blocks of 2048 */
|
||||
uint32_t appended_part_start[4];
|
||||
uint32_t appended_part_size[4];
|
||||
|
||||
};
|
||||
|
||||
#define BP(a,b) [(b) - (a) + 1]
|
||||
|
@ -1109,3 +1109,35 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the tree for a certain IsoNode and return its owning Ecma119Node
|
||||
* or NULL.
|
||||
*/
|
||||
static
|
||||
Ecma119Node *search_iso_node(Ecma119Node *root, IsoNode *node)
|
||||
{
|
||||
size_t i;
|
||||
Ecma119Node *res = NULL;
|
||||
|
||||
if (root->node == node)
|
||||
return root;
|
||||
for (i = 0; i < root->info.dir->nchildren && res == NULL; i++) {
|
||||
if (root->info.dir->children[i]->type == ECMA119_DIR)
|
||||
res = search_iso_node(root->info.dir->children[i], node);
|
||||
else if (root->info.dir->children[i]->node == node)
|
||||
res = root->info.dir->children[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node)
|
||||
{
|
||||
Ecma119Node *res = NULL;
|
||||
|
||||
if (img->root != NULL)
|
||||
res = search_iso_node(img->root, node);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -90,4 +90,11 @@ int ecma119_tree_create(Ecma119Image *img);
|
||||
*/
|
||||
void ecma119_node_free(Ecma119Node *node);
|
||||
|
||||
/**
|
||||
* Search the tree for a certain IsoNode and return its owning Ecma119Node
|
||||
* or NULL.
|
||||
*/
|
||||
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
|
||||
|
||||
|
||||
#endif /*LIBISO_ECMA119_TREE_H_*/
|
||||
|
@ -1150,7 +1150,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
|
||||
t = writer->target;
|
||||
cat = t->catalog;
|
||||
|
||||
iso_msg_debug(t->image->id, "Write El-Torito boot record");
|
||||
|
||||
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 2010 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -11,6 +12,7 @@
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#include "libisofs.h"
|
||||
#include "filesrc.h"
|
||||
#include "node.h"
|
||||
#include "util.h"
|
||||
@ -25,6 +27,21 @@
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#ifdef Xorriso_standalonE
|
||||
|
||||
#ifdef Xorriso_with_libjtE
|
||||
#include "../libjte/libjte.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
#include <libjte/libjte.h>
|
||||
#endif
|
||||
|
||||
#endif /* ! Xorriso_standalonE */
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
@ -317,6 +334,9 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
void *ctx= NULL;
|
||||
char md5[16], pre_md5[16];
|
||||
int pre_md5_valid = 0;
|
||||
#ifdef Libisofs_with_libjtE
|
||||
int jte_begun = 0;
|
||||
#endif
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
@ -380,6 +400,23 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (t->libjte_handle != NULL) {
|
||||
res = libjte_begin_data_file(t->libjte_handle, name,
|
||||
BLOCK_SIZE, file_size);
|
||||
if (res <= 0) {
|
||||
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_FILE_FAILED, 0);
|
||||
if (res < 0) {
|
||||
filesrc_close(file);
|
||||
ret = ISO_LIBJTE_FILE_FAILED;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
jte_begun = 1;
|
||||
}
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
if (file->checksum_index > 0) {
|
||||
/* initialize file checksum */
|
||||
res = iso_md5_start(&ctx);
|
||||
@ -481,12 +518,35 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
/* Write md5 into checksum buffer at file->checksum_index */
|
||||
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (t->libjte_handle != NULL) {
|
||||
res = libjte_end_data_file(t->libjte_handle);
|
||||
if (res <= 0) {
|
||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_FILE_FAILED, 0);
|
||||
ret = ISO_LIBJTE_FILE_FAILED;
|
||||
goto ex;
|
||||
}
|
||||
jte_begun = 0;
|
||||
}
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
}
|
||||
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ctx != NULL) /* avoid any memory leak */
|
||||
iso_md5_end(&ctx, md5);
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (jte_begun) {
|
||||
libjte_end_data_file(t->libjte_handle);
|
||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_END_FAILED, 0);
|
||||
}
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
*/
|
||||
int iso_image_new(const char *name, IsoImage **image)
|
||||
{
|
||||
int res;
|
||||
int res, i;
|
||||
IsoImage *img;
|
||||
|
||||
if (image == NULL) {
|
||||
@ -80,6 +80,9 @@ int iso_image_new(const char *name, IsoImage **image)
|
||||
}
|
||||
img->system_area_data = NULL;
|
||||
img->system_area_options = 0;
|
||||
img->num_mips_boot_files = 0;
|
||||
for (i = 0; i < 15; i++)
|
||||
img->mips_boot_file_paths[i] = NULL;
|
||||
img->builder_ignore_acl = 1;
|
||||
img->builder_ignore_ea = 1;
|
||||
img->inode_counter = 0;
|
||||
@ -89,6 +92,7 @@ int iso_image_new(const char *name, IsoImage **image)
|
||||
img->checksum_end_lba = 0;
|
||||
img->checksum_idx_count = 0;
|
||||
img->checksum_array = NULL;
|
||||
img->generator_is_running = 0;
|
||||
*image = img;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -102,7 +106,7 @@ void iso_image_ref(IsoImage *image)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the reference couting of the given image.
|
||||
* Decrements the reference counting of the given image.
|
||||
* If it reaches 0, the image is free, together with its tree nodes (whether
|
||||
* their refcount reach 0 too, of course).
|
||||
*/
|
||||
@ -126,6 +130,7 @@ void iso_image_unref(IsoImage *image)
|
||||
iso_node_builder_unref(image->builder);
|
||||
iso_filesystem_unref(image->fs);
|
||||
el_torito_boot_catalog_free(image->bootcat);
|
||||
iso_image_give_up_mips_boot(image, 0);
|
||||
free(image->volset_id);
|
||||
free(image->volume_id);
|
||||
free(image->publisher_id);
|
||||
@ -607,3 +612,46 @@ int iso_image_set_checksums(IsoImage *image, char *checksum_array,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iso_image_generator_is_running(IsoImage *image)
|
||||
{
|
||||
return image->generator_is_running;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag)
|
||||
{
|
||||
if (image->num_mips_boot_files >= 15)
|
||||
return ISO_BOOT_TOO_MANY_MIPS;
|
||||
image->mips_boot_file_paths[image->num_mips_boot_files] = strdup(path);
|
||||
if (image->mips_boot_file_paths[image->num_mips_boot_files] == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
image->num_mips_boot_files++;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < image->num_mips_boot_files; i++)
|
||||
paths[i] = image->mips_boot_file_paths[i];
|
||||
for (; i < 15; i++)
|
||||
paths[i] = NULL;
|
||||
return image->num_mips_boot_files;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_image_give_up_mips_boot(IsoImage *image, int flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < image->num_mips_boot_files; i++)
|
||||
if (image->mips_boot_file_paths[i] != NULL) {
|
||||
free(image->mips_boot_file_paths[i]);
|
||||
image->mips_boot_file_paths[i] = NULL;
|
||||
}
|
||||
image->num_mips_boot_files = 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
@ -58,6 +58,14 @@ struct Iso_Image
|
||||
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
|
||||
int system_area_options;
|
||||
|
||||
/*
|
||||
* Up to 15 boot files can be referred by a MIPS Big Endian Volume Header.
|
||||
The mips_boot_file_paths are ISO 9660 Rock Ridge paths.
|
||||
*/
|
||||
int num_mips_boot_files;
|
||||
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
|
||||
|
||||
|
||||
/* image identifier, for message origin identifier */
|
||||
int id;
|
||||
|
||||
@ -166,6 +174,12 @@ struct Iso_Image
|
||||
uint32_t checksum_idx_count;
|
||||
char *checksum_array;
|
||||
|
||||
/**
|
||||
* Whether a write run has been started by iso_image_create_burn_source()
|
||||
* and has not yet been finished.
|
||||
*/
|
||||
int generator_is_running;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -983,6 +983,7 @@ struct iso_stream
|
||||
/**
|
||||
* Initialize libisofs. Before any usage of the library you must either call
|
||||
* this function or iso_init_with_flag().
|
||||
* Only exception from this rule: iso_lib_version(), iso_lib_is_compatible().
|
||||
* @return 1 on success, < 0 on error
|
||||
*
|
||||
* @since 0.6.2
|
||||
@ -992,6 +993,7 @@ int iso_init();
|
||||
/**
|
||||
* Initialize libisofs. Before any usage of the library you must either call
|
||||
* this function or iso_init() which is equivalent to iso_init_with_flag(0).
|
||||
* Only exception from this rule: iso_lib_version(), iso_lib_is_compatible().
|
||||
* @param flag
|
||||
* Bitfield for control purposes
|
||||
* bit0= do not set up locale by LC_* environment variables
|
||||
@ -1084,6 +1086,7 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what);
|
||||
*/
|
||||
/**
|
||||
* Get version of the libisofs library at runtime.
|
||||
* NOTE: This function may be called before iso_init().
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
@ -1091,6 +1094,7 @@ void iso_lib_version(int *major, int *minor, int *micro);
|
||||
|
||||
/**
|
||||
* Check at runtime if the library is ABI compatible with the given version.
|
||||
* NOTE: This function may be called before iso_init().
|
||||
*
|
||||
* @return
|
||||
* 1 lib is compatible, 0 is not.
|
||||
@ -1118,7 +1122,7 @@ int iso_lib_is_compatible(int major, int minor, int micro);
|
||||
*/
|
||||
#define iso_lib_header_version_major 0
|
||||
#define iso_lib_header_version_minor 6
|
||||
#define iso_lib_header_version_micro 36
|
||||
#define iso_lib_header_version_micro 38
|
||||
|
||||
/**
|
||||
* Usage discussion:
|
||||
@ -1751,15 +1755,31 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
||||
* Either NULL or 32 kB of data. Do not submit less bytes !
|
||||
* @param options
|
||||
* Can cause manipulations of submitted data before they get written:
|
||||
* bit0= apply a --protective-msdos-label as of grub-mkisofs.
|
||||
* bit0= Only with System area type 0 = MBR
|
||||
* Apply a --protective-msdos-label as of grub-mkisofs.
|
||||
* This means to patch bytes 446 to 512 of the system area so
|
||||
* that one partition is defined which begins at the second
|
||||
* 512-byte block of the image and ends where the image ends.
|
||||
* This works with and without system_area_data.
|
||||
* bit1= apply isohybrid MBR patching to the system area.
|
||||
* bit1= Only with System area type 0 = MBR
|
||||
* Apply isohybrid MBR patching to the system area.
|
||||
* This works only with system area data from SYSLINUX plus an
|
||||
* ISOLINUX boot image (see iso_image_set_boot_image()) and
|
||||
* only if not bit0 is set.
|
||||
* bit2-7= System area type
|
||||
* 0= with bit0 or bit1: MBR
|
||||
* else: unspecified type which will be used unaltered.
|
||||
* @since 0.6.38
|
||||
* 1= MIPS Big Endian Volume Header
|
||||
* Submit up to 15 MIPS Big Endian boot files by
|
||||
* iso_image_add_mips_boot_file().
|
||||
* This will overwrite the first 512 bytes of the submitted
|
||||
* data.
|
||||
* 2= DEC Boot Block for MIPS Little Endian
|
||||
* The first boot file submitted by
|
||||
* iso_image_add_mips_boot_file() will be activated.
|
||||
* This will overwrite the first 512 bytes of the submitted
|
||||
* data.
|
||||
* @param flag
|
||||
* bit0 = invalidate any attached system area data. Same as data == NULL
|
||||
* (This re-activates eventually loaded image System Area data.
|
||||
@ -1848,6 +1868,101 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||
int secs_512_per_head, int heads_per_cyl);
|
||||
|
||||
|
||||
/** The minimum version of libjte to be used with this version of libisofs
|
||||
at compile time. The use of libjte is optional and depends on configure
|
||||
tests. It can be prevented by ./configure option --disable-libjte .
|
||||
@since 0.6.38
|
||||
*/
|
||||
#define iso_libjte_req_major 0
|
||||
#define iso_libjte_req_minor 1
|
||||
#define iso_libjte_req_micro 1
|
||||
|
||||
/**
|
||||
* Associate a libjte environment object to the upcomming write run.
|
||||
* libjte implements Jigdo Template Extraction as of Steve McIntyre and
|
||||
* Richard Atterer.
|
||||
* The call will fail if no libjte support was enabled at compile time.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param libjte_handle
|
||||
* Pointer to a struct libjte_env e.g. created by libjte_new().
|
||||
* It must stay existent from the start of image generation by
|
||||
* iso_image_create_burn_source() until the write thread has ended.
|
||||
* This can be inquired by iso_image_generator_is_running().
|
||||
* In order to keep the libisofs API identical with and without
|
||||
* libjte support the parameter type is (void *).
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
*
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_write_opts_attach_jte(IsoWriteOpts *opts, void *libjte_handle);
|
||||
|
||||
/**
|
||||
* Remove eventual association to a libjte environment handle.
|
||||
* The call will fail if no libjte support was enabled at compile time.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param libjte_handle
|
||||
* If not submitted as NULL, this will return the previously set
|
||||
* libjte handle.
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
*
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle);
|
||||
|
||||
|
||||
/**
|
||||
* Cause a number of blocks with zero bytes to be written after the payload
|
||||
* data, but before the eventual checksum data. Unlike libburn tail padding,
|
||||
* these blocks are counted as part of the image and covered by eventual
|
||||
* image checksums.
|
||||
* A reason for such padding can be the wish to prevent the Linux read-ahead
|
||||
* bug by sacrificial data which still belong to image and Jigdo template.
|
||||
* Normally such padding would be the job of the burn program which should know
|
||||
* that it is needed with CD write type TAO if Linux read(2) shall be able
|
||||
* to read all payload blocks.
|
||||
* 150 blocks = 300 kB is the traditional sacrifice to the Linux kernel.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param num_blocks
|
||||
* Number of extra 2 kB blocks to be written.
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
*
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
||||
|
||||
/**
|
||||
* Cause an arbitrary data file to be appended to the ISO image and to be
|
||||
* described by a partition table entry in an MBR at the start of the
|
||||
* ISO image.
|
||||
* The partition entry will bear the size of the image file rounded up to
|
||||
* the next multiple of 2048 bytes.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param partition_number
|
||||
* Depicts the partition table entry which shall describe the
|
||||
* appended image. Range 1 to 4.
|
||||
* 1 will cause the whole ISO image to be unclaimable space before
|
||||
* partition 1.
|
||||
* @param image_path
|
||||
* File address in the local file system.
|
||||
* @param image_type
|
||||
* The partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
|
||||
* Linux Native Partition = 0x83. See fdisk command L.
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
*
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||
uint8_t partition_type, char *image_path, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Inquire the start address of the file data blocks after having used
|
||||
* IsoWriteOpts with iso_image_create_burn_source().
|
||||
@ -1865,6 +1980,20 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||
int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
||||
int flag);
|
||||
|
||||
/**
|
||||
* Update the sizes of all files added to image.
|
||||
*
|
||||
* This may be called just before iso_image_create_burn_source() to force
|
||||
* libisofs to check the file sizes again (they're already checked when added
|
||||
* to IsoImage). It is useful if you have changed some files after adding then
|
||||
* to the image.
|
||||
*
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
* @since 0.6.8
|
||||
*/
|
||||
int iso_image_update_sizes(IsoImage *image);
|
||||
|
||||
/**
|
||||
* Create a burn_source and a thread which immediately begins to generate
|
||||
* the image. That burn_source can be used with libburn as a data source
|
||||
@ -1891,18 +2020,22 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
||||
struct burn_source **burn_src);
|
||||
|
||||
/**
|
||||
* Update the sizes of all files added to image.
|
||||
*
|
||||
* This may be called just before iso_image_create_burn_source() to force
|
||||
* libisofs to check the file sizes again (they're already checked when added
|
||||
* to IsoImage). It is useful if you have changed some files after adding then
|
||||
* to the image.
|
||||
*
|
||||
* Inquire whether the image generator thread is still at work. As soon as the
|
||||
* reply is 0, the caller of iso_image_create_burn_source() may assume that
|
||||
* the image generation has ended.
|
||||
* Nevertheless there may still be readily formatted output data pending in
|
||||
* the burn_source or its consumers. So the final delivery of the image has
|
||||
* also to be checked at the data consumer side,e.g. by burn_drive_get_status()
|
||||
* in case of libburn as consumer.
|
||||
* @param image
|
||||
* The image to inquire.
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
* @since 0.6.8
|
||||
* 1 generating of image stream is still in progress
|
||||
* 0 generating of image stream has ended meanwhile
|
||||
*
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_image_update_sizes(IsoImage *image);
|
||||
int iso_image_generator_is_running(IsoImage *image);
|
||||
|
||||
/**
|
||||
* Creates an IsoReadOpts for reading an existent image. You should set the
|
||||
@ -2867,6 +3000,58 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
|
||||
int iso_image_get_system_area(IsoImage *img, char data[32768],
|
||||
int *options, int flag);
|
||||
|
||||
/**
|
||||
* Add a MIPS boot file path to the image.
|
||||
* Up to 15 such files can be written into a MIPS Big Endian Volume Header
|
||||
* if this is enabled by value 1 in iso_write_opts_set_system_area() option
|
||||
* bits 2 to 7.
|
||||
* A single file can be written into a DEC Boot Block if this is enabled by
|
||||
* value 2 in iso_write_opts_set_system_area() option bits 2 to 7. So only
|
||||
* the first added file gets into effect with this system area type.
|
||||
* The data files which shall serve as MIPS boot files have to be brought into
|
||||
* the image by the normal means.
|
||||
* @param img
|
||||
* The image to be manipulated.
|
||||
* @param path
|
||||
* Absolute path of the boot file in the ISO 9660 Rock Ridge tree.
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* 1 on success, < 0 error
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag);
|
||||
|
||||
/**
|
||||
* Obtain the number of added MIPS Big Endian boot files and pointers to
|
||||
* their paths in the ISO 9660 Rock Ridge tree.
|
||||
* @param img
|
||||
* The image to be inquired.
|
||||
* @param paths
|
||||
* An array of pointers to be set to the registered boot file paths.
|
||||
* This are just pointers to data inside IsoImage. Do not free() them.
|
||||
* Eventually make own copies of the data before manipulating the image.
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* >= 0 is the number of valid path pointers , <0 means error
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
|
||||
|
||||
/**
|
||||
* Clear the list of MIPS Big Endian boot file paths.
|
||||
* @param img
|
||||
* The image to be manipulated.
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* 1 is success , <0 means error
|
||||
* @since 0.6.38
|
||||
*/
|
||||
int iso_image_give_up_mips_boot(IsoImage *image, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Increments the reference counting of the given node.
|
||||
*
|
||||
@ -6149,6 +6334,35 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
||||
*/
|
||||
#define ISO_OVWRT_FIFO_TOO_SMALL 0xE830FE96
|
||||
|
||||
/** Use of libjte was not enabled at compile time (FAILURE, HIGH, -363) */
|
||||
#define ISO_LIBJTE_NOT_ENABLED 0xE830FE95
|
||||
|
||||
/** Failed to start up Jigdo Template Extraction (FAILURE, HIGH, -364) */
|
||||
#define ISO_LIBJTE_START_FAILED 0xE830FE94
|
||||
|
||||
/** Failed to finish Jigdo Template Extraction (FAILURE, HIGH, -365) */
|
||||
#define ISO_LIBJTE_END_FAILED 0xE830FE93
|
||||
|
||||
/** Failed to process file for Jigdo Template Extraction
|
||||
(MISHAP, HIGH, -366) */
|
||||
#define ISO_LIBJTE_FILE_FAILED 0xE430FE92
|
||||
|
||||
/** Too many MIPS Big Endian boot files given (max. 15) (FAILURE, HIGH, -367)*/
|
||||
#define ISO_BOOT_TOO_MANY_MIPS 0xE830FE91
|
||||
|
||||
/** Boot file missing in image (MISHAP, HIGH, -368) */
|
||||
#define ISO_BOOT_FILE_MISSING 0xE430FE90
|
||||
|
||||
/** Partition number out of range (FAILURE, HIGH, -369) */
|
||||
#define ISO_BAD_PARTITION_NO 0xE830FE8F
|
||||
|
||||
/** Cannot open data file for appended partition (FAILURE, HIGH, -370) */
|
||||
#define ISO_BAD_PARTITION_FILE 0xE830FE8E
|
||||
|
||||
/** May not combine appended partition with non-MBR system area
|
||||
(FAILURE, HIGH, -371) */
|
||||
#define ISO_NON_MBR_SYS_AREA 0xE830FE8D
|
||||
|
||||
|
||||
/* Internal developer note:
|
||||
Place new error codes directly above this comment.
|
||||
|
@ -68,6 +68,7 @@ iso_get_local_charset;
|
||||
iso_get_messenger;
|
||||
iso_gzip_get_refcounts;
|
||||
iso_image_add_boot_image;
|
||||
iso_image_add_mips_boot_file;
|
||||
iso_image_attach_data;
|
||||
iso_image_create_burn_source;
|
||||
iso_image_filesystem_new;
|
||||
@ -80,6 +81,7 @@ iso_image_fs_get_publisher_id;
|
||||
iso_image_fs_get_system_id;
|
||||
iso_image_fs_get_volset_id;
|
||||
iso_image_fs_get_volume_id;
|
||||
iso_image_generator_is_running;
|
||||
iso_image_get_abstract_file_id;
|
||||
iso_image_get_all_boot_imgs;
|
||||
iso_image_get_application_id;
|
||||
@ -88,6 +90,7 @@ iso_image_get_biblio_file_id;
|
||||
iso_image_get_boot_image;
|
||||
iso_image_get_copyright_file_id;
|
||||
iso_image_get_data_preparer_id;
|
||||
iso_image_get_mips_boot_files;
|
||||
iso_image_get_msg_id;
|
||||
iso_image_get_publisher_id;
|
||||
iso_image_get_root;
|
||||
@ -96,6 +99,7 @@ iso_image_get_system_area;
|
||||
iso_image_get_system_id;
|
||||
iso_image_get_volset_id;
|
||||
iso_image_get_volume_id;
|
||||
iso_image_give_up_mips_boot;
|
||||
iso_image_import;
|
||||
iso_image_new;
|
||||
iso_image_ref;
|
||||
@ -243,6 +247,8 @@ iso_tree_set_ignore_special;
|
||||
iso_tree_set_replace_mode;
|
||||
iso_tree_set_report_callback;
|
||||
iso_util_decode_md5_tag;
|
||||
iso_write_opts_attach_jte;
|
||||
iso_write_opts_detach_jte;
|
||||
iso_write_opts_free;
|
||||
iso_write_opts_get_data_start;
|
||||
iso_write_opts_new;
|
||||
@ -273,6 +279,7 @@ iso_write_opts_set_omit_version_numbers;
|
||||
iso_write_opts_set_output_charset;
|
||||
iso_write_opts_set_overwrite_buf;
|
||||
iso_write_opts_set_part_offset;
|
||||
iso_write_opts_set_partition_img;
|
||||
iso_write_opts_set_pvd_times;
|
||||
iso_write_opts_set_record_md5;
|
||||
iso_write_opts_set_relaxed_vol_atts;
|
||||
@ -284,6 +291,7 @@ iso_write_opts_set_rrip_version_1_10;
|
||||
iso_write_opts_set_scdbackup_tag;
|
||||
iso_write_opts_set_sort_files;
|
||||
iso_write_opts_set_system_area;
|
||||
iso_write_opts_set_tail_blocks;
|
||||
iso_zisofs_get_params;
|
||||
iso_zisofs_get_refcounts;
|
||||
iso_zisofs_set_params;
|
||||
|
@ -17,6 +17,20 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef Xorriso_standalonE
|
||||
|
||||
#ifdef Xorriso_with_libjtE
|
||||
#include "../libjte/libjte.h"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
#include <libjte/libjte.h>
|
||||
#endif
|
||||
|
||||
#endif /* ! Xorriso_standalonE */
|
||||
|
||||
#include "libiso_msgs.h"
|
||||
#include "libisofs.h"
|
||||
#include "messages.h"
|
||||
@ -71,6 +85,41 @@ struct libiso_msgs *libiso_msgr = NULL;
|
||||
int iso_init_with_flag(int flag)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
/* Ugly compile time check for header version compatibility.
|
||||
If everthing matches, then it produces no C code. In case of mismatch,
|
||||
intentionally faulty C code will be inserted.
|
||||
*/
|
||||
/* The indendation is an advise of man gcc to help old compilers ignoring */
|
||||
#if iso_libjte_req_major > LIBJTE_VERSION_MAJOR
|
||||
#define Libisofs_libjte_dot_h_too_olD 1
|
||||
#endif
|
||||
#if iso_libjte_req_major == LIBJTE_VERSION_MAJOR && iso_libjte_req_minor > LIBJTE_VERSION_MINOR
|
||||
#define Libisofs_libjte_dot_h_too_olD 1
|
||||
#endif
|
||||
#if iso_libjte_req_minor == LIBJTE_VERSION_MINOR && iso_libjte_req_micro > LIBJTE_VERSION_MICRO
|
||||
#define Libisofs_libjte_dot_h_too_olD 1
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_libjte_dot_h_too_olD
|
||||
LIBJTE_MISCONFIGURATION = 0;
|
||||
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libjte_dot_h_TOO_OLD__SEE_libisofs_dot_h_AND_messages_c = 0;
|
||||
LIBJTE_MISCONFIGURATION_ = 0;
|
||||
#endif
|
||||
|
||||
if (! libjte__is_compatible(LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR,
|
||||
LIBJTE_VERSION_MICRO, 0)) {
|
||||
fprintf(stderr,
|
||||
"\nlibisofs: libjte TOO OLD ! Need at least libjte-%d.%d.%d\n\n",
|
||||
LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR,
|
||||
LIBJTE_VERSION_MICRO);
|
||||
return ISO_FATAL_ERROR;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
|
||||
if (! (flag & 1)) {
|
||||
iso_init_locale(0);
|
||||
}
|
||||
@ -292,6 +341,24 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Partition offset too small for first tree root.";
|
||||
case ISO_OVWRT_FIFO_TOO_SMALL:
|
||||
return "The ring buffer is too small for overwrite buffer";
|
||||
case ISO_LIBJTE_NOT_ENABLED:
|
||||
return "Use of libjte was not enabled at compile time";
|
||||
case ISO_LIBJTE_START_FAILED:
|
||||
return "Failed to start up Jigdo Template Extraction";
|
||||
case ISO_LIBJTE_END_FAILED:
|
||||
return "Failed to finish Jigdo Template Extraction";
|
||||
case ISO_LIBJTE_FILE_FAILED:
|
||||
return "Failed to process file for Jigdo Template Extraction";
|
||||
case ISO_BOOT_TOO_MANY_MIPS:
|
||||
return "Too many MIPS Big Endian boot files given (max. 15)";
|
||||
case ISO_BOOT_FILE_MISSING:
|
||||
return "Boot file missing in image";
|
||||
case ISO_BAD_PARTITION_NO:
|
||||
return "Partition number out of range";
|
||||
case ISO_BAD_PARTITION_FILE:
|
||||
return "Cannot open data file for appended partition";
|
||||
case ISO_NON_MBR_SYS_AREA:
|
||||
return "May not combine appended partition with non-MBR system area";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
@ -515,3 +582,33 @@ int iso_report_errfile(char *path, int error_code, int os_errno, int flag)
|
||||
path, os_errno, 0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int iso_libjte_forward_msgs(void *libjte_handle,
|
||||
int imgid, int errcode, int flag)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
char *msg = NULL;
|
||||
int res;
|
||||
struct libjte_env *handle = (struct libjte_env *) libjte_handle;
|
||||
|
||||
res = ISO_SUCCESS;
|
||||
while(1) {
|
||||
msg= libjte_get_next_message(handle);
|
||||
if(msg == NULL)
|
||||
break;
|
||||
res = iso_msg_submit(imgid, errcode, 0, msg);
|
||||
free(msg);
|
||||
}
|
||||
return res;
|
||||
|
||||
#else /* Libisofs_with_libjtE */
|
||||
|
||||
return ISO_SUCCESS;
|
||||
|
||||
#endif /* ! Libisofs_with_libjtE */
|
||||
|
||||
}
|
||||
|
||||
|
@ -54,4 +54,10 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...);
|
||||
int iso_report_errfile(char *path, int error_code, int os_errno, int flag);
|
||||
|
||||
|
||||
/* Drains the libjte message list and puts out the messages via
|
||||
iso_msg_submit()
|
||||
*/
|
||||
int iso_libjte_forward_msgs(void *libjte_handle,
|
||||
int imgid, int errcode, int flag);
|
||||
|
||||
#endif /*MESSAGES_H_*/
|
||||
|
@ -12,12 +12,19 @@
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#include "libisofs.h"
|
||||
#include "system_area.h"
|
||||
#include "eltorito.h"
|
||||
#include "filesrc.h"
|
||||
#include "ecma119_tree.h"
|
||||
#include "image.h"
|
||||
#include "messages.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -68,6 +75,85 @@ void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
||||
}
|
||||
|
||||
|
||||
/* Compute size and position of appended partitions.
|
||||
*/
|
||||
int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
{
|
||||
int ret, i;
|
||||
uint32_t pos, size;
|
||||
struct stat stbuf;
|
||||
|
||||
pos = (t->vol_space_size + t->ms_block);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (t->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
ret = stat(t->appended_partitions[i], &stbuf);
|
||||
if (ret == -1)
|
||||
return ISO_BAD_PARTITION_FILE;
|
||||
if (! S_ISREG(stbuf.st_mode))
|
||||
return ISO_BAD_PARTITION_FILE;
|
||||
size = ((stbuf.st_size + 2047) / 2048);
|
||||
t->appended_part_start[i] = pos;
|
||||
t->appended_part_size[i] = size;
|
||||
pos += size;
|
||||
t->total_size += size * 2048;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Note: partition_offset and partition_size are counted in 2048 blocks
|
||||
*/
|
||||
static int write_mbr_partition_entry(int partition_number, int partition_type,
|
||||
uint32_t partition_offset, uint32_t partition_size,
|
||||
int sph, int hpc, uint8_t *buf, int flag)
|
||||
{
|
||||
uint8_t *wpt;
|
||||
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||
uint32_t after_end;
|
||||
int i;
|
||||
|
||||
after_end = partition_offset + partition_size;
|
||||
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||
iso_compute_cyl_head_sec(&after_end, hpc, sph,
|
||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||
wpt = buf + 446 + (partition_number - 1) * 16;
|
||||
|
||||
/* Not bootable */
|
||||
*(wpt++) = 0x00;
|
||||
|
||||
/* C/H/S of the start */
|
||||
*(wpt++) = start_head;
|
||||
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||
*(wpt++) = start_cyl & 0xff;
|
||||
|
||||
/* (partition type) */
|
||||
*(wpt++) = partition_type;
|
||||
|
||||
/* 3 bytes of C/H/S end */
|
||||
*(wpt++) = end_head;
|
||||
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||
*(wpt++) = end_cyl & 0xff;
|
||||
|
||||
/* LBA start in little endian */
|
||||
for (i = 0; i < 4; i++)
|
||||
*(wpt++) = (start_lba >> (8 * i)) & 0xff;
|
||||
|
||||
/* Number of sectors in partition, little endian */
|
||||
end_lba = end_lba - start_lba + 1;
|
||||
for (i = 0; i < 4; i++)
|
||||
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||
|
||||
/* Afaik, partition tables are recognize donly with MBR signature */
|
||||
buf[510] = 0x55;
|
||||
buf[511] = 0xAA;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
||||
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
||||
"Currently we use first and not last entry. You need to:
|
||||
@ -88,11 +174,12 @@ void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
||||
bit1= do not mark partition as bootable
|
||||
*/
|
||||
static
|
||||
int make_grub_msdos_label(uint32_t img_blocks, uint8_t *buf, int flag)
|
||||
int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
|
||||
uint8_t *buf, int flag)
|
||||
{
|
||||
uint8_t *wpt;
|
||||
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||
int sph = 63, hpc = 255, i;
|
||||
int i;
|
||||
|
||||
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||
@ -151,17 +238,13 @@ int make_grub_msdos_label(uint32_t img_blocks, uint8_t *buf, int flag)
|
||||
*/
|
||||
static
|
||||
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||
int sph_in, int hpc_in, uint8_t *buf, int flag)
|
||||
int sph, int hpc, uint8_t *buf, int flag)
|
||||
{
|
||||
uint8_t *wpt;
|
||||
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||
int sph = 63, hpc = 255, i;
|
||||
int i;
|
||||
|
||||
if (sph_in > 0)
|
||||
sph = sph_in;
|
||||
if (hpc_in > 0)
|
||||
hpc = hpc_in;
|
||||
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||
@ -176,7 +259,7 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||
/* C/H/S of the start */
|
||||
*(wpt++) = start_head;
|
||||
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||
*(wpt++) = end_cyl & 0xff;
|
||||
*(wpt++) = start_cyl & 0xff;
|
||||
|
||||
/* (partition type) */
|
||||
wpt++;
|
||||
@ -208,9 +291,283 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||
}
|
||||
|
||||
|
||||
static int boot_nodes_from_iso_path(Ecma119Image *t, char *path,
|
||||
IsoNode **iso_node, Ecma119Node **ecma_node,
|
||||
char *purpose, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_tree_path_to_node(t->image, path, iso_node);
|
||||
if (ret < 0) {
|
||||
iso_msg_submit(t->image->id, ISO_BOOT_FILE_MISSING, 0,
|
||||
"Cannot find %s '%s'", purpose, path);
|
||||
return ISO_BOOT_FILE_MISSING;
|
||||
}
|
||||
if ((*iso_node)->type != LIBISO_FILE) {
|
||||
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
"Designated boot file is not a data file: '%s'", path);
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
|
||||
*ecma_node= ecma119_search_iso_node(t, *iso_node);
|
||||
if (*ecma_node == NULL) {
|
||||
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
"Program error: IsoFile has no Ecma119Node: '%s'", path);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
} else {
|
||||
if ((*ecma_node)->type != ECMA119_FILE) {
|
||||
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
"Program error: Ecma119Node of IsoFile is no ECMA119_FILE: '%s'",
|
||||
path);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* This function was implemented according to doc/boot_sectors.txt section
|
||||
"MIPS Volume Header" which was derived by Thomas Schmitt from
|
||||
cdrkit-1.1.10/genisoimage/boot-mips.c by Steve McIntyre which is based
|
||||
on work of Florian Lohoff and Thiemo Seufer who possibly learned from
|
||||
documents of MIPS Computer Systems, Inc. and Silicon Graphics Computer
|
||||
Systems, Inc.
|
||||
This function itself is entirely under copyright (C) 2010 Thomas Schmitt.
|
||||
*/
|
||||
static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
||||
{
|
||||
char *namept, *name_field;
|
||||
uint32_t num_cyl, idx, blocks, num, checksum;
|
||||
off_t image_size;
|
||||
static uint32_t bps = 512, spt = 32;
|
||||
Ecma119Node *ecma_node;
|
||||
IsoNode *node;
|
||||
IsoStream *stream;
|
||||
off_t file_size;
|
||||
uint32_t file_lba;
|
||||
int ret;
|
||||
|
||||
/* Bytes 512 to 32767 may come from image or external file */
|
||||
memset(buf, 0, 512);
|
||||
|
||||
image_size = t->curblock * 2048;
|
||||
|
||||
/* 0 - 3 | 0x0be5a941 | Magic number */
|
||||
iso_msb(buf, 0x0be5a941, 4);
|
||||
|
||||
/* 28 - 29 | num_cyl_l | Number of usable cylinder, lower two bytes */
|
||||
num_cyl = (image_size + (bps * spt) - 1) / (bps * spt);
|
||||
iso_msb(buf + 28, num_cyl & 0xffff, 2);
|
||||
|
||||
/* 32 - 33 | 1 | Number of tracks per cylinder */
|
||||
iso_msb(buf + 32, 1, 2);
|
||||
|
||||
/* 35 - 35 | num_cyl_h | Number of usable cylinders, high byte */
|
||||
buf[35] = (num_cyl >> 16) & 0xff;
|
||||
|
||||
/* 38 - 39 | 32 | Sectors per track */
|
||||
iso_msb(buf + 38, spt, 2);
|
||||
|
||||
/* 40 - 41 | 512 | Bytes per sector */
|
||||
iso_msb(buf + 40, bps, 2);
|
||||
|
||||
/* 44 - 47 | 0x00000034 | Controller characteristics */
|
||||
iso_msb(buf + 44, 0x00000034, 4);
|
||||
|
||||
/* 72 - 87 | ========== | Volume Directory Entry 1 */
|
||||
/* 72 - 79 | boot_name | Boot file basename */
|
||||
/* 80 - 83 | boot_block | ISO 9660 LBA of boot file * 4 */
|
||||
/* 84 - 87 | boot_bytes | File length in bytes */
|
||||
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
||||
|
||||
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
||||
&node, &ecma_node, "MIPS boot file", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
namept = (char *) iso_node_get_name(node);
|
||||
name_field = (char *) (buf + (72 + 16 * idx));
|
||||
strncpy(name_field, namept, 8);
|
||||
|
||||
file_lba = ecma_node->info.file->sections[0].block;
|
||||
|
||||
iso_msb(buf + (72 + 16 * idx) + 8, file_lba * 4, 4);
|
||||
|
||||
stream = iso_file_get_stream((IsoFile *) node);
|
||||
file_size = iso_stream_get_size(stream);
|
||||
|
||||
/* Shall i really round up to 2048 ? Steve says yes.*/
|
||||
iso_msb(buf + (72 + 16 * idx) + 12,
|
||||
((file_size + 2047) / 2048 ) * 2048, 4);
|
||||
|
||||
}
|
||||
|
||||
/* 408 - 411 | part_blks | Number of 512 byte blocks in partition */
|
||||
blocks = (image_size + bps - 1) / bps;
|
||||
iso_msb(buf + 408, blocks, 4);
|
||||
/* 416 - 419 | 0 | Partition is volume header */
|
||||
iso_msb(buf + 416, 0, 4);
|
||||
|
||||
/* 432 - 435 | part_blks | Number of 512 byte blocks in partition */
|
||||
iso_msb(buf + 432, blocks, 4);
|
||||
iso_msb(buf + 444, 6, 4);
|
||||
|
||||
/* 504 - 507 | head_chk | Volume header checksum
|
||||
The two's complement of bytes 0 to 503 read
|
||||
as big endian unsigned 32 bit:
|
||||
sum(32-bit-words) + head_chk == 0
|
||||
*/
|
||||
checksum = 0;
|
||||
for (idx = 0; idx < 504; idx += 4) {
|
||||
num = iso_read_msb(buf + idx, 4);
|
||||
/* Addition modulo a natural number is commutative and associative.
|
||||
Thus the inverse of a sum is the sum of the inverses of the addends.
|
||||
*/
|
||||
checksum -= num;
|
||||
}
|
||||
iso_msb(buf + 504, checksum, 4);
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* The following two functions were implemented according to
|
||||
doc/boot_sectors.txt section "MIPS Little Endian" which was derived
|
||||
by Thomas Schmitt from
|
||||
cdrkit-1.1.10/genisoimage/boot-mipsel.c by Steve McIntyre which is based
|
||||
on work of Florian Lohoff and Thiemo Seufer,
|
||||
and from <elf.h> by Free Software Foundation, Inc.
|
||||
|
||||
Both functions are entirely under copyright (C) 2010 Thomas Schmitt.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read the necessary ELF information from the first MIPS boot file.
|
||||
* This is done before image writing starts.
|
||||
*/
|
||||
int iso_read_mipsel_elf(Ecma119Image *t, int flag)
|
||||
{
|
||||
uint32_t phdr_adr, todo, count;
|
||||
int ret;
|
||||
uint8_t elf_buf[2048];
|
||||
IsoNode *iso_node;
|
||||
Ecma119Node *ecma_node;
|
||||
IsoStream *stream;
|
||||
|
||||
if (t->image->num_mips_boot_files <= 0)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
||||
&iso_node, &ecma_node, "MIPS boot file", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
stream = iso_file_get_stream((IsoFile *) iso_node);
|
||||
|
||||
ret = iso_stream_open(stream);
|
||||
if (ret < 0) {
|
||||
iso_msg_submit(t->image->id, ret, 0,
|
||||
"Cannot open designated MIPS boot file '%s'",
|
||||
t->image->mips_boot_file_paths[0]);
|
||||
return ret;
|
||||
}
|
||||
ret = iso_stream_read(stream, elf_buf, 32);
|
||||
if (ret != 32) {
|
||||
cannot_read:;
|
||||
iso_stream_close(stream);
|
||||
iso_msg_submit(t->image->id, ret, 0,
|
||||
"Cannot read from designated MIPS boot file '%s'",
|
||||
t->image->mips_boot_file_paths[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* 24 - 27 | e_entry | Entry point virtual address */
|
||||
t->mipsel_e_entry = iso_read_lsb(elf_buf + 24, 4);
|
||||
|
||||
/* 28 - 31 | e_phoff | Program header table file offset */
|
||||
phdr_adr = iso_read_lsb(elf_buf + 28, 4);
|
||||
|
||||
/* Skip stream up to byte address phdr_adr */
|
||||
todo = phdr_adr - 32;
|
||||
while (todo > 0) {
|
||||
if (todo > 2048)
|
||||
count = 2048;
|
||||
else
|
||||
count = todo;
|
||||
todo -= count;
|
||||
ret = iso_stream_read(stream, elf_buf, count);
|
||||
if (ret != count)
|
||||
goto cannot_read;
|
||||
}
|
||||
ret = iso_stream_read(stream, elf_buf, 20);
|
||||
if (ret != 20)
|
||||
goto cannot_read;
|
||||
|
||||
/* 4 - 7 | p_offset | Segment file offset */
|
||||
t->mipsel_p_offset = iso_read_lsb(elf_buf + 4, 4);
|
||||
|
||||
/* 8 - 11 | p_vaddr | Segment virtual address */
|
||||
t->mipsel_p_vaddr = iso_read_lsb(elf_buf + 8, 4);
|
||||
|
||||
/* 16 - 19 | p_filesz | Segment size in file */
|
||||
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
|
||||
|
||||
iso_stream_close(stream);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write DEC Bootblock from previously read ELF parameters.
|
||||
* This is done when image writing has already begun.
|
||||
*/
|
||||
static int make_mipsel_boot_block(Ecma119Image *t, uint8_t *buf, int flag)
|
||||
{
|
||||
int ret;
|
||||
uint32_t seg_size, seg_start;
|
||||
IsoNode *iso_node;
|
||||
Ecma119Node *ecma_node;
|
||||
|
||||
/* Bytes 512 to 32767 may come from image or external file */
|
||||
memset(buf, 0, 512);
|
||||
|
||||
if (t->image->num_mips_boot_files <= 0)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
||||
&iso_node, &ecma_node, "MIPS boot file", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* 8 - 11 | 0x0002757a | Magic number */
|
||||
iso_lsb(buf + 8, 0x0002757a, 4);
|
||||
|
||||
/* 12 - 15 | 1 | Mode 1: Multi extent boot */
|
||||
iso_lsb(buf + 12, 1, 4);
|
||||
|
||||
/* 16 - 19 | load_adr | Load address */
|
||||
iso_lsb(buf + 16, t->mipsel_p_vaddr, 4);
|
||||
|
||||
/* 20 - 23 | exec_adr | Execution address */
|
||||
iso_lsb(buf + 20, t->mipsel_e_entry, 4);
|
||||
|
||||
/* 24 - 27 | seg_size | Segment size in file. */
|
||||
seg_size = (t->mipsel_p_filesz + 511) / 512;
|
||||
iso_lsb(buf + 24, seg_size, 4);
|
||||
|
||||
/* 28 - 31 | seg_start | Segment file offset */
|
||||
seg_start = ecma_node->info.file->sections[0].block * 4
|
||||
+ (t->mipsel_p_offset + 511) / 512;
|
||||
iso_lsb(buf + 28, seg_start, 4);
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
{
|
||||
int ret, int_img_blocks;
|
||||
int ret, int_img_blocks, sa_type, i, will_append = 0;
|
||||
uint32_t img_blocks;
|
||||
|
||||
if ((t == NULL) || (buf == NULL)) {
|
||||
@ -220,12 +577,19 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
/* set buf to 0s */
|
||||
memset(buf, 0, 16 * BLOCK_SIZE);
|
||||
|
||||
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (t->appended_partitions[i] != NULL) {
|
||||
will_append = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
img_blocks = t->curblock;
|
||||
if (t->system_area_data != NULL) {
|
||||
/* Write more or less opaque boot image */
|
||||
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
|
||||
|
||||
} else if (t->catalog != NULL &&
|
||||
} else if (sa_type == 0 && t->catalog != NULL &&
|
||||
(t->catalog->bootimages[0]->isolinux_options & 0x0a) == 0x02) {
|
||||
/* Check for isolinux image with magic number of 3.72 and produce
|
||||
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||
@ -243,12 +607,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
if (t->system_area_options & 1) {
|
||||
if (sa_type == 0 && (t->system_area_options & 1)) {
|
||||
/* Write GRUB protective msdos label, i.e. a simple partition table */
|
||||
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
||||
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||
t->partition_heads_per_cyl, buf, 0);
|
||||
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||
return ISO_ASSERT_FAILURE;
|
||||
} else if(t->system_area_options & 2) {
|
||||
} else if(sa_type == 0 && (t->system_area_options & 2)) {
|
||||
/* Patch externally provided system area as isohybrid MBR */
|
||||
if (t->catalog == NULL || t->system_area_data == NULL) {
|
||||
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||
@ -257,17 +622,35 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
return ISO_ISOLINUX_CANT_PATCH;
|
||||
}
|
||||
ret = make_isolinux_mbr(&img_blocks, t->bootsrc[0]->sections[0].block,
|
||||
(uint32_t) 0, 64, 32, 0, 1, 0x17, buf, 1);
|
||||
(uint32_t) 0, t->partition_heads_per_cyl,
|
||||
t->partition_secs_per_head, 0, 1, 0x17, buf, 1);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
} else if(t->partition_offset > 0) {
|
||||
} else if (sa_type == 1) {
|
||||
ret = make_mips_volume_header(t, buf, 0);
|
||||
if (ret != ISO_SUCCESS)
|
||||
return ret;
|
||||
} else if (sa_type == 2) {
|
||||
ret = make_mipsel_boot_block(t, buf, 0);
|
||||
if (ret != ISO_SUCCESS)
|
||||
return ret;
|
||||
} else if ((t->partition_offset > 0 || will_append) && sa_type == 0) {
|
||||
/* Write a simple partition table. */
|
||||
ret = make_grub_msdos_label(img_blocks, buf, 2);
|
||||
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||
t->partition_heads_per_cyl, buf, 2);
|
||||
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||
return ISO_ASSERT_FAILURE;
|
||||
if (t->partition_offset == 0) {
|
||||
/* Re-write partion entry 1 : start at 0, type Linux */
|
||||
ret = write_mbr_partition_entry(1, 0x83, 0, img_blocks,
|
||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||
buf, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->partition_offset > 0) {
|
||||
if (t->partition_offset > 0 && sa_type == 0) {
|
||||
/* Adjust partition table to partition offset */
|
||||
img_blocks = t->curblock; /* value might be altered */
|
||||
ret = iso_offset_partition_start(img_blocks, t->partition_offset,
|
||||
@ -277,5 +660,17 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
/* This eventually overwrites the partition table entries made so far */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (t->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
|
||||
t->appended_part_start[i], t->appended_part_size[i],
|
||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||
buf, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
@ -46,4 +46,16 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
||||
*/
|
||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
|
||||
|
||||
|
||||
/**
|
||||
* Read the necessary ELF information from the first MIPS boot file.
|
||||
* See doc/boot_sectors.txt "DEC Boot Block" for "MIPS Little Endian".
|
||||
*/
|
||||
int iso_read_mipsel_elf(Ecma119Image *t, int flag);
|
||||
|
||||
|
||||
/* Compute size and position of appended partitions.
|
||||
*/
|
||||
int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
||||
|
||||
#endif /* SYSTEM_AREA_H_ */
|
||||
|
Reference in New Issue
Block a user