[syslinux] PXELINUX: suggestion for improvement

Andy Polyakov appro at fy.chalmers.se
Fri Mar 8 08:02:14 PST 2002


Hi,

We're planning to deploy PXELINUX as a primary kernel loader in cluster
environment. Problem is that we plan to have IP numbers assigned
dynamically while there is no guarantee that all machines has same CPU
architecture. This makes IP-based config search algorithm inappropriate
for our purposes because we [naturally] expect loaded kernel to match
hardware. For this reason I've modified PXELINUX so that it attempts to
load config file chosen upon CPU architecture right after the one named
after assigned IP number. I mean it now attempts to load e.g. i686-smp
(naming algorithm is described in commentary section) right after
409EDEE3 and before proceeding to 409EDEE. The code was tested under
Managed PC Boot Agent (MBA) v4.30 by Lanworks/3Com, Intel Boot Agent
1.0.15 (Gigabit desktop adapter), 3.0.5 and 4.0.13 (100Mbit built-in
adapters), all PXE 2.x implementations, and with Intel MP Spec 1.1 and
1.4 compliant ASUS motherboards. In case you wonder DHCP service is
provided by ISC dhcpd 2.0.

Cheers. Andy.
-------------- next part --------------
Binary files ./pxelinux.0.orig and ./pxelinux.0 differ
*** ./pxelinux.asm.orig	Sun Feb  3 22:37:55 2002
--- ./pxelinux.asm	Fri Mar  8 12:08:22 2002
***************
*** 954,959 ****
--- 954,964 ----
  		jnz .success
  
  .badness:	popa
+ 		cmp	cx,9
+ 		jl	.skip_cpuid
+ 		call	check_cpuid
+ 		jnz	.success
+ .skip_cpuid:
  		dec di
  		loop .tryagain
  
***************
*** 4827,4832 ****
--- 4832,4990 ----
  		popad
  		ret
  
