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