jaclaz Posted April 15 Posted April 15 This is another useful source for NASM fiddling: http://goncharov.pp.ru/en/osboot.htm The makebootfat things always worked for me (with the notable exception of some InsideH2o ones), but as you well know BIOSes are strange things. And yes, the MINI-MBR approach is a very nice one. Unfortunately Nuno has disappeared from radars, so I believe that yes, reboot.pro is gone. I am still in contact (like once a year we send each other a ping) with erwan.l , he does have some old backup/archive of the board (mid 2020 if I recall correctly) that could - in theory - be possible to put again online as read only. But don't count too much on it. I am attaching the result of some of my old fiddling with the Anvin/Mazzoleni code, maybe it is useful to you. Mbr_NTFS_BS_001.zip
deomsh Posted April 17 Author Posted April 17 (edited) Thanks for the update on reboot.pro. Sad it's gone. Also posts from the time I became a member are not accessible with the Wayback machine, only the forum index at the time. I looked into Goncharov, looks nice. But no source code and although he uses partly open source licenced software, his own eula is quite strict: 'You may not modify, translate, reverse engineer, decompile, or disassemble this SOFTWARE.'. Your NTFS code looks nice. To slow down reading I made a disassembly of the binary included and started to fill in all labels until it made more sense to me. But I do not understand the function of 42h on offset 2. Is this only searched/written during boot? Also if directed into the PBR-code, number of hidden sectors is read-out. Must the full (HDD-) BPB written to the first sector too? Edited April 17 by deomsh
jaclaz Posted April 17 Posted April 17 (edited) From the source code (scarce) comments I wrote at the time, the 42 is just a flag of sorts, it is used to tell the bootcode what to load, if you prefer a switch: Quote ; So I digged a couple of holes in the NTFS bootstor code and placed the MBR code in these holes. ; The first time the sector is loaded, it will check whether the third byte in the memory address 0x0600 is 42 ; since it normally isn't (it is either 00 or 90) it will continue to load the code as "MBR" and write the 42 to the appropriate ; place, then it will proceed to copy "itself" to 0x7C00 and from it "reload itself", since in the meantime the 42 "flag" has been ; written, the executed code will be that of the bootsector instead. And yes, the first part of the "dual-use" mbr/pbr (up to the FA31C0) must be filled wit the original BPB of the NTFS volume, while the "dummy part entry" should be replaced with the actual volume size as partition data. Edited April 17 by jaclaz
deomsh Posted April 17 Author Posted April 17 Thanks for clarification. I'd run some tests om my 16MB USB flash drive, formatted as NTFS. To see if bootcode(s) are booting something, I copied NTLDR and NTDETECT.COM to the USB drive. Tests on my AMI BIOS with USB legacy, looked the same as earlier, I reached messages missing BOOT.INI etc. so no problem booting as such. Same with your boot code, but also without any bootcode in the MBR like earlier with IO.SYS and 63 Sectors Per Track. So no real test possible with this setup. I used HxD as Admin under Windows 10 to transplant your MBR and the BPB into it. But when I inserted my USB drive again in my Windows 10 computer, it was given same drive letter as before, but no access to the drive anymore. Windows 10 wanted to format the drive. I experimented a bit, the OEM seems to be the culprit. Only if I changed 'NTFS ' to 'JTFS ', I got (immediate) access to the USB drive again. The full binary content from this USB drive copied to an image booted nice in Virtual Box. But too with EB 52 42 and NOT using the full BPB, even with only MediaByte F8h and DriveNum 80h with all other fields zero (like in your binary). I will try my emulator later (running in Qemu), so I am able to get full debug files (up to 1,000,000 instructions).
deomsh Posted April 18 Author Posted April 18 (edited) Tested two images of the 16MB USB drive in emulator.py. Bad news, but also really good news. The bad news is that the log's of MSSYS16NTFS_MBR_BOOT.instructions.log and MSSYS16NTFS_PBR_BOOT.instructions.log showed only one difference: So PBR-boot with 42h written at offset 2 and full BPB transplanted is not working in my emulator, it defaults to MBR-boot. Some highlights of the PBR-log: MSSYS16NTFS_PBR_BOOT.instructions.log [REGS] Initial register state: ax=0000 bx=0000 cx=0000 dx=0080 si=0000 di=0000 bp=0000 sp=7c00 cs=0000 ds=0000 ss=0000 es=0000 flags=0002 cf=0 zf=0 0000:7c00= 7c00|eb52 |jmp 0x7c54 0000:7c54= 7c54|fa |cli 0000:7c55= 7c55|31c0 |xor ax, ax|ax=0x0000 0000:7c57= 7c57|8ed0 |mov ss, ax|ax=0x0000 0000:7c59= 7c59|bc007c |mov sp, 0x7c00 0000:7c5c= 7c5c|fb |sti 0000:7c5d= 7c5d|a00206 |mov al, byte ptr [0x602]|mem[0x602]=0x00 0000:7c60= 7c60|3c42 |cmp al, 0x42|al=0x0000 0000:7c62= 7c62|742b |je 0x7c8f|flags=0x0297 0000:7c64= 7c64|fc |cld 0000:7c65= 7c65|89e6 |mov si, sp|sp=0x7c00 0000:7c67= 7c67|bf0006 |mov di, 0x600 0000:7c6a= 7c6a|b90001 |mov cx, 0x100 0000:7c6d= 7c6d|f3a5 |rep movsw word ptr es:[di], word ptr [si]|es=0x0000|di=0x0600|si=0x7c00|flags=0x0297|cx=0x0100|mem[0x600]=0x0000 (...) The good news: only one byte has to be changed to force PBR-boot, showed in my disassembly of your code: dualmbrbs.bin.txt (...) Start: ; --- Initialization --- 00000054 FA cli 00000055 31C0 xor ax,ax 00000057 8ED0 mov ss,ax 00000059 BC007C mov sp,0x7c00 0000005C FB sti ; --- End of Initialization --- ; reading from memory ; byte at address 0602h is unknown in first round and almost certainly is not 42 ; --- CHANGE NEEDED in emulator.py --- 0000005D A0027C mov al,[0x7C02] ; CHANGE !! ;0000005D A00206 mov al,[0x602] ; ?? ; ---- END of changes ---- 00000060 3C42 cmp al,0x42 ; ?? ; if it is 42 then jump to the bootsector code otherwise continue as MBR 00000062 742B jz Label ; 0x8f = jz _BS_start (...) Now everything is fine, some highlights of the PBR-log: MSSYS16NTFS_PBR_7C02_BOOT.instructions.log [REGS] Initial register state: ax=0000 bx=0000 cx=0000 dx=0080 si=0000 di=0000 bp=0000 sp=7c00 cs=0000 ds=0000 ss=0000 es=0000 flags=0002 cf=0 zf=0 0000:7c00= 7c00|eb52 |jmp 0x7c54 0000:7c54= 7c54|fa |cli 0000:7c55= 7c55|31c0 |xor ax, ax|ax=0x0000 0000:7c57= 7c57|8ed0 |mov ss, ax|ax=0x0000 0000:7c59= 7c59|bc007c |mov sp, 0x7c00 0000:7c5c= 7c5c|fb |sti 0000:7c5d= 7c5d|a0027c |mov al, byte ptr [0x7c02]|mem[0x7c02]=0x42 0000:7c60= 7c60|3c42 |cmp al, 0x42|al=0x0042 0000:7c62= 7c62|742b |je 0x7c8f|flags=0x0246 0000:7c8f= 7c8f|b8c007 |mov ax, 0x7c0 0000:7c92= 7c92|8ed8 |mov ds, ax|ax=0x07c0 0000:7c94= 7c94|b8000d |mov ax, 0xd00 0000:7c97= 7c97|8ec0 |mov es, ax|ax=0x0d00 0000:7c99= 7c99|31db |xor bx, bx|bx=0x0000 0000:7c9b= 7c9b|c6060e0010|mov byte ptr [0xe], 0x10|mem[0x7c0e]=0x00 0000:7ca0= 7ca0|e82400 |call 0x7cc7|sp=0x7c00|ip=0x7ca0|return_address=0x7ca3 0000:7cc7= 7cc7|6660 |pushal|di=0x0000|si=0x0000|bp=0x0000|bx=0x0000|dx=0x0080|cx=0x0000|ax=0x0d00|sp=0x7bfe 0000:7cc9= 7cc9|1e |push ds|ds=0x07c0 0000:7cca= 7cca|06 |push es|es=0x0d00 0000:7ccb= 7ccb|66a11000 |mov eax, dword ptr [0x10]|mem[0x7c10]=0x00000000 0000:7ccf= 7ccf|6603061c00|add eax, dword ptr [0x1c]|ax=0x0000|mem[0x7c1c]=0x0000003f 0000:7cd4= 7cd4|663b062000|cmp eax, dword ptr [0x20]|ax=0x003f|mem[0x7c20]=0x00000000 0000:7cd9= 7cd9|1e |push ds|ds=0x07c0 0000:7cda= 7cda|666a00 |push 0|sp=0x7bd8 0000:7cdd= 7cdd|6650 |push eax|ax=0x003f|sp=0x7bd4 0000:7cdf= 7cdf|06 |push es|es=0x0d00 0000:7ce0= 7ce0|53 |push bx|bx=0x0000|sp=0x7bce 0000:7ce1= 7ce1|666810000100|push 0x10010|sp=0x7bcc 0000:7ce7= 7ce7|803e140000|cmp byte ptr [0x14], 0|mem[0x7c14]=0x00 0000:7cec= 7cec|b442 |mov ah, 0x42 0000:7cee= 7cee|8a162400 |mov dl, byte ptr [0x24]|mem[0x7c24]=0x80 0000:7cf2= 7cf2|16 |push ss|ss=0x0000 0000:7cf3= 7cf3|1f |pop ds|ds=0x07c0 0000:7cf4= 7cf4|89e6 |mov si, sp|sp=0x7bc8 0000:7cf6= 7cf6|cd13 |int 0x13|int=0x13 f000:004c= f004c|cd13 |int 0x13|int=0x13 [intseq=0] Handling BIOS INT 0x13 -> Disk Services (Floppy/Hard Disk) [REGS] INT 0x13 BEFORE: ax=423f bx=0000 cx=0000 dx=0080 si=7bc8 di=0000 bp=0000 sp=7bc2 cs=f000 ds=0000 ss=0000 es=0d00 flags=0246 cf=0 zf=1 [INT 0x13] Extended read for drive 0x80 - LBA: 63, Sectors: 1, Buffer: 0x0d00:0x0000 ✓ Read sector 1/1 from LBA 63 to 0x0d000 - Data (32 bytes): eb 52 90 4e 54 46 53 20 20 20 20 00 02 01 00 00 00 00 00 00 00 f8 00 00 3f 00 ff 00 3f 00 00 00 [REGS] INT 0x13 AFTER: ax=003f bx=0000 cx=0000 dx=0080 si=7bc8 di=0000 bp=0000 sp=7bc2 cs=f000 ds=0000 ss=0000 es=0d00 flags=0246 cf=0 zf=1 f000:004e= f004e|cf |iret (...) I attached full highlights of all three boot-experiments if you want to see yourself (full log-files are about 1.35MB each). HIGHLIGHTS_MSSYS16NTFS_MBR_BOOT.instructions.log HIGHLIGHTS_MSSYS16NTFS_PBR_BOOT.instructions.log HIGHLIGHTS_MSSYS16NTFS_PBR_7C02_BOOT.instructions.log Edited April 18 by deomsh Grammar
jaclaz Posted April 18 Posted April 18 (edited) I don't know. The value 42 is written later at 0x0602: Quote ;writing to memory mov bx,0602h mov [bx], byte 42h ;byte at address 0602h is now certainly 42 at first pass both 0602 and 7C02 should be NOT 42. at second pass BOTH should be 42. Anyway whichever works, works. Edited April 18 by jaclaz
deomsh Posted April 18 Author Posted April 18 (edited) 1 hour ago, jaclaz said: at first pass both 0602 and 7C02 should be NOT 42. at second pass BOTH should be 42. In that case I misunderstood. But in WHAT scenario will there be a second pass to 0000:0600 or otherwise, so the initially EB 52 90 changed to EB 52 42 is read-out? This is the last part of the 'Normal boot' with EB 52 90 as start of the MBR. First jumping into the relocated MBR, copying LBA 63 and then jumping into the normal PBP-bootsector, just loaded at 0000:7c00: HIGHLIGHTS_MSSYS16NTFS_MBR_BOOT.instructions_BIG.log (...) 0000:7c6f= 7c6f|bb0206 |mov bx, 0x602 0000:7c72= 7c72|c60742 |mov byte ptr [bx], 0x42|bx=0x0602|mem[0x602]=0x90 0000:7c75= 7c75|ea1e070000|ljmp 0:0x71e 0000:071e= 71e|88160008 |mov byte ptr [0x800], dl|dl=0x0080|mem[0x800]=0x00 0000:0722= 722|bebe07 |mov si, 0x7be 0000:0725= 725|89f7 |mov di, si|si=0x07be 0000:0727= 727|57 |push di|di=0x07be|sp=0x7c00 0000:0728= 728|be4b07 |mov si, 0x74b 0000:072b= 72b|8b5d08 |mov bx, word ptr [di + 8]|di=0x07be|mem[0x7c6]=0x003f 0000:072e= 72e|895c08 |mov word ptr [si + 8], bx|si=0x074b|bx=0x003f|mem[0x753]=0x0000 0000:0731= 731|8b5d0a |mov bx, word ptr [di + 0xa]|di=0x07be|mem[0x7c8]=0x0000 0000:0734= 734|895c0a |mov word ptr [si + 0xa], bx|si=0x074b|bx=0x0000|mem[0x755]=0x0000 0000:0737= 737|8a160008 |mov dl, byte ptr [0x800]|mem[0x800]=0x80 0000:073b= 73b|8cd8 |mov ax, ds|ds=0x0000 0000:073d= 73d|8ec0 |mov es, ax|ax=0x0000 0000:073f= 73f|b80042 |mov ax, 0x4200 0000:0742= 742|cd13 |int 0x13|int=0x13 f000:004c= f004c|cd13 |int 0x13|int=0x13 [intseq=0] Handling BIOS INT 0x13 -> Disk Services (Floppy/Hard Disk) [REGS] INT 0x13 BEFORE: ax=4200 bx=0000 cx=0000 dx=0080 si=074b di=07be bp=0000 sp=7bf8 cs=f000 ds=0000 ss=0000 es=0000 flags=0297 cf=1 zf=0 [INT 0x13] Extended read for drive 0x80 - LBA: 63, Sectors: 1, Buffer: 0x0000:0x7c00 ✓ Read sector 1/1 from LBA 63 to 0x07c00 - Data (32 bytes): eb 52 90 4e 54 46 53 20 20 20 20 00 02 01 00 00 00 00 00 00 00 f8 00 00 3f 00 ff 00 3f 00 00 00 [REGS] INT 0x13 AFTER: ax=0000 bx=0000 cx=0000 dx=0080 si=074b di=07be bp=0000 sp=7bf8 cs=f000 ds=0000 ss=0000 es=0000 flags=0296 cf=0 zf=0 f000:004e= f004e|cf |iret 0000:0744= 744|5e |pop si|sp=0x7bfe 0000:0745= 745|fa |cli 0000:0746= 746|ea007c0000|ljmp 0:0x7c00 0000:7c00= 7c00|eb52 |jmp 0x7c54 0000:7c54= 7c54|fa |cli (...) ; Continue with original PBR NTFS boot code Edited April 18 by deomsh
jaclaz Posted April 18 Posted April 18 (edited) Mind you I am re-building this justification from memory and from re-reading some ten years later the files, so don't count too much on the accuracy of the details, but the general idea should be correct. The idea is (was) that a number of BIOSes (or programs) want to have as first sector a MBR, while some other want to use a volume (i.e. first sector is a bootsector/VBR) The original makebootfat code/approach (only valid for FAT) is to prepend a sector to a normal volume, then: 1) have in this sector the MBR code and a partition table covering itself and the following volume 2) have in this sector a copy of the BPB of the original VBR but with an added "hidden sector" (or "sectors before +1") So, if you look at it with a MBR viewer, it should be valid, and as well if you look at it with a VBR viewer it should be valid. The code is (should be) code. Once executed, it would map the whole stuff, execute the MBR boot code and the PBR boot code sequentially. With NTFS, since we cannot prepend a sector to the $Boot (the 16 sector VBR for NTFS) I tried to have the same effect by simplifying the original MBR code to save space and putting it in holes of the VBR code, hence there is the need to load the same sector twice, the first time as MBR code, the second as VBR code, and this is the purpose of the 42 flag. What happens is (should be) that: 1) sector is loaded (by the BIOS) at 0:7C00h but moved to 0600h (this is in the original makebootfat) 2) a check for 42 at 0602 makes it continue using the MBR code or the VBR code 3) since initially the byte is NOT 42 it continues with MBR code (that sets the 0602h byte to 42) 5) the MBR code execution continues on the copy at 0600h 6) and the sector is loaded at 7C00H 7) the SAME code (since it is the SAME sector) is executed but this time the byte at 7C02h (copied from 0602h) is 42 so it continues with the VBR code Edited April 18 by jaclaz
deomsh Posted April 20 Author Posted April 20 Thanks for all these info. On my hardware I can not test further, but I will keep this code in my collection. So far I didn't do much with MBR-code, only compiling SYSLINUX and porting MS-DOS 4.0 FDBOOT to NASM (apart from the F2 => F3 variation).
deomsh Posted May 6 Author Posted May 6 (edited) Third version of Part 8½ B: Full installation of Windows 98 Second Edition on a Rloew non-XMS Ramdrive Most important changes: 1) PROTHOOK.VXD ruled out in favour of PATCHMEM /P While working on Windows 95 versions of this project I found out PROTHOOK.VXD is not compatible with Windows 95, but PATCHMEM /P is working: And what is nice in case of Windows 98: possible to start Windows in Safe mode on a Rloew non-XMS Ramdrive. 2) Use of NOOFF.COM (optional). Found this small program again after many years in mdgx' Powertoys. If found during Setup NOOFF.COM will be used always, so it is now possible to make changes in Windows on a Ramdrive, shutdown to the command-line and start Windows again on the Ramdrive. Logo's must be deleted before, which is done automatic if NOOFF.COM is found. 3) Restart Windows in 'Normal mode' on Ramdrive after using Safe mode on Ramdrive (NOOFF.COM must be installed already). Normally it is not possible to start Windows in Normal mode AFTER been in Safe mode from the command-line. Always going back in Safe mode. But I developed a more or less reliable procedure to restart Windows in 'Normal mode'. Unless Windows Standard video driver is used in both 'Normal mode' and Safe mode, next two dialogs must be absolved (just click 2x OK): 4) Added U98SEUSB from Problemchild's SP3 to possible pre-installed USB-stack's with a menu to choose (IF files are copied before to their respective directories by the user): However, second phase of Setup will change a little because modded SYSDM.CPL from Windows ME is used in U98SEUSB: Overwriting SYSDM.CPL if Setup has been run is blocked inside Windows. But if starting Windows in Safe Mode on Ramdrive the original Windows 98 SYSDM.CPL is used again, also if restarted afterwards in 'Normal mode'. After next full boot modded SYSDM.CPL will be used again. 4) New Boot menu with choice to run Windows in Safe mode directly on the USB Bootdrive, with or without MS-DOS CD-drivers: BTW language of header is dependent on IO.SYS' language. 5) Choice of video-driver to use in Safe mode: Tihiy's modded SVGA driver or PlugMGMK's (Windows 3x) driver (if files are found by Setup). Even possible to set video in Safe mode to 1920x1200 with 32k colors (if available as VBE-mode). Be aware: there are currently six MSBATCH-versions. If you want to insert your Product ID, this must be done in all six files, unless you are sure which one will be used during Setup. 6) Option to disable Floppy seek inside Windows Explorer (but not elsewhere): 7) New choices before starting Windows on Ramdrive: Boot in 'Normal mode' with 'win' or 'WIN', in Safe mode with 'WIN /D:M' or 'win /d:m', both from C:\ to force use of WIN.BAT. Using other switches is supported too. Starting Windows from on Ramdrive from R:\ is possible too, but procedure to start 'Normal mode' after shutdown from Safe mode is not available in this case. I found on one of my chipsets with USB2.0 only, the USB-drive MUST be removed before starting Windows on a Ramdrive, even in Safe mode - while overmapping with SUSBST.EXE is helpfull too. On two of my chipset's USB2.0 is 'lost' after booting a second time from the command-line. If no USB1(.1) is available, only use Safe mode BEFORE starting in 'Normal mode' (found same with NDIS2-driver, IF started). 8) Supporting 64KB clusters. If the USB-drive is formatted with 64KB clusters (128 Sectors per Cluster), IO.SYS will not boot from such a disk (as far tested). But with use of Grub4dos, booting IO.SYS directly is possible (grldr with grldr-bootcode needed). The MENU.LST included will auto-highlight the (currently) right choice, but will wait a while for Enter. Even installation of this project from a Logical partition is possible (partly tested for now). Main problem: LCOPY.EXE does not support 64KB clusters (nor aligment with higher number of Reserved sectors on FAT16). These problems are solved in the included version of LCOPY.EXE, modifications mainly by my pi.ai-agent (original and changed source code included too, in directory SETUP982\README\LCOPYMOD). As probably known: SCANDISK.EXE will not support 64KB clusters (but SCANDISKW.EXE does). Currently solved with DOSFSCK.EXE from Freedos (CWSDPMI.EXE is needed too). DOSFSCK.EXE will only run during Setup to check the USB-drive, if installed, but not automatic if Safe mode is started directly from the USB-bootdrive and FAT16 or FAT32 is 'dirty' (SCANDISK.EXE is disabled in this case by Setup). WINONR8.5.2.USB.ZIP More information in the directory SETUP982\README EDIT: something went wrong with the zip, please delete and download latest version! Edited May 9 by deomsh Zip without master directory; additions; corrections; corrected zip
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now