Hmm... Having fixed the disk image for 720K (sectors=9), Linux 0.01 now loads way further, until a page fault on the stack of a CALL(opcode E8) instruction makes it hang? It now displays a bit more: "Linux 0.01 compiled by GCC version 1.40".
So, it reaches line 93 of init/main.c at least?
That happens at 000F:52A2. ESP is 18EA4. The PDE is 7FE027, the PTE is 18065? The CPL is 3, so it's in user mode at least?
Edit: Input seems to be responsive, but nothing is done?
Edit: OK, a single Ctrl-Alt-Del reboots the machine(instead of MS-DOS/Windows' need of pressing del twice with ctrl+alt pressed). So at least that part is working properly. Perhaps a part on the Init process's fault?
Edit: Hmmm... I see the IRET for bopping down to user mode (during the init process's start, init/main:93, just before the call to fork())?
Edit: Hmmm... The bopping down to user mode seems to have been a success. Then a 32-bit opcode 0x83 follows it.
Edit: Hmmm... I then see it add 8 to ESP(probably cleaing up some more stack), so 18E9C becomes 18EA4. So far at address 000F:5284. Then a MOV EAX,2 instruction. Then a INT 80h is issued(a call down into the Linux kernel). Hmmm... So far everything seems to be fine(at least theoretically).
Edit: Hmmm.... EAX's value is 2 for said syscall. Could that be the fork() system call?
Edit: The syscall seems to return the value 1(the child's PID) in EAX(so it's the parent again that's gotten control back), the value 18EA4 in ESP. The SS value is correctly gone back up to 0x17(the user-mode data segment), so that's successful.
It has now returned to 000F:528E.
Edit: Then a TEST EAX,EAX on the result check.
Edit: Then a JGE 529E, which is taken. So it's determined that the PID is bigger than zero? So it enters the inner of the fork statement?
Edit: Then another TEST EAX,EAX at EIP 529E.
Edit: Then a JNZ 52A7. That's taken.
Edit: Then a MOV EDX,192BC.
Edit: Then a MOV EAX,1D.
Edit: Then a INT 80h is issued. According to the unistd.h header, that's the pause() kernel call. So so far, so good.
Edit: I see the child running(without any IRET from the kernel), which on the call at 000F:52A2 calls 537B immediately causes a page fault. The error code pushed on the stack is 7. The PTE is 18065. The PDE is 7FE027. So present, not writable, user. So that's probably the COW mechanism going into effect?
Edit: I see an IRET to 52A2 again. ESP is returned to 18EA4 again. SS of 0x17. So are all other segment registers.
From F:538A there's an INT 0x80(function 0)? That's setup() being called. Thus it ends up at sys_setup() in hd.c?
Edit: I see an read sectors command to the first hard disk, then an IRET back to 52B3 of task F. So that's the idle task?
Edit: I see another INT 80h, function 1Dh(once again the pause() command). That seems to continue onwards?
Edit: I do see an IRQ0 being thrown. But after that, due to the Visual Studio debugger crashing, the netire debugging process go aborted 🙁
Edit: Looking at the hard disk controller, I see it erroring out on a read sector transfer that's executed? The LBA registers are loaded with values A0A90201h(drivehead(A0), cylinderhigh(A9), cylinderlow(02), sectornumber(01) registers). The hard drive is immediately erroring out, with no interrupt being fired? Perhaps that's the problem? According to the source code, it's trying to read sector #0(the MBR)? The code seems to expect an interrupt always, even if it's an error?
Edit: Hmmm.... Weird. I see the hard disk registers being written their values for sector #0(using CHS addressing method), but the register queue of the hard disk are completely different?
Edit: Aha! It's just writing it's parameters to the hard disk, BUT it's writing to the primary slave, while it's supposed to be writing to the Primary Master! When it's written all data to the primary slave, then writing the data for the primary master's drive/head register, switching the drive to the primary master(incurring a slight delay on the hard disk). Then(with all data entered into the primary slave) it's written the drive/head register only, finally executing a command to the primary master(0x20 read sector(s) command), while almost all registers are left in an unidentified state!