Chris Newton
2004-Oct-07 14:39 UTC
[syslinux] x86 vs. x86_64 detection proof of concept patch (try two)
Greetings all, Sorry, resending this with the attachment inline. First of all, a disclaimer: Please forgive my horrible assembly code. This is just a quick munging of code to achieve x86 versus x86_64 detection within pxelinux. So please look at it as a proof of concept and not a real piece of code. :) For example it only works on pxelinux and has no thought for extending it beyond simple x86 versus x86_64 architectures. I had the need for pxelinux to be able to detect if the cpu its running on is a x86 or x86_64 machine. Seeing as the two opteron motherboards I have don't specify any difference in the PXE identification string in the DHCP discover packets they send out. So I have copied some code from the linux kernel for detecting the cpu and added in a 'kernel64' configuration option. The kernel64 option is ignored if the cpu is not a x86_64. So my machines can now boot with a 32bit or 64bit kernel depending on their architecture. I did not put in a similar append64 option because my initrd works for both kind of kernels. Hopefully this can benefit someone. :) Best of luck. -- J. Christopher Newton Software Engineer Aspen Systems, Inc. 3900 Youngfield Street Wheat Ridge, Co 80033 Tel +01 (303) 431-4606 Ext. 132 Fax +01 (303) 431-7196 Email: chrisn at aspsys.com www.aspsys.com Common subdirectories: syslinux-2.11/com32 and syslinux-2.11.new/com32 diff -u syslinux-2.11/keywords syslinux-2.11.new/keywords --- syslinux-2.11/keywords 2004-05-29 16:11:23.000000000 -0600 +++ syslinux-2.11.new/keywords 2004-10-04 17:33:54.000000000 -0600 @@ -7,6 +7,7 @@ ipappend kbdmap kernel +kernel64 label localboot prompt diff -u syslinux-2.11/keywords.inc syslinux-2.11.new/keywords.inc --- syslinux-2.11/keywords.inc 2004-05-29 16:11:23.000000000 -0600 +++ syslinux-2.11.new/keywords.inc 2004-10-04 17:33:55.000000000 -0600 @@ -52,6 +52,7 @@ keyword implicit, pc_setint16, AllowImplicit keyword kbdmap, pc_filecmd, loadkeys keyword kernel, pc_kernel + keyword kernel64, pc_kernel64 keyword label, pc_label keyword prompt, pc_setint16, ForcePrompt keyword say, pc_say Common subdirectories: syslinux-2.11/memdisk and syslinux-2.11.new/memdisk Common subdirectories: syslinux-2.11/menu and syslinux-2.11.new/menu diff -u syslinux-2.11/parseconfig.inc syslinux-2.11.new/parseconfig.inc --- syslinux-2.11/parseconfig.inc 2003-11-26 22:36:16.000000000 -0700 +++ syslinux-2.11.new/parseconfig.inc 2004-10-04 17:33:55.000000000 -0600 @@ -100,6 +100,17 @@ .err: ret ; +; "kernel64" command +pc_kernel64: cmp word [VKernelCtr],byte 0 + je .err ; ("label" section only) + cmp word [CpuIs64], 0 + je .err ; Ignore if kernel cpu is 32bit + call pc_getline + mov di,VKernelBuf+vk_rname + call mangle_name +.err: ret + +; ; "timeout" command ; pc_timeout: call getint diff -u syslinux-2.11/pxelinux.asm syslinux-2.11.new/pxelinux.asm --- syslinux-2.11/pxelinux.asm 2004-08-04 00:16:53.000000000 -0600 +++ syslinux-2.11.new/pxelinux.asm 2004-10-04 17:33:56.000000000 -0600 @@ -304,6 +304,7 @@ command_line resb max_cmd_len+2 ; Command line buffer alignb 4 default_cmd resb max_cmd_len+1 ; "default" command line +CpuIs64 resw 1 ; Is this cpu a x86_64 machine? ; ; PXE packets which don't need static initialization @@ -392,6 +393,27 @@ call writestr ; +; ID the CPU: Shamelessly borrowed from the Linux kernel arch/x86_64/kernel/head.S +; + mov word [CpuIs64], 0 + mov eax, 80000000h + cpuid + cmp eax, 80000000h + jbe afterbits + ; Check if long mode is implemented + mov eax, 80000001h + cpuid + bt edx, 29 + jnc afterbits + mov word [CpuIs64], 1 +afterbits: + mov si, cpu64_str + cmp word [CpuIs64], 1 + je writecpustr + mov si, cpu32_str +writecpustr: 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 -- @@ -2366,6 +2388,8 @@ default_str db 'default', 0 default_len equ ($-default_str) syslinux_banner db CR, LF, 'PXELINUX ', version_str, ' ', date, ' ', 0 +cpu32_str db 'CPUID: x86', CR, LF, 0 +cpu64_str db 'CPUID: x86_64', CR, LF, 0 cfgprefix db 'pxelinux.cfg/' ; No final null! cfgprefix_len equ ($-cfgprefix) Common subdirectories: syslinux-2.11/sample and syslinux-2.11.new/sample Common subdirectories: syslinux-2.11/win32 and syslinux-2.11.new/win32
H. Peter Anvin
2004-Oct-07 18:17 UTC
[syslinux] x86 vs. x86_64 detection proof of concept patch (try two)
Chris Newton wrote:> Greetings all, > > Sorry, resending this with the attachment inline. > > First of all, a disclaimer: Please forgive my horrible assembly code. > This is just a quick munging of code to achieve x86 versus x86_64 > detection within pxelinux. So please look at it as a proof of concept > and not a real piece of code. :) For example it only works on pxelinux > and has no thought for extending it beyond simple x86 versus x86_64 > architectures. > > I had the need for pxelinux to be able to detect if the cpu its running > on is a x86 or x86_64 machine. Seeing as the two opteron motherboards I > have don't specify any difference in the PXE identification string in > the DHCP discover packets they send out. So I have copied some code from > the linux kernel for detecting the cpu and added in a 'kernel64' > configuration option. The kernel64 option is ignored if the cpu is not a > x86_64. > > So my machines can now boot with a 32bit or 64bit kernel depending on > their architecture. I did not put in a similar append64 option because > my initrd works for both kind of kernels. > > Hopefully this can benefit someone. :) Best of luck. >I think this kind of things are better done with a comboot image, mostly because x86 vs x86-64 is only one of *many* selections one may wish to make when selecting a kernel. Some people would want to have i586/i686/athlon/pentium4/k8/em64t kernels on tap, for example. -hpa