info-mtools
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Info-mtools] [PATCH] preserve info sector reserved fields


From: C. Masloch
Subject: [Info-mtools] [PATCH] preserve info sector reserved fields
Date: Mon, 19 Oct 2020 13:29:19 +0200

This allows the FSIBOOT stage of lDOS boot32.asm to remain
in the FSINFO sector even when the info entries are updated.

I reviewed several sources to determine whether we are in the right to
assume that the reserved 480 bytes used by FSIBOOT should be preserved
by drivers updating the FSINFO entry fields.

Quoting the document "Microsoft Extensible Firmware Initiative - FAT32
File System Specification - FAT: General Overview of On-Disk Format -
Version 1.03, December 6, 2000" on these bytes:

> [Name] FSI_Reserved1
>
> [Offset (byte)] 4
>
> [Size (bytes)] 480
>
> [Description] This field is currently reserved for future expansion.
FAT32 format code should always initialize all bytes of this field to 0.
Bytes in this field must currently never be used.

This specifically states that "FAT32 format code" should zero-initialise
this space. It does not specify that a driver should or should not reset
this space.

The FreeDOS kernel uses a struct [1] that does not include the space
used by FSIBOOT. Its driver's implementation [2] does preserve the
FSIBOOT area. I have verified this in dosemu2; if the FreeDOS kernel
updates the FSINFO sector it preserves this area.

The Linux kernel uses a struct with a "reserved1" member [3] which is
commented as being "Nothing as far as I can tell". If I am reading the
source correctly, its driver [4] also preserves this area when updating
the FSINFO entries.

Testing on MS-DOS version 7.10 (as bundled with MS Windows 98 SE) I
determined that it also preserves the area when updating the FSINFO entries.

The free software RxDOS/lDOS boot loader for FAT32 that I wrote uses
this reserved area to store its FSIBOOT stage, essentially an extension
to the primary boot sector loader. To avoid clashing with Microsoft
loaders which may use some of the reserved sectors, the large reserved
area in the FSINFO sector was selected to hold this stage (if sector
size is <= 512 bytes). If valid, the area starts with a signature [5]
the first four bytes of which form the letters "FSIB"; the subsequent
four bytes specify a protocol version. For example, the current
(non-experimental) version is "FSIBOOT3" [6].

If there is no FSINFO sector or the FSIBOOT signature does not match the
one expected, then the 'I' error code letter ("i"nvalid FS"I"BOOT) is
displayed and the loading is aborted [7]. Prior to this patch, using
mcopy of mtools to store a file in a FAT32 FS image would reset the
space used by FSIBOOT, rendering the image unbootable if the lDOS boot32
loader had been installed into the image.

I previously uploaded this patch [8] to a hg repo on the hgweb server
hosting most of my projects. I did not find an official SCM repo of
mtools so I simply extracted the 4.0.24 sources and committed them as
the initial commit of this repo.

[1]:
https://github.com/FDOS/kernel/blob/6e42bb6d7c6dd304f738cf0d7a2db719598f1b9e/hdr/device.h#L325
[2]:
https://github.com/FDOS/kernel/blob/6e42bb6d7c6dd304f738cf0d7a2db719598f1b9e/kernel/fattab.c#L116
[3]:
https://github.com/torvalds/linux/blob/7cf726a59435301046250c42131554d9ccc566b8/include/uapi/linux/msdos_fs.h#L163
[4]:
https://github.com/torvalds/linux/blob/7cf726a59435301046250c42131554d9ccc566b8/fs/fat/misc.c#L60
[5]: https://hg.ulukai.org/ecm/ldosboot/file/aa15fd7bc58e/boot32.asm#l1164
[6]: https://hg.ulukai.org/ecm/ldosboot/file/aa15fd7bc58e/boot32.asm#l27
[7]: https://hg.ulukai.org/ecm/ldosboot/file/aa15fd7bc58e/boot32.asm#l775
[8]: https://hg.ulukai.org/ecm/mtools/rev/d5f74b3a7c97

Here is the patch. I also attached it in an hg export format file, which
might be easier to work with or be better preserved across email.

diff --git a/fat.c b/fat.c
--- a/fat.c
+++ b/fat.c
@@ -454,9 +454,14 @@
                /* initialize info sector */
                InfoSector_t *infoSector;
                infoSector = (InfoSector_t *) safe_malloc(This->sector_size);
+               if(forceReadSector(This, (char *)infoSector,
+                                  This->infoSectorLoc, 1) !=
+                  (signed int) This->sector_size) {
+                       fprintf(stderr,"Trouble reading the info sector\n");
+                       memset(infoSector->filler1, 0, 
sizeof(infoSector->filler1));
+                       memset(infoSector->filler2, 0, 
sizeof(infoSector->filler2));
+               }
                set_dword(infoSector->signature1, INFOSECT_SIGNATURE1);
-               memset(infoSector->filler1, 0, sizeof(infoSector->filler1));
-               memset(infoSector->filler2, 0, sizeof(infoSector->filler2));
                set_dword(infoSector->signature2, INFOSECT_SIGNATURE2);
                set_dword(infoSector->pos, This->last);
                set_dword(infoSector->count, This->freeSpace);

Attachment: preserve-info-sector-reserved-fields.diff
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]