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

📄 pxelinux.asm

📁 linux内核
💻 ASM
📖 第 1 页 / 共 4 页
字号:
		movzx ecx,word [4*0x1a+2]		shl ecx,4		add eax,ecx		shr eax,10		cmp ax,dx			; Not in range		jae .ok		cmp ax,[BIOS_fbm]		jae .cant_free		; inc bx.ok:		mov [BIOS_fbm],dx.pop_ret:		pop es		pop ds		ret		.cant_free:		mov si,cant_free_msg		call writestr		push ax		xchg bx,ax		call writehex4		mov al,'-'		call writechr		pop ax		call writehex4		mov al,'-'		call writechr		mov eax,[4*0x1a]		call writehex8		call crlf		jmp .pop_ret		; We want to keep PXE around, but still we should reset		; it to the standard bootup configurationreset_pxe:		push es		push cs		pop es		mov bx,PXENV_UDP_CLOSE		mov di,pxe_udp_close_pkt		call pxenv		pop es		ret;; gendotquad;; Take an IP address (in network byte order) in EAX and; output a dotted quad string to ES:DI.; DI points to terminal null at end of string on exit.;gendotquad:		push eax		push cx		mov cx,4.genchar:		push eax		cmp al,10		; < 10?		jb .lt10		; If so, skip first 2 digits		cmp al,100		; < 100		jb .lt100		; If so, skip first digit		aam 100		; Now AH = 100-digit; AL = remainder		add ah,'0'		mov [es:di],ah		inc di.lt100:		aam 10		; Now AH = 10-digit; AL = remainder		add ah,'0'		mov [es:di],ah				inc di.lt10:		add al,'0'		stosb		mov al,'.'		stosb		pop eax		ror eax,8	; Move next char into LSB		loop .genchar		dec di		mov [es:di], byte 0		pop cx		pop eax		ret;; parse_dhcp;; Parse a DHCP packet.  This includes dealing with "overloaded"; option fields (see RFC 2132, section 9.3);; This should fill in the following global variables, if the; information is present:;; MyIP		- client IP address; ServerIP	- boot server IP address; Netmask	- network mask; Gateway	- default gateway router IP; BootFile	- boot file name; DNSServers	- DNS server IPs; LocalDomain	- Local domain name;; This assumes the DHCP packet is in "trackbuf" and the length; of the packet in in CX on entry.;parse_dhcp:		mov byte [OverLoad],0		; Assume no overload		mov eax, [trackbuf+bootp.yip]		and eax, eax		jz .noyip		cmp al,224			; Class D or higher -> bad		jae .noyip		mov [MyIP], eax.noyip:		mov eax, [trackbuf+bootp.sip]		and eax, eax		jz .nosip		cmp al,224			; Class D or higher -> bad		jae .nosip		mov [ServerIP], eax.nosip:		sub cx, bootp.options		jbe .nooptions		mov si, trackbuf+bootp.option_magic		lodsd		cmp eax, BOOTP_OPTION_MAGIC		jne .nooptions		call parse_dhcp_options.nooptions:		mov si, trackbuf+bootp.bootfile		test byte [OverLoad],1		jz .nofileoverload		mov cx,128		call parse_dhcp_options		jmp short .parsed_file.nofileoverload:		cmp byte [si], 0		jz .parsed_file			; No bootfile name		mov di,BootFile		mov cx,32		rep movsd		xor al,al		stosb				; Null-terminate.parsed_file:		mov si, trackbuf+bootp.sname		test byte [OverLoad],2		jz .nosnameoverload		mov cx,64		call parse_dhcp_options.nosnameoverload:		ret;; Parse a sequence of DHCP options, pointed to by DS:SI; the field; size is CX -- some DHCP servers leave option fields unterminated; in violation of the spec.;; For parse_some_dhcp_options, DH contains the minimum value for; the option to recognize -- this is used to restrict parsing to; PXELINUX-specific options only.;parse_dhcp_options:		xor dx,dxparse_some_dhcp_options:.loop:		and cx,cx		jz .done		lodsb		dec cx		jz .done	; Last byte; must be PAD, END or malformed		cmp al, 0	; PAD option		je .loop		cmp al,255	; END option		je .done		; Anything else will have a length field		mov dl,al	; DL <- option number		xor ax,ax		lodsb		; AX <- option length		dec cx		sub cx,ax	; Decrement bytes left counter		jb .done	; Malformed option: length > field size		cmp dl,dh	; Is the option value valid?		jb .opt_done		cmp dl,1	; SUBNET MASK option		jne .not_subnet		mov ebx,[si]		mov [Netmask],ebx		jmp .opt_done.not_subnet:		cmp dl,3	; ROUTER option		jne .not_router		mov ebx,[si]		mov [Gateway],ebx		jmp .opt_done.not_router:		cmp dl,6	; DNS SERVERS option		jne .not_dns		pusha		mov cx,ax		shr cx,2		cmp cl,DNS_MAX_SERVERS		jna .oklen		mov cl,DNS_MAX_SERVERS.oklen:		mov di,DNSServers		rep movsd		mov [LastDNSServer],di		popa		jmp .opt_done.not_dns:		cmp dl,15	; DNS LOCAL DOMAIN option		jne .not_localdomain		pusha		mov bx,si		add bx,ax		xor ax,ax		xchg [bx],al	; Zero-terminate option		mov di,LocalDomain		call dns_mangle	; Convert to DNS label set		mov [bx],al	; Restore ending byte		popa		jmp .opt_done.not_localdomain:		cmp dl,43	; VENDOR ENCAPSULATED option		jne .not_vendor		pusha		mov dh,208	; Only recognize PXELINUX options		mov cx,ax	; Length of option = max bytes to parse		call parse_some_dhcp_options	; Parse recursive structure		popa		jmp .opt_done.not_vendor:		cmp dl,52	; OPTION OVERLOAD option		jne .not_overload		mov bl,[si]		mov [OverLoad],bl		jmp .opt_done.not_overload:		cmp dl,67	; BOOTFILE NAME option		jne .not_bootfile		mov di,BootFile		jmp short .copyoption.done:		ret		; This is here to make short jumps easier.not_bootfile:		cmp dl,208	; PXELINUX MAGIC option		jne .not_pl_magic		cmp al,4	; Must have length == 4		jne .opt_done		cmp dword [si], htonl(0xF100747E)	; Magic number		jne .opt_done		or byte [DHCPMagic], byte 1		; Found magic #		jmp short .opt_done.not_pl_magic:		cmp dl,209	; PXELINUX CONFIGFILE option		jne .not_pl_config		mov di,ConfigName		or byte [DHCPMagic], byte 2	; Got config file		jmp short .copyoption.not_pl_config:		cmp dl,210	; PXELINUX PATHPREFIX option		jne .not_pl_prefix		mov di,PathPrefix		or byte [DHCPMagic], byte 4	; Got path prefix		jmp short .copyoption.not_pl_prefix:		cmp dl,211	; PXELINUX REBOOTTIME option		jne .not_pl_timeout		cmp al,4		jne .opt_done		mov ebx,[si]		xchg bl,bh	; Convert to host byte order		rol ebx,16		xchg bl,bh		mov [RebootTime],ebx		or byte [DHCPMagic], byte 8	; Got RebootTime		; jmp short .opt_done.not_pl_timeout:		; Unknown option.  Skip to the next one..opt_done:		add si,ax.opt_done_noskip:		jmp .loop		; Common code for copying an option verbatim.copyoption:		xchg cx,ax		rep movsb		xchg cx,ax	; Now ax == 0		stosb		; Null-terminate		jmp short .opt_done_noskip;; genipopt;; Generate an ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask>; option into IPOption based on a DHCP packet in trackbuf.; Assumes CS == DS == ES.;genipopt:		pushad		mov di,IPOption		mov eax,'ip='		stosd		dec di		mov eax,[MyIP]		call gendotquad		mov al,':'		stosb		mov eax,[ServerIP]		call gendotquad		mov al,':'		stosb		mov eax,[Gateway]		call gendotquad		mov al,':'		stosb		mov eax,[Netmask]		call gendotquad	; Zero-terminates its output		sub di,IPOption		mov [IPOptionLen],di		popad		ret;; Call the receive loop while idle.  This is done mostly so we can respond to; ARP messages, but perhaps in the future this can be used to do network; console.;; hpa sez: people using automatic control on the serial port get very; unhappy if we poll for ARP too often (the PXE stack is pretty slow,; typically.)  Therefore, only poll if at least 4 BIOS timer ticks have; passed since the last poll, and reset this when a character is; received (RESET_IDLE).;reset_idle:		push ax		mov ax,[cs:BIOS_timer]		mov [cs:IdleTimer],ax		pop ax		retcheck_for_arp:		push ax		mov ax,[cs:BIOS_timer]		sub ax,[cs:IdleTimer]		cmp ax,4		pop ax		jae .need_poll		ret.need_poll:	pushad		push ds		push es		mov ax,cs		mov ds,ax		mov es,ax		mov di,packet_buf		mov [pxe_udp_read_pkt.status],al	; 0		mov [pxe_udp_read_pkt.buffer],di		mov [pxe_udp_read_pkt.buffer+2],ds		mov word [pxe_udp_read_pkt.buffersize],packet_buf_size		mov eax,[MyIP]		mov [pxe_udp_read_pkt.dip],eax		mov word [pxe_udp_read_pkt.lport],htons(9)	; discard port		mov di,pxe_udp_read_pkt		mov bx,PXENV_UDP_READ		call pxenv		; Ignore result...		pop es		pop ds		popad		RESET_IDLE		ret; -----------------------------------------------------------------------------;  Common modules; -----------------------------------------------------------------------------%include "getc.inc"		; getc et al%include "conio.inc"		; Console I/O%include "writestr.inc"		; String outputwritestr	equ cwritestr%include "writehex.inc"		; Hexadecimal output%include "parseconfig.inc"	; High-level config file handling%include "parsecmd.inc"		; Low-level config file handling%include "bcopy32.inc"		; 32-bit bcopy%include "loadhigh.inc"		; Load a file into high memory%include "font.inc"		; VGA font stuff%include "graphics.inc"		; VGA graphics%include "highmem.inc"		; High memory sizing%include "strcpy.inc"		; strcpy()%include "rawcon.inc"		; Console I/O w/o using the console functions%include "dnsresolv.inc"	; DNS resolver; -----------------------------------------------------------------------------;  Begin data section; -----------------------------------------------------------------------------		section .datahextbl_lower	db '0123456789abcdef'copyright_str   db ' Copyright (C) 1994-', year, ' H. Peter Anvin'		db CR, LF, 0boot_prompt	db 'boot: ', 0wipe_char	db BS, ' ', BS, 0err_notfound	db 'Could not find kernel image: ',0err_notkernel	db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0err_noram	db 'It appears your computer has less than '		asciidec dosram_k		db 'K of low ("DOS")'		db CR, LF		db 'RAM.  Linux needs at least this amount to boot.  If you get'		db CR, LF		db 'this message in error, hold down the Ctrl key while'		db CR, LF		db 'booting, and I will take your word for it.', CR, LF, 0err_badcfg      db 'Unknown keyword in config file.', CR, LF, 0err_noparm      db 'Missing parameter in config file.', CR, LF, 0err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0err_nohighmem   db 'Not enough memory to load specified kernel.', CR, LF, 0err_highload    db CR, LF, 'Kernel transfer failure.', CR, LF, 0err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'                db CR, LF, 0err_notdos	db ': attempted DOS system call', CR, LF, 0err_comlarge	db 'COMBOOT image too large.', CR, LF, 0err_bssimage	db 'BSS images not supported.', CR, LF, 0err_a20		db CR, LF, 'A20 gate not responding!', CR, LF, 0err_bootfailed	db CR, LF, 'Boot failed: press a key to retry, or wait for reset...', CR, LF, 0bailmsg		equ err_bootfailederr_nopxe	db "No !PXE or PXENV+ API found; we're dead...", CR, LF, 0err_pxefailed	db 'PXE API call failed, error ', 0err_udpinit	db 'Failed to initialize UDP stack', CR, LF, 0err_oldtftp	db 'TFTP server does not support the tsize option', CR, LF, 0found_pxenv	db 'Found PXENV+ structure', CR, LF, 0using_pxenv_msg db 'Old PXE API detected, using PXENV+ structure', CR, LF, 0apiver_str	db 'PXE API version is ',0pxeentry_msg	db 'PXE entry point found (we hope) at ', 0pxenventry_msg	db 'PXENV entry point found (we hope) at ', 0trymempxe_msg	db 'Scanning memory for !PXE structure... ', 0trymempxenv_msg	db 'Scanning memory for PXENV+ structure... ', 0undi_data_msg	  db 'UNDI data segment at:   ',0undi_data_len_msg db 'UNDI data segment size: ',0 undi_code_msg	  db 'UNDI code segment at:   ',0undi_code_len_msg db 'UNDI code segment size: ',0 cant_free_msg	db 'Failed to free base memory, error ', 0notfound_msg	db 'not found', CR, LF, 0myipaddr_msg	db 'My IP address seems to be ',0tftpprefix_msg	db 'TFTP prefix: ', 0localboot_msg	db 'Booting from local disk...', CR, LF, 0cmdline_msg	db 'Command line: ', CR, LF, 0ready_msg	db 'Ready.', CR, LF, 0trying_msg	db 'Trying to load: ', 0crlfloading_msg	db CR, LF			; Fall throughloading_msg     db 'Loading ', 0dotdot_msg      db '.'dot_msg         db '.', 0fourbs_msg	db BS, BS, BS, BS, 0aborted_msg	db ' aborted.'			; Fall through to crlf_msg!crlf_msg	db CR, LFnull_msg	db 0crff_msg	db CR, FF, 0default_str	db 'default', 0default_len	equ ($-default_str)syslinux_banner	db CR, LF, 'PXELINUX ', version_str, ' ', date, ' ', 0cfgprefix	db 'pxelinux.cfg/'		; No final null!cfgprefix_len	equ ($-cfgprefix);; Command line options we'd like to take a look at;; mem= and vga= are handled as normal 32-bit integer valuesinitrd_cmd	db 'initrd='initrd_cmd_len	equ $-initrd_cmd; This one we make ourselvesbootif_str	db 'BOOTIF='bootif_str_len	equ $-bootif_str;; Config file keyword table;%include "keywords.inc";; Extensions to search for (in *forward* order).; (.bs and .bss are disabled for PXELINUX, since they are not supported);		align 4, db 0exten_table:	db '.cbt'		; COMBOOT (specific)		db '.0', 0, 0		; PXE bootstrap program		db '.com'		; COMBOOT (same as DOS)		db '.c32'		; COM32exten_table_end:		dd 0, 0			; Need 8 null bytes here;; PXE unload sequences;new_api_unload:		db PXENV_UDP_CLOSE		db PXENV_UNDI_SHUTDOWN		db PXENV_UNLOAD_STACK		db PXENV_STOP_UNDI		db 0old_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:.status:	dw 0			; Status.packettype:	dw 2			; DHCPACK packet.buffersize:	dw trackbufsize		; Packet size.buffer:	dw trackbuf, 0		; seg:off of buffer.bufferlimit:	dw trackbufsize		; Unusedpxe_bootp_query_pkt_3:.status:	dw 0			; Status.packettype:	dw 3			; Boot server packet.buffersize:	dw trackbufsize		; Packet size.buffer:	dw trackbuf, 0		; seg:off of buffer.bufferlimit:	dw trackbufsize		; Unusedpxe_bootp_size_query_pkt:.status:	dw 0			; Status.packettype:	dw 2			; DHCPACK packet.buffersize:	dw 0			; Packet size.buffer:	dw 0, 0			; seg:off of buffer.bufferlimit:	dw 0			; Unusedpxe_udp_open_pkt:.status:	dw 0			; Status.sip:		dd 0			; Source (our) IPpxe_udp_close_pkt:.status:	dw 0			; Statuspxe_udp_write_pkt:.status:	dw 0			; Status.sip:		dd 0			; Server IP.gip:		dd 0			; Gateway IP.lport:		dw 0			; Local port.rport:		dw 0			; Remote port.buffersize:	dw 0			; Size of packet.buffer:	dw 0, 0			; seg:off of bufferpxe_udp_read_pkt:.status:	dw 0			; Status.sip:		dd 0			; Source IP.dip:		dd 0			; Destination (our) IP.rport:		dw 0			; Remote port.lport:		dw 0			; Local port.buffersize:	dw 0			; Max packet size.buffer:	dw 0, 0			; seg:off of buffer;; Misc initialized (data) variables;		alignb 4, db 0BaseStack	dd StackBuf		; ESP of base stack		dw 0			; SS of base stackNextSocket	dw 49152		; Counter for allocating socket numbersKeepPXE		db 0			; Should PXE be kept around?;; TFTP commands;tftp_tail	db 'octet', 0				; Octet modetsize_str	db 'tsize' ,0				; Request sizetsize_len	equ ($-tsize_str)		db '0', 0blksize_str	db 'blksize', 0				; Request large blocksblksize_len	equ ($-blksize_str)		asciidec TFTP_LARGEBLK		db 0tftp_tail_len	equ ($-tftp_tail)		alignb 2, db 0;; Options negotiation parsing table (string pointer, string len, offset; into socket structure);tftp_opt_table:		dw tsize_str, tsize_len, tftp_filesize		dw blksize_str, blksize_len, tftp_blksizetftp_opts	equ ($-tftp_opt_table)/6;; Error packet to return on options negotiation error;tftp_opt_err	dw TFTP_ERROR				; ERROR packet		dw TFTP_EOPTNEG				; ERROR 8: bad options		db 'tsize option required', 0		; Error messagetftp_opt_err_len equ ($-tftp_opt_err)		alignb 4, db 0ack_packet_buf:	dw TFTP_ACK, 0				; TFTP ACK packet;; IP information (initialized to "unknown" values)MyIP		dd 0			; My IP addressServerIP	dd 0			; IP address of boot serverNetmask		dd 0			; Netmask of this subnetGateway		dd 0			; Default routerServerPort	dw TFTP_PORT		; TFTP server port;; Variables that are uninitialized in SYSLINUX but initialized here;		alignb 4, db 0BufSafe		dw trackbufsize/TFTP_BLOCKSIZE	; Clusters we can load into trackbufBufSafeSec	dw trackbufsize/512	; = how many sectors?BufSafeBytes	dw trackbufsize		; = how many bytes?EndOfGetCBuf	dw getcbuf+trackbufsize	; = getcbuf+BufSafeBytes%ifndef DEPEND%if ( trackbufsize % TFTP_BLOCKSIZE ) != 0%error trackbufsize must be a multiple of TFTP_BLOCKSIZE%endif%endifIPAppend	db 0			; Default IPAPPEND optionDHCPMagic	db 0			; DHCP site-specific option info

⌨️ 快捷键说明

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