Jump to content

exFAT Volume Boot Record for Chameleon


Zenith432
 Share

47 posts in this topic

Recommended Posts

"Type (Bundle)" is the value of kDADiskDescriptionVolumeKindKey, and it's the name of the bundle in /System/Library/Filesystems that is handling the volume.

Ok I'll do as you said..

[+ there's grep -i  :)]

 

Yep case insensitive, but I did not expect this... on one occasion it was like to play "the game of differences"  :hysterical: , because I just could not see.. :rofl:

Thanks for the new boot files :lol:

Link to comment
Share on other sites

Attached is a full implementation of exfat support for Chameleon's boot2 stage.

 

With this code, Chameleon supports reading its configuration files and modules form an exfat partition.  Along with boot1x and revised boot0, Chameleon can fully reside on an exfat volume on either MBR or GPT.

 

The patch is relative to revision 2510.

 

Enjoy.

exfat_from_r2510.patch.txt

  • Like 2
Link to comment
Share on other sites

Hi Zenith432,

 

this is the log installing Chameleon (in debug mode):ZeusPost.html.zip

 

this is the relevant code that install stage1:

 

if [ ${targetFormat} = "msdos" ]; then

    if [ ${fatType} = 3 ]; then

        echo "-----------> ExFAT"

        "${scriptDir}/Scripts/boot1-install" -yM -f "${selectedDestination}/usr/standalone/i386/${stage1LoaderExFAT}" ${targetDeviceRaw}

        echo "*******************************"

    else

        echo "-----------> FAT32"

        #echo "DEBUG: Executing command: dd if=${targetDeviceRaw} count=1 bs=512 of=/tmp/origbs"

        $localdd if=${targetDeviceRaw} count=1 bs=${blocksize} of="${tempDir}/origbs"

 

        #echo "DEBUG: Executing command: cp "${selectedDestination}"/usr/standalone/i386/${stage1LoaderFAT} /tmp/newbs"

        cp "${selectedDestination}"/usr/standalone/i386/${stage1LoaderFAT} "${tempDir}/newbs"

 

        #echo "DEBUG: Executing command: dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc"

        $localdd if="${tempDir}/origbs" of="${tempDir}/newbs" skip=3 seek=3 bs=1 count=87 conv=notrunc

 

        #echo "DEBUG: Executing command: dd of=${targetDeviceRaw} count=1 bs=512 if=/tmp/newbs"

        $localdd if="${tempDir}/newbs" of="${targetDeviceRaw}" count=1 bs=${blocksize}

 

        echo "Written ${stage1LoaderFAT} to ${targetDeviceRaw}."

    fi

fi

 

${fatType} = mean exfat, and this is used in the log, but the disk is now corrupted. Can you give me advice please?

Link to comment
Share on other sites

Do not use the -M switch by default with exfat.

 

Do not use the -M switch by default with exfat.

 

Do not use the -M switch by default with exfat.

 

The normal action for boot1-install (without -M) is to dismount the filesystem, do the install, remount the filesystem.

 

With "-M",  it installs while the filesystem is mounted.

 

exfat's boot sector also serves as a "superblock" - which means it has 3 bytes that get rewritten during filesystem activity (dirty bit + percent used).

This means the filesystem driver overwrites the boot sector when it syncs or dismounts the volume (such as when you reboot.)

This means if you use "-M", the boot code gets clobbered, and the filesystem reports as corrupt because the checksum is wrong.

 

So why did I put in the "-M" switch?

 

The "-M" switch is only meant to be used if the filesystem cannot be dismounted when the system is running - in other words, for the root filesystem (which is always HFS+).  In HFS+, the boot sector does not serve as a "superblock" and does not get overwritten by the filesystem driver.  So it's safe to install boot1h when the volume is mounted.

 

EDIT: There's a similar sync issue with FAT32.  In offset 0x41 (65) of fat32 boot sector there's a poorly documented field which is used by Windows NT or later as a dirty bit.

  • Like 1
Link to comment
Share on other sites

Hi Zenith432 thanks for the explanation and for the patch diff, I think that now tecnically the installation method is ok, but I got the boot0 Error for a stupid reason:

looking at the log I can see that  boot1-install was unable to umount the target Volume:

umount unsuccessful, status Resource busy
Unable to umount /dev/rdisk2s1, please 'diskutil umount' manually before running this program

Finder was closed at this volume  (we can close programmatically all windows before lauch boot1-install ..if helpfull). So only Spotlight remain to check.. or lauch umout -f ..... before..

Link to comment
Share on other sites

More likely the script or Terminal had the exfat volume as its "current directory". You can run 'lsof | grep <volume name>' to see which process has it open.

Anyway, I can add a 'force dismount' option to boot1-install, instead of doing diskutil umount -f. Is that useful?

Finder was closed at this volume  (we can close programmatically all windows before lauch boot1-install ..if helpfull). So only Spotlight remain to check.. or lauch umout -f ..... before..

  • Like 1
Link to comment
Share on other sites

Hi Zenith432,

I got update for 10.9.5 including XCode 6.1.1. And now I can't compile boot1-install.

Just cd to /Users/slice/Downloads/ChameleonExfatVBR_1.0.3/src and 

iMac:src slice$ make
clang -fvisibility=hidden -O2 -fno-exceptions -fno-stack-protector  -framework CoreFoundation -framework DiskArbitration -Wl,-no_source_version -Wl,-no_function_starts -Wl,-no_data_in_code_info -Wl,-no_version_load_command -Wl,-no_uuid -Wl,-no_dependent_dr_info  -o boot1-install boot1-install.c
In file included from boot1-install.c:22:
In file included from /System/Library/Frameworks/DiskArbitration.framework/Headers/DiskArbitration.h:29:
In file included from /System/Library/Frameworks/DiskArbitration.framework/Headers/DADisk.h:28:
In file included from /System/Library/Frameworks/IOKit.framework/Headers/IOKitLib.h:49:
In file included from /usr/include/IOKit/IOTypes.h:35:
In file included from /usr/include/IOKit/system.h:52:
/usr/include/kern/task.h:103:28: error: too many arguments provided to function-like macro invocation
extern task_t   current_task(void);
                             ^
/usr/include/mach/mach_init.h:77:9: note: macro 'current_task' defined here
#define current_task()  mach_task_self()
        ^
In file included from boot1-install.c:22:
In file included from /System/Library/Frameworks/DiskArbitration.framework/Headers/DiskArbitration.h:29:
In file included from /System/Library/Frameworks/DiskArbitration.framework/Headers/DADisk.h:28:
In file included from /System/Library/Frameworks/IOKit.framework/Headers/IOKitLib.h:49:
In file included from /usr/include/IOKit/IOTypes.h:35:
In file included from /usr/include/IOKit/system.h:57:
/usr/include/libkern/libkern.h:142:18: error: conflicting types for 'random'
extern u_int32_t        random(void);
                        ^
/usr/include/stdlib.h:207:7: note: previous declaration is here
long     random(void);
         ^
In file included from boot1-install.c:22:
In file included from /System/Library/Frameworks/DiskArbitration.framework/Headers/DiskArbitration.h:29:
In file included from /System/Library/Frameworks/DiskArbitration.framework/Headers/DADisk.h:28:
In file included from /System/Library/Frameworks/IOKit.framework/Headers/IOKitLib.h:49:
In file included from /usr/include/IOKit/IOTypes.h:35:
In file included from /usr/include/IOKit/system.h:57:
/usr/include/libkern/libkern.h:152:5: error: expected parameter declarator
int     snprintf(char *, size_t, const char *, ...) __printflike(3,4);
        ^

And many-many same messages.

Link to comment
Share on other sites

The files are inside the Xcode command line path (...Library/Developer.../usr/include..) inside the SDK??

 

EDIT:

 

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/mach/task.h  ....and similar for the others.

 

Probably you need to run xcode-select if you have more than one Xcode versions

Link to comment
Share on other sites

Attached is a full implementation of exfat support for Chameleon's boot2 stage.

 

With this code, Chameleon supports reading its configuration files and modules form an exfat partition.  Along with boot1x and revised boot0, Chameleon can fully reside on an exfat volume on either MBR or GPT.

 

The patch is relative to revision 2510.

 

Enjoy.

Thx again!

I will add those improvements at the end of the next week ( I'm not at home until 15th)

ErmaC

Link to comment
Share on other sites

More likely the script or Terminal had the exfat volume as its "current directory". You can run 'lsof | grep ' to see which process has it open.

Anyway, I can add a 'force dismount' option to boot1-install, instead of doing diskutil umount -f. Is that useful?

Added -u option to force umont the target partition from your advice ( kDADiskUnmountOptionForce ). :)

-u suppress -M if given.

If -u is not given it always try to politely umount the volume..

For me is working, need testers..

boot1-install.c.zip

  • Like 1
Link to comment
Share on other sites

I've updated the package at post #1 to version 1.0.4 that incorporates Micky1979's -u option from post #38, and uses xcrun in the Makefile to (hopefully) improve build issue in post #35 - should make it use SDK from Xcode folders instead of /System/Library/Frameworks or /usr/include.

  • Like 2
Link to comment
Share on other sites

I was absent in the latest weeks...

 

Added -u option to force umont the target partition from your advice ( kDADiskUnmountOptionForce )

-u suppress -M if given.

If -u is not given it always try to politely umount the volume..

Done 2514

 

Attached is a full implementation of exfat support for Chameleon's boot2 stage.

 

With this code, Chameleon supports reading its configuration files and modules form an exfat partition.  Along with boot1x and revised boot0, Chameleon can fully reside on an exfat volume on either MBR or GPT.

patch merged commit 2516

 

ErmaC

Link to comment
Share on other sites

  • 4 weeks later...

I've uploaded (in post #1) v1.0.5 with the following changes

  • Implemented 2nd-stage boot selection feature used in Clover with two-second delay for a keypress.  If a digit X is pressed during the delay, load file /bootX instead of /boot.  The code for this in the source is activated by defining symbol SELECTION_FEATURE.  boot1x is a binary without the selection feature.  boot1xalt is a binary with the selection feature.  The rationale for two binaries is that people who do not want the option to select may not like the two-second delay.
  • Implemented feature for boot1x to load its own second sector in case the previous (MBR) boot sector only loaded 1 sector.  As a result, the expectation from prior bootcode is now 1) To load at least 1 sector at address 0x7c00 and 2) Pass bios drive number in DL.  This means boot1x may now be used on a 'naked' exFAT partition not wrapped in MBR, and may also be used with MBR bootcode from other OSes such as Windows.
  • Re-engineered ("optimized") some of the code to eliminate reading of inessential FAT sectors while scanning the root directory.  It now loads precisely the minimal set of sectors necessary to find and load /boot.

