Well, first of all, about pxe.h. It has error in structure naming t_PXENV_UNDI_INITALIZE, it took some time to find, which letter is missed. Other issues with this fie: not armoured header (which disturbed me while compiling, cause included twice), PXENV_UNDI_GET_STATE related structure and definitions are missing. I’ve updated it only locally, but may be it’ll be better to make perforce mapping later.
After successfull complilation of libpxe_http.a, I’ve thought all is good, however linker thought differently. There was “R_386_16 relocation truncated” error. Now I know, it was gas ‘feature’, it’s rather problematic to write mixed 16 and 32 bit code with it, but first time I was in confusion. Now pxe_isr.S uses manualy rewritten segment:offset adresses, based on calculating sement and offset to data_start. I’ve thought about using code segment as data segment (in fact used data is placed in code segment), but first try gived me bad results, so for first time it will be somehow ugly, but working code
ARP related code was already near working state, so main problem was how to test it. I’ve modified pxe.c (implements pxenet device and NFS (via UDP) loading of kernel), just to start test of arp (this test sends broadcast request who-is provided ip and receives replies, updating internal arp_table structure). And after some trys understood, that pxe_core_receive() code is doing nothing, cause UNDI returns pointer to buffer, to which there is no access from userspace (starts at 0xa000, buffer is in lower addresses). So, __mem_copy() in pxe_isr.S was born with destiny to copy data in vm86 mode, and data_buffer array finally came in handy as place to copy to. There was also bug in receiving cycle, so I’ve made debug macro and started printing out to screen everything useful and useless. And have found, that receiving buffer includes media header and transmit (at least, for known by UNDI protocols) doesn’t include ethernet header.
Meanwhile, command ‘arp’ was added to loader (just to check, if I understand right how to add cmmands there), it performs arp test (but to say true, it not works, cause earlier started by autoboot pxe related code, and thus other test, from pxe.c function pxe_open() which shutdowns undi after all).
After fixing of some bugs and rebuilding – arp test began working in virtual machine (I am omitting tonnes of messages ‘unknown hardware address format’ in dmesg and some stupid errors with broadcast address for ethernet). It sends broadcast message for my home computer in localnet and receives reply, caches it and finishes. Well, I was such happy, that even rebooted desktop trying to perform test on one of it’s NICs (internal Realtek 8168; there is also 3Com 3C905C-TX, but I’ve not tested on it yet). Well, as always, reality was cruel. All pxe_core_transmit() calls were unsuccessfull, I’ve tryed other virtual machine (with different implementation of PXE) and found the same result.
I think, problem is incorrect sequence of initialization of UNDI services in pxe_core_init(). PXE spec says, that on remote.0 stage (started pxeldr) it’s possible to stop everything (STOP_BASE. UNLOAD_STACK, STOP_UNDI) and start remote.2 (the same executable in my case) with initialization UNDI again, but after that even first virtual machine rejected my code (mmm… in fact I’ve done also UNDI_CLOSE, UNDI_CLEANUP, UNDI_SHUTDOWN). there is also two mysteries – GET_STATE function always returns ‘failed’ result, but it seems, returned UNDI state value is not such incorrect. And some transmit calls fails with Status = 0 (which is something like ‘not any error’ status). It’s strange (I guess if I understand right – call failed, if ax register != 0).
So main problem for next few days – to find correct initialization sequence of calls, if problem is in that. And when problem will be solved – start first testing and implementing of ip protocol.