aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-08-01 05:15:52 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-08-01 05:15:52 +0800
commitf0477aa673fc3c130553eb77324b0c5349241f52 (patch)
tree056c234f5cb3ffe4f03e012645a4c67b79b4b92f
parent93dc20622287f0c15333e5ff3e6498b74d090c57 (diff)
downloadpxelinux-f0477aa673fc3c130553eb77324b0c5349241f52.tar.gz
pxelinux-f0477aa673fc3c130553eb77324b0c5349241f52.tar.xz
pxelinux-f0477aa673fc3c130553eb77324b0c5349241f52.zip
Core:PXELINUX: fixed the fill_buffer bug
-rw-r--r--core/comboot.inc4
-rw-r--r--core/extern.inc2
-rw-r--r--core/getc.inc2
-rw-r--r--core/loadhigh.inc2
-rw-r--r--core/pxe.c10
-rw-r--r--core/pxelinux.asm244
-rw-r--r--core/runkernel.inc2
7 files changed, 10 insertions, 256 deletions
diff --git a/core/comboot.inc b/core/comboot.inc
index 5a3d149f..4bfef259 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -126,7 +126,7 @@ is_comboot_image:
mov bx,100h ; Load at <seg>:0100h
mov cx,10000h >> SECTOR_SHIFT
; Absolute maximum # of sectors
- call getfssec
+ pm_call getfssec
cmp ecx,65536-256-2 ; Maximum size
ja comboot_too_large
@@ -535,7 +535,7 @@ comapi_read:
mov bx,P_BX
mov si,P_SI
mov cx,P_CX
- call getfssec
+ pm_call getfssec
jnc .noteof
xor si,si ; SI <- 0 on EOF, CF <- 0
.noteof: mov P_SI,si
diff --git a/core/extern.inc b/core/extern.inc
index 236e6cc7..d6847d94 100644
--- a/core/extern.inc
+++ b/core/extern.inc
@@ -19,7 +19,7 @@
extern free_socket, ip_ok, mangle_name, ack_packet, pxe_get_cached_info
extern udp_init, get_prefix, network_init, parse_dhcp_options
extern get_packet_gpxe, pxe_init
- extern getfssec_c, fill_buffer
+ extern getfssec, fill_buffer
; debug.c
extern debug, print_reg
diff --git a/core/getc.inc b/core/getc.inc
index 82f1016e..87dbeefa 100644
--- a/core/getc.inc
+++ b/core/getc.inc
@@ -136,7 +136,7 @@ getc:
mov [di+gc_bufbytes],si ; In case SI == 0
jz .empty
mov cx,bytes_per_getc >> SECTOR_SHIFT
- call getfssec
+ pm_call getfssec
mov [di+gc_bufbytes],cx
mov [di+gc_file],si
jcxz .empty
diff --git a/core/loadhigh.inc b/core/loadhigh.inc
index 42a1354b..86a1bf6d 100644
--- a/core/loadhigh.inc
+++ b/core/loadhigh.inc
@@ -69,7 +69,7 @@ load_high:
push edi ; <C> Target buffer
mov cx,ax
xor bx,bx ; ES:0
- call getfssec ; Load the data into xfer_buf_seg
+ pm_call getfssec ; Load the data into xfer_buf_seg
pop edi ; <C> Target buffer
pushf ; <C> EOF status
lea ebx,[edi+ecx] ; End of data
diff --git a/core/pxe.c b/core/pxe.c
index e09c9ff7..836198fe 100644
--- a/core/pxe.c
+++ b/core/pxe.c
@@ -1330,7 +1330,7 @@ void fill_buffer(com32sys_t *regs)
* Start by ACKing the previous packet; this should cause
* the next packet to be sent.
*/
- again:
+ ack_again:
regs->eax.w[0] = file->tftp_lastpkt;
ack_packet(regs);
@@ -1387,10 +1387,8 @@ void fill_buffer(com32sys_t *regs)
* This is presumably because the ACK got lost,
* so the server just resent the previous packet.
*/
- printf("Wrong packet, wanted %d, got %d\n", last_pkt, *(uint16_t *)(data+2));
- regs->eax.w[0] = *(uint16_t *)(data + 2);
- ack_packet(regs);
- goto again;
+ printf("Wrong packet, wanted %04x, got %04x\n", htons(last_pkt), htons(*(uint16_t *)(data+2)));
+ goto ack_again;
}
/* It's the packet we want. We're also EOF if the size < blocksize */
@@ -1431,7 +1429,7 @@ void fill_buffer(com32sys_t *regs)
; ECX -> number of bytes actually read
;
*/
-void getfssec_c(com32sys_t *regs)
+void getfssec(com32sys_t *regs)
{
uint16_t pktbuf_seg = 0x4000;
char *buf = MK_PTR(regs->es, regs->ebx.w[0]);
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 7a1f6f76..5e593d75 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -948,250 +948,6 @@ PXEEntry equ pxenv.jump+1
alignb 2
PXEStatus resb 2
- section .text16
-%if 1
-getfssec:
- pm_call getfssec_c
- ret
-%else
-
-;
-; getfssec: Get multiple clusters from a file, given the starting cluster.
-;
-; In this case, get multiple blocks from a specific TCP connection.
-;
-; On entry:
-; ES:BX -> Buffer
-; SI -> TFTP socket pointer
-; CX -> 512-byte block count; 0FFFFh = until end of file
-; On exit:
-; SI -> TFTP socket pointer (or 0 on EOF)
-; CF = 1 -> Hit EOF
-; ECX -> number of bytes actually read
-;
-getfssec:
- push eax
- push edi
- push bx
- push si
- push fs
- mov di,bx
- mov ax,pktbuf_seg
- mov fs,ax
-
- xor eax,eax
- movzx ecx,cx
- shl ecx,TFTP_BLOCKSIZE_LG2 ; Convert to bytes
- push ecx ; Initial request size
- jz .hit_eof ; Nothing to do?
-
-.need_more:
- pm_call fill_buffer
- movzx eax,word [si+tftp_bytesleft]
- and ax,ax
- jz .hit_eof
-
- push ecx
- cmp ecx,eax
- jna .ok_size
- mov ecx,eax
-.ok_size:
- mov ax,cx ; EAX<31:16> == ECX<31:16> == 0
- mov bx,[si+tftp_dataptr]
- sub [si+tftp_bytesleft],cx
- xchg si,bx
- fs rep movsb ; Copy from packet buffer
- xchg si,bx
- mov [si+tftp_dataptr],bx
-
- pop ecx
- sub ecx,eax
- jnz .need_more
-
-.hit_eof:
- pm_call fill_buffer
-
- pop eax ; Initial request amount
- xchg eax,ecx
- sub ecx,eax ; ... minus anything not gotten
-
- pop fs
- pop si
-
- ; Is there anything left of this?
- mov eax,[si+tftp_filesize]
- sub eax,[si+tftp_filepos]
- jnz .bytes_left
-
- cmp [si+tftp_bytesleft],ax ; AX == 0
- jne .bytes_left
-
- cmp byte [si+tftp_goteof],1
- je .done
- ; I'm 99% sure this can't happen, but...
- pm_call fill_buffer ; Receive/ACK the EOF packet
-.done:
- ; The socket is closed and the buffer drained
- ; Close socket structure and re-init for next user
- pm_call free_socket
- stc
- jmp .ret
-.bytes_left:
- clc
-.ret:
- pop bx
- pop edi
- pop eax
- ret
-
-;
-; Get a fresh packet if the buffer is drained, and we haven't hit
-; EOF yet. The buffer should be filled immediately after draining!
-;
-; expects fs -> pktbuf_seg and ds:si -> socket structure
-;
-fill_buffer:
- cmp word [si+tftp_bytesleft],0
- je .empty
- ret ; Otherwise, nothing to do
-
-.empty:
- push es
- pushad
- mov ax,ds
- mov es,ax
-
- ; Note: getting the EOF packet is not the same thing
- ; as tftp_filepos == tftp_filesize; if the EOF packet
- ; is empty the latter condition can be true without
- ; having gotten the official EOF.
- cmp byte [si+tftp_goteof],0
- jne .ret ; Already EOF
-
-%if GPXE
- cmp word [si+tftp_localport], -1
- jne .get_packet_tftp
- pm_call get_packet_gpxe
- jmp .ret
-.get_packet_tftp:
-%endif ; GPXE
-
- ; TFTP code...
-.packet_loop:
- ; Start by ACKing the previous packet; this should cause the
- ; next packet to be sent.
- mov bx,TimeoutTable
-
-.send_ack: push bx ; <D> Retry pointer
- movzx cx,byte [bx] ; Timeout
-
- mov ax,[si+tftp_lastpkt]
- pm_call ack_packet ; Send ACK
-
- ; We used to test the error code here, but sometimes
- ; PXE would return negative status even though we really
- ; did send the ACK. Now, just treat a failed send as
- ; a normally lost packet, and let it time out in due
- ; course of events.
-
-.send_ok: ; Now wait for packet.
- mov dx,[BIOS_timer] ; Get current time
-
-.wait_data: push cx ; <E> Timeout
- push dx ; <F> Old time
-
- mov bx,[si+tftp_pktbuf]
- mov [pxe_udp_read_pkt.buffer],bx
- mov [pxe_udp_read_pkt.buffer+2],fs
- mov [pxe_udp_read_pkt.buffersize],word PKTBUF_SIZE
- mov eax,[si+tftp_remoteip]
- mov [pxe_udp_read_pkt.sip],eax
- mov eax,[MyIP]
- mov [pxe_udp_read_pkt.dip],eax
- mov ax,[si+tftp_remoteport]
- mov [pxe_udp_read_pkt.rport],ax
- mov ax,[si+tftp_localport]
- mov [pxe_udp_read_pkt.lport],ax
- mov di,pxe_udp_read_pkt
- mov bx,PXENV_UDP_READ
- call pxenv
- jnc .recv_ok
-
- ; No packet, or receive failure
- mov dx,[BIOS_timer]
- pop ax ; <F> Old time
- pop cx ; <E> Timeout
- cmp ax,dx ; Same time -> don't advance timeout
- je .wait_data ; Same clock tick
- loop .wait_data ; Decrease timeout
-
- pop bx ; <D> Didn't get any, send another ACK
- inc bx
- cmp bx,TimeoutTableEnd
- jb .send_ack
- jmp kaboom ; Forget it...
-
-.recv_ok: pop dx ; <F>
- pop cx ; <E>
-
- cmp word [pxe_udp_read_pkt.buffersize],byte 4
- jb .wait_data ; Bad size for a DATA packet
-
- mov bx,[si+tftp_pktbuf]
- cmp word [fs:bx],TFTP_DATA ; Not a data packet?
- jne .wait_data ; Then wait for something else
-
- mov ax,[si+tftp_lastpkt]
- xchg ah,al ; Host byte order
- inc ax ; Which packet are we waiting for?
- xchg ah,al ; Network byte order
- cmp [fs:bx+2],ax
- je .right_packet
-
- ; Wrong packet, ACK the packet and then try again
- ; This is presumably because the ACK got lost,
- ; so the server just resent the previous packet
- mov ax,[fs:bx+2]
- pm_call ack_packet
- jmp .send_ok ; Reset timeout
-
-.right_packet: ; It's the packet we want. We're also EOF if the
- ; size < blocksize
-
- pop cx ; <D> Don't need the retry count anymore
-
- mov [si+tftp_lastpkt],ax ; Update last packet number
-
- movzx ecx,word [pxe_udp_read_pkt.buffersize]
- sub cx,byte 4 ; Skip TFTP header
-
- ; Set pointer to data block
- lea ax,[bx+4] ; Data past TFTP header
- mov [si+tftp_dataptr],ax
-
- add [si+tftp_filepos],ecx
- mov [si+tftp_bytesleft],cx
-
- cmp cx,[si+tftp_blksize] ; Is it a full block?
- jb .last_block ; If not, it's EOF
-
-.ret:
- popad
- pop es
- ret
-
-
-.last_block: ; Last block - ACK packet immediately
- mov ax,[fs:bx+2]
- pm_call ack_packet
-
- ; Make sure we know we are at end of file
- mov eax,[si+tftp_filepos]
- mov [si+tftp_filesize],eax
- mov byte [si+tftp_goteof],1
-
- jmp .ret
-%endif
;
; TimeoutTable: list of timeouts (in 18.2 Hz timer ticks)
diff --git a/core/runkernel.inc b/core/runkernel.inc
index ecaaceb0..93949ec8 100644
--- a/core/runkernel.inc
+++ b/core/runkernel.inc
@@ -58,7 +58,7 @@ is_linux_kernel:
mov cx,8000h >> SECTOR_SHIFT ; Half a moby (32K)
xor bx,bx
pop si ; <A> file pointer
- call getfssec
+ pm_call getfssec
cmp cx,1024
jb kernel_corrupt
cmp word [es:bs_bootsign],0AA55h