USBHost_t36 USB Mass Storage Driver Experiments

Damn - should have mentioned that one - when I did the formatting for exFAT the warning was to use MBR to make it compatible with everything - basically don't use GPR. So all my partitions are MBR formatted.

I didn't see the warning or option from the GUI - it may have done that because my first attempt to format was with the TWO partitions - and then it just carried over through the multiple recreate of the partitions. I even went looking for that option in EASEUS … that may be when I accidentally wiped the partitions from that bad drive of Bill's :( thinking it was the Seagate of mine - that meant I didn't do then

Would be nice if it could at least recognize GPT and give a custom message if it can't support them, the 'FR_NO_FILESYSTEM' error is in the code 10 or more times I saw when trying to glance at why it was failing Perhaps :: Mount: Failed with rc=FR_NO_MBR

This is EXHAUSTING … I feel like I'm at work in 1995 again !!!!! Half a DOZEN drives in front of me and Half a dozen drive adapter boxes … except I didn't have 8 Teensys on my desk {3 beta T$'s and 5 others - not counting the two Teensy64's I put away} and - 6 of which are faster than my Win 95 computer back then … Those were IDE and SCSI drives … Back in the day when Iomega was making single platter 1GB removable Hard disk platters.

ANYHOW one last combo tested! … NEW 500GB SEAGATE BARRACUDA in the ORICO POWERED HUB Drive Box :: WORKS !!!!
>> That HUB plugged into AMAZON BASICS powered hub Works
>> That HUB plugged into Teensy Host port WORKS!
-- Both combos result in ~9.7 MB/sec with Buffsize 30K

That is the HUB that puts power into the Teensy Host port - NOT ALWAYS - only when Teensy unpowered - After it was powered! KurtE said he had a device that did this before and he like it because it would back feed and power an rPi and other stuff on a robot.

@mjs513 - you need to add this to the code in post #213!
Code:
#include <USBHost_t36.h>
extern USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);

That works now on my ORICO HUB drive adapter.

That USB_HUB code is also needed in the test_diskio.ino.

Problem with my Orico HUB adapter is the Native Hard drive is always found first - so using that I cannot test any other drives - unless I pull that drive. But if we ever get a sample with Bt or Joystick devices that will work!

BTW - in my disk search I found another NIB Bluetooth adapter labeled 'Support Windows VISTA' I can try out then.
 
Just thought to look at the OCZ SSD - it is marked GPT too … will change that and hopefully see it work.

So no drive has peaked USB Write over 11 MB/sec - I wonder if there is something holding it back? I was thinking of bumping F_CPU_Actual and testing. Paul's current USB write is also max about 10 MB/sec where Linux was getting about 300,000 lines/sec where a line is 30-35 characters.

I wonder what the read speed it - I haven't seen or gotten to make a read test yet?
 
Again I am not an expert on this code and could easily be wrong, but figured that the performance is probably somewhat limited by things being done in lock step...

For example when you do something like f_write(&fil, buffer, BUFFSIZE, &wr)...

Especially in multiples of the sector size...

