User Tools

Site Tools


blog:pushbx:2022:1107_ldos_boot_loader_review

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
blog:pushbx:2022:1107_ldos_boot_loader_review [2022-11-07 21:39:05 +0100 Nov Mon]
ecm [read_sector hardening, optimisations]
blog:pushbx:2022:1107_ldos_boot_loader_review [2022-11-13 15:21:17 +0100 Nov Sun]
ecm [read_sector hardening, optimisations] code format register names
Line 40: Line 40:
 In any case, today I noticed that the ever-crucial read_sector function of ldosboot and also lDebug could be optimised a bit. The savings were 3 bytes in the FAT12 and FAT16 and FAT32 loaders and 5 bytes in the initial loader. What actually made me stumble on this was a vaguely recalled comment that there are ROM-BIOS implementations of the LBA extensions that require ''es'' to be set to the buffer segment, even though for the extensions the buffer address is supposed to be passed in the disk access packet. In any case, today I noticed that the ever-crucial read_sector function of ldosboot and also lDebug could be optimised a bit. The savings were 3 bytes in the FAT12 and FAT16 and FAT32 loaders and 5 bytes in the initial loader. What actually made me stumble on this was a vaguely recalled comment that there are ROM-BIOS implementations of the LBA extensions that require ''es'' to be set to the buffer segment, even though for the extensions the buffer address is supposed to be passed in the disk access packet.
  
-Cue my surprise at finding that setting es unconditionally, before the LBA or CHS dispatching, actually saved a few precious bytes! This is because we previously pushed the input bx (data target segment) onto the stack and later loaded that into es, whereas es was not used other than to hold that exact value. So early on in read_sector we now do ''mov es, bx'' and leave it at that.+Cue my surprise at finding that setting ''es'' unconditionally, before the LBA or CHS dispatching, actually saved a few precious bytes! This is because we previously pushed the input ''bx'' (data target segment) onto the stack and later loaded that into ''es'', whereas ''es'' was not used other than  to hold that exact value. So early on in read_sector we now do ''mov es, bx'' and leave it at that.
  
 During adaptation of this patch to the initial loader and the test status writer kernel we had to carefully consider the different paths. In addition to the plain LBA read and CHS read, both of them also have a "sector segment" assisted read (again LBA and CHS). That means when a data boundary error (code 09h) is returned constantly, the read is done into the aligned "sector segment" and then copied to the target. In addition to that, the test writer also has write functions for all four cases: LBA, LBA sectorseg, CHS, and CHS sectorseg. During adaptation of this patch to the initial loader and the test status writer kernel we had to carefully consider the different paths. In addition to the plain LBA read and CHS read, both of them also have a "sector segment" assisted read (again LBA and CHS). That means when a data boundary error (code 09h) is returned constantly, the read is done into the aligned "sector segment" and then copied to the target. In addition to that, the test writer also has write functions for all four cases: LBA, LBA sectorseg, CHS, and CHS sectorseg.
Line 49: Line 49:
 ==== The lDebug bug ==== ==== The lDebug bug ====
  
-During testing lDDebug within qemu, tracing the sectorseg read/write LBA/CHS cases, it happened to be the case that sectorseg reading loaded a random value into cx to copy the data from the sector segment to the target. The desired value would have been 200h, or 512. This happened because lDebug's branch of the sector access handling uses ds to address its data segment with the BPB in use, including the word holding the sector size in bytes. During coding of its sectorseg read handling it wasn't noticed that ds was set to address the source for rep movsb (ie, the sector segment) before loading cx from the sector size variable using the ds. So it ended up accessing a random word somewhere in memory.+During testing lDDebug within qemu, tracing the sectorseg read/write LBA/CHS cases, it happened to be the case that sectorseg reading loaded a random value into ''cx'' to copy the data from the sector segment to the target. The desired value would have been 200h, or 512. This happened because lDebug's branch of the sector access handling uses ''ds'' to address its data segment with the BPB in use, including the word holding the sector size in bytes. During coding of its sectorseg read handling it wasn't noticed that ''ds'' was set to address the source for ''rep movsb'' (ie, the sector segment) before loading ''cx'' from the sector size variable using the ''ds''. So it ended up accessing a random word somewhere in memory.
  
  
blog/pushbx/2022/1107_ldos_boot_loader_review.txt ยท Last modified: 2022-11-13 15:21:17 +0100 Nov Sun by ecm