--- ./stage2/asm.S.voros 2004-05-23 18:22:23.000000000 +0200 +++ ./stage2/asm.S 2004-09-11 00:48:08.000000000 +0200 @@ -951,6 +951,8 @@ pushl %esi pushl %ebx + pushl %ecx + pushl %edx /* compute the address of disk_address_packet */ movl 0x10(%ebp), %eax @@ -980,6 +982,8 @@ movb %dl, %al /* return value in %eax */ + popl %edx + popl %ecx popl %ebx popl %esi popl %ebp @@ -1610,6 +1614,66 @@ ret + ENTRY(reset_vbe_mode) + pushl %ebp + movl %esp, %ebp + pushl %ebx + + call EXT_C(prot_to_real) + .code16 + + movw $0x0003, %ax + int $0x10 + + DATA32 call EXT_C(real_to_prot) + .code32 + + popl %ebx + popl %ebp + ret + + + ENTRY(get_vbe_pmif) + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %esi + pushl %edi + + pushl %ebp + + call EXT_C(prot_to_real) + .code16 + + movw $0x4F0A, %ax + xorw %bx,%bx + xorw %di,%di + int $0x10 + xorl %ebx,%ebx + cmpw $0x004F,%ax + jnz nopm + + movw %es,%bx + shll $16,%ebx + movw %di,%bx + + nopm: DATA32 call EXT_C(real_to_prot) + .code32 + + popl %ebp + + movl 0x8(%ebp),%eax + movl %ebx,(%eax) + movl 0xc(%ebp),%eax + andl $0xFFFF,%ecx + movl %ecx,(%eax) + + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + /* * gateA20(int linear) * --- ./stage2/bios.c.voros 2004-03-27 17:34:04.000000000 +0100 +++ ./stage2/bios.c 2004-09-11 00:59:35.000000000 +0200 @@ -86,6 +86,10 @@ #ifndef NO_INT13_FALLBACK if (err) { + /* We can't switch to CHS mode */ + if (geometry->cylinders == 0) + return err; + if (geometry->flags & BIOSDISK_FLAG_CDROM) return err; @@ -187,6 +191,7 @@ /* Clear the flags. */ geometry->flags = 0; + geometry->total_sectors = 0; if (drive & 0x80) { --- ./stage2/boot.c.voros 2004-03-30 13:44:08.000000000 +0200 +++ ./stage2/boot.c 2004-09-11 01:06:31.000000000 +0200 @@ -769,6 +769,16 @@ if (!grub_open (module)) return 0; + if ((cur_addr + filemax) >= (1024*(1024+mbi.mem_upper))) + { + printf("Want to load module to 0x%x len 0x%x but only have 0x%x RAM\n", + cur_addr, filemax, 1024*(1024+mbi.mem_upper)); + errnum = ERR_BADMODADDR; + grub_close (); + return 0; + } + + len = grub_read ((char *) cur_addr, -1); if (! len) { @@ -795,6 +805,36 @@ return 1; } +void +create_vbe_module(void *ctrl_info, int ctrl_info_len, + void *mode_info, int mode_info_len, + int mode, int pmif, int pmif_len, + unsigned int version) +{ + /* if we are supposed to load on 4K boundaries */ + cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; + + printf (" [VESA %d.%d info @ 0x%x, 0x%x bytes]\n", + version >> 8, version & 0xFF, + cur_addr, ctrl_info_len + mode_info_len); + + grub_memmove((char*)cur_addr, ctrl_info, ctrl_info_len); + mbi.vbe_control_info = (int)cur_addr; + cur_addr += ctrl_info_len; + + grub_memmove((char*)cur_addr, mode_info, mode_info_len); + mbi.vbe_mode_info = (int)cur_addr; + cur_addr += mode_info_len; + + mbi.flags |= MB_INFO_VIDEO_INFO; + + mbi.vbe_mode = mode; + mbi.vbe_interface_seg = (pmif >> 16) & 0xFFFF; + mbi.vbe_interface_off = pmif & 0xFFFF; + mbi.vbe_interface_len = pmif_len; +} + + int load_initrd (char *initrd) { @@ -854,6 +894,13 @@ } +void +set_load_addr (int addr) +{ + printf ("Setting module load address to 0x%x\n", addr); + cur_addr = addr; +} + #ifdef GRUB_UTIL /* Dummy function to fake the *BSD boot. */ static void --- ./stage2/builtins.c.voros 2004-05-14 21:30:52.000000000 +0200 +++ ./stage2/builtins.c 2004-09-11 16:48:30.000000000 +0200 @@ -2542,6 +2542,40 @@ }; #endif /* USE_MD5_PASSWORDS */ +/* modaddr */ +static int +modaddr_func (char *arg, int flags) +{ + int addr; + + switch (kernel_type) + { + case KERNEL_TYPE_MULTIBOOT: + if (safe_parse_maxint(&arg, &addr)) + { + set_load_addr(addr); + break; + } + + /* else fallthrough */ + + default: + errnum = ERR_NEED_MB_KERNEL; + return 1; + } + + return 0; +} + +static struct builtin builtin_modaddr = +{ + "modaddr", + modaddr_func, + BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "modaddr ADDRESS", + "Set the load address for the next Multiboot module to ADDRESS" +}; + /* module */ static int @@ -4664,6 +4698,1005 @@ " the information about only the mode." }; +/* vbeset MODE */ +static int +vbeset_func (char *arg, int flags) +{ +#ifndef GRUB_UTIL + int mode_number; + int pmif_segoff, pmif_len; + struct vbe_controller controller; + struct vbe_mode mode; + + if (kernel_type != KERNEL_TYPE_MULTIBOOT) + { + grub_printf("Multiboot kernel must be loaded before vbeset command\n"); + errnum = MAX_ERR_NUM; + return 1; + } + + if (! *arg) + { + reset_vbe_mode (); + return 0; + } + + if (! safe_parse_maxint (&arg, &mode_number)) + return 1; + + /* Preset `VBE2'. */ + grub_memmove (controller.signature, "VBE2", 4); + + /* Detect VBE BIOS. */ + if (get_vbe_controller_info (&controller) != 0x004F) + { + grub_printf (" VBE BIOS is not present.\n"); + return 1; + } + if (controller.version < 0x0200) + { + grub_printf (" VBE version %d.%d is not supported.\n", + (int) (controller.version >> 8), + (int) (controller.version & 0xFF)); + errnum = MAX_ERR_NUM; + return 1; + } + + if (get_vbe_mode_info (mode_number, &mode) != 0x004F + || (mode.mode_attributes & 0x0091) != 0x0091) + { + grub_printf (" Mode 0x%x is not supported.\n", mode_number); + errnum = MAX_ERR_NUM; + return 1; + } + + /* Now trip to the graphics mode. */ + if (set_vbe_mode (mode_number | (1 << 14)) != 0x004F) + { + grub_printf (" Switching to Mode 0x%x failed.\n", mode_number); + errnum = MAX_ERR_NUM; + return 1; + } + + get_vbe_pmif(&pmif_segoff, &pmif_len); + create_vbe_module(&controller, sizeof(struct vbe_controller), + &mode, sizeof(struct vbe_mode), + mode_number, pmif_segoff, pmif_len, controller.version); + + /* mode setting was successful */ + return 0; +#else + errnum = ERR_BAD_ARGUMENT; + return 1; +#endif +} + +static struct builtin builtin_vbeset = +{ + "vbeset", + vbeset_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "vbeset [MODE]", + "Set the VBE mode MODE. If no MODE is given, switch back to text mode." +}; + + +#define VARIABLE_STORE_SIZE 1024 +char variable_store[VARIABLE_STORE_SIZE]; +unsigned int variable_store_actpos; /* Points to the next free entry */ +struct variable_list_struct { + char *name; + char *value; +} variable_list[VARIABLES_MAX]; + +static void var_show(void) +{ + int i = 0; + + for (; i < VARIABLES_MAX; i++) + if (variable_list[i].name) + { + grub_printf("%s = %s\n", + variable_list[i].name, + variable_list[i].value); + } +} + +static int var_get_index(char *var) +{ + int i = 0; + + if (!*var) + return -1; + + for (; i < VARIABLES_MAX; i++) + if (variable_list[i].name && + grub_strcmp(variable_list[i].name, var) == 0) + return i; + + return -1; +} + +char *var_get(char *var) +{ + int i; + + if ((i = var_get_index(var)) == -1) + return NULL; + + return variable_list[i].value; +} + +static char *var_alloc_mem(unsigned int len) +{ + if (VARIABLE_STORE_SIZE < variable_store_actpos + len + || !len) + return NULL; + + variable_store_actpos += len; + return &variable_store[variable_store_actpos - len]; +} + +/* Maybe we're implementing "unset" later? */ +static int var_get_free_var(void) +{ + int i = 0; + + for (; i < VARIABLES_MAX; i++) + if (variable_list[i].name == NULL) + return i; + + return -1; +} +static inline char *skip_ws(char *s) +{ + while (isspace(*s)) + s++; + return s; +} + +static int var_sprint_once(char *buf, char *str) +{ + char *b = buf; + + while (*str) + { + if (*str == '$' && *(str + 1) == '(') + { + /* Found start of variable */ + char *end_var; + char *c = str + 2; + + end_var = c; + while (*end_var && *end_var != ')') + end_var++; + + if (*end_var == ')') + { + char *val; + + /* Copy variable name into var */ + + str = end_var + 1; + + *end_var = 0; + if ((val = var_get(c))) + { + /* All ok, we got it */ + /* Copy to buf */ + while (*val) + *b++ = *val++; + + *end_var = ')'; + + continue; + } + /* else + grub_printf("Unknown variable: %var!\n", var); */ + + *end_var = ')'; + } + } + *b++ = *str++; + } + + *b = 0; + + return b - buf; +} + +int var_sprint(char *buf, char *str) +{ + int i = 10; + /* Waste some stack here... */ + const int buffer_size = 1000; + char buffer[buffer_size]; + + grub_strcpy(buf, str); + + /* We're not checking any return values here or any array overflows... :( */ + do + { + if (grub_strlen(buf) > buffer_size) + { + grub_printf("Buffer overflow: %s(%d)\n", __FILE__, __LINE__); + while (1) {} + } + + grub_strcpy(buffer, buf); + + var_sprint_once(buf, buffer); + } + while (--i && grub_strcmp(buf, buffer)); + if (!i) + { + grub_printf("Possible loop in var_sprintf!\n"); + getkey(); + } + + return grub_strlen(buf); +} + +/* Use our own buffer instead of a supplied one and + * return the pointer to the buffer and not the bytes + * processed. */ +/* We try to detect buffer overruns... */ +static char var_sprint_buffer[1500]; +static const long var_sprint_magic = 0x14233241; +char *var_sprint_buf(char *str, int *bytes) +{ + *(long *)(var_sprint_buffer + sizeof(var_sprint_buffer) - sizeof(var_sprint_magic)) = var_sprint_magic; + + *bytes = var_sprint(var_sprint_buffer, str); + + if (*(long *)(var_sprint_buffer + sizeof(var_sprint_buffer) - sizeof(var_sprint_magic)) != var_sprint_magic) + { + grub_printf("Possible buffer overrun: %s(%d)\n", __FILE__, __LINE__); + while (1) {} + } + return var_sprint_buffer; +} +/* This function just updates the pointer to the value, this value has to + * be inside the variable_store */ +static int var_set_no_copy(char *name, char *val) +{ + int i; + + if (val < variable_store || val >= (variable_store + VARIABLE_STORE_SIZE)) + return 1; + + i = var_get_index(name); + + if (i == -1) + { + /* The variable doesn't exist yet, so we have a new variable */ + char *a = name; + + /* Some sanity check */ + while (*a) + { + if (*a == '(' || *a == ')' || *a == ' ') + return 1; + a++; + } + + + if ((i = var_get_free_var()) == -1) + return 1; + + if ((a = var_alloc_mem(grub_strlen(name) + 1)) == NULL) + return 1; + + grub_strcpy(a, name); + variable_list[i].name = a; + } + + variable_list[i].value = val; + + return 0; /* Ok */ +} + +/* XXX: this is a bit code duplication with var_set_no_copy, + * so if someone has some free time, feel free to join this + */ +int var_set(char *name, char *value, int parse) +{ + int i; + + if (parse) + value = var_sprint_buf(value, &i); + + i = var_get_index(name); + + if (i == -1) + { + /* The variable doesn't exist yet, so we have a new variable */ + char *a = name; + + /* Some sanity check */ + while (*a) + { + if (*a == '(' || *a == ')' || *a == ' ') + return 1; + a++; + } + + if ((i = var_get_free_var()) == -1) + return 1; + + if ((a = var_alloc_mem(grub_strlen(name) + 1)) == NULL) + return 1; + + grub_strcpy(a, name); + variable_list[i].name = a; + + if ((a = var_alloc_mem(grub_strlen(value) + 1)) == NULL) + return 1; + + grub_strcpy(a, value); + variable_list[i].value = a; + } + else + { + /* Variable already exists */ + if (grub_strlen(variable_list[i].value) >= grub_strlen(value)) + { + /* We can just replace the value but we're potentially + * loosing space */ + grub_strcpy(variable_list[i].value, value); + } + else + { + /* New value is longer then the old one, we need to + + * allocate a new place and drop the old one (i.e. wasting it) */ + char *a; + if ((a = var_alloc_mem(grub_strlen(value) + 1)) == NULL) + return 1; + + grub_strcpy(a, value); + + variable_list[i].value = a; + } + } + + //grub_printf("Saved %s=\"%s\" in slot %d.\n", variable_list[i].name, variable_list[i].value, i + 1); + //getkey(); + + return 0; /* Ok */ +} + + +static int +set_func(char *arg, int flags) +{ + char *a = arg; + char *variable, *value; + char *end_variable, end_variable_val; + char *end_value, end_value_val; + char end_char; + int i = 0, parse = 0, emptysetonly = 0; + + a = skip_ws(a); + + if (!*a) + { + var_show(); + return 0; + } + + variable = a; + while (*a && *a != ':' && *a != '=' && *a != ' ') + a++; + end_variable_val = *a; + end_variable = a; + a = skip_ws(a); + + if (*a == ':') + { + parse = 1; + a++; + } + if (*a == '?') + { + emptysetonly = 1; + a++; + } + + if (*a != '=') + goto bad_arg; + + a++; + a = skip_ws(a); + + end_char = ' '; + if (*a == '"') + { + end_char = *a; + a++; + } + /* XXX: add/fix \" and \\ stuff */ + value = a; + while (*a && *a != end_char) + a++; + end_value_val = *a; + end_value = a; + + *end_value = *end_variable = 0; + + if ((emptysetonly && var_get_index(variable) == -1) || + !emptysetonly) + i = var_set(variable, value, parse); + + *end_value = end_value_val; + *end_variable = end_variable_val; + + return i; + +bad_arg: + grub_printf("%s: ERR_BAD_ARGUMENT\n", __func__); + getkey(); + errnum = ERR_BAD_ARGUMENT; + return 1; +} + +static struct builtin builtin_set = +{ + "set", + set_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "set var=val", + "Set a variable to a value." +}; + +static int +print_func(char *arg, int flags) +{ + grub_printf("%s\n", var_sprint_buf(arg, &flags)); + return 0; +} + +static struct builtin builtin_print = +{ + "print", + print_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "print \"string with vars\"", + "Print a string which may contain variables. Variables are enclosed" + " in $( and ) (like \"make\")." +}; + +static struct builtin builtin_echo = +{ + "echo", + print_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "echo \"string with vars\"", + "Alias for \"print\"." +}; + + + + +#define TOGGLES 10 +#define MAX_BLOCKS 7 +#define MAX_VAR_PER_BLOCK 4 + +struct toggle_data_struct { + int key; /* int because of F-keys !? */ + int current_block; + char nr_blocks; + struct { + char nr_vars; + struct { + int var; /* index of variable_list */ + char *value; /* pointer to value */ + } var[MAX_VAR_PER_BLOCK]; + } block[MAX_BLOCKS]; +} toggle_data[TOGGLES]; +int toggles_used = 0; + +char toggle_trigger_init_done; + +static int get_toggle_slot_for_key(int key) +{ + int i = 0; + + for (; i < TOGGLES; i++) + if (toggle_data[i].key == key) + return i; + + return -1; +} + +int toggle_print_status(int x, int y) +{ + /* Basically print all variable which are on the left side on toggles */ + int printed[VARIABLES_MAX]; + int printed_something = 0; + int i, t, b, v, dummy; + const int ylines = 6; + int xpos[ylines]; + int dy = 0; + + for (i = 0; i < ylines; i++) + xpos[i] = x; + for (i = 0; i < VARIABLES_MAX; i++) + printed[i] = 0; + + for (t = 0; t < toggles_used; t++) + { + for (b = 0; b < toggle_data[t].nr_blocks; b++) + { + for (v = 0; v < toggle_data[t].block[b].nr_vars; v++) + { + i = toggle_data[t].block[b].var[v].var; + if (!printed[i]) + { + int len; + char *vals; + + gotoxy(xpos[dy], y + dy); + + /* don't use printf here since we need the lengths + * of the printed string and we don't want to use another + * buffer for sprintf + */ + grub_putstr(variable_list[i].name); + grub_putchar('='); + len = grub_strlen(variable_list[i].name) + 1; + + vals = var_sprint_buf(variable_list[i].value, &dummy); + grub_putstr(vals); + len += grub_strlen(vals); + + xpos[dy] += len + 2; + + if (++dy == ylines) { + dy = 0; + } + + printed[i] = printed_something = 1; + } + } + } + } + + return printed_something; +} + +static int toggle_do_block(int slot, int block_nr) +{ + int v; + + if (slot >= toggles_used || block_nr >= toggle_data[slot].nr_blocks) + return 0; + + /* Set all variables in th block block_nr to their new values */ + for (v = 0; v < toggle_data[slot].block[block_nr].nr_vars; v++) + { + int l = toggle_data[slot].block[block_nr].var[v].var; + + var_set_no_copy(variable_list[l].name, toggle_data[slot].block[block_nr].var[v].value); + } + + return 1; /* Ok */ +} +static int toggle_find_slot(int key) +{ + int i = 0; + + for (; i < toggles_used; i++) + if (toggle_data[i].key == key) + return i; + + return -1; +} + +int toggle_do_key(int key) +{ + int slot; + + if ((slot = toggle_find_slot(key)) == -1) + return 0; + + /* Proceed to the next block */ + if (++toggle_data[slot].current_block == toggle_data[slot].nr_blocks) + toggle_data[slot].current_block = 0; + + toggle_do_block(slot, toggle_data[slot].current_block); + + return 1; +} + +static int +toggle_func(char *arg, int flags) +{ + int slot, key, block = 0, i; + char *a = arg, *eb; + int command; + enum { + COMMAND_SET, + COMMAND_SELECT, + COMMAND_TRIGGER, + }; + + static int process_var(int bl, int var, char *start, char *end) + { + char *p, origvar, *origvarp, origval, *v; + + //grub_printf("VAR(%d, %d) %s [%d]\n", bl, var, start, end-start+1); + + start = skip_ws(start); + p = start; + while (p < end && *p != '=' && !isspace(*p)) + p++; + + origvar = *p; + origvarp = p; + + p = skip_ws(p); + if (*p != '=') + return 1; + + p = skip_ws(p+1); + + // value is now from p to end (both inclusive) + + origval = *(end + 1); + *(end + 1) = 0; + *origvarp = 0; + + /* See if we already have the same value in that toggle + * (in case we're entering a menu multiple time we would + * allocate memory multiple time) */ + + if (toggle_data[slot].block[bl].var[var].value && + var_get_index(start) != -1 && + !grub_strcmp(toggle_data[slot].block[bl].var[var].value, p)) + { + } + else + { + /* Allocate space for the value and hang it in */ + if ((v = var_alloc_mem(grub_strlen(p) + 1)) == NULL) + return 1; + grub_strcpy(v, p); + + var_set_no_copy(start, v); + + if ((toggle_data[slot].block[bl].var[var].var = var_get_index(start)) == -1) + return 1; /* internal error */ + toggle_data[slot].block[bl].var[var].value = v; + } + + *origvarp = origvar; + *(end + 1) = origval; + + //grub_printf("slot=%d block=%d var=%d %d=%s\n", slot, bl, var, toggle_data[slot].block[bl].var[var].var, v); + + if (var >= toggle_data[slot].block[bl].nr_vars) + toggle_data[slot].block[bl].nr_vars = var + 1; + + return 0; + } + + static int process_block(int bl, char *start, char *end) + { + char *p = start; + int var = 0; + + //grub_printf("BL(%d) %s [%d]\n", bl, start, end-start+1); + + while (p <= end) + { + if (*p == ',' || p == end) + { + if (var == MAX_VAR_PER_BLOCK) + return ERR_WONT_FIT; + + if (process_var(bl, var, start, (p == end) ? p : (p-1))) + return ERR_BAD_ARGUMENT; + + var++; + start = p + 1; + } + p++; + } + + return 0; + } + + + /* parse args */ + /* proceed to next arg */ + while (*a && *a == ' ') + a++; + + /* Get command */ + { + eb = a; + + while (!isspace(*eb)) + eb++; + + if (!isspace(*eb)) + goto bad_arg; + + //grub_printf("trigger: processing line: %s\n", a); + + *eb = 0; + + if (!grub_strcmp(a, "set")) + command = COMMAND_SET; + else if (!grub_strcmp(a, "select")) + command = COMMAND_SELECT; + else if (!grub_strcmp(a, "trigger")) + command = COMMAND_TRIGGER; + else + { + grub_printf("toggle: Unknown command!\n"); + goto bad_arg; + } + *eb = ' '; + a = eb + 1; + } + + a = skip_ws(a); + + if (command == COMMAND_SET) + { + + if (!*a || !*(a+1)) + goto bad_arg; + + key = *a; + a++; + + //grub_printf("key: %c\n", key); + + /* Find slot for key */ + slot = get_toggle_slot_for_key(key); + if (slot == -1) + { + /* Get next free toggle_data slot */ + slot = toggles_used; + if (slot == TOGGLES) + goto wont_fit; + toggle_data[slot].key = key; + toggles_used++; + } + + /* Reset current slot */ + toggle_data[slot].nr_blocks = toggle_data[slot].current_block = 0; + for (i = 0; i < MAX_VAR_PER_BLOCK; i++) + toggle_data[slot].block[i].nr_vars = 0; + + while (*a) + { + int ret; + + a = skip_ws(a); + + if (*a != '{') + goto bad_arg; + /* find the correspondig '}' */ + eb = a++; + while (*eb && *eb != '}') + eb++; + if (*eb != '}') + goto bad_arg; + /* Now we have the block between a and eb-1 */ + ret = process_block(block, a, eb-1); + if (ret == ERR_WONT_FIT) + goto wont_fit; + if (ret) + goto bad_arg; + + a = eb + 1; + + block++; + if (*a) { + if (block == MAX_BLOCKS) + goto wont_fit; + } + } + toggle_data[slot].nr_blocks = block; + + /* finally, set all vars from the first block */ + toggle_do_block(slot, 0); + } + else if (command == COMMAND_SELECT) + { + while (*a) + { + int k, b, s; + + /* there's something between a and eb-1 now*/ + /* *a is a key and *(a+1) == '=' */ + k = *a++; + + if (*a++ != '=') + goto bad_arg; + + if (!safe_parse_maxint(&a, &b)) + goto bad_arg; + + if ((s = toggle_find_slot(k)) == -1) + goto bad_arg; + + if (!toggle_do_block(s, b)) + goto bad_arg; + + toggle_data[s].current_block = b; + + toggle_data[s].current_block = b; + + a = skip_ws(a); + } + } + else if (command == COMMAND_TRIGGER) + { + char *vr, *vre, *vl, *vle, *vrval; + char o; + int cmp; + // remaining a(rg) format: VAR==VAL "command" + //grub_printf("%s: trigger\n"); + + /* Find the '=' */ + vr = a; + while (*a && *a != ' ' && *a != '=') + a++; + + if (*a != '=' || *(a+1) != '=') + goto bad_arg; + + vre = a; + + if (vr == vre) + goto bad_arg; + + a += 2; + vl = a; + + while (!isspace(*a)) + a++; + + vle = a; + + if (vl == vle) + goto bad_arg; + + + *vre = 0; + vrval = var_get(vr); + *vre = '='; + + if (!vrval) + goto bad_arg; + + o = *vle; + *vle = 0; + cmp = grub_strcmp(vrval, vl); + *vle = o; + + a = skip_ws(a); + + if (!cmp) + toggle_func(a, 0); + } + + return 0; + +wont_fit: + grub_printf("%s: ERR_WONT_FIT\n", __func__); + getkey(); + errnum = ERR_WONT_FIT; + return 1; + +bad_arg: + grub_printf("%s: ERR_BAD_ARGUMENT\n", __func__); + getkey(); + errnum = ERR_BAD_ARGUMENT; + return 1; +} + +void toggle_trigger_init(void) +{ + static int detect_vmware(void) + { +#ifndef GRUB_UTIL + char *start = (char *)0xc0000; + int size = 16 << 10; + int i = 0, p = 0; + char *s = "VMware, Inc."; + + + while (i < size) + { + if (*(start + i) == s[p]) + { + p++; + if (!s[p]) + return 1; + } + else + p = 0; + i++; + } +#endif + return 0; + } + + if (toggle_trigger_init_done) + return; + toggle_trigger_init_done = 1; + + var_set("TT_VMWARE", (detect_vmware()) ? "1" : "0", 0); +} + +static struct builtin builtin_toggle = +{ + "toggle", + toggle_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "toggle [command] args...", + "Doc me." +}; + + + + +static char var_expand_line_edit = 1; + +char is_var_expand(void) +{ + return var_expand_line_edit; +} + +static int +varexpand_func(char *arg, int flags) +{ + static const char *on_vals[] = { "on", "true", "1" }; + static const char *off_vals[] = { "off", "false", "0" }; + int i; + + arg = skip_ws(arg); + + for (i = 0; i < sizeof(on_vals) / sizeof(on_vals[0]); i++) + if (!grub_memcmp(arg, on_vals[i], sizeof(*on_vals[i]))) + { + var_expand_line_edit = 1; + goto out; + } + for (i = 0; i < sizeof(off_vals) / sizeof(off_vals[0]); i++) + if (!grub_memcmp(arg, off_vals[i], sizeof(*off_vals[i]))) + { + var_expand_line_edit = 0; + goto out; + } + + if (*arg) + { + grub_printf("Unknown argument: %s\n", arg); + return 1; + } + + var_expand_line_edit = !var_expand_line_edit; + +out: + grub_printf("Expansion is %s\n", var_expand_line_edit ? "on" : "off"); + return 0; +} +static struct builtin builtin_varexpand = +{ + "varexpand", + varexpand_func, + BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, + "varexpand [on|off]", + "Expand lines in line editing? Default is on. It toggles without arguments." +}; + + /* The table of builtin commands. Sorted in dictionary order. */ struct builtin *builtin_table[] = @@ -4691,6 +5724,7 @@ #ifdef GRUB_UTIL &builtin_dump, #endif /* GRUB_UTIL */ + &builtin_echo, &builtin_embed, &builtin_fallback, &builtin_find, @@ -4714,6 +5748,7 @@ #ifdef USE_MD5_PASSWORDS &builtin_md5crypt, #endif /* USE_MD5_PASSWORDS */ + &builtin_modaddr, &builtin_module, &builtin_modulenounzip, &builtin_pager, @@ -4721,6 +5756,7 @@ &builtin_parttype, &builtin_password, &builtin_pause, + &builtin_print, #ifdef GRUB_UTIL &builtin_quit, #endif /* GRUB_UTIL */ @@ -4735,6 +5771,7 @@ #ifdef SUPPORT_SERIAL &builtin_serial, #endif /* SUPPORT_SERIAL */ + &builtin_set, &builtin_setkey, &builtin_setup, #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) @@ -4750,8 +5787,11 @@ #endif /* SUPPORT_NETBOOT */ &builtin_timeout, &builtin_title, + &builtin_toggle, &builtin_unhide, &builtin_uppermem, + &builtin_varexpand, &builtin_vbeprobe, + &builtin_vbeset, 0 }; --- ./stage2/cmdline.c.voros 2004-03-18 00:08:48.000000000 +0100 +++ ./stage2/cmdline.c 2004-09-11 01:56:37.000000000 +0200 @@ -134,6 +134,8 @@ { struct builtin *builtin; char *arg; + int len; + char dump[700]; *heap = 0; print_error (); @@ -147,8 +149,10 @@ if (! heap[0]) continue; + len = var_sprint(dump, heap); + /* Find a builtin. */ - builtin = find_command (heap); + builtin = find_command (dump); if (! builtin) continue; @@ -168,7 +172,7 @@ count_lines = 0; /* Run BUILTIN->FUNC. */ - arg = skip_to (1, heap); + arg = skip_to (1, dump); (builtin->func) (arg, BUILTIN_CMDLINE); /* Finish the line count. */ @@ -192,6 +196,8 @@ { struct builtin *builtin; char *arg; + int len; + char dump[700]; print_error (); @@ -228,16 +234,22 @@ grub_memmove (heap, "boot", 5); } + len = var_sprint(dump, heap); + /* Find a builtin. */ - builtin = find_command (heap); + builtin = find_command(dump); if (! builtin) { grub_printf ("%s\n", old_entry); + grub_printf("dump=%s\n",dump); continue; } if (! (builtin->flags & BUILTIN_NO_ECHO)) - grub_printf ("%s\n", old_entry); + { + grub_printf ("old_entry=%s\n", old_entry); + grub_printf ("dump=%s\n", dump); + } /* If BUILTIN cannot be run in the command-line, skip it. */ if (! (builtin->flags & BUILTIN_CMDLINE)) @@ -251,7 +263,7 @@ buf_drive = -1; /* Run BUILTIN->FUNC. */ - arg = skip_to (1, heap); + arg = skip_to (1, dump); (builtin->func) (arg, BUILTIN_SCRIPT); } } --- ./stage2/common.c.voros 2004-03-27 17:25:44.000000000 +0100 +++ ./stage2/common.c 2004-09-11 01:57:47.000000000 +0200 @@ -88,6 +88,7 @@ [ERR_UNRECOGNIZED] = "Unrecognized command", [ERR_WONT_FIT] = "Selected item cannot fit into memory", [ERR_WRITE] = "Disk write error", + [ERR_BADMODADDR] = "Bad modaddr", }; --- ./stage2/shared.h.voros 2004-05-14 21:38:37.000000000 +0200 +++ ./stage2/shared.h 2004-09-11 16:45:29.000000000 +0200 @@ -541,6 +541,7 @@ ERR_DEV_NEED_INIT, ERR_NO_DISK_SPACE, ERR_NUMBER_OVERFLOW, + ERR_BADMODADDR, MAX_ERR_NUM } grub_error_t; @@ -765,6 +766,25 @@ /* Set VBE mode. */ int set_vbe_mode (int mode_number); +/* Switch to text mode */ +void reset_vbe_mode (void); + +/* Get VBE pm interface entry */ +void get_vbe_pmif (unsigned int *segoff, unsigned int *len); + +/* Variable definitions and functions. */ +#define VARIABLES_MAX 30 + +char *var_get(char *); +int var_sprint(char *, char *); +char *var_sprint_buf(char *, int *); +int var_set(char *, char *, int); +int toggle_print_status(int, int); +int toggle_do_key(int key); +void toggle_trigger_init(void); +char is_var_expand(void); + + /* Return the data area immediately following our code. */ int get_code_end (void); @@ -979,6 +999,12 @@ int load_module (char *module, char *arg); int load_initrd (char *initrd); +void set_load_addr (int addr); +void create_vbe_module(void *ctrl_info, int ctrl_info_len, + void *mode_info, int mode_info_len, + int mode, int pmif, int pmif_len, + unsigned int version); + int check_password(char *entered, char* expected, password_t type); #endif --- ./stage2/stage2.c.voros 2004-03-27 17:09:41.000000000 +0100 +++ ./stage2/stage2.c 2004-09-11 17:19:01.000000000 +0200 @@ -19,6 +19,7 @@ #include #include +#define MASTER_CONFIG_FILE "(nd)/grubmenu.lst" grub_jmp_buf restart_env; @@ -76,6 +77,20 @@ #endif /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */ +/* config_file is 128 Bytes long (see grub/asmstub.c) */ +#define CONFIG_FILE_LEN 128 +#define CONFIG_FILE_HISTORY_ENTRIES 10 +struct config_file_history_struct { + char filename[CONFIG_FILE_LEN]; + int entryno; + int first_entry; +}; +static struct config_file_history_struct + config_file_history[CONFIG_FILE_HISTORY_ENTRIES]; +static int config_file_history_pos, config_file_history_start, + config_file_history_prev_pos; +static int config_file_history_menu_pos = -1; + static char * get_entry (char *list, int num, int nested) { @@ -105,6 +120,7 @@ if (highlight && current_term->setcolorstate) current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); + entry = var_sprint_buf(entry, &x); gotoxy (2, y); grub_putchar (' '); for (x = 3; x < 75; x++) @@ -233,12 +249,108 @@ { int c, time1, time2 = -1, first_entry = 0; char *cur_entry = 0; + char shortcut_buf[5]; + int sc_matches; +#define SEARCH_BUF_SIZE 20 + char search_buf[SEARCH_BUF_SIZE]; + int search_mode = 0, search_found = 0, search_direction = 0; + + /* nested function, we need the code in multiple places */ + static void set_bar_to(int i) + { + first_entry = i - 5; + entryno = 5; + + if (first_entry < 0 || num_entries < 13) + { + entryno = i; + first_entry = 0; + } + else if (num_entries - i < 7) + { + first_entry = num_entries - 12; + entryno = i - first_entry; + } + + print_entries (3, 12, first_entry, + entryno, menu_entries); + } + + /* search through menu_entries once around */ + static int search_menu(char *buf, int current, int direction, int advance) + { + int i; + /* make direction a delta */ + direction = (direction ? -1 : 1); + + if (advance) + { + /* go to next search item */ + current += direction; + + /* correct overflows */ + if (current < 0) + current = num_entries - 1; + else if (current == num_entries) + current = 0; + } + + i = current; + + do + { + int x; + + /* get_entry is probably overkill here... */ + char *s = var_sprint_buf(get_entry(menu_entries, + i, 0), &x); + for (; *s; s++) + { + char *sb = buf; + char *ss = s; + /* incasesensitive search */ + while (*ss && *sb && grub_tolower(*ss) == *sb) + ss++, sb++; + + + if (!*sb) /* Found something! */ + { + set_bar_to(i); + return i; + } + } + + if (direction == -1 && i == 0) + i = num_entries; + i += direction; + if (direction == 1 && i == num_entries) + i = 0; + } + while (i != current); + + /* Found nothing */ + return -1; + } + + + *shortcut_buf = *search_buf = 0; + /* * Main loop for menu UI. */ restart: + + if (config_file_history_menu_pos != -1) + { + /* we're in a history back movement, set menu values to previous ones */ + entryno = config_file_history[config_file_history_menu_pos].entryno; + first_entry = config_file_history[config_file_history_menu_pos].first_entry; + config_file_history_menu_pos = -1; + } + + /* Dumb terminal always use all entries for display invariant for TERM_DUMB: first_entry == 0 */ if (! (current_term->flags & TERM_DUMB)) @@ -317,15 +429,23 @@ else { if (config_entries) - printf ("\ - Press enter to boot the selected OS, \'e\' to edit the\n\ - commands before booting, or \'c\' for a command-line."); + { + if (!toggle_print_status(3, 18)) + { + printf ("\n\n\ + Press enter or %c to boot the selected OS,\n\ + \'e\' to edit the commands before booting, or\ + \'c\' for a command-line."); + } + } else + { printf ("\ Press \'b\' to boot, \'e\' to edit the selected command in the\n\ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ after (\'O\' for before) the selected line, \'d\' to remove the\n\ - selected line, or escape to go back to the main menu."); + selected line, \'/?nN\' to search, or escape to go back to the main menu."); + } } if (current_term->flags & TERM_DUMB) @@ -366,6 +486,73 @@ grub_timeout--; } +menu_restart: + + /* Print the number of the current entry in the right upper corner of + * the menu, up to 999 entries are supported, modify the coordinates + * and putchar command to add more + * Additionally, print the shortcut buffer upper left if there's + * something in there */ + if (! (current_term->flags & TERM_DUMB)) + { + int x=0, i, l; + + if (current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_NORMAL); + + /* current entry */ + gotoxy(69, 3); + grub_printf("[%d]", first_entry + entryno); + grub_putchar(DISP_HORIZ); + grub_putchar(DISP_HORIZ); + + + /* print shortcut buffer */ + gotoxy(5, 3); + if (search_mode) + { + grub_printf("%c%s%c%c%c%c", + x, search_buf, x = search_direction ? '?' : '/', + DISP_HORIZ, + search_found >= 0 ? DISP_HORIZ : 'X', DISP_HORIZ); + } + else if (shortcut_buf[0]) + { + grub_printf("<%s..>", shortcut_buf); + } + else + { + for (x = 0; x < 24; x++) + { + grub_putchar(DISP_HORIZ); + } + } + gotoxy(52, 16); + l = grub_strlen(search_buf); + for (i = SEARCH_BUF_SIZE + 2 - + ((search_found >= 0 && (l || search_mode)) ? l + 2 : 0); + i; i--) + { + grub_putchar(DISP_HORIZ); + } + if (search_found >= 0 && (l || search_mode)) + { + x = search_direction ? '?' : '/'; + grub_putchar(x); + for (i = 0; i < l; i++) + { + grub_putchar(search_buf[i]); + } + grub_putchar(x); + } + + if (current_term->setcolorstate) + { + current_term->setcolorstate (COLOR_STATE_STANDARD); + } + + gotoxy(74, 4 + entryno); + } /* Check for a keypress, however if TIMEOUT has been expired (GRUB_TIMEOUT == -1) relax in GETKEY even if no key has been @@ -395,9 +582,114 @@ gotoxy (74, 4 + entryno); } + if (search_mode) + { + int inplen = grub_strlen(search_buf); + + if (c == '\r' || c == '\n' || c == 27) + { + search_mode = 0; + goto menu_restart; + } + else if (c != 8 && c < ' ') /* any other "move around" key */ + { + search_mode = 0; + /* fall through to other keys */ + } + else + { + if (c == 8) /* Backspace */ + { + if (!inplen) + search_mode = 0; + else + search_buf[--inplen] = 0; + } + else if (inplen < sizeof(search_buf) - 1) + { + search_buf[inplen] = grub_tolower(c); + search_buf[++inplen] = 0; + } + + if (search_mode) + search_found = search_menu(search_buf, + first_entry + entryno, + search_direction, 0); + + goto menu_restart; + } + } + else if (c == '/' || c == '?') + { + search_mode = 1; + search_direction = (c == '?'); + *search_buf = search_found = 0; + } + + if (c == 'n') /* search again forwards */ + if (search_found >= 0) + search_menu(search_buf, first_entry + entryno, + search_direction, 1); + + if (c == 'N') /* search again backwards */ + if (search_found >= 0) + search_menu(search_buf, first_entry + entryno, + !search_direction, 1); + + if (c >= '0' && c <= '9') + { + int inplen = grub_strlen(shortcut_buf); + int i; + + sc_matches = 0; + + shortcut_buf[inplen] = c; + shortcut_buf[++inplen] = 0; + + + for (i = 0; i < num_entries; i++) + { + char buf[4]; + int a = 0; + + /* no strncmp in grub? do it ourselves */ + /* If shortcut_buf is entirely in the beginning + * of buf, mark it as the first valid entry, + * if the first entry is already set, we have at least + * two entries matching, bail out then */ + grub_sprintf(buf, "%d", i); + while (shortcut_buf[a] && buf[a] && + shortcut_buf[a] == buf[a]) + a++; + + if (a == inplen) + { + sc_matches++; + + if (sc_matches == 1) + set_bar_to(i); + else + break; + } + } + if (sc_matches <= 1) + { + shortcut_buf[0] = 0; + } + if (sc_matches == 1 && config_entries) + { + c = '\n'; /* Will hit the next check */ + } + } + else + { + shortcut_buf[0] = sc_matches = 0; + } + + /* We told them above (at least in SUPPORT_SERIAL) to use '^' or 'v' so accept these keys. */ - if (c == 16 || c == '^') + if (c == 16 || c == '^' || c == 'k') { if (current_term->flags & TERM_DUMB) { @@ -455,6 +747,35 @@ else if (c == 7) { /* Page Up */ + + if (first_entry > 11) + { + first_entry -= 12; + print_entries (3, 12, first_entry, entryno, menu_entries); + } + else if (first_entry) + { + if (entryno + first_entry - 12 < 0) + entryno = 0; + else + entryno = first_entry + entryno - 12; + first_entry = 0; + print_entries (3, 12, first_entry, entryno, menu_entries); + } + else if (entryno) + { + print_entry (4 + entryno, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); + entryno = 0; + print_entry (4, 1, + get_entry (menu_entries, + first_entry, + 0)); + } + +#if 0 first_entry -= 12; if (first_entry < 0) { @@ -464,10 +785,39 @@ entryno = 0; } print_entries (3, 12, first_entry, entryno, menu_entries); +#endif } else if (c == 3) { /* Page Down */ + if (first_entry + 12 < num_entries) + { + if (first_entry + 23 < num_entries) + first_entry += 12; + else + { + if (entryno + first_entry + 12 >= num_entries) + entryno = 11; + else + entryno += 24 + first_entry - num_entries; + first_entry = num_entries - 12; + } + print_entries (3, 12, first_entry, entryno, menu_entries); + } + else if (first_entry + entryno + 1 != num_entries) + { + print_entry (4 + entryno, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); + entryno = num_entries - first_entry - 1; + print_entry (4 + entryno, 1, + get_entry (menu_entries, + first_entry + entryno, + 0)); + } + +#if 0 first_entry += 12; if (first_entry + entryno + 1 >= num_entries) { @@ -477,12 +827,53 @@ entryno = num_entries - first_entry - 1; } print_entries (3, 12, first_entry, entryno, menu_entries); +#endif } + if (c == 'M') + { + grub_memmove(config_file, MASTER_CONFIG_FILE, + grub_strlen(MASTER_CONFIG_FILE) + 1); + return; + } + if (config_entries) { +#if 0 if ((c == '\n') || (c == '\r') || (c == 6)) break; +#endif + if (c == 'r') + return; + + if (c == '\n' || c == '\r' || c == 6 || c == 'l') + { + config_file_history[config_file_history_prev_pos].entryno = + entryno; + config_file_history[config_file_history_prev_pos].first_entry += + first_entry; + + break; + } + + if (c == 2 || c == 'h') /* KEY_LEFT */ + { + /* go back in history if possible */ + int p = config_file_history_prev_pos; + if (p != config_file_history_start) + { + p = (p == 0) ? CONFIG_FILE_HISTORY_ENTRIES - 1 : p - 1; + memmove(config_file, config_file_history[p].filename, + CONFIG_FILE_LEN); + config_file_history_pos = p; + config_file_history_menu_pos = p; + + return; + } + } + + } else { @@ -663,6 +1054,12 @@ saved_partition = install_partition; current_drive = GRUB_INVALID_DRIVE; + if (is_var_expand()) + { + int _s; + new_heap = var_sprint_buf(new_heap, &_s); + } + if (! get_cmdline (PACKAGE " edit> ", new_heap, NEW_HEAPSIZE + 1, 0, 1)) { @@ -704,6 +1101,13 @@ stop (); } #endif + + /* Check toggles here so that we don't "overwrite" existing + * key binding... (user should choose another key then) */ + if (toggle_do_key(c)) + { + goto restart; + } } } } @@ -717,11 +1121,17 @@ while (1) { + int len; + if (config_entries) + { printf (" Booting \'%s\'\n\n", - get_entry (menu_entries, first_entry + entryno, 0)); + var_sprint_buf(get_entry (menu_entries, first_entry + entryno, 0),&len)); + } else + { printf (" Booting command-list\n\n"); + } if (! cur_entry) cur_entry = get_entry (config_entries, first_entry + entryno, 1); @@ -848,6 +1258,9 @@ /* Initialize the environment for restarting Stage 2. */ grub_setjmp (restart_env); + /* Init toggle triggers. */ + toggle_trigger_init(); + /* Initialize the kill buffer. */ *kill_buf = 0; @@ -982,10 +1395,26 @@ } if (is_preset) + { close_preset_menu (); + } else + { grub_close (); } + + /* Save history for config_file */ + memmove(config_file_history[config_file_history_pos].filename, + config_file, + CONFIG_FILE_LEN); + config_file_history_prev_pos = config_file_history_pos; + if (++config_file_history_pos == CONFIG_FILE_HISTORY_ENTRIES) + config_file_history_pos = 0; + if (config_file_history_start == config_file_history_pos && + ++config_file_history_start == CONFIG_FILE_HISTORY_ENTRIES) + config_file_history_start = 0; + + } while (is_preset); } --- ./netboot/config.c.voros 2003-07-09 13:45:37.000000000 +0200 +++ ./netboot/config.c 2004-09-10 23:47:17.000000000 +0200 @@ -122,6 +122,12 @@ "Intel EtherExpressPro100 ID1029", 0, 0, 0, 0}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, "Intel Corporation 82559 InBusiness 10/100", 0, 0, 0, 0}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1031, + "Intel EtherExpressPro100 ID1031", 0, 0, 0, 0}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1039, + "Intel EtherExpressPro100 ID1039", 0, 0, 0, 0}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1050, + "Intel EtherExpressPro100 82555 10/100", 0, 0, 0, 0}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, "Intel EtherExpressPro100 82562EM", 0, 0, 0, 0}, #endif @@ -281,6 +287,9 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, eepro100_probe }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, eepro100_probe }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, eepro100_probe }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1031, eepro100_probe }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1039, eepro100_probe }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1050, eepro100_probe }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, eepro100_probe }, # endif /* INCLUDE_EEPRO100 */ # ifdef INCLUDE_EPIC100 --- ./netboot/misc.c.voros 2003-07-09 13:45:37.000000000 +0200 +++ ./netboot/misc.c 2004-09-10 23:53:11.000000000 +0200 @@ -39,7 +39,7 @@ static const char tiddles[]="-\\|/"; unsigned long ticks; - if (debug) + /*if (debug) */ { if ((ticks = currticks ()) == lastticks) return; --- ./netboot/pci.h.voros 2003-07-09 13:45:38.000000000 +0200 +++ ./netboot/pci.h 2004-09-10 23:56:09.000000000 +0200 @@ -129,6 +129,9 @@ #define PCI_DEVICE_ID_INTEL_82559ER 0x1209 #define PCI_DEVICE_ID_INTEL_ID1029 0x1029 #define PCI_DEVICE_ID_INTEL_ID1030 0x1030 +#define PCI_DEVICE_ID_INTEL_ID1031 0x1031 +#define PCI_DEVICE_ID_INTEL_ID1039 0x1039 +#define PCI_DEVICE_ID_INTEL_ID1050 0x1050 #define PCI_DEVICE_ID_INTEL_82562 0x2449 #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 --- ./configure.voros 2004-06-13 19:42:59.000000000 +0200 +++ ./configure 2004-09-10 23:16:20.000000000 +0200 @@ -269,8 +269,8 @@ # Identity of this package. PACKAGE_NAME='GRUB' PACKAGE_TARNAME='grub' -PACKAGE_VERSION='0.95' -PACKAGE_STRING='GRUB 0.95' +PACKAGE_VERSION='0.95-os' +PACKAGE_STRING='GRUB 0.95-os' PACKAGE_BUGREPORT='bug-grub@gnu.org' ac_unique_file="stage2/stage2.c" @@ -780,7 +780,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures GRUB 0.95 to adapt to many kinds of systems. +\`configure' configures GRUB 0.95-os to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -846,7 +846,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of GRUB 0.95:";; + short | recursive ) echo "Configuration of GRUB 0.95-os:";; esac cat <<\_ACEOF @@ -1039,7 +1039,7 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -GRUB configure 0.95 +GRUB configure 0.95-os generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -1053,7 +1053,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by GRUB $as_me 0.95, which was +It was created by GRUB $as_me 0.95-os, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1691,7 +1691,7 @@ # Define the identity of the package. PACKAGE='grub' - VERSION='0.95' + VERSION='0.95-os' cat >>confdefs.h <<_ACEOF @@ -6543,7 +6543,7 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by GRUB $as_me 0.95, which was +This file was extended by GRUB $as_me 0.95-os, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6606,7 +6606,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -GRUB config.status 0.95 +GRUB config.status 0.95-os configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"