Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

INT25/26 fail for uninitialized FAT-12/16 partitions leading to format error #144

Closed
boeckmann opened this issue Mar 4, 2024 · 0 comments

Comments

@boeckmann
Copy link
Contributor

boeckmann commented Mar 4, 2024

Kernel returns 0x0207 in AX if INT 25/26 is called on an uninitialized FAT-16 partition, making format.exe fail to format a FAT-16 partition (see screenshots, formatting a 500MB FAT-16). This is at least for kernel versions 2043-master. Partition table is good. Error value suggests INT25/26 gives up at the following lines:

kernel/kernel/inthndlr.c

Lines 1835 to 1840 in 8552d83

if (dpbp != NULL && ISFAT32(dpbp))
{
r->ax = 0x207;
SET_CARRY_FLAG();
return;
}

The ISFAT32 macro seems to be involved, which tests dpb_fatsize for zero.The INT25/26 calls eventually succeed after querying the DPB via INT21,32 (after the DPB is rebuilt?!?), leading to the assumption that the dpb is not fully initialized after system boot (at least dpb_fatsize is likely zero, so ISFAT32 triggers erroneously).

This is originally from Willi Spiegl, noticing that he could not format a 500MB primary on the second disk with T2403, but the bug is likely to be older.

Screenshot 2024-03-04 010508
Screenshot 2024-03-04 010539

Minimal assembler example to verify 0x0207 is returned:

.model small
.stack 512
.data?
read_buf db 512 dup(?)

.data
  sect_num dd 0
  count dw 1
  buf_off dw offset read_buf
  buf_seg dw seg read_buf
  
.code
.startup
	mov al,3  ; drive D:
	mov bx,offset sect_num
	mov cx,0ffffh
	int 25h  ; read from it
	int 3  ; and bail out to lDebug
end
PerditionC pushed a commit that referenced this issue Mar 5, 2024
getbpb now returns 0 instead of S_DONE in case of an uninitialized
partition, copying the default BPB into the BPB.

The previous return of S_DONE in case of uninitialized partitions
resulted in rp->r_bpptr not getting set in bldbpb. This in
combination with indicating success resulted in garbage returned
via rp->r_bpptr.

The DPB values are now being set to the default BPB ones in media_check
https://github.com/FDOS/kernel/blob/ea951d8136444e334f06a313465b5844f738354e/kernel/fatfs.c#L1728
via call to bpb_to_dpb in case of an uninitialized partition.
This may have side effects. But because DF_NOACCESS is still set, I
think it is the right way to do it.

The commit also masks high bit of AL for INT25/26 containing the drive
number. Some programs may set the bit according to RBIL:

"examination of CPWIN386.CPL indicates that if this call fails with
error 0408h on an old-style (<32M) call, one should retry the
call with the high bit of the drive number in AL set"

Leaving the bit set may render the given drive number unusable.
It should do no harm to mask it to increase the chance of the operation
to succeed. Also, the AH should be set to zero, because drive is given
only in AL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant