⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pxelinux.asm

📁 Windows上的精简Linux系统
💻 ASM
📖 第 1 页 / 共 5 页
字号:
; -*- fundamental -*- (asm-mode sucks); $Id: pxelinux.asm,v 1.146 2004/05/29 22:11:23 hpa Exp $; ****************************************************************************;;  pxelinux.asm;;  A program to boot Linux kernels off a TFTP server using the Intel PXE;  network booting API.  It is based on the SYSLINUX boot loader for;  MS-DOS floppies.;;   Copyright (C) 1994-2004  H. Peter Anvin;;  This program is free software; you can redistribute it and/or modify;  it under the terms of the GNU General Public License as published by;  the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,;  USA; either version 2 of the License, or (at your option) any later;  version; incorporated herein by reference.; ; ****************************************************************************%define IS_PXELINUX 1%include "macros.inc"%include "config.inc"%include "kernel.inc"%include "bios.inc"%include "tracers.inc"%include "pxe.inc";; Some semi-configurable constants... change on your own risk.;my_id		equ pxelinux_idFILENAME_MAX_LG2 equ 7			; log2(Max filename size Including final null)FILENAME_MAX	equ (1 << FILENAME_MAX_LG2)NULLFILE	equ 0			; Zero byte == null file nameREBOOT_TIME	equ 5*60		; If failure, time until full reset%assign HIGHMEM_SLOP 128*1024		; Avoid this much memory near the topMAX_SOCKETS_LG2	equ 5			; log2(Max number of open sockets)MAX_SOCKETS	equ (1 << MAX_SOCKETS_LG2)PKTBUF_SIZE	equ (65536/MAX_SOCKETS)	; Per-socket packet buffer sizeTFTP_PORT	equ htons(69)		; Default TFTP port PKT_RETRY	equ 6			; Packet transmit retry countPKT_TIMEOUT	equ 12			; Initial timeout, timer ticks @ 55 ms; Desired TFTP block size; For Ethernet MTU is normally 1500.  Unfortunately there seems to; be a fair number of networks with "substandard" MTUs which break.; The code assumes TFTP_LARGEBLK <= 2K.TFTP_MTU	equ 1472TFTP_LARGEBLK	equ (TFTP_MTU-20-8-4)	; MTU - IP hdr - UDP hdr - TFTP hdr; Standard TFTP block sizeTFTP_BLOCKSIZE_LG2 equ 9		; log2(bytes/block)TFTP_BLOCKSIZE	equ (1 << TFTP_BLOCKSIZE_LG2)%assign USE_PXE_PROVIDED_STACK 1	; Use stack provided by PXE?;; This is what we need to do when idle;%macro	RESET_IDLE 0	call reset_idle%endmacro%macro	DO_IDLE 0	call check_for_arp%endmacro;; TFTP operation codes;TFTP_RRQ	equ htons(1)		; Read requestTFTP_WRQ	equ htons(2)		; Write requestTFTP_DATA	equ htons(3)		; Data packetTFTP_ACK	equ htons(4)		; ACK packetTFTP_ERROR	equ htons(5)		; ERROR packetTFTP_OACK	equ htons(6)		; OACK packet;; TFTP error codes;TFTP_EUNDEF	equ htons(0)		; Unspecified errorTFTP_ENOTFOUND	equ htons(1)		; File not foundTFTP_EACCESS	equ htons(2)		; Access violationTFTP_ENOSPACE	equ htons(3)		; Disk fullTFTP_EBADOP	equ htons(4)		; Invalid TFTP operationTFTP_EBADID	equ htons(5)		; Unknown transferTFTP_EEXISTS	equ htons(6)		; File existsTFTP_ENOUSER	equ htons(7)		; No such userTFTP_EOPTNEG	equ htons(8)		; Option negotiation failure;; The following structure is used for "virtual kernels"; i.e. LILO-style; option labels.  The options we permit here are `kernel' and `append; Since there is no room in the bottom 64K for all of these, we; stick them at vk_seg:0000 and copy them down before we need them.;; Note: this structure can be added to, but it must ;%define vk_power	6		; log2(max number of vkernels)%define	max_vk		(1 << vk_power)	; Maximum number of vkernels%define vk_shift	(16-vk_power)	; Number of bits to shift%define vk_size		(1 << vk_shift)	; Size of a vkernel buffer		struc vkernelvk_vname:	resb FILENAME_MAX	; Virtual name **MUST BE FIRST!**vk_rname:	resb FILENAME_MAX	; Real namevk_ipappend:	resb 1			; "IPAPPEND" flag		resb 1			; Padvk_appendlen:	resw 1		alignb 4vk_append:	resb max_cmd_len+1	; Command line		alignb 4vk_end:		equ $			; Should be <= vk_size		endstruc%ifndef DEPEND%if (vk_end > vk_size) || (vk_size*max_vk > 65536)%error "Too many vkernels defined, reduce vk_power"%endif%endif;; Segment assignments in the bottom 640K; 0000h - main code/data segment (and BIOS segment);real_mode_seg	equ 4000hvk_seg          equ 3000h		; Virtual kernelsxfer_buf_seg	equ 2000h		; Bounce buffer for I/O to high mempktbuf_seg	equ 1000h		; Packet buffers segmentscomboot_seg	equ real_mode_seg	; COMBOOT image loading zone;; BOOTP/DHCP packet pattern;		struc bootp_t		bootp:.opcode		resb 1			; BOOTP/DHCP "opcode".hardware	resb 1			; ARP hardware type.hardlen	resb 1			; Hardware address length.gatehops	resb 1			; Used by forwarders.ident		resd 1			; Transaction ID.seconds	resw 1			; Seconds elapsed.flags		resw 1			; Broadcast flags.cip		resd 1			; Client IP.yip		resd 1			; "Your" IP.sip		resd 1			; Next server IP.gip		resd 1			; Relay agent IP.macaddr	resb 16			; Client MAC address.sname		resb 64			; Server name (optional).bootfile	resb 128		; Boot file name.option_magic	resd 1			; Vendor option magic cookie.options	resb 1260		; Vendor options		endstruc	BOOTP_OPTION_MAGIC	equ htonl(0x63825363)	; See RFC 2132;; TFTP connection data structure.  Each one of these corresponds to a local; UDP port.  The size of this structure must be a power of 2.; HBO = host byte order; NBO = network byte order; (*) = written by options negotiation code, must be dword sized;		struc tftp_port_ttftp_localport	resw 1			; Local port number	(0 = not in use)tftp_remoteport	resw 1			; Remote port numbertftp_remoteip	resd 1			; Remote IP addresstftp_filepos	resd 1			; Bytes downloaded (including buffer)tftp_filesize	resd 1			; Total file size(*)tftp_blksize	resd 1			; Block size for this connection(*)tftp_bytesleft	resw 1			; Unclaimed data bytestftp_lastpkt	resw 1			; Sequence number of last packet (NBO)tftp_dataptr	resw 1			; Pointer to available data		resw 2			; Currently unusued		; At end since it should not be zeroed on socked closetftp_pktbuf	resw 1			; Packet buffer offset		endstructftp_clear_words equ (tftp_pktbuf/2)	; Number of words to zero on socket close%ifndef DEPEND%if (tftp_port_t_size & (tftp_port_t_size-1))%error "tftp_port_t is not a power of 2"%endif%endif; ---------------------------------------------------------------------------;   BEGIN CODE; ---------------------------------------------------------------------------;; Memory below this point is reserved for the BIOS and the MBR; 		absolute 1000htrackbuf	resb 8192		; Track buffer goes heretrackbufsize	equ $-trackbuf;		trackbuf ends at 3000h;; Constants for the xfer_buf_seg;; The xfer_buf_seg is also used to store message file buffers.  We; need two trackbuffers (text and graphics), plus a work buffer; for the graphics decompressor.;xbs_textbuf	equ 0			; Also hard-coded, do not changexbs_vgabuf	equ trackbufsizexbs_vgatmpbuf	equ 2*trackbufsize                absolute 4000h          ; Here we keep our BSS stuffVKernelBuf:	resb vk_size		; "Current" vkernel		alignb 4AppendBuf       resb max_cmd_len+1	; append=Ontimeout	resb max_cmd_len+1	; ontimeoutOnerror		resb max_cmd_len+1	; onerrorKbdMap		resb 256		; Keyboard mapPathPrefix	resb 256		; Path prefix derived from the aboveBootFile	resb 256		; Boot file from DHCP packetConfigName	resb 256		; Configuration file from DHCP optionFKeyName	resb 10*FILENAME_MAX	; File names for F-key help		alignb FILENAME_MAXKernelName      resb FILENAME_MAX       ; Mangled name for kernelKernelCName     resb FILENAME_MAX	; Unmangled kernel nameInitRDCName     resb FILENAME_MAX       ; Unmangled initrd nameMNameBuf	resb FILENAME_MAXInitRD		resb FILENAME_MAX; Warning here: RBFG build 22 randomly overwrites memory location; [0x5680,0x576c), possibly more.  It seems that it gets confused and; screws up the pointer to its own internal packet buffer and starts; writing a received ARP packet into low memory.		absolute 6000hNumBuf		resb 15			; Buffer to load numberNumBufEnd	resb 1			; Last byte in NumBufDotQuadBuf	resb 16			; Buffer for dotted-quad IP addressIPOption	resb 80			; ip= option bufferMACLen		resb 1			; MAC address lenMACType		resb 1			; MAC address typeMAC		resb 16			; Actual MAC addressMACStr		resb 3*17		; MAC address as a stringPartInfo	resb 16			; Partition table entryE820Buf		resd 5			; INT 15:E820 data bufferE820Mem		resd 1			; Memory detected by E820E820Max		resd 1			; Is E820 memory capped?HiLoadAddr      resd 1			; Address pointer for high load loopHighMemSize	resd 1			; End of memory pointer (bytes)RamdiskMax	resd 1			; Highest address for a ramdiskKernelSize	resd 1			; Size of kernel (bytes)SavedSSSP	resd 1			; Our SS:SP while running a COMBOOT imagePMESP		resd 1			; Protected-mode ESPInitStack	resd 1			; Pointer to reset stackRebootTime	resd 1			; Reboot timeout, if set by optionKernelClust	resd 1			; Kernel size in clustersStrucPtr	resd 1			; Pointer to PXENV+ or !PXE structureFBytes		equ $			; Used by open/getcFBytes1		resw 1FBytes2		resw 1FClust		resw 1			; Number of clusters in open/getc fileFNextClust	resw 1			; Pointer to next cluster in d:oFPtr		resw 1			; Pointer to next char in bufferCmdOptPtr       resw 1			; Pointer to first option on cmd lineKernelCNameLen  resw 1			; Length of unmangled kernel nameInitRDCNameLen  resw 1			; Length of unmangled initrd nameNextCharJump    resw 1			; Routine to interpret next print charSetupSecs	resw 1			; Number of setup sectorsA20Test		resw 1			; Counter for testing status of A20A20Type		resw 1			; A20 typeCmdLineLen	resw 1			; Length of command line including nullGraphXSize	resw 1			; Width of splash screen fileVGAPos		resw 1			; Pointer into VGA memoryVGACluster	resw 1			; Cluster pointer for VGA image fileVGAFilePtr	resw 1			; Pointer into VGAFileBufCom32SysSP	resw 1			; SP saved during COM32 syscallConfigFile	resw 1			; Socket for config filePktTimeout	resw 1			; Timeout for current packetKernelExtPtr	resw 1			; During search, final null pointerIPOptionLen	resw 1			; Length of IPOptionLocalBootType	resw 1			; Local boot return codeRealBaseMem	resw 1			; Amount of DOS memory after freeingAPIVer		resw 1			; PXE API version foundIdleTimer	resw 1			; Time to check for ARP?CursorDX        equ $CursorCol       resb 1			; Cursor column for message fileCursorRow       resb 1			; Cursor row for message fileScreenSize      equ $VidCols         resb 1			; Columns on screen-1VidRows         resb 1			; Rows on screen-1BaudDivisor	resw 1			; Baud rate divisorFlowControl	equ $FlowOutput	resb 1			; Outputs to assert for serial flowFlowInput	resb 1			; Input bits for serial flowFlowIgnore	resb 1			; Ignore input unless these bits setTextAttribute   resb 1			; Text attribute for message fileRetryCount      resb 1			; Used for disk access retriesKbdFlags	resb 1			; Check for keyboard escapesLoadFlags	resb 1			; Loadflags from kernelA20Tries	resb 1			; Times until giving up on A20FuncFlag	resb 1			; == 1 if <Ctrl-F> pressedDisplayMask	resb 1			; Display modes maskOverLoad	resb 1			; Set if DHCP packet uses "overloading"TextColorReg	resb 17			; VGA color registers for text modeVGAFileBuf	resb FILENAME_MAX	; Unmangled VGA image nameVGAFileBufEnd	equ $VGAFileMBuf	resb FILENAME_MAX	; Mangled VGA image name;; PXE packets which don't need static initialization;		alignb 4pxe_unload_stack_pkt:.status:	resw 1			; Status.reserved:	resw 10			; Reservedpxe_unload_stack_pkt_len	equ $-pxe_unload_stack_pkt		alignb tftp_port_t_sizeSockets		resb MAX_SOCKETS*tftp_port_t_size		alignb 16		; BOOTP/DHCP packet buffer		alignb 16packet_buf	resb 2048		; Transfer packetpacket_buf_size	equ $-packet_buf		section .text                org 7C00hStackBuf	equ $-44		; Base of stack if we use our own;; Primary entry point.;bootsec		equ $_start:		jmp 0:_start1		; Canonicalize address_start1:		pushfd			; Paranoia... in case of return to PXE		pushad			; ... save as much state as possible		push ds		push es		push fs		push gs		mov bp,sp		les bx,[bp+48]		; ES:BX -> !PXE or PXENV+ structure		mov ax,cs		mov ds,ax		; That is all pushed onto the PXE stack.  Save the pointer		; to it and switch to an internal stack.		mov [InitStack],sp		mov [InitStack+2],ss%if USE_PXE_PROVIDED_STACK		; Apparently some platforms go bonkers if we		; set up our own stack...		mov [BaseStack],sp		mov [BaseStack+4],ss%endif		cli			; Paranoia		lss esp,[BaseStack]		sti			; Stack set up and ready		cld			; Copy upwards;; Initialize screen (if we're using one);		; Now set up screen parameters		call adjust_screen		; Wipe the F-key area		mov al,NULLFILE		mov di,FKeyName		mov cx,10*(1 << FILENAME_MAX_LG2)		push es			; Save ES -> PXE structure		push ds			; ES <- DS		pop es		rep stosb		pop es			; Restore ES;; Tell the user we got this far;		mov si,syslinux_banner		call writestr		mov si,copyright_str		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.; FIX: ES:BX should point to the PXENV+ structure on entry as well.; We should make that the second test, and not trash ES:BX...; 		cmp dword [es:bx], '!PXE'		je have_pxe		; Uh-oh, not there... try plan B		mov ax, 5650h		int 1Ah					; May trash regs		jc no_pxe		cmp ax,564Eh		jne no_pxe		; Okay, that gave us the PXENV+ structure, find !PXE		; structure from that (if available)		cmp dword [es:bx], 'PXEN'		jne no_pxe		cmp word [es:bx+4], 'V+'		je have_pxenv		; Nothing there either.  Last-ditch: scan memory		call memory_scan_for_pxe_struct		; !PXE scan		jnc have_pxe		call memory_scan_for_pxenv_struct	; PXENV+ scan		jnc have_pxenvno_pxe:		mov si,err_nopxe		call writestr		jmp kaboomhave_pxenv:		mov [StrucPtr],bx		mov [StrucPtr+2],es		mov si,found_pxenv		call writestr		mov si,apiver_str		call writestr		mov ax,[es:bx+6]		mov [APIVer],ax		call writehex4		call crlf		cmp ax,0201h			; API version 2.1 or higher		jb old_api		mov si,bx		mov ax,es		les bx,[es:bx+28h]		; !PXE structure pointer		cmp dword [es:bx],'!PXE'		je have_pxe		; Nope, !PXE structure missing despite API 2.1+, or at least		; the pointer is missing.  Do a last-ditch attempt to find it.		call memory_scan_for_pxe_struct		jnc have_pxe		; Otherwise, no dice, use PXENV+ structure		mov bx,si		mov es,axold_api:	; Need to use a PXENV+ structure		mov si,using_pxenv_msg		call writestr		mov eax,[es:bx+0Ah]		; PXE RM API		mov [PXENVEntry],eax		mov si,undi_data_msg		; ***		call writestr		mov ax,[es:bx+20h]		call writehex4		call crlf		mov si,undi_data_len_msg		call writestr		mov ax,[es:bx+22h]		call writehex4		call crlf		mov si,undi_code_msg		call writestr		mov ax,[es:bx+24h]		call writehex4		call crlf		mov si,undi_code_len_msg		call writestr		mov ax,[es:bx+26h]		call writehex4		call crlf		; Compute base memory size from PXENV+ structure		xor esi,esi		movzx eax,word [es:bx+20h]	; UNDI data seg		cmp ax,[es:bx+24h]		; UNDI code seg		ja .use_data		mov ax,[es:bx+24h]		mov si,[es:bx+26h]		jmp short .combine.use_data:		mov si,[es:bx+22h].combine:		shl eax,4		add eax,esi		shr eax,10			; Convert to kilobytes		mov [RealBaseMem],ax		mov si,pxenventry_msg		call writestr		mov ax,[PXENVEntry+2]		call writehex4		mov al,':'		call writechr		mov ax,[PXENVEntry]		call writehex4		call crlf		jmp have_entrypointhave_pxe:		mov [StrucPtr],bx		mov [StrucPtr+2],es		mov eax,[es:bx+10h]		mov [PXEEntry],eax		mov si,undi_data_msg		; ***		call writestr		mov eax,[es:bx+2Ah]		call writehex8		call crlf		mov si,undi_data_len_msg		call writestr		mov ax,[es:bx+2Eh]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -