Hi Chris, Bertho,

>> Dear List... I'm calling back with respect to the 4k-sector USB disk  
>> drive. I'm considering writing a loadable DOS 'block' driver for it, as  
>> Eric Auer suggested.
> This doesn't belong on Freedos-user then.

Maybe Czerno / Bertho is not on freedos-devel? Or maybe there is
simply too little traffic on freedos-devel, so he preferred to
give it a try on freedos-user... I am CCing -devel here, as the
kernel discussion is a bit separate: You can either patch that
or not, but you can always enjoy a new block device driver ;-)

>> I would like to take the simplest approach possible first

You could wait for the big sector size support patch to work
in the kernel - but of course I do like the idea of using a
block device driver to "hide" the actual sector size from a
DOS kernel, so DOS can I/O in 512 byte units. This is WORSE
speed-wise but BETTER kernel-RAM-usage-wise... And of course
it is the only chance to use 4k disks on old kernels at all.

>> - Using a loadable driver for the block device implies DOS won't
>> use /its/ internal buffers, so I don't have to care about DOS...

If your block device driver shows the DOS kernel a device
with 512 byte per sector "virtual" sectors then the kernel
will happily use 512 byte per sector BUFFERS for them...

However, your own driver will need one 4096 byte buffer
to do any I/O which is not mappable to aligned physical
4 kB sectors. For example imagine the following situation:

Real: ... aaaaaaaa bbbbbbbb ... (two sectors of 4k each)
Virt: ... ,,,,,,,X X,,,,,,, ... (DOS wants 1k of data)

Now you first read all aaaaaaaa into your buffer, copy
the first X to the start of the buffer of the caller,
then read all bbbbbbbb into your buffer, copy the 2nd
X to the end of the buffer of the caller. Note how you
read 8kB in two parts of 4kB each while your user only
wanted 1kB in one part. This is more or less the worst
case performance wise, other cases are better. If your
driver has a larger buffer, it gets a BIT better...

If the user wants to WRITE data, you will first have to
READ the whole 4kB sector, then overwrite the part that
the user wants to write, then write the whole sector to
disk, so you again get a performance loss.

If the user wants to read or write MORE data, you will
be lucky for the "middle" area of that data: Imagine a
write of 10 kB with a pretty unpleasant mis-alignment:

Real: aaaaaaaa bbbbbbbb cccccccc dddddddd

Now you can write sectors b and c as a whole and only
have to use your buffer and the read-modify-write style
access for the first 1 kB and the last 1 kB. You do not
have to read b or c, because they are fully overwritten.
So for large I/O transfers, performance loss is smaller.

As said, this is separate from what DOS BUFFERS will do
and each buffer of the kernel can buffer the usual 512
bytes, which is NICE for your other disks and your RAM.

> This is wrong. Block drivers directly interact with DOS and its buffering  
> scheme. If what you want is to circumvent the restrictions imposed by  
> DOS's buffering scheme (for example, current 512B-/2048B-sector limits of  
> the FDK) you'll have to write your own (FAT) file system driver which  
> interfaces downwards with the block device driver (in your case,  
> USBASPI.SYS) and upwards with DOS's file system redirector interface.

This is also wrong. Because the filesystem still is FAT
and the kernel does already understand FAT, your driver
can present your 4 kB per sector disk as a BLOCK device
or in other words: As a bunch of sectors. However, your
driver has to transform what the DOS kernel sees of the
boot sector and BPB, because the whole idea of having a
4 kB disk support driver for 512 byte per sector DOSes
is that it shows the kernel a bunch of 512 BYTE SECTORS
(virtual ones) instead of showing the real 4 kB sectors.

This DOES circumvent the limitation of the DOS kernel:
The kernel only sees 512 byte per sector "blocks". But
as explained above, now your driver will have to spend
at least 4 kB of buffer space for the transformations.

> redirector interface is what file system drivers for non-FAT file systems  
> (eg *CDEX) and networked file systems use to make their files accessible

That would mean that you duplicate the whole logics of
understanding the FAT filesystem into your driver. My
suggestion is a TRANSFORMATION of sector SIZES which
keeps things simple but SLOW: Everything stays FAT...

Of course if you want to support ISO9660, UDF, ExFAT,
NTFS, EXT2, EXT3, EXT4 or similar fancy filesystems,
there is efficient no way to make them look similar to
FAT at all. This is the reason why SHSUCDX, MSCDEX and
similar drivers are NOT block device drivers but, as
you say, are based on the CD / network redirector API.

NOTE: Transformation of sector sizes is easiest in FAT32.
Other FAT sizes may take more effort. Also, you can only
transform from 4096 byte units to 512 byte units if the
filesystem is at most 2 Terabytes and cluster size is at
most 32 or maybe 64 kilobytes. You CANNOT transform from
512 to 4096 usually, as format tools do not take care to
align things in a way that would make this easy enough.

Of course you CAN transform back a FAT32 partition from
an originally 4 kB per sector disk to 4 kB sector disks
after you accessed it in 512 byte units and even if you
actually stored it on a physically 512 byte per sector
disk and used it there. This only needs the boot sector
transform to be transformed back :-)

To prove this, I can send you two demo FAT32 filesystems:
They only differ in a few boot sector bytes, but one uses
512 bytes per "sector" and the other uses 4096 bytes :-)

Contact me off-list if you want a copy. The ZIP is only a
few kilobytes, but you will need 2 or 4 GB to unzip this!

Regards, Eric

Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
Freedos-user mailing list

Reply via email to