I have been recently developing on my PXE Stage 1 boot loader, and being the inexperienced man I am, I have encountered yet another problem.
I have managed to get as far as writing the complete OpenFile, CloseFile and ReadFile (from a offset) wrappers (which would then file a ReadCompFile function). These wrappers even work in QEMU, on which I can successfully load and execute the common BIOS Stage. However, recently, when I was testing the OpenFile wrapper on my PIII, I encountered a problem.
On further debugging, I found that PXE was leaving the error code 0x35 for me, which translated to "PXENV_STATUS_TFTP_READ_TIMEOUT" - as I found out after referring to the specifications. After a little googling, and hours spent on IRC, the two suggestions I was given were:
- Try with a Linux distribution, and check whether your TFTP server is good enough. I did try that, and found out that my TFTP server is intact (which was already proven by the fact that iPXE was able to load my boot file).
- Try disabling your firewall, such that nothing blocks the port. This one seemed valuable advice, but unfortunately, this didn't solve the problem, as I didn't have any firewall enabled for a start.
Code: Select all
%define PACKET_SIZE 512 ; Keep the size to the minimum and most supported 512.
%define UDP_PORT (69 << 8) ; The port is 69, or 69 << 8 in big endian.
PXENV_TFTP_OPEN:
.Status dw 0
.SIP dd 0
.GIP dd 0
.Filename times 128 db 0
.Port dw 0
.PacketSize dw 0
; Save PacketSize here, for future reference by code.
PacketSize: dw 0
; Opens a file from the TFTP server, so that it can be read from.
; @si Should point to the asciiz filename.
; @ecx Should contain the length of the filename (< 128).
OpenFile:
pushad
; Zero out the PXENV_TFTP_OPEN structure.
push ecx ; Save the size of the filename.
mov di, PXENV_TFTP_OPEN
mov ecx, 71 ; Store 71-words.
xor eax, eax ; We need to zero out the structure.
rep stosw ; Clear out the entire structure.
pop ecx ; Restore the size of the filename.
; Put some default values in there.
mov word [PXENV_TFTP_OPEN.Port], UDP_PORT
mov word [PXENV_TFTP_OPEN.PacketSize], PACKET_SIZE
mov eax, [SIP]
bswap eax ; PXE expects SIP to be in big endian format - BSWAP!
mov [PXENV_TFTP_OPEN.SIP], eax
mov eax, [GIP]
bswap eax
mov [PXENV_TFTP_OPEN.GIP], eax
; Store the "filename" at PXENV_TFTP_OPEN.Filename
mov di, PXENV_TFTP_OPEN.Filename
rep movsb
; Store the address of the input buffer, and the opcode at BX.
mov di, PXENV_TFTP_OPEN
mov bx, TFTP_OPEN
call UsePXEAPI
or ax, [PXENV_TFTP_OPEN]
test ax, ax
jnz .Error ; Test if any error occured. If it did, abort boot!
; Store PacketSize for future reference.
mov eax, [PXENV_TFTP_OPEN.PacketSize]
mov [PacketSize], eax
.Return:
popad
ret
.Error:
xor ax, ax
mov si, PXEAPIError
call AbortBoot
NOTE: I am using iPXE on my PIII, since the network card doesn't support PXE.
I've already tried printing out and verifying the entire PXENV_TFTP_OPEN structure. The structure, as I expected was correct. If anyone could be of any help, I'd be great.
Regards,
Shikhin