Author: stepan Date: Fri Mar 26 12:57:34 2010 New Revision: 114 URL: http://tracker.coreboot.org/trac/filo/changeset/114
Log: grub interface update - add support for "default" (aka grubonce) support through cmos - add dumpmem command - add isolinux parser
Signed-off-by: Stefan Reinauer stepan@coresystems.de
Modified: trunk/filo/Config.in trunk/filo/include/grub/shared.h trunk/filo/main/grub/builtins.c trunk/filo/main/grub/grub.c
Modified: trunk/filo/Config.in ============================================================================== --- trunk/filo/Config.in Fri Mar 26 12:55:18 2010 (r113) +++ trunk/filo/Config.in Fri Mar 26 12:57:34 2010 (r114) @@ -79,6 +79,14 @@ help Time in second before booting AUTOBOOT_FILE
+config ISOLINUX_PARSER + bool "Support for parsing isolinux.cfg config files" + default n + depends on USE_GRUB + help + If you enable this function, FILO will be able to parse isolinux.cfg + config files in addition to filo.lst/menu.lst files. + endmenu
menu "Drivers"
Modified: trunk/filo/include/grub/shared.h ============================================================================== --- trunk/filo/include/grub/shared.h Fri Mar 26 12:55:18 2010 (r113) +++ trunk/filo/include/grub/shared.h Fri Mar 26 12:57:34 2010 (r114) @@ -132,7 +132,6 @@ MAX_ERR_NUM } grub_error_t;
-extern int saved_entryno; extern char config_file[];
/* GUI interface variables. */
Modified: trunk/filo/main/grub/builtins.c ============================================================================== --- trunk/filo/main/grub/builtins.c Fri Mar 26 12:55:18 2010 (r113) +++ trunk/filo/main/grub/builtins.c Fri Mar 26 12:57:34 2010 (r114) @@ -2,7 +2,7 @@ * This file is part of FILO. * * Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc. - * Copyright (C) 2005-2008 coresystems GmbH + * Copyright (C) 2005-2010 coresystems GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@
#include <libpayload-config.h> #include <libpayload.h> +#include <getopt.h> + #include <config.h> #include <fs.h> #include <lib.h> @@ -45,7 +47,6 @@ // other.. unsigned long install_partition = 0x20000; unsigned long boot_drive = 0; -int saved_entryno = 0; char config_file[128] = "\0";
kernel_t kernel_type; @@ -336,6 +337,15 @@ /* default */ static int default_func(char *arg, int flags) { + unsigned char buf[1]; + if (get_option(buf, "boot_default")) + buf[0] = 0xff; + + if ((unsigned char)buf[0] != 0xff) { + printf("Default override by CMOS.\n"); + return 0; + } + if (!safe_parse_maxint(&arg, &default_entry)) return 1;
@@ -354,7 +364,47 @@ };
#if CONFIG_DEVELOPER_TOOLS -/* default */ +/* dumpmem */ +static int dumpmem_func(char *arg, int flags) +{ + int ret = string_to_args("dumpmem", arg); + unsigned int mem_base, mem_len; + void *i; + + if(ret || (string_argc != 3)) { + errnum = ERR_BAD_ARGUMENT; + return 1; + } + + // FIXME + if (!safe_parse_maxint(&string_argv[1], &mem_base)) + return 1; + if (!safe_parse_maxint(&string_argv[2], &mem_len)) + return 1; + + grub_printf("Dumping memory at 0x%08x (0x%x bytes)\n", + mem_base, mem_len); + + for (i=phys_to_virt(mem_base); i<phys_to_virt(mem_base + mem_len); i++) { + if (((unsigned long)i & 0x0f) == 0) + grub_printf("\n%08x:", i); + unsigned char val = *((unsigned char *)i); + grub_printf(" %02x", val); + } + grub_printf("\n"); + + return 0; +} + +static struct builtin builtin_dumpmem = { + "dumpmem", + dumpmem_func, + BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "dumpmem", + "Dump memory" +}; + +/* dumppm */ static int dumppm_func(char *arg, int flags) { u16 pmbase; @@ -651,9 +701,16 @@ }
if (disk == -1) { - /* The user did specify a FILO name already */ - // grub_printf("No drive.\n"); - len = 0; // just copy the drive name + int cnt = 0; + len = 0; + while ((arg[cnt] != 0) && (arg[cnt+1] != 0)) { + if (arg[cnt] == ':' && arg[cnt+1] == '/') { + /* The user did specify a FILO name already */ + len = cnt; + break; + } + cnt++; + } } else { if (part == -1) { // No partition sprintf(devicename, "%s%c:", drivername, disk + 'a'); @@ -895,7 +952,7 @@
for (i=0; i<lspci_indent; i++) grub_printf("| "); - grub_printf("|- %x:%x.%x [%x:%x]\n", bus, slot, func, + grub_printf("|- %02x:%02x.%x [%04x:%04x]\n", bus, slot, func, val & 0xffff, val >> 16);
/* If this is a bridge, then follow it. */ @@ -1704,6 +1761,7 @@ &builtin_configfile, &builtin_default, #ifdef CONFIG_DEVELOPER_TOOLS + &builtin_dumpmem, &builtin_dumppm, #endif #ifdef CONFIG_EXPERIMENTAL
Modified: trunk/filo/main/grub/grub.c ============================================================================== --- trunk/filo/main/grub/grub.c Fri Mar 26 12:55:18 2010 (r113) +++ trunk/filo/main/grub/grub.c Fri Mar 26 12:57:34 2010 (r114) @@ -32,6 +32,9 @@ char PASSWORD_BUF[PASSWORD_BUFLEN]; /* The buffer for the password. */ char DEFAULT_FILE_BUF[DEFAULT_FILE_BUFLEN]; /* THe buffer for the filename of "/boot/grub/default". */ char CMDLINE_BUF[CMDLINE_BUFLEN]; /* The buffer for the command-line. */ +#ifdef CONFIG_ISOLINUX_PARSER +char CMDLINE_TMP[CMDLINE_BUFLEN]; /* The buffer for the command-line. */ +#endif char HISTORY_BUF[HISTORY_BUFLEN]; /* The history buffer for the command-line. */ char COMPLETION_BUF[COMPLETION_BUFLEN]; /* The buffer for the completion. */ char UNIQUE_BUF[UNIQUE_BUFLEN]; /* The buffer for the unique string. */ @@ -173,6 +176,12 @@ return; if (probe_menulst(bootdevice, "/boot/menu.lst")) return; +#ifdef CONFIG_ISOLINUX_PARSER + if (probe_menulst(bootdevice, "/boot/isolinux/isolinux.cfg")) + return; + if (probe_menulst(bootdevice, "/isolinux/isolinux.cfg")) + return; +#endif } } while (bootdevice);
@@ -871,6 +880,88 @@ return pos; }
+#ifdef CONFIG_ISOLINUX_PARSER +static int rewrite_isolinux_config(void) +{ + /* TODO implement "default" */ + /* TODO implement "timeout" */ + if (!memcmp(CMDLINE_BUF, "LABEL ", 6) || + !memcmp(CMDLINE_BUF, "label ", 6)) { + strcpy(CMDLINE_TMP, "title "); + strlcat(CMDLINE_TMP, CMDLINE_BUF + 6, NEW_HEAPSIZE - 6); + memcpy(CMDLINE_BUF, CMDLINE_TMP, NEW_HEAPSIZE); + } else + if (!memcmp(CMDLINE_BUF, "KERNEL ", 7) || + !memcmp(CMDLINE_BUF, "kernel ", 7)) { + char *spos; + int pstart = 7, plen = 0; + strcpy(CMDLINE_TMP, "kernel "); + + /* Find path of kernel */ + if (strstr(CMDLINE_BUF, " /")) { + // Our kernel has an absolute path, so + // we only grab the device portion of the + // config file + + // (hd0,0)/configfile.cfg or hda1:/configfile.cfg + spos = strchr(config_file, '/'); + if (!spos) { + // (hd0,0)configfile.cfg + spos = strchr(config_file, ')'); + if (spos) spos++; + } + if (!spos) { + // hda1:configfile.cfg + spos = strchr(config_file, ':'); + if (spos) spos++; + } + } else { + spos = strrchr(config_file, '/'); + if (spos) spos++; + } + + if (spos) { + char sback = spos[0]; + spos[0]=0; + strlcat(CMDLINE_TMP, config_file, NEW_HEAPSIZE); + plen = strlen(CMDLINE_TMP) - pstart; // path name len + spos[0]=sback; + } + + /* copy kernel name */ + strlcat(CMDLINE_TMP, CMDLINE_BUF + 7, NEW_HEAPSIZE); + + /* recalculate the new kernel path length, + * we're going to need this for initrd + */ + plen = strrchr(CMDLINE_TMP, '/') - (CMDLINE_TMP + 7) + 1; + + /* read APPEND line */ + get_line_from_config(CMDLINE_BUF, NEW_HEAPSIZE, 1); + if (!memcmp(CMDLINE_BUF, "APPEND ", 7) || + !memcmp(CMDLINE_BUF, "append ", 7)) { + /* append APPEND line */ + strlcat(CMDLINE_TMP, " ", NEW_HEAPSIZE); + strlcat(CMDLINE_TMP, CMDLINE_BUF + 7, NEW_HEAPSIZE); + spos = strstr(CMDLINE_TMP, "initrd=") + 7; + if (spos && plen) { + strncpy(spos, CMDLINE_TMP + pstart, plen); + spos[plen] = 0; + spos = strstr(CMDLINE_BUF, "initrd=") + 7; + strlcat(CMDLINE_TMP, spos, NEW_HEAPSIZE); + } + } + + /* copy temp string to real string */ + memcpy(CMDLINE_BUF, CMDLINE_TMP, NEW_HEAPSIZE); + } else { + // printf("skip: %s\n", CMDLINE_BUF); + return 1; + } + return 0; +} +#endif + int is_opened = 0, is_preset = 0;
/* This is the starting function in C. */ @@ -912,6 +1003,7 @@
/* Never return. */ for (;;) { + char buf[10]; /* This is good enough. */ char *default_file = (char *) DEFAULT_FILE_BUF; int i;
@@ -920,34 +1012,41 @@ /* Here load the configuration file. */
/* Get a saved default entry if possible. */ - saved_entryno = 0; *default_file = 0;
- strncat(default_file, config_file, DEFAULT_FILE_BUFLEN); - for (i = strlen(default_file); i >= 0; i--) - if (default_file[i] == '/') { - i++; - break; - } - default_file[i] = 0; - strncat(default_file + i, "default", DEFAULT_FILE_BUFLEN - i); - if (file_open(default_file)) { - char buf[10]; /* This is good enough. */ - char *p = buf; - int len; - - len = file_read(buf, sizeof(buf)); - if (len > 0) { - buf[sizeof(buf) - 1] = 0; - safe_parse_maxint(&p, &saved_entryno); - } + /* Look into CMOS first */ + if (!get_option(buf, "boot_default")) { + default_entry = ((unsigned char)buf[0] != 0xff) ? + (unsigned char)buf[0] : 0; + } else { + strncat(default_file, config_file, DEFAULT_FILE_BUFLEN); + for (i = strlen(default_file); i >= 0; i--) + if (default_file[i] == '/') { + i++; + break; + } + default_file[i] = 0; + strncat(default_file + i, "default", DEFAULT_FILE_BUFLEN - i); + if (file_open(default_file)) { + char *p = buf; + int len; + + len = file_read(buf, sizeof(buf)); + if (len > 0) { + buf[sizeof(buf) - 1] = 0; + safe_parse_maxint(&p, &default_entry); + }
- file_close(); + file_close(); + } }
errnum = ERR_NONE;
do { +#ifdef CONFIG_ISOLINUX_PARSER + int isolinux_cfg = 0; +#endif /* STATE 0: Before any title command. STATE 1: In a title command. STATE >1: In a entry after a title command. */ @@ -960,6 +1059,12 @@ if (!is_opened) { is_opened = file_open(config_file); errnum = ERR_NONE; +#ifdef CONFIG_ISOLINUX_PARSER + if (strstr(config_file, "isolinux.cfg")) { + printf("detected isolinux.cfg\n"); + isolinux_cfg = 1; + } +#endif }
if (!is_opened) { @@ -975,6 +1080,12 @@ cmdline = (char *) CMDLINE_BUF; while (get_line_from_config(cmdline, NEW_HEAPSIZE, !is_preset)) { struct builtin *builtin; +#ifdef CONFIG_ISOLINUX_PARSER + if (isolinux_cfg) { + if (rewrite_isolinux_config()) + continue; + } +#endif
/* Get the pointer to the builtin structure. */ builtin = find_command(cmdline);