It probably funnels through:
Code:
uint8_t writeSectors(void *sectorBuffer,uint32_t BlockAddress, uint8_t Blocks) {
	uint8_t msResult = 0;
	msResult = msDrive1.msWriteBlocks(BlockAddress,Blocks,(uint16_t)512,sectorBuffer);
	return msResult;
}
Which funnels through:
Code:
uint8_t msController::msWriteBlocks(
                                  const uint32_t BlockAddress,
                                  const uint8_t Blocks,
                                  const uint16_t BlockSize,
								  void * sectorBuffer)
	{
	msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t)
	{
		.Signature          = CBWSIGNATURE,
		.Tag                = ++CBWTag,
		.TransferLength     = (uint32_t)(Blocks * BlockSize),
		.Flags              = CMDDIRDATAOUT,
		.LUN                = currentLUN,
		.CommandLength      = 10,
		.CommandData        = {CMDWR10, 0x00,
		                      (uint8_t)(BlockAddress >> 24),
							  (uint8_t)(BlockAddress >> 16),
							  (uint8_t)(BlockAddress >> 8),
							  (uint8_t)(BlockAddress & 0xFF),
							  0x00, 0x00, Blocks, 0x00}
	};
	return msDoCommand(&CommandBlockWrapper, sectorBuffer);
}
And finally to:
Code:
uint8_t msController::msDoCommand(msCommandBlockWrapper_t *CBW,	void *buffer)
{
	uint8_t CSWResult = 0;

	if(CBWTag == 0xFFFFFFFF)
		CBWTag = 1;
	if((CBW->Flags == CMDDIRDATAIN)) { // Data from device
		queue_Data_Transfer(datapipeOut, CBW, sizeof(msCommandBlockWrapper_t), this);
		while(!msOutCompleted);  // Wait for out transaction to complete.
		msOutCompleted = false;
		queue_Data_Transfer(datapipeIn, buffer, CBW->TransferLength, this);
		while(!msInCompleted);  // Wait for in transaction to complete.
		msInCompleted = false;
		if((CSWResult = msGetCSW()) != 0)
			return CSWResult;
	} else { // Data to device
		queue_Data_Transfer(datapipeOut, CBW, sizeof(msCommandBlockWrapper_t), this);
		while(!msOutCompleted);  // Wait for out transaction to complete.
		msOutCompleted = false;
		queue_Data_Transfer(datapipeOut, buffer, CBW->TransferLength, this);
		while(!msOutCompleted);  // Wait for second out transaction to complete.
		msOutCompleted = false;
		if((CSWResult = msGetCSW()) != 0)
			return CSWResult;
	}
	return CSWResult;  // Return CSW status
}

Which this code will wait until the USB system has told us that our transfer has completed before it returns... the msOutCompleted is set by ISR callback.

Some questions, may be, can we somehow shorten up delays between packets? Can we queue multiple ones? Maybe it already is, but if not wonder if we can have multiple buffers that f_write goes to, and somehow setup the code such that when the disk operation is going on, that we can somehow use that time to allow the app to be filling in other buffer(s)...

My Logic Analyzer if fast, but not fast enough to track USB at 480mhz speeds, so may be hard to see exactly what gaps there are in the USB packet timings...

I may have to play a little on this. Which app are you using to best measure the speed? logger_RamWrite? logger_RamWrite_fs (does not compile for me)...
 
@KurtE - glad you looked after that - it will make more sense to you than I would have found. Promising that currently it blocks waiting for confirmation - but in some fashion it shouldn't have to - maybe it sends and leaves and waits to delete the local buffer until the confirmation returns with an interrupt - then resends prior or sends the next?

