From 172f1e3aae1ce8848ad4bb9574d1837d75b67ff5 Mon Sep 17 00:00:00 2001 From: hpa Date: Sat, 15 Jun 2002 05:24:25 +0000 Subject: [PATCH] Merge in changes from SYSLINUX 1.75 --- Makefile.private | 3 +- NEWS | 5 +++ bootsect.inc | 4 +- com32.inc | 3 +- pxe.inc | 6 ++- pxelinux.asm | 119 ++++++++++++++++++++++++++++++++++++++++++------------- pxelinux.doc | 15 +++++-- runkernel.inc | 11 +++++ 8 files changed, 126 insertions(+), 40 deletions(-) diff --git a/Makefile.private b/Makefile.private index 164400b..fee4f3b 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 42068e6..954c4e2 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 7d32ba8..d3e50fc 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 ac0440f..3d445c1 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 759115f..92da3bb 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 67894fa..125d018 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 6ee1777..04842f1 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 3ee28f9..f968168 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 -- 2.7.4