aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2002-06-15 05:24:25 +0000
committerhpa <hpa>2002-06-15 05:24:25 +0000
commit172f1e3aae1ce8848ad4bb9574d1837d75b67ff5 (patch)
treeee31d6aeb3b33e3ae2b229feaa432edac9ec709e
parent7cc2b27d059d8e06f0216c002868654f5f4a2acc (diff)
downloadsyslinux-elf-172f1e3aae1ce8848ad4bb9574d1837d75b67ff5.tar.gz
syslinux-elf-172f1e3aae1ce8848ad4bb9574d1837d75b67ff5.tar.xz
syslinux-elf-172f1e3aae1ce8848ad4bb9574d1837d75b67ff5.zip
Merge in changes from SYSLINUX 1.75syslinux-2.00-pre4
-rw-r--r--Makefile.private3
-rw-r--r--NEWS5
-rw-r--r--bootsect.inc4
-rw-r--r--com32.inc3
-rw-r--r--pxe.inc6
-rw-r--r--pxelinux.asm119
-rw-r--r--pxelinux.doc15
-rw-r--r--runkernel.inc11
8 files changed, 126 insertions, 40 deletions
diff --git a/Makefile.private b/Makefile.private
index 164400b6..fee4f3b6 100644
--- a/Makefile.private
+++ b/Makefile.private
@@ -43,7 +43,8 @@ release:
cp -rP $(SOURCES) $(DOCS) $(OTHER) release/syslinux-$(VERSION)
find release/syslinux-$(VERSION) -name CVS -type d -print0 | \
xargs -0rt rm -rf
- ln $(PRIVATE) release/syslinux-$(VERSION)
+ ln -f $(PRIVATE) release/syslinux-$(VERSION)
+ cd release/syslinux-$(VERSION) && $(MAKE) depend
cd release/syslinux-$(VERSION) && $(MAKE) official
cd release/syslinux-$(VERSION) && rm -f $(PRIVATE)
cd release && tar cvvf - syslinux-$(VERSION) | \
diff --git a/NEWS b/NEWS
index 42068e62..954c4e24 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,11 @@ Changes in 1.75:
bigger.
* PXELINUX: Put the PXE stack back in the init state before
invoking a chain-loaded NBP.
+ * PXELINUX: Actually found the combination of calls that
+ allows some (most?) PXE 2+ stacks to be unloaded from memory
+ properly.
+ * PXELINUX: Add "keeppxe" command-line option to disable
+ the standard unloading of the PXE stack.
Changes in 1.74:
* SYSLINUX: fix bug that would cause valid kernel images to be
diff --git a/bootsect.inc b/bootsect.inc
index 7d32ba8c..d3e50fc9 100644
--- a/bootsect.inc
+++ b/bootsect.inc
@@ -80,9 +80,7 @@ load_bootsec:
%elif IS_PXELINUX
; Close the UDP stack so the PXE stack is in a known state for
; the new NBP
- mov di,pxe_udp_close_pkt
- mov bx,PXENV_UDP_CLOSE
- call far [PXENVEntry]
+ call reset_pxe
%endif
pop ecx ; Byte count to copy
diff --git a/com32.inc b/com32.inc
index ac0440f8..3d445c10 100644
--- a/com32.inc
+++ b/com32.inc
@@ -55,10 +55,9 @@ com32_start:
mov ebx,com32_call_start ; Where to go in PM
com32_enter_pm:
+ cli
mov [SavedSSSP],sp
mov [SavedSSSP+2],ss
-
- cli
cld
call a20_test
jnz .a20ok
diff --git a/pxe.inc b/pxe.inc
index 759115f6..92da3bbd 100644
--- a/pxe.inc
+++ b/pxe.inc
@@ -53,14 +53,16 @@
%define PXENV_UNDI_GET_NIC_TYPE 0012h
%define PXENV_UNDI_GET_IFACE_INFO 0013h
%define PXENV_UNDI_ISR 0014h
-%define PXENV_STOP_UNDI 0015h ; HUH????
-%define PXENV_UNDI_GET_STATE 0016h
+%define PXENV_STOP_UNDI 0015h ; Overlap...?
+%define PXENV_UNDI_GET_STATE 0015h ; Overlap...?
%define PXENV_UNLOAD_STACK 0070h
%define PXENV_GET_CACHED_INFO 0071h
%define PXENV_RESTART_DHCP 0072h
%define PXENV_RESTART_TFTP 0073h
%define PXENV_MODE_SWITCH 0074h
+%define PXENV_START_BASE 0075h
+%define PXENV_STOP_BASE 0076h
%define PXENV_EXIT_SUCCESS 0x0000
%define PXENV_EXIT_FAILURE 0x0001
diff --git a/pxelinux.asm b/pxelinux.asm
index 67894fa1..125d0183 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -222,6 +222,7 @@ KernelExtPtr resw 1 ; During search, final null pointer
IPOptionLen resw 1 ; Length of IPOption
LocalBootType resw 1 ; Local boot return code
RealBaseMem resw 1 ; Amount of DOS memory after freeing
+APIVer resw 1 ; PXE API version found
TextAttrBX equ $
TextAttribute resb 1 ; Text attribute for message file
TextPage resb 1 ; Active display page
@@ -247,6 +248,15 @@ VGAFileBuf resb FILENAME_MAX ; Unmangled VGA image name
VGAFileBufEnd equ $
VGAFileMBuf resb FILENAME_MAX ; Mangled VGA image name
+;
+; PXE packets which don't need static initialization
+;
+ alignb 4
+pxe_unload_stack_pkt:
+.status: resw 1 ; Status
+.reserved: resw 10 ; Reserved
+pxe_unload_stack_pkt_len equ $-pxe_unload_stack_pkt
+
alignb tftp_port_t_size
Sockets resb MAX_SOCKETS*tftp_port_t_size
@@ -306,6 +316,15 @@ _start1:
call writestr
;
+; Assume API version 2.1, in case we find the !PXE structure without
+; finding the PXENV+ structure. This should really look at the Base
+; Code ROM ID structure in have_pxe, but this is adequate for now --
+; if we have !PXE, we have to be 2.1 or higher, and we don't care
+; about higher versions than that.
+;
+ mov word [APIVer],0201h
+
+;
; Now we need to find the !PXE structure. It's *supposed* to be pointed
; to by SS:[SP+4], but support INT 1Ah, AX=5650h method as well.
;
@@ -343,10 +362,11 @@ have_pxenv:
mov si,apiver_str
call writestr
mov ax,[es:bx+6]
+ mov [APIVer],ax
call writehex4
call crlf
- cmp word [es:bx+6], 0201h ; API version 2.1 or higher
+ cmp ax,0201h ; API version 2.1 or higher
jb old_api
mov si,bx
mov ax,es
@@ -1923,44 +1943,77 @@ ack_packet:
; unload_pxe:
;
; This function unloads the PXE and UNDI stacks and unclaims
-; the memory.
+; the memory. Assumes CS == DS == ES.
;
unload_pxe:
- mov di,pxe_udp_close_pkt
- mov bx,PXENV_UDP_CLOSE
- call far [PXENVEntry]
- mov di,pxe_undi_shutdown_pkt
- mov bx,PXENV_UNDI_SHUTDOWN
- call far [PXENVEntry]
+ test byte [KeepPXE],01h ; Should we keep PXE around?
+ jnz reset_pxe
+
+ mov si,new_api_unload
+ cmp byte [APIVer+1],2 ; Major API version >= 2?
+ jae .new_api
+ mov si,old_api_unload
+.new_api:
+
+.call_loop: xor ax,ax
+ lodsb
+ and ax,ax
+ jz .call_done
+ xchg bx,ax
mov di,pxe_unload_stack_pkt
- mov bx,PXENV_UNLOAD_STACK
+ push di
+ xor ax,ax
+ mov cx,pxe_unload_stack_pkt_len >> 1
+ rep stosw
+ pop di
call far [PXENVEntry]
jc .cant_free
- cmp word [pxe_unload_stack_pkt.status],byte PXENV_STATUS_SUCCESS
+ cmp word [pxe_unload_stack_pkt.status],PXENV_STATUS_SUCCESS
jne .cant_free
+ jmp .call_loop
+
+.call_done:
+ mov bx,0FF00h
- mov ax,[RealBaseMem]
- cmp ax,[BIOS_fbm] ; Sanity check
+ mov dx,[RealBaseMem]
+ cmp dx,[BIOS_fbm] ; Sanity check
jna .cant_free
+ inc bx
; Check that PXE actually unhooked the INT 1Ah chain
- movzx ebx,word [4*0x1a]
+ movzx eax,word [4*0x1a]
movzx ecx,word [4*0x1a+2]
shl ecx,4
- add ebx,ecx
- shr ebx,10
- cmp bx,ax ; Not in range
+ add eax,ecx
+ shr eax,10
+ cmp ax,dx ; Not in range
jae .ok
- cmp bx,[BIOS_fbm]
- jae .cant_free
+ cmp ax,[BIOS_fbm]
+ jae .cant_free
+ ; inc bx
.ok:
- mov [BIOS_fbm],ax
+ mov [BIOS_fbm],dx
ret
.cant_free:
mov si,cant_free_msg
- jmp writestr
+ call writestr
+ xchg ax,bx
+ call writehex4
+ mov al,'-'
+ call writechr
+ mov eax,[4*0x1a]
+ call writehex8
+ jmp crlf
+
+ ; We want to keep PXE around, but still we should reset
+ ; it to the standard bootup configuration
+reset_pxe:
+ mov bx,PXENV_UDP_CLOSE
+ mov di,pxe_udp_close_pkt
+ call far [PXENVEntry]
+ ret
;
; gendotquad
@@ -2279,7 +2332,7 @@ undi_data_msg db 'UNDI data segment at: ',0
undi_data_len_msg db 'UNDI data segment size: ',0
undi_code_msg db 'UNDI code segment at: ',0
undi_code_len_msg db 'UNDI code segment size: ',0
-cant_free_msg db 'Failed to free base memory, sorry...', CR, LF, 0
+cant_free_msg db 'Failed to free base memory, error ', 0
notfound_msg db 'not found', CR, LF, 0
myipaddr_msg db 'My IP address seems to be ',0
tftpprefix_msg db 'TFTP prefix: ', 0
@@ -2332,6 +2385,22 @@ exten_table_end:
PXENVEntry dw pxe_thunk,0
;
+; PXE unload sequences
+;
+new_api_unload:
+ db PXENV_UDP_CLOSE
+ db PXENV_UNDI_SHUTDOWN
+ db PXENV_UNLOAD_STACK
+ db PXENV_STOP_UNDI
+ db 0
+old_api_unload:
+ db PXENV_UDP_CLOSE
+ db PXENV_UNDI_SHUTDOWN
+ db PXENV_UNLOAD_STACK
+ db PXENV_UNDI_CLEANUP
+ db 0
+
+;
; PXE query packets partially filled in
;
pxe_bootp_query_pkt_2:
@@ -2380,13 +2449,6 @@ pxe_udp_read_pkt:
.buffersize: dw 0 ; Max packet size
.buffer: dw 0, 0 ; seg:off of buffer
-pxe_unload_stack_pkt:
-.status: dw 0 ; Status
-.reserved: times 10 db 0 ; Reserved
-
-pxe_undi_shutdown_pkt:
-.status: dw 0 ; Status
-
;
; Misc initialized (data) variables
;
@@ -2403,6 +2465,7 @@ NextSocket dw 49152 ; Counter for allocating socket numbers
VGAFontSize dw 16 ; Defaults to 16 byte font
UserFont db 0 ; Using a user-specified font
ScrollAttribute db 07h ; White on black (for text mode)
+KeepPXE db 0 ; Should PXE be kept around?
;
; TFTP commands
diff --git a/pxelinux.doc b/pxelinux.doc
index 6ee17776..04842f18 100644
--- a/pxelinux.doc
+++ b/pxelinux.doc
@@ -302,6 +302,17 @@ varying degrees of severity. Please see:
if known.
+ ++++ KEEPING THE PXE STACK AROUND ++++
+
+Normally, PXELINUX will unload the PXE and UNDI stacks before invoking
+the kernel. In special circumstances (for example, when using MEMDISK
+to boot an operating system with an UNDI network driver) it might be
+desirable to keep the PXE stack in memory. If the option "keeppxe"
+is given on the kernel command line, PXELINUX will keep the PXE and
+UNDI stacks in memory. (If you don't know what this means, you
+probably don't need it.)
+
+
++++ CURRENTLY KNOWN PROBLEMS ++++
The following problems are known with PXELINUX, so far:
@@ -309,10 +320,6 @@ The following problems are known with PXELINUX, so far:
+ Requires a TFTP server which supports the "tsize" option.
+ The error recovery routine doesn't work quite right. For right now,
it just does a hard reset - seems good enough.
-+ There may be funnies with memory management. The PXE spec has no
- decent way of telling it to free up all memory and unchain any
- interrupts; it allows the base stack to be unloaded, but not the
- UNDI driver.
+ We should probably call the UDP receive function in the keyboard
entry loop, so that we answer ARP requests.
+ Boot sectors/disk images are not supported yet.
diff --git a/runkernel.inc b/runkernel.inc
index 3ee28f9b..f968168f 100644
--- a/runkernel.inc
+++ b/runkernel.inc
@@ -145,6 +145,16 @@ get_next_opt: lodsb
je is_vga_cmd
cmp eax,'mem='
je is_mem_cmd
+%if IS_PXELINUX
+ cmp eax,'keep' ; Is it "keeppxe"?
+ jne .notkeep
+ cmp dword [si+3],'ppxe'
+ jne .notkeep
+ cmp byte [si+7],' ' ; Must be whitespace or EOS
+ ja .notkeep
+ or byte [cs:KeepPXE],1
+.notkeep:
+%endif
push es ; Save ES -> real_mode_seg
push cs
pop es ; Set ES <- normal DS
@@ -152,6 +162,7 @@ get_next_opt: lodsb
mov cx,initrd_cmd_len
repe cmpsb
jne not_initrd
+
mov di,InitRD
push si ; mangle_dir mangles si
call mangle_name ; Mangle ramdisk name