Paul's Device code AFAIK does multiple buffers and lots of stuff 'off the clock' in some fashion. Device is the other end of Host - but seems there should be symmetry in usage given both ends send and receive. In the end maybe this could work with a callback perhaps where the user buffer is processed in chunks or as needed until the buffer is not needed. Device USB doesn't call back it just buffers all it can while it can then blocks ( though it doesn't block based on latency_lps test ) seems to trust the user to find 'AvailableForWrite()' [not yet working on T$ ] - doing call backs would hold the user buffer in Limbo until complete in some fashion - but avoid duplicate buffers outside the user control. Then the user could send one buffer to write while filling the next and doing other work.

Wondering what Paul implemented in the Serial (?) example for T_3.6? Didn't he do that and also a sketch to use a T_3.6 to upload code to another Teensy?
 
BTW: Just compiled and tested this _FS on T_3.6 and the Orico Hub/Drive box with new Seagate compiles! and works the same - 8K buffsize and 5.3 MB/sec write speed. And it works WITH and WITHOUT the Amazon powered Hub between the powered HUB/Drive enclosure at the same speed.

Also - when I formatted that 500 GB drive - I did do it with FAT32?

@KurtE - this is with the sketch: \uSDFS\examples\logger_RawWrite_FS\logger_RawWrite_FS.ino - not sure why it won't compile for you - see below ?
Code:
Test logger_RawWrite
2019-05-24 01:09:13
BUFFSIZE :8192
Dev Type :2
Using uSDFS
uSDFS_VER:15_MAY_19_08_16
File System FS_FAT32
Free Disk Size 2741421 clusters
Cluster Size 128 sectors
Sector Size 512 bytes

Change drive
A_00001.dat
stat FR_OK 0
 opened FR_OK 0

................................................................
.................................... (6164982 - 5.315182 MB/s)
 (open: 74809 us; close: 24837 us; write: min,max: 5831 35835 us)

I had to take out this in the _FS sketch to compile as the T$ doesn't have #define for '__rtc_localtime':
Code:
extern void *__rtc_localtime;
void rtc_sync(void)
{
  rtc_init();
[B][COLOR="#FF0000"]#if 0
  if((uint32_t)&__rtc_localtime > (rtc_secs()+10))
    rtc_set_time((uint32_t)&__rtc_localtime);   //LPSRTC will start at 0 otherwise
#endif[/COLOR]
[/B]}

I don't find it offhand - but think I made note of that - that and it really needs to have the cool HUB code [and some warnings fixed]:
Code:
[COLOR="#FF0000"]const[/COLOR] char *fnamePrefix = "A";
#include <USBHost_t36.h>
extern USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
 
Hi @mjs513, @defragster, @wwatson, @WMXZ...

Thought I would get some more information, about how things are actually running... So I updated my copy of logger_RawWrtie_FS (Still the actual one of the library)
To have the logical mapping table I mentioned yesterday, since that option is currently turned on, plus added the two USBHub objects....

Fixed the __RTC... issue by updating the boards.txt as mentioned in the text of the example...

And have it running. Currently going to IOMega drive...

Wondered how many times things were called, so I added some counters to functions like: msWriteBlocks where it added:
count_calls_msWriteBlocks++;
count_blocks_msWriteBlocks+=Blocks;

I then added a simple print function:
Code:
// Temporary Hack to see how many times things are called.
uint16_t count_calls_docommand = 0;
uint16_t count_calls_msReadBlocks = 0;
uint16_t count_blocks_msReadBlocks = 0;
uint16_t count_calls_msWriteBlocks = 0;
uint16_t count_blocks_msWriteBlocks = 0;

void MSC_PrintCallStats() {
	Serial.printf("MSC Call data: Cmds: %d, Reads: %d, %d %d, Writes:%d %d %d\n", count_calls_docommand,
		count_calls_msReadBlocks, count_blocks_msReadBlocks, count_calls_msReadBlocks? count_blocks_msReadBlocks/count_calls_msReadBlocks : 0,
		count_calls_msWriteBlocks, count_blocks_msWriteBlocks, count_calls_msWriteBlocks? count_blocks_msWriteBlocks/count_calls_msWriteBlocks : 0);

	count_calls_docommand = 0;
	count_calls_msReadBlocks = 0;
	count_blocks_msReadBlocks = 0;
	count_calls_msWriteBlocks = 0;
	count_blocks_msWriteBlocks = 0;

}
And hacked in a call to this in the test program right after it printed out it's statistics...
Code:
Test logger_RawWrite
2019-05-24 07:46:51
BUFFSIZE :8192
Dev Type :2
Using uSDFS
uSDFS_VER:15_MAY_19_08_16
## f_mount path=2:/ vol=2
File System FS_EXFAT
Free Disk Size -1 clusters
Cluster Size 512 sectors
Sector Size 512 bytes

Change drive
A_00001.dat
stat FR_OK 0
 opened FR_OK 0

................................................................
.................................... (4008994 - 8.173621 MB/s)
 (open: 15018 us; close: 8979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1012, Reads: 7, 7 1, Writes:1003 64003 63
A_00002.dat
stat FR_OK 9
 opened FR_OK 0

................................................................
.................................... (4020994 - 8.149229 MB/s)
 (open: 5984 us; close: 20979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1005, Reads: 2, 2 1, Writes:1003 64003 63
A_00003.dat
stat FR_OK 86
 opened FR_OK 0

................................................................
.................................... (4018994 - 8.153284 MB/s)
 (open: 5985 us; close: 18979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1005, Reads: 2, 2 1, Writes:1003 64003 63
A_00004.dat
stat FR_OK 103
 opened FR_OK 0

................................................................
.................................... (4017994 - 8.155313 MB/s)
 (open: 14985 us; close: 17979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1008, Reads: 5, 5 1, Writes:1003 64003 63
A_00005.dat
stat FR_OK 180
 opened FR_OK 0

................................................................
.................................... (4022994 - 8.145178 MB/s)
 (open: 17985 us; close: 22979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1009, Reads: 6, 6 1, Writes:1003 64003 63
A_00006.dat
stat FR_OK 1fd
 opened FR_OK 0

................................................................
.................................... (4022994 - 8.145178 MB/s)
 (open: 17985 us; close: 22979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1009, Reads: 6, 6 1, Writes:1003 64003 63
A_00007.dat
stat FR_OK 27a
 opened FR_OK 0

................................................................
.................................... (4022994 - 8.145178 MB/s)
 (open: 17985 us; close: 22979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1009, Reads: 6, 6 1, Writes:1003 64003 63
A_00008.dat
stat FR_OK 2f7
 opened FR_OK 0

................................................................
.................................... (4023994 - 8.143153 MB/s)
 (open: 17985 us; close: 23979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1009, Reads: 6, 6 1, Writes:1003 64003 63
A_00009.dat
stat FR_OK 374
 opened FR_OK 0

................................................................
.................................... (4024994 - 8.141130 MB/s)
 (open: 32985 us; close: 24979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1018, Reads: 13, 13 1, Writes:1005 64005 63
A_00010.dat
stat FR_OK 3f1
 opened FR_OK 0

................................................................
.................................... (4024994 - 8.141130 MB/s)
 (open: 23983 us; close: 24979 us; write: min,max: 3977 3993 us)

MSC Call data: Cmds: 1011, Reads: 8, 8 1, Writes:1003 64003 63
## f_mount path=2:/ vol=2
unmount FR_OK
So it verified that it is already minimizing calls to do the write sectors...
That is Each file we do 1000 writes (plus a few probably for cluster tables, dir...) and each of those 1000 writes are doing 64 sectors at a time...

Note: In my version I have the calls to waitDriveReady commented out...
 
KurtE said:
Note: In my version I have the calls to waitDriveReady commented out..
Sounds like this is going to be a defacto standard since it doesn't seem to hurt anything.

Anyway, you are really making progress and having fun I see. The only thing I noticed in playing around with the lib was that the only thing that changed the speed was the buffer size. But we can only get up to max of 12 mps. I got close to that with 30x1024 buffer
 
Sounds like this is going to be a defacto standard since it doesn't seem to hurt anything.
I will then comment it out also

After all this disk jockeying, would it be possible to get a summary of which situation is NOT working? (it seems most situation ARE working)
(I'm somewhat lost, also working on other stuff for my day job)
 
I will then comment it out also

After all this disk jockeying, would it be possible to get a summary of which situation is NOT working? (it seems most situation ARE working)
(I'm somewhat lost, also working on other stuff for my day job)
I think the big issue with wasn't working was when disks are formatted as with GPT vs MBR. Don't know if there is a way to identify this with a warning.
 
Last edited:
I think the big issue with wasn't working was when disks are formatted as with GPT vs MBR. Don't know if there is a way to identify this with a warning.

Any link to a GPT? (I only realized that my Win10 does not format exFAT with MBR) So I could detect that, but with FAT32?
 
Any link to a GPT? (I only realized that my Win10 does not format exFAT with MBR) So I could detect that, but with FAT32?
When you create the partition it should give you that option - when I do a quick format from explorer seems to give me more options on drive formatting regardless I think - never tried GPT to be honest. I didn't want it to be windows only.

I been looking for references on GPT but couldn't find any.
 
This is probably along the same line as your link: https://www.howtogeek.com/193669/whats-the-difference-between-gpt-and-mbr-when-partitioning-a-drive/

What I haven't been able to find any kind of spec associate with it to be able to read it. I think I did see something referencing to look at FreeBSD? Wikipedia does have some good info though: https://en.wikipedia.org/wiki/GUID_Partition_Table

EDIT: Followed one of the links on Wikipedia and this looked interesting even though MS Specific: https://docs.microsoft.com/en-us/pr.../it-pro/windows-server-2003/cc739412(v=ws.10)

PS. Kurt its amazing how you start me off and all of a sudden I can find things that I was looking for - thank you.
 
@mjs513 and others... maybe including @paul... ;)

As I mentioned my LA is probably not fast enough to decode USB480 stuff It can capture up to 500mhz speed, but...

So first off was curious on how much of our time is spent in the functionss like msWriteBlocks, which as I mentioned mostly writes out 64x512 byte at a time...

So I instrumented the call with digitalWriteFast calls...
Code:
uint8_t msController::msWriteBlocks(
                                  const uint32_t BlockAddress,
                                  const uint8_t Blocks,
                                  const uint16_t BlockSize,
								  void * sectorBuffer)
	{
	digitalWriteFast(15, HIGH);
	msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t)
	{
		.Signature          = CBWSIGNATURE,
		.Tag                = ++CBWTag,
		.TransferLength     = (uint32_t)(Blocks * BlockSize),
		.Flags              = CMDDIRDATAOUT,
		.LUN                = currentLUN,
		.CommandLength      = 10,
		.CommandData        = {CMDWR10, 0x00,
		                      (uint8_t)(BlockAddress >> 24),
							  (uint8_t)(BlockAddress >> 16),
							  (uint8_t)(BlockAddress >> 8),
							  (uint8_t)(BlockAddress & 0xFF),
							  0x00, 0x00, Blocks, 0x00}
	};
	count_calls_msWriteBlocks++;
	count_blocks_msWriteBlocks+=Blocks;
	uint8_t retval = msDoCommand(&CommandBlockWrapper, sectorBuffer);
	digitalWriteFast(15, LOW);
	return retval;
}

screenshot.jpg
As you can see we are spending the vast majority of the time within this call.

The write were taking about 3.978ms to do the transfer and the whole cycle took about 3.998ms

Which comes out to about: 8.2mbs if just looking at the writes...

Not sure how to speed this up, as almost all of this is taken up within the FS...

Edit: Wondering if this USB object can be sped up like Paul did on the main USB object.
 
@mjs513 and others... maybe including @paul... ;)

As I mentioned my LA is probably not fast enough to decode USB480 stuff It can capture up to 500mhz speed, but...

So first off was curious on how much of our time is spent in the functionss like msWriteBlocks, which as I mentioned mostly writes out 64x512 byte at a time...

So I instrumented the call with digitalWriteFast calls...
...
Not sure how to speed this up, as almost all of this is taken up within the FS...

Edit: Wondering if this USB object can be sped up like Paul did on the main USB object.


Cool - again good you are having time to look - I just got back to PC and other things to do first …

As noted the transfer rate for disk is about equal to what Paul has on USB Device Serial transfer to Host PC ~10-12 MB/sec - only I don't think that Serial.print() is consuming the CPU blocking during the write process?

A simple edit to the latency_LPS sketch could see what the effect is going from NO output to MAX output in a few steps of a few seconds perhaps - with a loop counter and some BUSY work each loop to reduction in loops/busy_work when progressively filling the USB with Serial.Print?

@mjs513 - nice view of GPT .vs. MBR in the 'EDIT' link p#238! I'm guessing the GPT 'protective MBR' is as far as the current code looks and following that will result in 'failure to find FS' error as returned. I didn't look enough just now to see the way past that in the next step to see the MBR is phony and this is a GPT drive so say that and return that as the error.
 
Hi @KurtE, @defragster, @wwatson, @WMXZ...

Was out in the yard yesterday putting a small shed together and air conditioners in windows, argh.

Anyway in going through that link it looks like there may be a System ID in the MBR that could identify it is a GPT partitioned disk:
System ID. Must be EE to specify that the single partition is a GPT partition. If you move a GPT disk to a computer running Windows 2000 with Service Pack 1 or greater or Windows Server 2003, the partition is displayed as a GPT Protective Partition and cannot be deleted.
Now not sure if this is applicable to all operating systems or not.
 
It is written like this:
Protective MBR

The Extensible Firmware Interface (EFI) specification requires that LBA 0 be reserved for compatibility code and a Protective MBR. The Protective MBR has the same format as an existing MBR, and it contains one partition entry with a System ID value of 0xEE. This entry reserves the entire space of the disk, including the space used by the GPT header, as a single partition. The Protective MBR is included to prevent disk utilities that were designed for MBR disks from interpreting the disk as having available space and overwriting GPT partitions. The Protective MBR is ignored by EFI; no MBR code is run.

I saw Prime # code the other day - planned to use it to fill disk space perhaps so it could be read back and verified. Seemed like a good busy work tool deciding how long to run is just how many prime numbers to get. Getting small primes up to 65K:
Code:
# small Primes: 6543
Calc Small Prime time us= 18566 // up to 65535
Calc of 78498 Primes in  us= 393426 // Up to 1 million
Storing the small primes for use as a list for getting the primes up to 65K*65K.

Anyhow I started a sketch that shows some diff using TyComm in T_3.6 and T$ - not surprising with the current T$ USB - changes when Serial goes offline - and faster when TyComm gets buffer emptied until it fills and had to dump. Still debugging/adding desired behavior test/etc. It was showing T$ empty loop() cycling at 20M+ now it is suddenly half of that? Same on T_3.6 - not sure what I did to pollute that ...
 
Ok, I reformatted my Seagate drive to be a GPT drive and left my SSD as a MBR. Ran Disk_IO sketch and printed out part->type (assumed this would contain the System ID):
Code:
Seagate:
Type: F2EE7AAE

SSD
Type: 484FDC09
Don't have my other disks laying around so can not test but if some other brave sole wants to see the types and if it contains the SystID would be good - have to go out shopping - family coming over for BBQ later.

I just added this to the loop for MBR:
Code:
    Serial.print("Type: "); 
    Serial.println(mbr->part[ii].type, HEX);
 
Hi @mjs513,

Which app are you running for this? I tried this in the app you posted in #213...

Changed the MBR print loop like:
Code:
  mbr_t *mbr = (mbr_t *) buffer;
  Serial.println("\nMaster Boot Record");
  for (int ii = 0; ii < 4; ii++)
  {
    Serial.print("  Partition: "); Serial.print(ii);
    Serial.print(" Type: "); 
    Serial.print(mbr->part[ii].type, HEX);
    Serial.print(" first Sector: ");
    Serial.print(mbr->part[ii].firstSector);
    Serial.print(" total Sectors: ");
    Serial.println(mbr->part[ii].totalSectors);
  }
And on the IOMega this part prints out like:
Code:
Master Boot Record
  Partition: 0 Type: 7 first Sector: 63 total Sectors: 1953520002
  Partition: 1 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 2 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 3 Type: 0 first Sector: 0 total Sectors: 0

Which maybe make sense as I believe the type field is defined as: uint8_t type;

I also ran it on Toshiba drive: with two fat like partitions...
Code:
Master Boot Record
  Partition: 0 Type: C first Sector: 2048 total Sectors: 16433152
  Partition: 1 Type: 7 first Sector: 16435200 total Sectors: 1937084416
  Partition: 2 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 3 Type: 0 first Sector: 0 total Sectors: 0
Which later printed out Partition 0 FAT32
and 2nd as ExFat...
 
Yep that's the app that I am running. I did it this way:
Code:
  for(int ii=0;ii<4;ii++)
  {
    Serial.print("  Partition: "); Serial.print(ii);
    Serial.print(" first Sector: ");
    Serial.print(mbr->part[ii].firstSector);
    Serial.print(" total Sectors: ");
    Serial.println(mbr->part[ii].totalSectors);
    Serial.print("Type: "); 
    Serial.println(mbr->part[ii].type, HEX);
  }
wonder if order makes a difference. I changed to yours and this is what I am seeing.

Code:
Test diskio
uSDFS_VER:15_MAY_19_08_16
Disk initialize Status: STA_OK
Disk read Result: FR_OK
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 [COLOR="#FF0000"]ae 7a ee f2 00 00 00 00
02 00 ee fe ff 00 01 00 00 00 ff ff ff ff 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 [B]55 aa[/B][/COLOR]

Master Boot Record
  Partition: 0 first Sector: 1 total Sectors: 4294967295
Type: F2EE7AAE
  Partition: 1 first Sector: 0 total Sectors: 0
Type: F2EE7AAE
  Partition: 2 first Sector: 0 total Sectors: 0
Type: F2EE7AAE
  Partition: 3 first Sector: 0 total Sectors: 0
Type: F2EE7AAE

First partition Sector
Disk read Result: FR_OK
45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00
54 09 af ed 00 00 00 00 01 00 00 00 00 00 00 00
af 6d 70 74 00 00 00 00 22 00 00 00 00 00 00 00
8e 6d 70 74 00 00 00 00 e2 34 12 ce 52 9c 0f 49
92 c4 c1 e5 20 ba fa 8c 02 00 00 00 00 00 00 00
80 00 00 00 80 00 00 00 a5 f2 23 51 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
@KurtE

Is there a way to do the MBR print so it looks like this:
Code:
000001B0: 00 00 00 00 00 00 00 00 - 04 06 04 06 00 00 00 00   ................
000001C0: 02 00 EE FF FF FF 01 00 - 00 00 FF FF FF FF 00 00   ................
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 55 AA   ..............U.

EDIT: Reason is that EE you see at 0x01C2 indicates its a GPT disk. Which I am seeing my disks MBR

EDIT2: I did it but its not pretty:
Code:
1C0: 02 1C1: 00 [B]1C2: ee[/B] 1C3: fe 1C4: ff
So that's how we can really identify if its a GPT disk

EDIT3: On the SSD which is MBR with 2 partitions (exFAT and then a FAT32) that address shows:
Code:
1C2: 07
 
Last edited:
Hi again @mjs513 - Sorry I am still a bit confused... Not unusual ;)

In your above Hex dump - part in red - After the 440 bytes of code.
Code:
00 00 00 00 00 00 00 00 [COLOR="#FF0000"]ae 7a ee f2[/COLOR] 00 00 [COLOR="#0000FF"]00 00
02 00 ee fe ff 00 01 00 00 00 ff ff ff ff [/COLOR]00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
You are printing out Type: F2EE7AAE
Which looks like the first 4 bytes of the RED, which looking at your data structure for Master Boot Record Would be the: mbr->diskSignature, I think?

The Part I put in blue should be the 16 bytes associated with the first partition? With I believe the 5th byte being the type which in this case is 0xee?

But I am probably missing something!
 
@KurtE

No I don't think you are missing anything - think you are right and I am wrong because when I first did it I got the same results as you then something got screwy with my sketch. Going to recopy it from the post and try again.

EDIT: Yep - told you I screwed something up:
Code:
Master Boot Record
  Partition: 0 Type: EE first Sector: 1 total Sectors: 4294967295
  Partition: 1 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 2 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 3 Type: 0 first Sector: 0 total Sectors: 0
 
Sounds like the same results of when I converted the IOMega drive from MBR to GPT...
Code:
Master Boot Record
  Partition: 0 Type: EE first Sector: 1 total Sectors: 4294967295
  Partition: 1 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 2 Type: 0 first Sector: 0 total Sectors: 0
  Partition: 3 Type: 0 first Sector: 0 total Sectors: 0
 
Yep. Interesting if you look at that MS link I posted the data printed for the first sector of the first partition contains the "GUID Partition Table Header". Have to disappear for a while otherwise I would create another structure for the GUID Header. Always happens when I start to figure things out. :)

REF: https://docs.microsoft.com/en-us/pre...39412(v=ws.10)
 
Back
Top