+ ;
+ ; check_cpuid by <appro at fy.chalmers.se>.
+ ;
+ ; This routine attempts to fetch config file based on CPU architecture
+ ; instead of [partial] IP number. Attempted file name matches following
+ ; expression:
+ ;
+ ;	[XY86|ipiv|ia64][-smp]
+ ;
+ ; where X is either 'a' for AMD or 'i' for all others, Y varies from 3
+ ; to 6 on non-AMD CPUs and from 4 to 7 on AMD with exclusion for AMD
+ ; x86-64 where Y turns 'w' (as in "wide":-). Intel P4 which is denoted
+ ; by 'ipiv', while Intel IA-64 family - by 'ia64' (assuming that if PXE
+ ; runs on IA-64, then it runs in IA-32 mode). For further details see
+ ; http://www.sandpile.org/ia32/cpuid.htm. Finally, '-smp' suffix is
+ ; appended on Intel MP 1.x compliant machines.
+ ;
+ check_cpuid:
+ 		push	dword [di-4]
+ 		push	dword [di-8]
+ 		pushad
+ 
+ 		mov	dword [di-8],'i386'
+ 		mov	dword [di-4],0
+ 
+ 		; check if we can change EFLAGS.ID
+ 		pushfd
+ 		pop	eax
+ 		mov	edx,eax
+ 		xor	eax,1<<21	; EFLAGS.ID
+ 		push	eax
+ 		popfd
+ 		pushfd
+ 		pop	eax
+ 		xor	eax,edx
+ 		and	eax,1<<21
+ 		jnz	.do_cpuid
+ .done_cpuid:
+ 		mov	si,trying_msg
+ 		call	writestr
+ 		mov	di,trackbuf
+ 		mov	si,di
+ 		call	writestr
+ 		call	crlf
+ 		call	open
+ 		popad
+ 		pop	dword [di-8]
+ 		pop	dword [di-4]
+ 		ret
+ 
+ .do_cpuid:
+ 		xor	eax,eax
+ 		cpuid
+ 		cmp	ecx,'cAMD'
+ 		jne	.not_amd
+ 		mov	byte [di-8],'a'
+ 		mov	eax,80000001h
+ 		cpuid
+ 		shr	eax,8
+ 		and	ax,0Fh
+ 		add	ax,'0'
+ 		mov	byte [di-7],al
+ 		and	edx,1<<29	; x86-64 Long Mode
+ 		jz	.smp_search
+ 		mov	byte [di-7],'w'
+ 		jmp	.smp_search
+ .not_amd:
+ 		mov	eax,1
+ 		cpuid
+ 		mov	edx,eax
+ 		shr	eax,8
+ 		and	ax,0Fh
+ 		cmp	ax,0Fh
+ 		je	.ext_family
+ 		add	ax,'0'
+ 		mov	byte [di-7],al
+ 		jmp	.smp_search
+ .ext_family:	shr	edx,20
+ 		and	dx,0FFh
+ 		jnz	.ia64
+ 		mov	dword [di-8],'ipiv'
+ 		jmp	.smp_search
+ .ia64:		mov	dword [di-8],'ia64'
+ ;
+ ; search for the MP Floating Pointer according to
+ ; http://www.intel.com/design/pro/datashts/242016.htm
+ ;
+ .smp_search:
+ 		push	es
+ 		mov	ax,040Eh	; First 1KB of Extended BIOS Data Area
+ 		mov	es,ax
+ 		mov	cx,1024/16
+ 		call	smp_scan_config
+ 		je	.smp_found
+ 
+ %if 1
+ 		int	12h
+ 		dec	ax		; Last KB of system base memory
+ 		shl	ax,6		; *1024/16
+ %else
+ 		mov	ax,639*1024/16	; This is how Linux does it...
+ %endif
+ 		mov	es,ax
+ 		mov	cx,1024/16
+ 		call	smp_scan_config
+ 		je	.smp_found
+ 
+ 		mov	ax,0F000h	; Last 64K of BIOS
+ 		mov	es,ax
+ 		mov	cx,64*1024/16
+ 		call	smp_scan_config
+ 		jne	.smp_done
+ .smp_found:	mov	dword [di-4],'-smp'
+ .smp_done:	pop	es
+ 		jmp	.done_cpuid
+ 
+ smp_scan_config:
+ 		xor	esi,esi
+ 		jmp	.scan_first
+ .scan_lap:	add	si,16
+ .scan_first:	cmp	dword [es:si],'_MP_'	; signature
+ .scan_loop:	loopne	.scan_lap
+ 		je	._mp_found
+ 		ret
+ 
+ ._mp_found:	inc	cx		; we're going though loop instruction
+ 					; one more time
+ 		cmp	byte [es:si+8],1; length is expected to be 1 paragraph
+ 		jne	.scan_loop
+ 		xor	eax,eax
+ 		add	al,byte [es:si+0]
+ 		add	al,byte [es:si+1]
+ 		add	al,byte [es:si+2]
+ 		add	al,byte [es:si+3]
+ 		add	al,byte [es:si+4]
+ 		add	al,byte [es:si+5]
+ 		add	al,byte [es:si+6]
+ 		add	al,byte [es:si+7]
+ 		add	al,byte [es:si+8]
+ 		add	al,byte [es:si+9]
+ 		add	al,byte [es:si+10]
+ 		add	al,byte [es:si+11]
+ 		add	al,byte [es:si+12]
+ 		add	al,byte [es:si+13]
+ 		add	al,byte [es:si+14]
+ 		add	al,byte [es:si+15]
+ 		cmp	al,0		; whole paragraph is expected to
+ 					; add up to zero
+ 		jne	.scan_loop
+ 		ret
+ ;
+ ; end of check_cpuid
+ ;
  
  		; Map colors to consecutive DAC registers
  linear_color	db 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0


More information about the Syslinux mailing list