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

📄 pxelinux.asm

📁 Windows上的精简Linux系统
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		call writehex4		call crlf		mov si,undi_code_msg		call writestr		mov ax,[es:bx+32h]		call writehex8		call crlf		mov si,undi_code_len_msg		call writestr		mov ax,[es:bx+36h]		call writehex4		call crlf		; Compute base memory size from !PXE structure		xor esi,esi		mov eax,[es:bx+2Ah]		cmp eax,[es:bx+32h]		ja .use_data		mov eax,[es:bx+32h]		mov si,[es:bx+36h]		jmp short .combine.use_data:		mov si,[es:bx+2Eh].combine:		add eax,esi		shr eax,10		mov [RealBaseMem],ax		mov si,pxeentry_msg		call writestr		mov ax,[PXEEntry+2]		call writehex4		mov al,':'		call writechr		mov ax,[PXEEntry]		call writehex4		call crlfhave_entrypoint:;; Clear Sockets structures;clear_sockets:		mov ax,ds	; Set ES <- DS		mov es,ax		mov di,Sockets		mov cx,(MAX_SOCKETS*tftp_port_t_size)/4		xor eax,eax		push di		rep stosd		pop di		; di <- Sockets		mov cx,MAX_SOCKETS.setbufptr:		mov [di+tftp_pktbuf],ax		add di,tftp_port_t_size		add ax,PKTBUF_SIZE		loop .setbufptr;; Now attempt to get the BOOTP/DHCP packet that brought us life (and an IP; address).  This lives in the DHCPACK packet (query info 2).;query_bootp:		mov di,pxe_bootp_query_pkt_2		mov bx,PXENV_GET_CACHED_INFO		call pxenv		push word [pxe_bootp_query_pkt_2.status]		jc .pxe_err1		cmp ax,byte 0		je .pxe_ok.pxe_err1:		mov di,pxe_bootp_size_query_pkt		mov bx,PXENV_GET_CACHED_INFO		call pxenv		jc .pxe_err.pxe_size:		mov ax,[pxe_bootp_size_query_pkt.buffersize]		call writehex4		call crlf.pxe_err:		mov si,err_pxefailed		call writestr		call writehex4		mov al, ' '		call writechr		pop ax				; Status		call writehex4		call crlf		jmp kaboom			; We're dead.pxe_ok:		pop cx				; Forget status		mov cx,[pxe_bootp_query_pkt_2.buffersize]		call parse_dhcp			; Parse DHCP packet;; Save away MAC address (assume this is in query info 2.  If this; turns out to be problematic it might be better getting it from; the query info 1 packet.);.save_mac:		movzx cx,byte [trackbuf+bootp.hardlen]		mov [MACLen],cl		mov al,[trackbuf+bootp.hardware]		mov [MACType],al		mov si,trackbuf+bootp.macaddr		mov di,MAC		push cx		rep movsb		mov cx,MAC+16		sub cx,di		xor ax,ax		rep stosb		pop cx				mov si,MACType		mov di,MACStr		inc cx		mov bx,hextbl_lower.hexify_mac:		lodsb		mov ah,al		shr al,4		xlatb		stosb		mov al,ah		and al,0Fh		xlatb		stosb		mov al,'-'		stosb		loop .hexify_mac		mov [di-1],byte 0		; Null-terminate and strip final colon;; Now, get the boot file and other info.  This lives in the CACHED_REPLY; packet (query info 3).;		mov [pxe_bootp_size_query_pkt.packettype], byte 3		mov di,pxe_bootp_query_pkt_3		mov bx,PXENV_GET_CACHED_INFO		call pxenv		push word [pxe_bootp_query_pkt_3.status]		jc .pxe_err1		cmp ax,byte 0		jne .pxe_err1		; Packet loaded OK...		pop cx				; Forget status		mov cx,[pxe_bootp_query_pkt_3.buffersize]		call parse_dhcp			; Parse DHCP packet;; Generate ip= option;		call genipopt;; Print IP address;		mov eax,[MyIP]		mov di,DotQuadBuf		push di		call gendotquad			; This takes network byte order input		xchg ah,al			; Convert to host byte order		ror eax,16			; (BSWAP doesn't work on 386)		xchg ah,al		mov si,myipaddr_msg		call writestr		call writehex8		mov al,' '		call writechr		pop si				; DotQuadBuf		call writestr		call crlf		mov si,IPOption		call writestr		call crlf;; Check to see if we got any PXELINUX-specific DHCP options; in particular,; if we didn't get the magic enable, do not recognize any other options.;check_dhcp_magic:		test byte [DHCPMagic], 1	; If we didn't get the magic enable...		jnz .got_magic		mov byte [DHCPMagic], 0		; If not, kill all other options.got_magic:	;; Initialize UDP stack;udp_init:		mov eax,[MyIP]		mov [pxe_udp_open_pkt.sip],eax		mov di,pxe_udp_open_pkt		mov bx,PXENV_UDP_OPEN		call pxenv		jc .failed		cmp word [pxe_udp_open_pkt.status], byte 0		je .success.failed:	mov si,err_udpinit		call writestr		jmp kaboom.success:;; Common initialization code;%include "cpuinit.inc";; Now we're all set to start with our *real* business.	First load the; configuration file (if any) and parse it.;; In previous versions I avoided using 32-bit registers because of a; rumour some BIOSes clobbered the upper half of 32-bit registers at; random.  I figure, though, that if there are any of those still left; they probably won't be trying to install Linux on them...;; The code is still ripe with 16-bitisms, though.  Not worth the hassle; to take'm out.  In fact, we may want to put them back if we're going; to boot ELKS at some point.;		mov si,linuxauto_cmd		; Default command: "linux auto"		mov di,default_cmd                mov cx,linuxauto_len		rep movsb		mov di,KbdMap			; Default keymap 1:1		xor al,al		mov cx,256mkkeymap:	stosb		inc al		loop mkkeymap;; Store standard filename prefix;prefix:		test byte [DHCPMagic], 04h	; Did we get a path prefix option		jnz .got_prefix		mov si,BootFile		mov di,PathPrefix		cld		call strcpy		lea cx,[di-PathPrefix-1]		std		lea si,[di-2]			; Skip final null!.find_alnum:	lodsb		or al,20h		cmp al,'.'			; Count . or - as alphanum		je .alnum		cmp al,'-'		je .alnum		cmp al,'0'		jb .notalnum		cmp al,'9'		jbe .alnum		cmp al,'a'		jb .notalnum		cmp al,'z'		ja .notalnum.alnum:		loop .find_alnum		dec si.notalnum:	mov byte [si+2],0		; Zero-terminate after delimiter		cld.got_prefix:		mov si,tftpprefix_msg		call writestr		mov si,PathPrefix		call writestr		call crlf;; Load configuration file;find_config:		mov di,trackbuf		mov si,cfgprefix		mov cx,cfgprefix_len		rep movsb;; Begin looking for configuration file;config_scan:		test byte [DHCPMagic], 02h		jz .no_option		; We got a DHCP option, try it first		push di		mov si,trying_msg		call writestr		mov di,ConfigName		mov si,di		call writestr		call crlf		call open		pop di		jnz .success.no_option:	; Have to guess config file name		; Try loading by MAC address		push di		mov si,MACStr		mov cx,(3*17+1)/2		rep movsw		mov si,trying_msg		call writestr		mov di,trackbuf		mov si,di		call writestr		call crlf		call open		pop di		jnz .success.scan_ip:		mov cx,8		mov eax,[MyIP]		xchg ah,al			; Convert to host byte order		ror eax,16		xchg ah,al.hexify_loop:	rol eax,4		push eax		and al,0Fh		cmp al,10		jae .high.low:		add al,'0'		jmp short .char.high:		add al,'A'-10.char:		stosb		pop eax		loop .hexify_loop		mov cx,9			; Up to 9 attempts.tryagain:	mov byte [di],0		cmp cx,byte 1		jne .not_default		pusha		mov si,default_str		mov cx,default_len		rep movsb			; Copy "default" string		popa.not_default:	pusha		mov si,trying_msg		call writestr		mov di,trackbuf		mov si,di		call writestr		call crlf		call open		popa		jnz .success		dec di		loop .tryagain		jmp no_config_file.success:;; Now we have the config file open.  Parse the config file and; run the user interface.;%include "ui.inc";; Linux kernel loading code is common.  However, we need to define; a couple of helper macros...;; Handle "ipappend" option%define HAVE_SPECIAL_APPEND%macro	SPECIAL_APPEND 0		test byte [IPAppend],01h	; ip=		jz .noipappend1		mov si,IPOption		mov cx,[IPOptionLen]		rep movsb		mov al,' '		stosb.noipappend1:		test byte [IPAppend],02h		jz .noipappend2		mov si,bootif_str		mov cx,bootif_str_len		rep movsb		mov si,MACStr		call strcpy		mov byte [es:di-1],' '		; Replace null with space.noipappend2:%endmacro; Unload PXE stack%define HAVE_UNLOAD_PREP%macro	UNLOAD_PREP 0		call unload_pxe%endmacro%include "runkernel.inc";; COMBOOT-loading code;%include "comboot.inc"%include "com32.inc"%include "cmdline.inc";; Boot sector loading code;%include "bootsect.inc";; Boot to the local disk by returning the appropriate PXE magic.; AX contains the appropriate return code.;local_boot:		mov si,cs		mov ds,si			; Restore DI		lss esp,[BaseStack]		mov [LocalBootType],ax		call vgaclearmode		mov si,localboot_msg		call writestr		; Restore the environment we were called with		lss sp,[InitStack]		pop gs		pop fs		pop es		pop ds		popad		mov ax,[cs:LocalBootType]		popfd		retf				; Return to PXE;; abort_check: let the user abort with <ESC> or <Ctrl-C>;abort_check:		call pollchar		jz ac_ret1		pusha		call getchar		cmp al,27			; <ESC>		je ac_kill		cmp al,3			; <Ctrl-C>		jne ac_ret2ac_kill:	mov si,aborted_msg;; abort_load: Called by various routines which wants to print a fatal;             error message and return to the command prompt.  Since this;             may happen at just about any stage of the boot process, assume;             our state is messed up, and just reset the segment registers;             and the stack forcibly.;;             SI    = offset (in _text) of error message to print;abort_load:                mov ax,cs                       ; Restore CS = DS = ES                mov ds,ax                mov es,ax		lss esp,[BaseStack]		sti                call cwritestr                  ; Expects SI -> error msgal_ok:          jmp enter_command               ; Return to command prompt;; End of abort_check;ac_ret2:	popaac_ret1:	ret;; kaboom: write a message and bail out.  Wait for quite a while,;	  or a user keypress, then do a hard reboot.;kaboom:		mov ax,cs		mov es,ax		mov ds,ax		lss esp,[BaseStack]		sti.patch:		mov si,bailmsg		call writestr		; Returns with AL = 0.drain:		call pollchar		jz .drained		call getchar		jmp short .drain.drained:		mov edi,[RebootTime]		mov al,[DHCPMagic]		and al,09h		; Magic+Timeout		cmp al,09h		je .time_set		mov edi,REBOOT_TIME.time_set:		mov cx,18.wait1:		push cx		mov ecx,edi.wait2:		mov dx,[BIOS_timer].wait3:		call pollchar		jnz .keypress		cmp dx,[BIOS_timer]		je .wait3		loop .wait2,ecx		mov al,'.'		call writechr		pop cx		loop .wait1.keypress:		call crlf		mov word [BIOS_magic],0	; Cold reboot		jmp 0F000h:0FFF0h	; Reset vector address;; memory_scan_for_pxe_struct:;;	If none of the standard methods find the !PXE structure, look for it;	by scanning memory.

⌨️ 快捷键说明

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