User Tools

Site Tools


blog:pushbx:2024:0204_various_freedos_boot_sector_loaders_memory_overlap_cases

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

blog:pushbx:2024:0204_various_freedos_boot_sector_loaders_memory_overlap_cases [2024-02-04 12:47:25 +0100 Feb Sun] (current)
ecm created
Line 1: Line 1:
 +====== Various FreeDOS boot sector loaders memory overlap cases ======
 +
 +I created several test cases to figure out how some of the FreeDOS loaders can exhibit memory overlap in some conditions. I uploaded all the files involved (except for the repos, qemu, and NASM) to https://pushbx.org/ecm/test/20240204/
 +
 +===== Common preparation =====
 +
 +  * Install qemu (''qemu-system-i386'') and NASM
 +  * Get ''kernel.sys'' from https://pushbx.org/ecm/download/fdkernel.zip (also shown below)
 +  * Get ''command.com'' from https://pushbx.org/ecm/download/freecom.zip (also shown below)
 +  * Get ''himemx.exe'' from https://github.com/Baron-von-Riedesel/HimemX/releases/tag/v3.38
 +  * Get ''ldebug.com'', ''lddebug.com'', ''extlib.eld'', ''quit.com'', ''instsect.com'' from lDebug
 +  * Get the repos for lmacros, ldosboot, ldosmbr, bootimg from https://hg.pushbx.org/ecm/
 +  * Get the repo for the kernel from https://github.com/FDOS/kernel
 +  * Create ''int3.com'' (hexadecimal dump: ''CC B8 00 4C CD 21'')
 +  * Create the files ''fdconfig.sys'', ''makk128.bat'', ''callmakk.bat'' (contents shown below)
 +
 +<code>
 +disktest$ unzip -jq ~/wwwecm/download/fdkernel.zip bin/kernel.sys
 +disktest$ unzip -jq ~/wwwecm/download/freecom.zip command.com
 +disktest$ dd if=/dev/zero bs=1024 count=128 | tr '\0' '\377' > k128kib1.sys
 +128+0 records in
 +128+0 records out
 +131072 bytes (131 kB, 128 KiB) copied, 0.000498291 s, 263 MB/s
 +disktest$ dd if=/dev/zero bs=1024 count=128 > k128kib0.sys
 +128+0 records in
 +128+0 records out
 +131072 bytes (131 kB, 128 KiB) copied, 0.000682236 s, 192 MB/s
 +disktest$ dd if=../ldebug/bin/lddebug.com of=k128kib0.sys conv=notrunc
 +169+0 records in
 +169+0 records out
 +86528 bytes (87 kB, 84 KiB) copied, 0.00103689 s, 83.4 MB/s
 +disktest$ dd if=../ldebug/bin/lddebug.com of=k128kib1.sys conv=notrunc
 +169+0 records in
 +169+0 records out
 +86528 bytes (87 kB, 84 KiB) copied, 0.00120152 s, 72.0 MB/s
 +disktest$ cat fdconfig.sys
 +switches=/f
 +files=128
 +device=a:\himemx.exe /verbose /method:bios
 +shell=a:\command.com /e:2048 /p:fdautoex.bat
 +disktest$ file fdconfig.sys
 +fdconfig.sys: ASCII text, with CRLF line terminators
 +disktest$ cat makk128.bat
 +c:instsect c: /f=k128kib0.sys /b=c:\k128kib0.bin /s12=c:\boot12.bin /s16=c:\boot16.bin /s32=c:\boot32.bin
 +c:instsect c: /f=k128kib1.sys /b=c:\k128kib1.bin /s12=c:\boot12.bin /s16=c:\boot16.bin /s32=c:\boot32.bin
 +disktest$ file makk128.bat
 +makk128.bat: ASCII text, with CRLF line terminators
 +disktest$ cat callmakk.bat
 +call c:makk128.bat
 +quit
 +disktest$ file callmakk.bat
 +callmakk.bat: ASCII text, with CRLF line terminators
 +disktest$
 +</code>
 +
 +===== Assemble loaders =====
 +
 +Assemble the boot sector loaders in the kernel repo, using the revision created by https://github.com/FDOS/kernel/pull/120
 +
 +<code>
 +kernel/boot$ nasm boot.asm -DISFAT12 -o boot12.bin -l boot12.lst
 +kernel/boot$ nasm boot.asm -DISFAT16 -o boot16.bin -l boot16.lst
 +kernel/boot$ nasm boot32.asm -o boot32.bin -l boot32.lst
 +kernel/boot$ nasm boot32lb.asm -o boot32lb.bin -l boot32lb.lst
 +</code>
 +
 +
 +===== Prepare hard disk images =====
 +
 +Preparing a FAT12 image looks like this:
 +
 +''disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=12 -o k128f12.img -D_PAYLOADFILE=k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,::rename,boot32lb.bin,boot32.bin,instsect.com,makk128.bat''
 +
 +Preparing a FAT32 image with the 386+ LBA loader looks like this (note the changed BPE and output filename):
 +
 +''disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=32 -o k128f321.img -D_PAYLOADFILE=k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,::rename,boot32lb.bin,boot32.bin,instsect.com,makk128.bat''
 +
 +Preparing a FAT32 image with the 386+ LBA loader and the padded directory looks like this (note the ::directorypad keyword and output filename):
 +
 +''disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=32 -o k128f322.img -D_PAYLOADFILE=::directorypad,$(%%%%(256 * 512 / 32)),k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,::rename,boot32lb.bin,boot32.bin,instsect.com,makk128.bat''
 +
 +The same commands are used to create k128f323.img and k128f324.img, except that ''::rename,boot32lb.bin,'' is dropped.
 +
 +
 +==== Preparation of all hard disk images ====
 +
 +All the preparation for creating the boot images:
 +
 +<code>
 +disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=12 -o k128f12.img -D_PAYLOADFILE=k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,::rename,boot32lb.bin,boot32.bin,instsect.com,makk128.bat
 +disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=32 -o k128f321.img -D_PAYLOADFILE=k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,::rename,boot32lb.bin,boot32.bin,instsect.com,makk128.bat
 +../bootimg/bootimg.asm:522: warning: FAT would be detected as FAT12 (39 = 27h clusters) [-w+user]
 +disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=32 -o k128f322.img -D_PAYLOADFILE=::directorypad,$((256 * 512 / 32)),k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,::rename,boot32lb.bin,boot32.bin,instsect.com,makk128.bat
 +../bootimg/bootimg.asm:522: warning: FAT would be detected as FAT12 (39 = 27h clusters) [-w+user]
 +disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=32 -o k128f323.img -D_PAYLOADFILE=k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,boot32.bin,instsect.com,makk128.bat
 +../bootimg/bootimg.asm:522: warning: FAT would be detected as FAT12 (39 = 27h clusters) [-w+user]
 +disktest$ nasm -I ../kernel/boot/ -I ../lmacros/ -I ../ldebug/bin/ ../bootimg/bootimg.asm -D_MBR -D_MEDIAID=0F8h -D_UNIT=80h -D_SPC=256 -D_SPI=10240 -D_SPF=1 -D_ERROR_SMALL32=0 -D_BPE=32 -o k128f324.img -D_PAYLOADFILE=::directorypad,$((256 * 512 / 32)),k128kib0.sys,k128kib1.sys,extlib.eld,boot12.bin,boot16.bin,boot32.bin,instsect.com,makk128.bat
 +../bootimg/bootimg.asm:522: warning: FAT would be detected as FAT12 (39 = 27h clusters) [-w+user]
 +disktest$
 +</code>
 +
 +
 +==== Create the chain files ====
 +
 +To create the boot sector loader chain files for k128f12.img (the FAT12 image):
 +
 +''disktest$ nasm -l oldmbr.lst ../ldosmbr/oldmbr.asm -I ../lmacros/ -o oldmbr.bin; nasm -l boot12fd.lst ../ldosboot/boot.asm -I ../lmacros/ -D_COMPAT_FREEDOS -D_LBA=0 -D_USE_PART_INFO=0 -o boot12fd.bin; nasm ../bootimg/bootimg.asm -I ../lmacros/ -I ../ldebug/bin/ -o diskette.img -D_ALIGNDATA=0 -D_BOOTPATCHFILE=boot12fd.bin -D_MBRPATCHFILE=oldmbr.bin -D_PAYLOADFILE=ldebug.com,quit.com,kernel.sys,command.com,::rename,callmakk.bat,fdautoex.bat,fdconfig.sys,int3.com,himemx.exe,extlib.eld -D_ERROR_SMALL32=0 -D_BOOTINFOFILE=::bootpatchfile && qemu-system-i386 -fda diskette.img -boot order=a -display curses -hda k128f12.img''
 +
 +The parameter after ''-hda'' is swapped to create the chain files for the FAT32 images.
 +
 +
 +===== Running the loaders =====
 +
 +==== Prepare the serial terminal ====
 +
 +To use the serial I/O of lDebug on a Linux host, you can run socat as in:
 +
 +''$ socat -r /tmp/trace.log pty,link=/tmp/vptty-dos,rawer pty,link=/tmp/vptty-linux,rawer & disown''
 +
 +Then picocom like: ''picocom /tmp/vptty-linux''
 +
 +
 +==== Running qemu ====
 +
 +Finally, run qemu like so:
 +
 +''disktest$ nasm -l oldmbr.lst ../ldosmbr/oldmbr.asm -I ../lmacros/ -o oldmbr.bin; nasm -l boot12ld.lst ../ldosboot/boot.asm -I ../lmacros/ -D_LOAD_NAME="'LDEBUG'" -o boot12ld.bin; nasm ../bootimg/bootimg.asm -I ../lmacros/ -I ../ldebug/bin/ -o diskette.img -D_ALIGNDATA=0 -D_BOOTPATCHFILE=boot12ld.bin -D_MBRPATCHFILE=oldmbr.bin -D_PAYLOADFILE=ldebug.com,quit.com,kernel.sys,command.com,::fill,1,32,fdautoex.bat,fdconfig.sys,int3.com,himemx.exe,extlib.eld -D_ERROR_SMALL32=0 -D_BOOTINFOFILE=::bootpatchfile && qemu-system-i386 -fda diskette.img -boot order=a -display curses -chardev serial,id=serial2,path=/tmp/vptty-dos -serial null -serial chardev:serial2 -hda k128f12.img''
 +
 +(Replace the parameter after ''-hda'' with the other filenames to run the FAT32 loaders.)
 +
 +
 +==== Running the chainloaders ====
 +
 +Once the lDebug command line prompts for input (with a ''-'' dash prompt), enter a BOOT command like ''boot protocol chain hda1/k128kib0.bin'' or ''boot protocol chain hda1/k128kib1.bin''. If it is expected to work, run a ''g'' command and the lDDebug prompt (tilde dash, ''~-'') should show up. Entering ''q'' to lDDebug will return control to the lDebug instance.
 +
 +At the lDebug prompt, enter ''install timer, serial'' to connect to the serial terminal. This will prompt the serial terminal for a "KEEP" keyword confirmation.
 +
 +
 +===== FAT12: Higher /L segments will overwrite the cluster list =====
 +
 +The FAT12 loader (in k128f12.img) will run as expected by default. However, if the load segment (FreeDOS SYS /L switch) is set to a larger value than the usual 60h or 70h, such as 200h, then the loader will corrupt its cluster list once it has read the full first cluster of the kernel file. If the kernel file is padded with zeros then the cluster list will be corrupted with zeroes, which happen to be the End Of Chain marker. However, if the file contains other data such as all-1s in the trail then the cluster list will be corrupted differently, leading to errors.
 +
 +<code>
 +-boot protocol chain hda1/k128kib0.bin
 +-e cs:7C5C
 +0000:7C5C  60.00   00.02
 +</code>
 +
 +Patch the /L parameter address to 200h:0 rather than 60h:0.
 +
 +<code>
 +-p 10 silent 1
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BA0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C66 NV UP EI PL ZR NA PE NC
 +1FE0:7C66 885624            mov     [bp+24], dl                      SS:7C24=80
 +</code>
 +
 +Skip the initial relocation of the loader, to allow to use breakpoints next.
 +
 +<code>
 +-g 7CE3
 +AX=0002 BX=0000 CX=0000 DX=0080 SP=7BA0 BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7CE3 NV UP EI PL ZR NA PE NC
 +1FE0:7CE3 50                push    ax
 +</code>
 +
 +Skip to where the directory scan has found the file.
 +
 +<code>
 +-p
 +AX=0002 BX=0000 CX=0000 DX=0080 SP=7B9E BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7CE4 NV UP EI PL ZR NA PE NC
 +1FE0:7CE4 C45E5A            les     bx, [bp+5A]               SS:7C5A=0200:0000
 +-
 +AX=0002 BX=0000 CX=0000 DX=0080 SP=7B9E BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7CE7 NV UP EI PL ZR NA PE NC
 +1FE0:7CE7 8B7E16            mov     di, [bp+16]                    SS:7C16=0001
 +-
 +AX=0002 BX=0000 CX=0000 DX=0080 SP=7B9E BP=7C00 SI=7DFC DI=0001
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7CEA NV UP EI PL ZR NA PE NC
 +1FE0:7CEA 8B46D2            mov     ax, [bp-2E]                    SS:7BD2=0025
 +-
 +AX=0025 BX=0000 CX=0000 DX=0080 SP=7B9E BP=7C00 SI=7DFC DI=0001
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7CED NV UP EI PL ZR NA PE NC
 +1FE0:7CED 8B56D4            mov     dx, [bp-2C]                    SS:7BD4=0000
 +-
 +AX=0025 BX=0000 CX=0000 DX=0000 SP=7B9E BP=7C00 SI=7DFC DI=0001
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7CF0 NV UP EI PL ZR NA PE NC
 +1FE0:7CF0 E86C00            call    7D5F
 +-
 +AX=0020 BX=0000 CX=0004 DX=0080 SP=7B9E BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=0220 SS=1FE0 CS=1FE0 IP=7CF3 NV UP EI PL ZR NA PE NC
 +1FE0:7CF3 58                pop     ax
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=0220 SS=1FE0 CS=1FE0 IP=7CF4 NV UP EI PL ZR NA PE NC
 +1FE0:7CF4 1E                push    ds
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7B9E BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=0220 SS=1FE0 CS=1FE0 IP=7CF5 NV UP EI PL ZR NA PE NC
 +1FE0:7CF5 07                pop     es
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=7DFC DI=0000
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CF6 NV UP EI PL ZR NA PE NC
 +1FE0:7CF6 8E5E5C            mov     ds, [bp+5C]                    SS:7C5C=0200
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=7DFC DI=0000
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CF9 NV UP EI PL ZR NA PE NC
 +1FE0:7CF9 BF0020            mov     di, 2000
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=7DFC DI=2000
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CFC NV UP EI PL ZR NA PE NC
 +1FE0:7CFC AB                stosw
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=7DFC DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CFD NV UP EI PL ZR NA PE NC
 +1FE0:7CFD 89C6              mov     si, ax
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0002 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CFF NV UP EI PL ZR NA PE NC
 +1FE0:7CFF 01F6              add     si, si
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0004 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D01 NV UP EI PL NZ NA PO NC
 +1FE0:7D01 01C6              add     si, ax
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0006 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D03 NV UP EI PL NZ NA PE NC
 +1FE0:7D03 D1EE              shr     si, 1
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0003 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D05 NV UP EI PL NZ NA PE NC
 +1FE0:7D05 AD                lodsw
 +-
 +AX=FFFF BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D06 NV UP EI PL NZ NA PE NC
 +1FE0:7D06 7304              jae     7D0C                                jumping
 +-
 +AX=FFFF BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D0C NV UP EI PL NZ NA PE NC
 +1FE0:7D0C 80E40F            and     ah, 0F
 +-
 +AX=0FFF BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D0F NV UP EI PL NZ NA PE NC
 +1FE0:7D0F 3DF80F            cmp     ax, 0FF8
 +-
 +AX=0FFF BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D12 NV UP EI PL NZ NA PO NC
 +1FE0:7D12 72E8              jb      7CFC                            not jumping
 +-
 +AX=0FFF BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D14 NV UP EI PL NZ NA PO NC
 +1FE0:7D14 31C0              xor     ax, ax
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2002
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D16 NV UP EI PL ZR NA PE NC
 +1FE0:7D16 AB                stosw
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2004
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D17 NV UP EI PL ZR NA PE NC
 +1FE0:7D17 0E                push    cs
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7B9E BP=7C00 SI=0005 DI=2004
 +DS=0200 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D18 NV UP EI PL ZR NA PE NC
 +1FE0:7D18 1F                pop     ds
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2004
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7D19 NV UP EI PL ZR NA PE NC
 +1FE0:7D19 C45E5A            les     bx, [bp+5A]               SS:7C5A=0200:0000
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=0005 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D1C NV UP EI PL ZR NA PE NC
 +1FE0:7D1C BE0020            mov     si, 2000
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2000 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D1F NV UP EI PL ZR NA PE NC
 +1FE0:7D1F AD                lodsw
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D20 NV UP EI PL ZR NA PE NC
 +1FE0:7D20 09C0              or      ax, ax
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D22 NV UP EI PL NZ NA PO NC
 +1FE0:7D22 7505              jnz     7D29                                jumping
 +-
 +AX=0002 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D29 NV UP EI PL NZ NA PO NC
 +1FE0:7D29 48                dec     ax
 +-
 +AX=0001 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D2A NV UP EI PL NZ NA PO NC
 +1FE0:7D2A 48                dec     ax
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D2B NV UP EI PL ZR NA PE NC
 +1FE0:7D2B 8B7E0D            mov     di, [bp+0D]                    SS:7C0D=0100
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=0100
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D2E NV UP EI PL ZR NA PE NC
 +1FE0:7D2E 4F                dec     di
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=00FF
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D2F NV UP EI PL NZ AC PE NC
 +1FE0:7D2F 81E7FF00          and     di, 00FF
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=00FF
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D33 NV UP EI PL NZ NA PE NC
 +1FE0:7D33 47                inc     di
 +-
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=0100
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D34 NV UP EI PL NZ AC PE NC
 +1FE0:7D34 F7E7              mul     di
 +-
 +AX=0000 BX=0000 CX=0004 DX=0000 SP=7BA0 BP=7C00 SI=2002 DI=0100
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D36 NV UP EI PL ZR NA PE NC
 +1FE0:7D36 0346DA            add     ax, [bp-26]                    SS:7BDA=0035
 +-
 +AX=0035 BX=0000 CX=0004 DX=0000 SP=7BA0 BP=7C00 SI=2002 DI=0100
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D39 NV UP EI PL NZ NA PE NC
 +1FE0:7D39 1356DC            adc     dx, [bp-24]                    SS:7BDC=0000
 +-
 +AX=0035 BX=0000 CX=0004 DX=0000 SP=7BA0 BP=7C00 SI=2002 DI=0100
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D3C NV UP EI PL ZR NA PE NC
 +1FE0:7D3C E82000            call    7D5F
 +-p
 +AX=0020 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=0000
 +DS=1FE0 ES=2200 SS=1FE0 CS=1FE0 IP=7D3F NV UP EI PL ZR NA PE NC
 +1FE0:7D3F EBDE              jmp     7D1F
 +-
 +AX=0020 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=0000
 +DS=1FE0 ES=2200 SS=1FE0 CS=1FE0 IP=7D1F NV UP EI PL ZR NA PE NC
 +1FE0:7D1F AD                lodsw
 +-h linear es:0
 +00022000  decimal: 139264
 +-h linear ds:si
 +00021E02  decimal: 138754
 +-t
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2004 DI=0000
 +DS=1FE0 ES=2200 SS=1FE0 CS=1FE0 IP=7D20 NV UP EI PL ZR NA PE NC
 +1FE0:7D20 09C0              or      ax, ax
 +</code>
 +
 +The linear of ''es:0'' points past the last data read from the kernel file by the prior readDisk call. The linear of ''ds:si'' indicates where the next entry of the cluster list is read from. As is visible, the cluster list entry is located in memory below the end of the read file data.
 +
 +<code>
 +-boot protocol chain hda1/k128kib1.bin
 +-e cs:7C5C
 +0000:7C5C  60.00   00.02
 +-p 10 silent 1
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BA0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C66 NV UP EI PL ZR NA PE NC
 +1FE0:7C66 885624            mov     [bp+24], dl                      SS:7C24=80
 +-g 7D1F
 +AX=0000 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2000 DI=2004
 +DS=1FE0 ES=0200 SS=1FE0 CS=1FE0 IP=7D1F NV UP EI PL ZR NA PE NC
 +1FE0:7D1F AD                lodsw
 +-
 +AX=0020 BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2002 DI=0000
 +DS=1FE0 ES=2200 SS=1FE0 CS=1FE0 IP=7D1F NV UP EI PL ZR NA PE NC
 +1FE0:7D1F AD                lodsw
 +-h linear es:0
 +00022000  decimal: 139264
 +-h linear ds:si
 +00021E02  decimal: 138754
 +-t
 +AX=FFFF BX=0000 CX=0004 DX=0080 SP=7BA0 BP=7C00 SI=2004 DI=0000
 +DS=1FE0 ES=2200 SS=1FE0 CS=1FE0 IP=7D20 NV UP EI PL ZR NA PE NC
 +1FE0:7D20 09C0              or      ax, ax
 +-
 +</code>
 +
 +Same test case, except this time with the file ending in all-1s. It is plainly visible that the corrupted cluster list entry reads as 0FFFFh, which is invalid. Continuing the run with a G command to lDebug at this point results in the "Error!" display from the loader. A keypress then will return to the debugger, with the "Boot load called" interrupt message.
 +
 +The cutoff value of the /L load segment is that it works if the segment is 1E0h or lower, and fails if it is 1E1h or higher. This is also visible above in that the second cluster list entry is loaded from linear 21E02h which is just above the file data if an 128 KiB file is loaded to 1E00h (segmented 1E0h:0).
 +
 +<code>
 +lDebug connected to serial port. Enter KEEP to confirm.
 += keep
 +-boot protocol chain hda1/k128kib1.bin
 +-d cs:ip
 +0000:7C00  EB 3C 90 00 00 00 00 00-00 00 00 00 02 00 01 00 .<..............
 +0000:7C10  02 E0 00 00 28 F8 01 00-12 00 02 00 24 00 00 00 ....(.......$...
 +0000:7C20  00 00 00 00 80 00 29 00-00 00 00 4E 4F 20 4E 41 ......)....NO NA
 +0000:7C30  4D 45 20 20 20 20 46 41-54 31 32 20 20 20 FA FC ME    FAT12   ..
 +0000:7C40  31 C0 8E D8 BD 00 7C B8-E0 1F 8E C0 89 EE 89 EF 1.....|.........
 +0000:7C50  B9 00 01 F3 A5 EA 5E 7C-E0 1F 00 00 60 00 8E D8 ......^|....`...
 +0000:7C60  8E D0 8D 66 A0 FB 88 56-24 C7 46 C0 10 00 C7 46 ...f...V$.F....F
 +0000:7C70  C2 01 00 8C 5E C6 C7 46-C4 A0 63 8B 76 1C 8B 7E ....^..F..c.v..~
 +-e 0:7C5C as words 1E0
 +-g
 +Boot load called
 +</code>
 +
 +This works, the qemu terminal displays the lDDebug prompt.
 +
 +<code>
 +-boot protocol chain hda1/k128kib1.bin
 +-e 0:7C5C as words 1E1
 +-g
 +Boot load called
 +-
 +</code>
 +
 +This does not work, the qemu terminal displays the "Error!" message from the loader.
 +
 +
 +===== FAT32: 128 KiB file will be corrupted by FAT sector read =====
 +
 +This requires using k128f321.img or k128f323.img, the images that are formatted without the directory padding. Using k128f321.img (the LBA 386 loader):
 +
 +<code>
 +-boot protocol chain hda1/k128kib0.bin
 +-p 10 silent 1
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C82 NV UP EI PL ZR NA PE NC
 +1FE0:7C82 885640            mov     [bp+40], dl                      SS:7C40=80
 +</code>
 +
 +Skip the initial relocation.
 +
 +<code>
 +-
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C85 NV UP EI PL ZR NA PE NC
 +1FE0:7C85 BEC67D            mov     si, 7DC6
 +-
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DC6 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C88 NV UP EI PL ZR NA PE NC
 +1FE0:7C88 E8F900            call    7D84
 +-
 +AX=0E00 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C8B NV UP EI PL ZR NA PE NC
 +1FE0:7C8B 6631C0            xor     eax, eax
 +-
 +AX=0000 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C8E NV UP EI PL ZR NA PE NC
 +1FE0:7C8E 66894644          mov     [bp+44], eax               SS:7C44=4E000000
 +-
 +AX=0000 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C92 NV UP EI PL ZR NA PE NC
 +1FE0:7C92 8B460E            mov     ax, [bp+0E]                    SS:7C0E=0010
 +-
 +AX=0010 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C95 NV UP EI PL ZR NA PE NC
 +1FE0:7C95 6603461C          add     eax, [bp+1C]               SS:7C1C=00000024
 +-
 +AX=0034 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C99 NV UP EI PL NZ NA PO NC
 +1FE0:7C99 66894648          mov     [bp+48], eax               SS:7C48=414E204F
 +-
 +AX=0034 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C9D NV UP EI PL NZ NA PO NC
 +1FE0:7C9D 6689464C          mov     [bp+4C], eax               SS:7C4C=2020454D
 +-
 +AX=0034 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CA1 NV UP EI PL NZ NA PO NC
 +1FE0:7CA1 668B4610          mov     eax, [bp+10]               SS:7C10=00000002
 +-
 +AX=0002 BX=0000 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CA5 NV UP EI PL NZ NA PO NC
 +1FE0:7CA5 66F76E24          imul    dword [bp+24]              SS:7C24=00000001
 +-
 +AX=0002 BX=0000 CX=0000 DX=0000 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CA9 NV UP EI PL NZ NA PO NC
 +1FE0:7CA9 6601464C          add     [bp+4C], eax               SS:7C4C=00000034
 +-
 +AX=0002 BX=0000 CX=0000 DX=0000 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CAD NV UP EI PL NZ NA PE NC
 +1FE0:7CAD B80002            mov     ax, 0200
 +-
 +AX=0200 BX=0000 CX=0000 DX=0000 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CB0 NV UP EI PL NZ NA PE NC
 +1FE0:7CB0 3B460B            cmp     ax, [bp+0B]                    SS:7C0B=0200
 +-
 +AX=0200 BX=0000 CX=0000 DX=0000 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CB3 NV UP EI PL ZR NA PE NC
 +1FE0:7CB3 7408              jz      7CBD                                jumping
 +-
 +AX=0200 BX=0000 CX=0000 DX=0000 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CBD NV UP EI PL ZR NA PE NC
 +1FE0:7CBD 668B462C          mov     eax, [bp+2C]               SS:7C2C=00000002
 +-
 +AX=0002 BX=0000 CX=0000 DX=0000 SP=7BE0 BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CC1 NV UP EI PL ZR NA PE NC
 +1FE0:7CC1 6650              push    eax
 +-
 +AX=0002 BX=0000 CX=0000 DX=0000 SP=7BDC BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CC3 NV UP EI PL ZR NA PE NC
 +1FE0:7CC3 E89600            call    7D5C
 +-
 +AX=0036 BX=0000 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CC6 NV UP EI PL NZ NA PE NC
 +1FE0:7CC6 724F              jb      7D17                            not jumping
 +-
 +AX=0036 BX=0000 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7CC8 NV UP EI PL NZ NA PE NC
 +1FE0:7CC8 C45E76            les     bx, [bp+76]               SS:7C76=0060:0000
 +-
 +AX=0036 BX=0000 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CCB NV UP EI PL NZ NA PE NC
 +1FE0:7CCB E8BC00            call    7D8A
 +-
 +AX=0037 BX=0200 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DD7 DI=7E00
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CCE NV UP EI PL NZ NA PE NC
 +1FE0:7CCE 31FF              xor     di, di
 +-
 +AX=0037 BX=0200 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DD7 DI=0000
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CD0 NV UP EI PL ZR NA PE NC
 +1FE0:7CD0 B90B00            mov     cx, 000B
 +-
 +AX=0037 BX=0200 CX=000B DX=0100 SP=7BDC BP=7C00 SI=7DD7 DI=0000
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CD3 NV UP EI PL ZR NA PE NC
 +1FE0:7CD3 BEF17D            mov     si, 7DF1
 +-
 +AX=0037 BX=0200 CX=000B DX=0100 SP=7BDC BP=7C00 SI=7DF1 DI=0000
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CD6 NV UP EI PL ZR NA PE NC
 +1FE0:7CD6 F3A6              repe    cmpsb
 +-
 +AX=0037 BX=0200 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CD8 NV UP EI PL ZR NA PE NC
 +1FE0:7CD8 7415              jz      7CEF                                jumping
 +-gt
 +AX=0037 BX=0200 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CEF NV UP EI PL ZR NA PE NC
 +1FE0:7CEF 26FF7509          push    word [es:di+09]                ES:0014=0000
 +</code>
 +
 +Skip until the directory scan has found its match.
 +
 +<code>
 +-p
 +AX=0037 BX=0200 CX=0000 DX=0100 SP=7BDA BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CF3 NV UP EI PL ZR NA PE NC
 +1FE0:7CF3 26FF750F          push    word [es:di+0F]                ES:001A=0003
 +-
 +AX=0037 BX=0200 CX=0000 DX=0100 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CF7 NV UP EI PL ZR NA PE NC
 +1FE0:7CF7 6658              pop     eax
 +-
 +AX=0003 BX=0200 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CF9 NV UP EI PL ZR NA PE NC
 +1FE0:7CF9 29DB              sub     bx, bx
 +-
 +AX=0003 BX=0000 CX=0000 DX=0100 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CFB NV UP EI PL ZR NA PE NC
 +1FE0:7CFB 6650              push    eax
 +-
 +AX=0003 BX=0000 CX=0000 DX=0100 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7CFD NV UP EI PL ZR NA PE NC
 +1FE0:7CFD E85C00            call    7D5C
 +-
 +AX=0136 BX=0000 CX=0000 DX=0100 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7D00 NV UP EI PL NZ NA PE NC
 +1FE0:7D00 720D              jb      7D0F                            not jumping
 +-
 +AX=0136 BX=0000 CX=0000 DX=0100 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7D02 NV UP EI PL NZ NA PE NC
 +1FE0:7D02 E88500            call    7D8A
 +-
 +AX=0137 BX=0200 CX=0000 DX=0100 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7D05 NV UP EI PL NZ NA PE NC
 +1FE0:7D05 4A                dec     dx
 +-
 +AX=0137 BX=0200 CX=0000 DX=00FF SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=0060 SS=1FE0 CS=1FE0 IP=7D06 NV UP EI PL NZ AC PE NC
 +1FE0:7D06 75FA              jnz     7D02                                jumping
 +-gnt
 +AX=0236 BX=0000 CX=0000 DX=0000 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D08 NV UP EI PL ZR NA PE NC
 +1FE0:7D08 6658              pop     eax
 +-t
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D0A NV UP EI PL ZR NA PE NC
 +1FE0:7D0A E81600            call    7D23
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D23 NV UP EI PL ZR NA PE NC
 +1FE0:7D23 06                push    es
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D24 NV UP EI PL ZR NA PE NC
 +1FE0:7D24 57                push    di
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD6 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D25 NV UP EI PL ZR NA PE NC
 +1FE0:7D25 53                push    bx
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D26 NV UP EI PL ZR NA PE NC
 +1FE0:7D26 89C7              mov     di, ax
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=0003
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D28 NV UP EI PL ZR NA PE NC
 +1FE0:7D28 C1E702            shl     di, 02
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D2B NV UP EI PL NZ NA PE NC
 +1FE0:7D2B 50                push    ax
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D2C NV UP EI PL NZ NA PE NC
 +1FE0:7D2C 8B460B            mov     ax, [bp+0B]                    SS:7C0B=0200
 +-
 +AX=0200 BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D2F NV UP EI PL NZ NA PE NC
 +1FE0:7D2F 48                dec     ax
 +-
 +AX=01FF BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D30 NV UP EI PL NZ AC PE NC
 +1FE0:7D30 21C7              and     di, ax
 +-
 +AX=01FF BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D32 NV UP EI PL NZ NA PE NC
 +1FE0:7D32 58                pop     ax
 +-
 +AX=0003 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D33 NV UP EI PL NZ NA PE NC
 +1FE0:7D33 66C1E807          shr     eax, 07
 +-
 +AX=0000 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D37 NV UP EI PL ZR NA PE NC
 +1FE0:7D37 66034648          add     eax, [bp+48]               SS:7C48=00000034
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D3B NV UP EI PL NZ NA PO NC
 +1FE0:7D3B BB0020            mov     bx, 2000
 +-
 +AX=0034 BX=2000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D3E NV UP EI PL NZ NA PO NC
 +1FE0:7D3E 8EC3              mov     es, bx
 +-
 +AX=0034 BX=2000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D40 NV UP EI PL NZ NA PO NC
 +1FE0:7D40 29DB              sub     bx, bx
 +-p
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D42 NV UP EI PL ZR NA PE NC
 +1FE0:7D42 663B4644          cmp     eax, [bp+44]               SS:7C44=00000000
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D46 NV UP EI PL NZ NA PO NC
 +1FE0:7D46 7407              jz      7D4F                            not jumping
 +</code>
 +
 +This comparison checks whether the requested FAT sector has been read yet. In this case, it has not (no FAT sector at all is loaded yet) so the branch is not taken, so as to read in the FAT sector next.
 +
 +<code>
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D48 NV UP EI PL NZ NA PO NC
 +1FE0:7D48 66894644          mov     [bp+44], eax               SS:7C44=00000000
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D4C NV UP EI PL NZ NA PO NC
 +1FE0:7D4C E83B00            call    7D8A
 +-p
 +AX=0035 BX=0200 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D4F NV UP EI PL NZ NA PE NC
 +1FE0:7D4F 268065030F        and     byte [es:di+03], 0F              ES:000F=0F
 +-
 +AX=0035 BX=0200 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D54 NV UP EI PL NZ NA PE NC
 +1FE0:7D54 26668B05          mov     eax, [es:di]               ES:000C=0FFFFFFF
 +</code>
 +
 +The sector having been read, this loads the correct FAT entry from the sector.
 +
 +<code>
 +-
 +AX=FFFF BX=0200 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D58 NV UP EI PL NZ NA PE NC
 +1FE0:7D58 5B                pop     bx
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BD6 BP=7C00 SI=7DFC DI=000C
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D59 NV UP EI PL NZ NA PE NC
 +1FE0:7D59 5F                pop     di
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D5A NV UP EI PL NZ NA PE NC
 +1FE0:7D5A 07                pop     es
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D5B NV UP EI PL NZ NA PE NC
 +1FE0:7D5B C3                retn
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D0D NV UP EI PL NZ NA PE NC
 +1FE0:7D0D EBEC              jmp     7CFB
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BDC BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7CFB NV UP EI PL NZ NA PE NC
 +1FE0:7CFB 6650              push    eax
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7CFD NV UP EI PL NZ NA PE NC
 +1FE0:7CFD E85C00            call    7D5C
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D00 NV UP EI PL NZ NA PO CY
 +1FE0:7D00 720D              jb      7D0F                                jumping
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0000 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D0F NV UP EI PL NZ NA PO CY
 +1FE0:7D0F 8A5640            mov     dl, [bp+40]                      SS:7C40=80
 +-
 +AX=FFFF BX=0000 CX=0000 DX=0080 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D12 NV UP EI PL NZ NA PO CY
 +1FE0:7D12 88D3              mov     bl, dl
 +-
 +AX=FFFF BX=0080 CX=0000 DX=0080 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D14 NV UP EI PL NZ NA PO CY
 +1FE0:7D14 FF6E76            jmp     far [bp+76]               SS:7C76=0060:0000
 +-
 +AX=FFFF BX=0080 CX=0000 DX=0080 SP=7BD8 BP=7C00 SI=7DFC DI=000B
 +DS=1FE0 ES=2060 SS=1FE0 CS=0060 IP=0000 NV UP EI PL NZ NA PO CY
 +0060:0000 4D                dec     bp
 +-d 2000:0 l 100
 +2000:0000  F8 FF FF 0F FF FF FF 0F-FF FF FF 0F FF FF FF 0F ................
 +2000:0010  FF FF FF 0F 06 00 00 00-FF FF FF 0F FF FF FF 0F ................
 +2000:0020  FF FF FF 0F FF FF FF 0F-FF FF FF 0F FF FF FF 0F ................
 +2000:0030  FF FF FF 0F FF FF FF 0F-00 00 00 00 00 00 00 00 ................
 +2000:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0080  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0090  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +-
 +</code>
 +
 +The file data in the area 600h to below 20600h is corrupted with the FAT sector data at 20000h to 201FFh.
 +
 +
 +The same test with the trailing all-1s file makes it clearer that the file data is corrupted:
 +
 +<code>
 +-boot protocol chain hda1/k128kib1.bin
 +-p 10 silent 1                        
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C82 NV UP EI PL ZR NA PE NC
 +1FE0:7C82 885640            mov     [bp+40], dl                      SS:7C40=80
 +-g 7D14                               
 +AX=FFFF BX=0080 CX=0000 DX=0080 SP=7BD8 BP=7C00 SI=7DFC DI=002B
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D14 NV UP EI PL NZ NA PO CY
 +1FE0:7D14 FF6E76            jmp     far [bp+76]               SS:7C76=0060:0000
 +-d 2000:0 l 210
 +2000:0000  F8 FF FF 0F FF FF FF 0F-FF FF FF 0F FF FF FF 0F ................
 +2000:0010  FF FF FF 0F 06 00 00 00-FF FF FF 0F FF FF FF 0F ................
 +2000:0020  FF FF FF 0F FF FF FF 0F-FF FF FF 0F FF FF FF 0F ................
 +2000:0030  FF FF FF 0F FF FF FF 0F-00 00 00 00 00 00 00 00 ................
 +2000:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0080  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0090  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0100  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0110  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0120  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0130  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0140  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0150  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0160  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0170  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0180  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0190  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0200  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
 +-
 +</code>
 +
 +The entire area of 20000h to below 20600h should be filled with 0FFh bytes. However, the FAT sector corrupts this area.
 +
 +
 +Using k128f323.img (the CHS 8086 FAT32 loader, without directory padding) the same error can be discovered:
 +
 +<code>
 +-boot protocol chain hda1/k128kib1.bin
 +-p 10 silent 1
 +AX=1FE0 BX=0080 CX=0000 DX=0F80 SP=7BE0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C82 NV UP EI PL ZR NA PE NC
 +1FE0:7C82 885640            mov     [bp+40], dl                      SS:7C40=80
 +-g 7D77
 +AX=FFFF BX=0000 CX=0111 DX=0FFF SP=7BD0 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2060 SS=1FE0 CS=1FE0 IP=7D77 NV UP EI PL NZ NA PO CY
 +1FE0:7D77 8A5640            mov     dl, [bp+40]                      SS:7C40=80
 +-d 2000:0 l 210
 +2000:0000  F8 FF FF 0F FF FF FF 0F-FF FF FF 0F FF FF FF 0F ................
 +2000:0010  FF FF FF 0F 06 00 00 00-FF FF FF 0F FF FF FF 0F ................
 +2000:0020  FF FF FF 0F FF FF FF 0F-FF FF FF 0F FF FF FF 0F ................
 +2000:0030  FF FF FF 0F FF FF FF 0F-00 00 00 00 00 00 00 00 ................
 +2000:0040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0080  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0090  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:00F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0100  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0110  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0120  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0130  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0140  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0150  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0160  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0170  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0180  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0190  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:01F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
 +2000:0200  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF ................
 +-
 +</code>
 +
 +
 +===== FAT32: 128 KiB file will corrupt FAT sector buffer =====
 +
 +This test, in turn, requires using the images that are formatted with the directory padding, that is k128f322.img or k128f324.img. The former ends up like so:
 +
 +<code>
 +lDebug connected to serial port. Enter KEEP to confirm.
 += keep
 +-boot protocol chain hda1/k128kib0.bin
 +-p 10 silent 1
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C82 NV UP EI PL ZR NA PE NC
 +1FE0:7C82 885640            mov     [bp+40], dl                      SS:7C40=80
 +</code>
 +
 +As before, skip the relocation.
 +
 +<code>
 +-g 7D42
 +AX=0034 BX=0000 CX=000A DX=0000 SP=7BD8 BP=7C00 SI=7DF2 DI=0008
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D42 NV UP EI PL ZR NA PE NC
 +1FE0:7D42 663B4644          cmp     eax, [bp+44]               SS:7C44=00000000
 +</code>
 +
 +This is the first time that next_cluster is called. It is caused by the root directory scanning continuing past the first root cluster, which we filled with empty deleted directory entries. No FAT sector is buffered yet, so past this comparison the function will load the first FAT sector.
 +
 +<code>
 +-g 7D42
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D42 NV UP EI PL ZR NA PE NC
 +1FE0:7D42 663B4644          cmp     eax, [bp+44]               SS:7C44=00000034
 +</code>
 +
 +This is the second time that next_cluster is called. In this case, it wants to read the FAT entry that corresponds to the first data cluster of the kernel file. As the FAT sector was already read prior, the variable matches the FAT sector to load. Therefore, the sector is not loaded again as it is expected that it was preserved.
 +
 +
 +<code>
 +-t
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D46 NV UP EI PL ZR NA PE NC
 +1FE0:7D46 7407              jz      7D4F                                jumping
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D4F NV UP EI PL ZR NA PE NC
 +1FE0:7D4F 268065030F        and     byte [es:di+03], 0F              ES:0013=00
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D54 NV UP EI PL ZR NA PE NC
 +1FE0:7D54 26668B05          mov     eax, [es:di]               ES:0010=00000000
 +-
 +AX=0000 BX=0000 CX=0000 DX=0000 SP=7BD4 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D58 NV UP EI PL ZR NA PE NC
 +1FE0:7D58 5B                pop     bx
 +-
 +</code>
 +
 +Turns out the FAT sector was actually overwritten by the file data, so when using the file with the trailing all-0s the code will read a zero as the content of the FAT entry. This is wrong, and results in a hang.
 +
 +
 +The same error can be observed with k128f324.img (the 8086 CHS loader):
 +
 +<code>
 +lDebug connected to serial port. Enter KEEP to confirm.
 += keep
 +-boot protocol chain hda1/k128kib0.bin
 +-p 10 silent 1
 +AX=1FE0 BX=0080 CX=0000 DX=0080 SP=7BE0 BP=7C00 SI=7E00 DI=7E00
 +DS=1FE0 ES=1FE0 SS=1FE0 CS=1FE0 IP=7C82 NV UP EI PL ZR NA PE NC
 +1FE0:7C82 885640            mov     [bp+40], dl                      SS:7C40=80
 +</code>
 +
 +As before, skip the relocation.
 +
 +<code>
 +-g 7D5A
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DF2 DI=0008
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D5A NV UP EI PL ZR NA PE NC
 +1FE0:7D5A 3B4648            cmp     ax, [bp+48]                    SS:7C48=0000
 +-t
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DF2 DI=0008
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D5D NV UP EI PL NZ NA PO NC
 +1FE0:7D5D 7505              jnz     7D64                                jumping
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DF2 DI=0008
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D64 NV UP EI PL NZ NA PO NC
 +1FE0:7D64 894648            mov     [bp+48], ax                    SS:7C48=0000
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DF2 DI=0008
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D67 NV UP EI PL NZ NA PO NC
 +1FE0:7D67 89564A            mov     [bp+4A], dx                    SS:7C4A=0000
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BDA BP=7C00 SI=7DF2 DI=0008
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D6A NV UP EI PL NZ NA PO NC
 +1FE0:7D6A E83D00            call    7DAA
 +</code>
 +
 +No FAT sector is loaded yet during root directory traversal. As the directory entry is not found in the first cluster, the next root cluster is loaded.
 +
 +<code>
 +-g 7D5A
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD0 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D5A NV UP EI PL ZR NA PE NC
 +1FE0:7D5A 3B4648            cmp     ax, [bp+48]                    SS:7C48=0034
 +-t
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD0 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D5D NV UP EI PL ZR NA PE NC
 +1FE0:7D5D 7505              jnz     7D64                            not jumping
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD0 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D5F NV UP EI PL ZR NA PE NC
 +1FE0:7D5F 3B564A            cmp     dx, [bp+4A]                    SS:7C4A=0000
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD0 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D62 NV UP EI PL ZR NA PE NC
 +1FE0:7D62 7409              jz      7D6D                                jumping
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD0 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D6D NV UP EI PL ZR NA PE NC
 +1FE0:7D6D 5B                pop     bx
 +-
 +AX=0034 BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D6E NV UP EI PL ZR NA PE NC
 +1FE0:7D6E 268B05            mov     ax, [es:di]                    ES:0010=0000
 +-
 +AX=0000 BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D71 NV UP EI PL ZR NA PE NC
 +1FE0:7D71 268B5502          mov     dx, [es:di+02]                 ES:0012=0000
 +-
 +AX=0000 BX=0000 CX=0000 DX=0000 SP=7BD2 BP=7C00 SI=7DFC DI=0010
 +DS=1FE0 ES=2000 SS=1FE0 CS=1FE0 IP=7D75 NV UP EI PL ZR NA PE NC
 +1FE0:7D75 07                pop     es
 +-
 +</code>
 +
 +The FAT sector is expected to be already loaded, but it was corrupted by the file data. Continuing after this will result in a division error interrupt from a ''div cx'' that expects to divide the sector number in order to calculate the CHS tuple. As the quotient overflows 16 bits, an interrupt 0 is fired.
 +
 +
 +===== Conclusion on FAT32 large file loader overlap =====
 +
 +The large file overlap only occurs if the file, rounded up to a cluster boundary, reaches close to 128 KiB. To be precise, a rounded up file size up to 129_536 Bytes (126.5 KiB) will not run into problems with the default /L load segment of 60h. If the cluster size is 128 KiB, the file will always run into problems. If it is 64 KiB, then a file larger than 64 KiB will run into problems. If it is 32 KiB, then a file larger than 96 KiB will run into problems. And so on.
 +
 +The nature of the overlap is determined by which FAT sectors are read, and when. To simplify the example, assume a 128 KiB cluster size and that the file has only one cluster (as in our test cases). If the first cluster of the file has its FAT entry in another sector than the last root directory FAT entry read, then the loader will read the new FAT sector and find the appropriate entry in it. This is also true if the root directory scan only accessed the first cluster of the root directory, as in that case no FAT sector is read by the scan at all.
 +
 +In this case, the trailing file data will be corrupted by the FAT sector, but the FAT sector is not corrupted. For a cluster size of 128 KiB, this case is very likely because 4_096 directory entries will fit in the first root cluster. (In the example tests, I had to pad the root directory with as many entries to force the directory scan to load a FAT sector.) If the actual file size is not larger than 126.5 KiB and the 128 KiB read occurs only because of rounding up to the cluster size, then the corruption is benign as it does not affect the actual file data read by the loader. Otherwise, the trail of the file data is corrupted.
 +
 +If the root directory scan did load a FAT sector and the same FAT sector is needed throughout until after more than 126.5 KiB of file data have been read, then the FAT sector is corrupted and the exact behaviour that results depends on the loader, what exact FAT entry it tries to read, and what trailing data from the file read has overwritten the FAT sector.
 +
 +Using a higher /L load segment than 60h will shrink the allowed rounded up size of the file before it runs into problems. For example, with ''/L 200'', the rounded up file size must not exceed 120 KiB.
 +
 +File sizes beyond 128 KiB will generally always be a problem and might overwrite any of the data structures, including the stack of the loader. The code is located in the 512 Bytes starting at 1FE0h:7C00h or linear 27A00h, while the stack lives below this address. So a read that corrupts the code would also corrupt the stack first, at which point a crash is almost entirely inevitable.
 +
 +{{tag>freedos ldebug instsect bootimg qemu}}
 +
 +
 +~~DISCUSSION~~
  
blog/pushbx/2024/0204_various_freedos_boot_sector_loaders_memory_overlap_cases.txt ยท Last modified: 2024-02-04 12:47:25 +0100 Feb Sun by ecm