On Mon, Jun 9, 2008 at 1:08 PM, Frans Pop <[EMAIL PROTECTED]> wrote: > * Installer images for i386 and amd64 have a new boot menu using > syslinux's vesamenu. This allows for a more user-friendly selection > of for example the regular or graphical installer. For the multi- > architecture CD/DVD images this change means the 64-bits version of > the installer needs to be selected manually from the menu. See the > Installation Guide [2] for details on how to use the new menu.
Beta 2 is looking nice, but not having multi-arch boot detection was a bummer. So I took it upon myself to add the missing functionality to menu.c32/vesamenu.c32. I'm posting the patch here first because I Am Not A C Programmer(TM), and I really need more set of eyes on it. Functionally it seems to be working well, as I converted my own distro's[0] straight isolinux setup to a vesamenu system[1], and it's been guessing correctly on everything I've thrown at it so far. RF [0] http://www.finnix.org/ [1] http://www.finnix.org/Image:Finnix_dev_boot_menu.png
diff -ruN syslinux-3.63+dfsg-orig/com32/menu/menu.h syslinux-3.63+dfsg/com32/menu/menu.h --- syslinux-3.63+dfsg-orig/com32/menu/menu.h 2008-04-10 10:30:35.000000000 -0700 +++ syslinux-3.63+dfsg/com32/menu/menu.h 2008-06-10 00:48:38.424152595 -0700 @@ -163,6 +163,8 @@ struct color_table *color_table; struct fkey_help fkeyhelp[12]; + + int has_default64; }; extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list; diff -ruN syslinux-3.63+dfsg-orig/com32/menu/readconfig.c syslinux-3.63+dfsg/com32/menu/readconfig.c --- syslinux-3.63+dfsg-orig/com32/menu/readconfig.c 2008-04-10 10:30:35.000000000 -0700 +++ syslinux-3.63+dfsg/com32/menu/readconfig.c 2008-06-10 01:01:58.937589284 -0700 @@ -66,6 +66,28 @@ NULL }; +#define cpuid(func,ax,bx,cx,dx)\ + __asm__ __volatile__ ("cpuid":\ + "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); + +/* + * Determine if a CPU is x86_64 capable + */ +int is_64bit(void) { + unsigned int eax,ebx,ecx,edx; + + cpuid(0x80000000,eax,ebx,ecx,edx); + /* if 0x80000001 is available, it's an AMD and/or x86_64 CPU */ + if(eax >= 0x80000001) { + cpuid(0x80000001,eax,ebx,ecx,edx); + /* Bit 29 of 0x80000001_edx specifies x86_64 */ + if((edx&(1<<29)) == (1<<29)) { + return 1; + } + } + return 0; +} + /* * Search the list of all menus for a specific label */ @@ -206,6 +228,7 @@ unsigned int ipappend; unsigned int menuhide; unsigned int menudefault; + unsigned int menudefault64; unsigned int menuseparator; unsigned int menudisabled; unsigned int menuindent; @@ -273,6 +296,8 @@ struct menu_entry *me; const struct syslinux_ipappend_strings *ipappend; + int cpu_is_64bit = is_64bit(); + if (!ld->label) return; /* Nothing defined */ @@ -361,8 +386,26 @@ break; } - if ( ld->menudefault && me->action == MA_CMD ) + /* If this ld has DEFAULT on it, it's a candidate for the default entry. + * But if a 64-bit default has already been set, we know that A) the CPU + * is 64-bit, and B) a DEFAULT64 has already occurred, so we don't even + * want to attempt 32-bit defaults anymore. If it's a 64-bit CPU, + * regular DEFAULTs can of course be considered for the default, + * but any past or future DEFAULT64 (with a corresponding 64-bit CPU) + * will eventually win. + */ + if ( ld->menudefault && me->action == MA_CMD && !m->has_default64 ) m->defentry = m->nentries-1; + + /* If the CPU is 64-bit and DEFAULT64 is set for this ld, set it as + * default. However, if DEFAULT64 is set and the CPU is NOT 64-bit, + * don't even consider it for a default. + */ + if ( ld->menudefault64 && me->action == MA_CMD && cpu_is_64bit ) { + m->defentry = m->nentries-1; + m->has_default64 = 1; + } + } clear_label_data(ld); @@ -620,6 +663,8 @@ } } else if ( looking_at(p, "default") ) { ld.menudefault = 1; + } else if ( looking_at(p, "default64") ) { + ld.menudefault64 = 1; } else if ( looking_at(p, "hide") ) { ld.menuhide = 1; } else if ( looking_at(p, "passwd") ) { @@ -875,6 +920,7 @@ ld.ipappend = ipappend; ld.menudefault = ld.menuhide = ld.menuseparator = ld.menudisabled = ld.menuindent = 0; + ld.menudefault64 = 0; } else if ( (ep = is_kernel_type(p, &type)) ) { if ( ld.label ) { refstr_put(ld.kernel);