OK. Having added the FDC BIOS from http://www.malinov.com/Home/sergeys-projects/ … sa-fdc-and-uart, I now see Windows NT 4 changing the read data request's maximum sector number to 0x24 for most acceses, but 0xF at the end of the loading process with the initialization error. So a CPU error?
Edit: It's 8 sectors at 1a/0/8 from disk #2 that's last read into memory. Anyone knows more about this?
TC is reached, with 4K being read to D000-E000, count 0xFFF(thus 0x1000=4K being transferred). the page address register being 0x49, thus 49D000-49E000 being loaded by the DMA transfer from the 8 sectors of the FDC(a 4K memory block being loaded through DMA).
So perhaps the issue isn't with the 4K load itself, but somehow the starting of whatever's loaded at said address that's failing?
CR2 is 96000h, so some access down to user mode was failing or last handled?
Looking at the current TLB contents, I can see that 0x80000000 seems to have all of the RAM mapped in a direct fashion(linear to physical memory mapping, just like Linux has). I also see just one some single page mappings in the TLB (FFD00000 to VRAM at B8000 and FFDF0000 to 279000, FDC13000 to 5B000, FF6EE000 to 404000, FFDFF000 to 278000). one seemingly direct mapped memory(at 80000000 to PA 0) for what seems to be the full physical memory range? The value in CR2 isn't present in that map, so it must be the cause of the BSOD somehow?
Edit: After looking at all the page faults thrown for the user-mode memory addresses(everything below 0x80000000), I actually see one and the same instruction(0FB7 MOVZX) keep throwing page faults from a very low memory address in 4KB increments all the way up to 0x96000! The modr/m parameters of said instruction have a calculated offset that's exactly those 4KB page increments.
Could it be that the page fault handling in the OS is somehow getting itself into a loop?
The flags pushed are 0x0000 in all cases with those instructions.
Looking at the CS:EIP of the faulting insruction reveals that all those exceptions take place at only one instruction: 0008:8018B47B.
It starts with opcode A5 at 8:80139e8e from addresses 10000h until 33000h.
Then it starts faults for opcode 89 within page 40000 at 0008:8018a065 and opcode C7 at 0008:801b286f(both after each other twice).
Then I get the 0FB7 opcode faulting at 8018b47b for address 40000h through 96000h.
After it returns to said instruction, the PDE is loaded with 380867h, while the PTE is loaded with 49C025h.
So the PDE is user,present,writable. And the PTE is user,present,readonly. Thus the result becomes user,present,readonly(for user mode only, since it's a user mode page).
Edit: OK. Found out a bit more: The GDT is at 80036000(400h bytes long), while the IDT follows it immediately at 80036400(with a size 800h bytes long, thus the entire IDT is mapped).
Edit: Hmmm... The last data read from the FDC during that part is from offset 75E00 on the second disk(8 sectors, so 4KB). The first 2 sectors seem to contain some program(seeing as it starts with the MZ header), then the rest of the sectors contain zeroed data.
Hmmm... Looking at what data is read from the disk, those seem to be the first 8 sectors containing the contents of ntdll.dll? Although I haven't verified it yet.
Edit: Just verified using a combination of XVI32(to copy the blocks from the file and disk) and WinMerge to compare them(ntdll and the 8 blocks at address 75E00 in the disk 2 image). They fully match.
So the 8 sector load from the disk is the first 4K block(first page) of ntdll.dll.
And the issue is somewhere after that, loading/executing the ntdll.dll executable.
This is what happens: