diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/Makefile.am grub-0.97/stage2/Makefile.am --- grub-0.97.old/stage2/Makefile.am 2006-04-24 18:01:54.000000000 +0200 +++ grub-0.97/stage2/Makefile.am 2006-04-24 19:11:34.000000000 +0200 @@ -7,7 +7,7 @@ fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ - terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h + terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h env.h biosacpi.h EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) # For . @@ -19,7 +19,7 @@ disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ - terminfo.c tparm.c + terminfo.c tparm.c env.c biosacpi.c libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ @@ -90,7 +90,7 @@ cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ - hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c + hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c env.c biosacpi.c pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/biosacpi.c grub-0.97/stage2/biosacpi.c --- grub-0.97.old/stage2/biosacpi.c 1970-01-01 01:00:00.000000000 +0100 +++ grub-0.97/stage2/biosacpi.c 2006-04-24 19:56:36.000000000 +0200 @@ -0,0 +1,166 @@ +/*- + * Copyright (c) 2001 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.1 2001/08/30 00:42:09 msmith Exp $ + */ + +#include +#include + +int +grub_strncmp (s1, s2, n) + const char *s1; + const char *s2; + long unsigned int n; +{ + unsigned char c1 = '\0'; + unsigned char c2 = '\0'; + + if (n >= 4) + { + long unsigned int n4 = n >> 2; + do + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + } + while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0' || c1 != c2) + return c1 - c2; + n--; + } + + return c1 - c2; +} + +/* + * Detect ACPI and export information about the APCI BIOS into the + * environment. + */ + +#define RSDP_CHECKSUM_LENGTH 20 + +void +biosacpi_detect (void) +{ + RSDP_DESCRIPTOR *rsdp; + char buf[16]; + int revision; + + /* XXX check the BIOS datestamp */ + + /* locate and validate the RSDP */ + if ((rsdp = biosacpi_find_rsdp ()) == NULL) + return; + + /* export values from the RSDP */ + revision = rsdp->Revision; + if (revision == 0) + revision = 1; + sprintf (buf, "%d", revision); + grub_setenv ("FreeBSD.hint.acpi.0.revision", buf); + sprintf (buf, "%6s", rsdp->OemId); + grub_setenv ("FreeBSD.hint.acpi.0.oem", buf); + sprintf (buf, "0x%08x", rsdp->RsdtPhysicalAddress); + grub_setenv ("FreeBSD.hint.acpi.0.rsdt", buf); + if (revision >= 2) + { + /* XXX extended checksum? */ + sprintf (buf, "0x%016llx", rsdp->XsdtPhysicalAddress); + grub_setenv ("FreeBSD.hint.acpi.0.xsdt", buf); + sprintf (buf, "%d", rsdp->Length); + grub_setenv ("FreeBSD.hint.acpi.0.xsdt_length", buf); + } +} + +/* + * Find the RSDP in low memory. + */ +static RSDP_DESCRIPTOR * +biosacpi_find_rsdp (void) +{ + RSDP_DESCRIPTOR *rsdp; + + /* search the EBDA */ + if ((rsdp = biosacpi_search_rsdp ((char *) 0, 0x400)) != NULL) + return (rsdp); + + /* search the BIOS space */ + if ((rsdp = biosacpi_search_rsdp ((char *) 0xe0000, 0x20000)) != NULL) + return (rsdp); + + return (NULL); +} + +static RSDP_DESCRIPTOR * +biosacpi_search_rsdp (char *base, int length) +{ + RSDP_DESCRIPTOR *rsdp; + unsigned char *cp, sum; + int ofs, idx; + + /* search on 16-byte boundaries */ + for (ofs = 0; ofs < length; ofs += 16) + { + rsdp = (RSDP_DESCRIPTOR *) (base + ofs); + + /* compare signature, validate checksum */ + if (!grub_strncmp (rsdp->Signature, RSDP_SIG, strlen (RSDP_SIG))) + { + cp = (unsigned char *) rsdp; + sum = 0; + for (idx = 0; idx < RSDP_CHECKSUM_LENGTH; idx++) + sum += *(cp + idx); + if (sum != 0) + { + printf ("acpi: bad RSDP checksum (%d)\n", sum); + continue; + } + return (rsdp); + } + } + return (NULL); +} diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/biosacpi.h grub-0.97/stage2/biosacpi.h --- grub-0.97.old/stage2/biosacpi.h 1970-01-01 01:00:00.000000000 +0100 +++ grub-0.97/stage2/biosacpi.h 2006-04-24 19:56:40.000000000 +0200 @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2001 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.1 2001/08/30 00:42:09 msmith Exp $ + */ + +#ifndef _BIOSACPI_H +# define _BIOSACPI_H + +# include + +/* stolen from sys/contrib/dev/acpica/actbl.h */ +# ifndef RSDP_SIG +# define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ +# endif + +/* stolen from sys/contrib/dev/acpica/actbl.h */ +# ifndef RSDP_DESCRIPTOR +/* + * ACPI Version-independent tables + * + * NOTE: The tables that are specific to ACPI versions (1.0, 2.0, etc.) + * are in separate files. + */ +typedef struct rsdp_descriptor /* Root System Descriptor Pointer */ +{ + char Signature[8]; /* ACPI signature, contains "RSD PTR " */ + unsigned char Checksum; /* To make sum of struct == 0 */ + char OemId[6]; /* OEM identification */ + unsigned char Revision; /* Must be 0 for 1.0, 2 for 2.0 */ + unsigned int RsdtPhysicalAddress; /* 32-bit physical address of RSDT */ + unsigned int Length; /* XSDT Length in bytes including hdr */ + unsigned long long XsdtPhysicalAddress; /* 64-bit physical address of XSDT */ + unsigned char ExtendedChecksum; /* Checksum of entire table */ + char Reserved[3]; /* Reserved field must be 0 */ +} RSDP_DESCRIPTOR; +# endif + +void biosacpi_detect (void); +static RSDP_DESCRIPTOR *biosacpi_find_rsdp (void); +static RSDP_DESCRIPTOR *biosacpi_search_rsdp (char *base, int length); + +#endif diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/boot.c grub-0.97/stage2/boot.c --- grub-0.97.old/stage2/boot.c 2006-04-24 18:01:54.000000000 +0200 +++ grub-0.97/stage2/boot.c 2006-04-24 19:55:49.000000000 +0200 @@ -25,9 +25,11 @@ #include "imgact_aout.h" #include "i386-elf.h" -static int cur_addr; +#include "env.h" + +int cur_addr; entry_func entry_addr; -static struct mod_list mll[99]; +struct mod_list mll[99]; static int linux_mem_size; /* @@ -616,6 +618,13 @@ if (memaddr < RAW_ADDR (0x100000)) errnum = ERR_BELOW_1MB; + if ((cur_addr==0) && (type == KERNEL_TYPE_FREEBSD)) + { + mll[0].mod_start=memaddr; + mll[0].cmdline=(int)arg; + mll[0].pad=0; + } + /* If the memory range contains the entry address, get the physical address here. */ if (type == KERNEL_TYPE_MULTIBOOT @@ -755,6 +764,14 @@ return KERNEL_TYPE_NONE; } + if (type == KERNEL_TYPE_FREEBSD) + { + mll[0].mod_end=cur_addr; + mbi.mods_count=1; + mbi.flags |= MB_INFO_MODS; + mbi.mods_addr = (int) mll; + } + return type; } @@ -764,7 +781,7 @@ int len; /* if we are supposed to load on 4K boundaries */ - cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; + cur_addr=(grub_getopt('a'))?page_align(cur_addr):dword_align(cur_addr); if (!grub_open (module)) return 0; @@ -776,7 +793,8 @@ return 0; } - printf (" [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len); + printf (" [%s-module @ 0x%x, 0x%x bytes]\n", + (kernel_type==KERNEL_TYPE_FREEBSD)?"FreeBSD":"Multiboot", cur_addr, len); /* these two simply need to be set if any modules are loaded at all */ mbi.flags |= MB_INFO_MODS; @@ -980,6 +998,78 @@ bi.bi_esymtab = 0; } + // Set environment + cur_addr = (grub_getopt('a'))?page_align(cur_addr):dword_align(cur_addr); + bi.bi_envp = cur_addr; + { + char* pp; + + grub_fstenv("FreeBSD.*"); + while ((pp=grub_nxtenv())!=NULL) + { + pp+=8; + if ((*pp=='=') || (*pp==0)) continue; + strcpy((char*)cur_addr,pp); + cur_addr+=strlen(pp)+1; + } + memset((char*)cur_addr,0,1); + cur_addr++; + } + + // Set module infos + cur_addr = (grub_getopt('a'))?page_align(cur_addr):dword_align(cur_addr); + bi.bi_modulep = cur_addr; + for (i=0;i #endif +#include + /* The type of kernel loaded. */ kernel_t kernel_type; /* The boot device. */ @@ -1720,6 +1722,23 @@ return 1; break; + case KERNEL_TYPE_FREEBSD: + { + int len=grub_strlen(arg); + + if (mb_cmdline + len + 17 > (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN) + { + errnum = ERR_WONT_FIT; + return 1; + } + grub_memmove (mb_cmdline, arg, len); + grub_memmove(mb_cmdline+len, " --type=mfs_root", 17); + if (! load_module (arg, mb_cmdline)) + return 1; + mb_cmdline += len + 17; + break; + } + default: errnum = ERR_NEED_LX_KERNEL; return 1; @@ -2436,6 +2455,30 @@ }; +/* lsmod */ +static int +lsmod_func (char *arg, int flags) +{ + int i; + extern struct mod_list mll[99]; + extern int cur_addr; + + for (i=0;i (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN) { errnum = ERR_WONT_FIT; @@ -2619,12 +2663,13 @@ "module", module_func, BUILTIN_CMDLINE | BUILTIN_HELP_LIST, - "module FILE [ARG ...]", + "module FILE [--type=TYPE] [ARG ...]", "Load a boot module FILE for a Multiboot format boot image (no" " interpretation of the file contents is made, so users of this" " command must know what the kernel in question expects). The" " rest of the line is passed as the \"module command line\", like" - " the `kernel' command." + " the `kernel' command. For FreeBSD modules, you can specify its" + " type using the --type option." }; @@ -3528,6 +3573,137 @@ #endif /* SUPPORT_SERIAL */ +/* show */ +static int +show_func (char *arg, int flags) +{ + if (*arg==0) { grub_prtopt(); grub_prtenv(); } else + do + { + char* ev; + + ev=get_str(&arg); + if (*ev=='-') + { + if (*(ev+1)==0) grub_prtopt(); else + { + int rs; + + rs=grub_getopt(*(++ev)); + if (rs!=-1) printf("%c%c\n",(rs)?'+':'-',*ev); + } + } else + if (*ev) + { + char* pp; + + grub_fstenv(ev); + while ((pp=grub_nxtenv())!=NULL) + printf("%s\n",pp); + } + } while (*arg); + return 0; +} + +static struct builtin builtin_show = +{ + "show", + show_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "show [name ...]", + "Show the value of variable or option" +}; + + +/* set */ +static int +set_func (char *arg, int flags) +{ + if (*arg==0) show_func(arg,flags); else + do + { + char* ev; + + ev=get_str(&arg); + if (*ev=='-') + { + if (grub_setopt(*(++ev))) + printf("Option %c is not supported\n",ev); + } else + if (*ev) + { + char *nn; + + nn=ev; + while ((*nn!='=') && (*nn)) nn++; + if (*nn=='=') *(nn++)=0; + if ((*ev) && (grub_setenv(ev,nn))) + printf("Variable %s too long\n",ev); + } + } while (*arg); + return 0; +} + +static struct builtin builtin_set = +{ + "set", + set_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "set [-op | +op | name=value]", + "Set environment variable or option. Variable name can be any string" + " that doesn\'t begin with - . Option is a single character in the" + " range of \"a\"-\"z\", \"A\"-\"Z\", and \"0\"-\"9\"." +}; + +/* loadenv */ +static int +loadenv_func (char *arg) +{ + return grub_loadenv(get_str(&arg)); +} + +static struct builtin builtin_loadenv = +{ + "loadenv", + loadenv_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "loadenv file", + "Loads variable definitions into environment." +}; + + +/* unset */ +static int +unset_func (char *arg, int flags) +{ + if (*arg=='*') grub_clsenv(); else + while (*arg) + { + char* ev; + + ev=get_str(&arg); + if (*ev=='-') + { + if (*(ev+1)==0) grub_clsopt(); else + if (grub_unsetopt(*(++ev))) + printf("Option %c is not supported\n",ev); + } else + if (*ev) grub_unsetenv(ev); + } + return 0; +} + +static struct builtin builtin_unset= +{ + "unset", + unset_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, + "unset [parm | *]", + "Unset environment variable. Use \"unset *\" to clear all variables." + " Use \"unset -\" to clear all options." +}; + + /* setkey */ struct keysym { @@ -4835,7 +5011,9 @@ &builtin_install, &builtin_ioprobe, &builtin_kernel, + &builtin_loadenv, &builtin_lock, + &builtin_lsmod, &builtin_makeactive, &builtin_map, #ifdef USE_MD5_PASSWORDS @@ -4862,8 +5040,10 @@ #ifdef SUPPORT_SERIAL &builtin_serial, #endif /* SUPPORT_SERIAL */ + &builtin_set, &builtin_setkey, &builtin_setup, + &builtin_show, #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) &builtin_terminal, #endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ @@ -4878,6 +5058,7 @@ &builtin_timeout, &builtin_title, &builtin_unhide, + &builtin_unset, &builtin_uppermem, &builtin_vbeprobe, 0 diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/cmdline.c grub-0.97/stage2/cmdline.c --- grub-0.97.old/stage2/cmdline.c 2006-04-24 18:01:54.000000000 +0200 +++ grub-0.97/stage2/cmdline.c 2006-04-24 19:08:06.000000000 +0200 @@ -46,6 +46,32 @@ return cmdline; } +/* This new function extract string from cmd */ +char* +get_str(char** cmd) +{ + char *p1,*p2; + + p2=*cmd; + p1=p2; + if (*p2=='\"') + { + p1++; + p2++; + while ((*p2!='"') && (*p2)) p2++; + } else + { + while ((*p2!=' ') && (*p2!='\t') && (*p2)) p2++; + } + if (*p2) + { + *(p2++)=0; + } + while ((*p2==' ') || (*p2=='\t')) p2++; + *cmd=p2; + return p1; +} + /* Print a helpful message for the command-line interface. */ void print_cmdline_message (int forever) diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/env.c grub-0.97/stage2/env.c --- grub-0.97.old/stage2/env.c 1970-01-01 01:00:00.000000000 +0100 +++ grub-0.97/stage2/env.c 2006-04-24 19:57:11.000000000 +0200 @@ -0,0 +1,316 @@ +/* env.c - Environment manipulation function */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +char ev_buf[EV_BUFLEN]; +int ev_len = 1; +unsigned long ev_opt0 = 0, ev_opt1 = 0; + +int +grub_setenv (char *name, char *value) +{ + int len; + + grub_unsetenv (name); + len = strlen (name) + 2; + if (value) + len += strlen (value); + if (ev_len + len > EV_BUFLEN) + return 1; + ev_len--; + strcpy (&ev_buf[ev_len], name); + ev_len += strlen (name); + ev_buf[ev_len++] = '='; + if (value) + { + strcpy (&ev_buf[ev_len], value); + ev_len += strlen (value) + 1; + } + else + ev_buf[ev_len++] = 0; + ev_buf[ev_len++] = 0; + return 0; +} + +int +grub_loadenv (char *filename) +{ + char buf[4096]; + char fbsd_name[256]; + int len; + char *ptr; + + /* FIXME: I guess this doesn't really belong here :) */ + biosacpi_detect (); + + if (!grub_open (filename)) + return 1; + + strcpy (fbsd_name, "FreeBSD."); + + grub_read (buf, -1); + grub_close (); + ptr = buf; + + while (*ptr) + switch (*ptr) + { + case '\n': + case ' ': + ptr++; + break; + case '#': + while (*ptr != '\n') + ptr++; + break; + default: + { + char *name = ptr; + char *value; + while (*ptr != '=') + ptr++; + *ptr = '\0'; + ptr++; + value = ptr; + while (*ptr != '\n') + ptr++; + *ptr = '\0'; + strcpy (fbsd_name + 8, name); + grub_setenv (fbsd_name, value); + *ptr = '\n'; + } + break; + } + return 0; +} + +int +grub_unsetenv (char *name) +{ + char *ev; + + ev = grub_getenv (name); + if (ev == NULL) + return 1; + else + { + char *s, *d; + int len; + + d = ev - strlen (name) - 1; + s = ev + strlen (ev) + 1; + len = &ev_buf[ev_len] - s; + memcpy (d, s, len); + ev_len -= (s - d); + } + return 0; +} + +char * +grub_getenv (char *name) +{ + char *ev; + int len; + + len = strlen (name); + for (ev = ev_buf; *ev != 0; ev += strlen (ev) + 1) + { + if ((memcmp (ev, name, len) == 0) && (*(ev + len) == '=')) + return ev + len + 1; + } + return NULL; +} + +void +grub_prtenv (void) +{ + char *ev; + + for (ev = ev_buf; *ev != 0; ev += strlen (ev) + 1) + printf ("%s\n", ev); +} + +void +grub_clsenv (void) +{ + ev_len = 1; + ev_buf[0] = 0; +} + +static char *ms, *mp; +static int ml, mf; + +void +grub_fstenv (char *mask) +{ + ms = mask; + mf = 0; + while (*ms == '*') + { + mf |= 1; + ms++; + } + if (*ms) + { + char *pp; + + pp = ms + 1; + while ((*pp != '*') && (*pp)) + pp++; + if (*pp == '*') + mf |= 2; + ml = pp - ms; + } + else + ml = 0; + mp = ev_buf; +} + +char * +grub_nxtenv (void) +{ + while (*mp) + { + char *cp; + + cp = mp; + mp += strlen (mp) + 1; + if (ml == 0) + return cp; + else + { + char *pp; + int nn; + + pp = strstr (cp, "="); + if (pp == NULL) + continue; + nn = pp - cp; + if (mf == 0) + { + if ((ml == nn) && (memcmp (cp, ms, ml) == 0)) + return cp; + } + else if (ml <= nn) + { + if (mf == 1) + { + if (memcmp (cp + (nn - ml), ms, ml) == 0) + return cp; + } + else if (mf == 2) + { + if (memcmp (cp, ms, ml) == 0) + return cp; + } + else + { + int i; + + for (i = 0; i <= nn - ml; i++) + if ((cp[i] == ms[0]) && (memcmp (cp + i, ms, ml) == 0)) + return cp; + } + } + } + } + return NULL; +} + +int +grub_setopt (char opt) +{ + if ((opt >= 'a') && (opt <= 'z')) + ev_opt0 |= (1l << (opt - 'a')); + else if ((opt >= '0') && (opt <= '4')) + ev_opt0 |= (1l << (opt - '0' + 26)); + else if ((opt >= 'A') && (opt <= 'Z')) + ev_opt1 |= (1l << (opt - 'A')); + else if ((opt >= '5') && (opt <= '9')) + ev_opt1 |= (1l << (opt - '5' + 26)); + else + return 1; + return 0; +} + +int +grub_unsetopt (char opt) +{ + if ((opt >= 'a') && (opt <= 'z')) + ev_opt0 &= ~(1l << (opt - 'a')); + else if ((opt >= '0') && (opt <= '4')) + ev_opt0 &= ~(1l << (opt - '0' + 26)); + else if ((opt >= 'A') && (opt <= 'Z')) + ev_opt1 &= ~(1l << (opt - 'A')); + else if ((opt >= '5') && (opt <= '9')) + ev_opt1 &= ~(1l << (opt - '5' + 26)); + else + return 1; + return 0; +} + +int +grub_getopt (char opt) +{ + if ((opt >= 'a') && (opt <= 'z')) + return ev_opt0 & (1l << (opt - 'a')); + else if ((opt >= '0') && (opt <= '4')) + return ev_opt0 & (1l << (opt - '0' + 26)); + else if ((opt >= 'A') && (opt <= 'Z')) + return ev_opt1 & (1l << (opt - 'A')); + else if ((opt >= '5') && (opt <= '9')) + return ev_opt1 & (1l << (opt - '5' + 26)); + else + return -1; +} + +void +grub_prtopt (void) +{ + int i; + unsigned long mk; + + mk = 1; + for (i = 0; i < 26; i++) + { + if (ev_opt0 & mk) + putchar (i + 'a'); + if (ev_opt1 & mk) + putchar (i + 'A'); + mk <<= 1; + } + for (; i < 31; i++) + { + if (ev_opt0 & mk) + putchar (i - 26 + '0'); + if (ev_opt1 & mk) + putchar (i - 26 + '5'); + mk <<= 1; + } + putchar ('\n'); +} + +void +grub_clsopt (void) +{ + ev_opt0 = ev_opt1 = 0; +} diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/env.h grub-0.97/stage2/env.h --- grub-0.97.old/stage2/env.h 1970-01-01 01:00:00.000000000 +0100 +++ grub-0.97/stage2/env.h 2006-04-24 19:56:46.000000000 +0200 @@ -0,0 +1,43 @@ +/* env.h - Header files for env.c */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef GRUB_ENV_HEADER +# define GRUB_ENV_HEADER + +# define EV_BUFLEN 4096 + +extern char ev_buf[]; +extern int ev_len; + +int grub_setenv (char *, char *); +int grub_loadenv (char *); +int grub_unsetenv (char *); +char *grub_getenv (char *); +void grub_prtenv (void); +void grub_clsenv (void); +void grub_fstenv (char *); +char *grub_nxtenv (void); +int grub_setopt (char); +int grub_unsetopt (char); +int grub_getopt (char); +void grub_prtopt (void); +void grub_clsopt (void); + +#endif diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/freebsd.h grub-0.97/stage2/freebsd.h --- grub-0.97.old/stage2/freebsd.h 2006-04-24 18:01:54.000000000 +0200 +++ grub-0.97/stage2/freebsd.h 2006-04-24 19:08:06.000000000 +0200 @@ -92,4 +92,67 @@ unsigned long bi_extmem; unsigned long bi_symtab; unsigned long bi_esymtab; + unsigned long bi_kernend; + unsigned long bi_envp; + unsigned long bi_modulep; }; + +#define page_align(addr) (((addr) + 0xFFF) & 0xFFFFF000) +#define dword_align(addr) (((addr) + 0x3) & 0xFFFFFFFC) + +#define MODINFO_END 0x0000 /* End of list */ +#define MODINFO_NAME 0x0001 /* Name of module (string) */ +#define MODINFO_TYPE 0x0002 /* Type of module (string) */ +#define MODINFO_ADDR 0x0003 /* Loaded address */ +#define MODINFO_SIZE 0x0004 /* Size of module */ +#define MODINFO_EMPTY 0x0005 /* Has been deleted */ +#define MODINFO_ARGS 0x0006 /* Parameters string */ +#define MODINFO_METADATA 0x8000 /* Module-specfic */ + +#define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ +#define MODINFOMD_ELFHDR 0x0002 /* ELF header */ +#define MODINFOMD_SSYM 0x0003 /* start of symbols */ +#define MODINFOMD_ESYM 0x0004 /* end of symbols */ +#define MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */ +#define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ + +#define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */ + +#define COPY32(v, a) { \ + unsigned long x = (v); \ + grub_memmove((void*)a, (void*)&x, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s) { \ + COPY32(t, a); \ + COPY32(strlen(s) + 1, a); \ + grub_memmove((void*)a, s, strlen(s) + 1); \ + a += dword_align(strlen(s) + 1); \ +} + +#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) +#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) +#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s) + +#define MOD_VAR(t, a, s) { \ + COPY32(t, a); \ + COPY32(sizeof(s), a); \ + grub_memmove((void*)a, &s, sizeof(s)); \ + a += dword_align(sizeof(s)); \ +} + +#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) +#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) + +#define MOD_METADATA(a, tt, dd, ss) { \ + COPY32(MODINFO_METADATA | tt, a); \ + COPY32(ss, a); \ + grub_memmove((void*)a, dd, ss); \ + a += dword_align(ss); \ +} + +#define MOD_END(a) { \ + COPY32(MODINFO_END, a); \ + COPY32(0, a); \ +} diff -Nur -x Makefile.in -x '*.8' -x '*.1' -x configure grub-0.97.old/stage2/shared.h grub-0.97/stage2/shared.h --- grub-0.97.old/stage2/shared.h 2006-04-24 18:01:54.000000000 +0200 +++ grub-0.97/stage2/shared.h 2006-04-24 19:55:49.000000000 +0200 @@ -859,6 +859,7 @@ void init_builtins (void); void init_config (void); char *skip_to (int after_equal, char *cmdline); +char *get_str (char**); struct builtin *find_command (char *command); void print_cmdline_message (int forever); void enter_cmdline (char *heap, int forever);