All components other than boot1x have not changed.

  • Like 1
Link to comment
Share on other sites

Thanks Zenith432!

and...this mean that this require manual installation only?

(or elaborate a Java function for the Distribution file to navigate into IO registry to see if the target is Exfat... :worried_anim:, using the installer..)

Link to comment
Share on other sites

Manual installation of what?  boot1x can be used same as before.

 

boot1xalt is in Clover package.  Chameleon does not distribute these alt boot sectors (boot1f32alt, boot1h2, boot1xalt) with the keypress option.

 

The option to use with Windows MBR code or naked exfat partition wasn't meant to be put into packager :)  It's special scenario for people want to set it up manually....

 

The redesign with less fat sector reading is just in there - doesn't need any handling.

 

[Edit: Maybe my wording wasn't clear - but the new stuff is all added and presents new possibilities.  Nothing was taken away.]

 

Thanks Zenith432!

and...this mean that this require manual installation only?

(or elaborate a Java function for the Distribution file to navigate into IO registry to see if the target is Exfat... :worried_anim:, using the installer..)

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi Zenith432,
I have modified the boot1-install to remember the mount point of the volume that will be umounted. This because I've change how Chameleon install all the stage1 (boot1f32, boot1h and boot1x) using only your boot1-install command line (no more dd).
In this way non-root volumes get always umounted, but this was a problem when the target partition was the ESP because have no "automount units":
umounting the ESP if already founded mounted, and with a particular mount point (ex.: /Volumes/myESP), then at re-mount time boot1-install simply assigning "/Volumes/EFI" since this is the standard location.
Now the NULL parameter in the "mount" function is sosbistituted with the CFURLRef object aquired before umointing the volume (anyway the NULL parameter is always passed if  has already been found not mounted).
 
Can you check the code?

 
Micky
 
EDIT
 
The code was bad, because CFurlRef is a beast converting to const char. Using a CFDictionary  kDADiskDescriptionVolumePathKey is a url... using  and NSDictionary the same return  a C string.. But this require to convert boot1-install to an obj-c command (at least is more easy for me :P )

Link to comment
Share on other sites

  • 2 months later...
 Share

×
×
  • Create New...