From 075a165076df2405d8f1b7904f8c7074ff1f9554 Mon Sep 17 00:00:00 2001 From: okuji Date: Sun, 24 Jul 2005 18:16:26 +0000 Subject: [PATCH] 2005-07-24 Yoshinori K. Okuji * DISTLIST: Added util/i386/pc/grub-install.in. * util/i386/pc/grub-install.in: New file. * conf/i386-pc.rmk (sbin_SCRIPTS): New variable. (grub_install_SOURCES): Likewise. * genmk.rb: Added support for scripts. (Script): New class. (scripts): New variable. * Makefile.in (install-local): Install sbin_SCRIPTS by INSTALL_SCRIPT. (uninstall): Remove sbin_SCRIPTS. * util/i386/pc/grub-setup.c (main): If the argument is not a GRUB device, try to get a GRUB device by grub_util_biosdisk_get_grub_dev. Free DEST_DEV. * util/i386/pc/grub-mkdevicemap.c (usage): Remove a duplicated description for --device-map. --- DISTLIST | 1 + Makefile.in | 9 +- conf/i386-pc.mk | 11 ++ conf/i386-pc.rmk | 6 + genmk.rb | 37 +++++- util/i386/pc/grub-install.in | 221 ++++++++++++++++++++++++++++++++ util/i386/pc/grub-mkdevicemap.c | 3 +- util/i386/pc/grub-setup.c | 28 ++-- 8 files changed, 300 insertions(+), 16 deletions(-) create mode 100644 util/i386/pc/grub-install.in diff --git a/DISTLIST b/DISTLIST index cf302c616..fbc6f9b9e 100644 --- a/DISTLIST +++ b/DISTLIST @@ -166,6 +166,7 @@ term/i386/pc/vga.c term/powerpc/ieee1275/ofconsole.c util/i386/pc/biosdisk.c util/i386/pc/getroot.c +util/i386/pc/grub-install.in util/i386/pc/grub-mkdevicemap.c util/i386/pc/grub-mkimage.c util/i386/pc/grub-setup.c diff --git a/Makefile.in b/Makefile.in index 68a93f954..11530b6a6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -75,7 +75,7 @@ MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES)) DATA = $(pkgdata_IMAGES) $(pkgdata_MODULES) $(pkgdata_PROGRAMS) \ $(pkgdata_DATA) PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES) -SCRIPTS = +SCRIPTS = $(sbin_SCRIPTS) CLEANFILES = MOSTLYCLEANFILES = @@ -122,6 +122,11 @@ install-local: all dest="`echo $$file | sed 's,.*/,,'`"; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ done + @list='$(sbin_SCRIPTS)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)"; fi; \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ + done install-strip: $(MAKE) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" install @@ -136,7 +141,7 @@ uninstall: dest="`echo $$file | sed 's,.*/,,'`"; \ rm -f $(DESTDIR)$(bindir)/$$dest; \ done - @list='$(sbin_UTILITIES)'; for file in $$list; do \ + @list='$(sbin_UTILITIES) $(sbin_SCRIPTS)'; for file in $$list; do \ dest="`echo $$file | sed 's,.*/,,'`"; \ rm -f $(DESTDIR)$(sbindir)/$$dest; \ done diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk index 13f572f32..b697a00e7 100644 --- a/conf/i386-pc.mk +++ b/conf/i386-pc.mk @@ -972,6 +972,17 @@ genmoddep-util_genmoddep.d: util/genmoddep.c -include genmoddep-util_genmoddep.d +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/pc/grub-install.in +CLEANFILES += grub-install + +grub-install: util/i386/pc/grub-install.in config.status + ./config.status --file=grub-install:util/i386/pc/grub-install.in + + # Modules. pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod \ ext2.mod minix.mod hfs.mod jfs.mod normal.mod hello.mod vga.mod \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index cbe77d803..72f40f8b1 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -90,6 +90,12 @@ grub_emu_LDFLAGS = -lncurses # For genmoddep. genmoddep_SOURCES = util/genmoddep.c +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/pc/grub-install.in + # Modules. pkgdata_MODULES = _chain.mod _linux.mod linux.mod fat.mod ufs.mod \ ext2.mod minix.mod hfs.mod jfs.mod normal.mod hello.mod vga.mod \ diff --git a/genmk.rb b/genmk.rb index 68205469b..9a6910957 100644 --- a/genmk.rb +++ b/genmk.rb @@ -268,10 +268,36 @@ MOSTLYCLEANFILES += #{deps_str} end end +class Script + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + if sources.length != 1 + raise "only a single source file must be specified for a script" + end + src = sources[0] + if /\.in$/ !~ src + raise "unknown source file `#{src}'" + end + + "CLEANFILES += #{@name} + +#{@name}: #{src} config.status + ./config.status --file=#{name}:#{src} + +" + end +end + images = [] utils = [] pmodules = [] programs = [] +scripts = [] cont = false s = nil @@ -310,8 +336,13 @@ while l = gets end when 'PROGRAMS' - programs += args.split(/\s+/).collect do |util| - Program.new(prefix, util) + programs += args.split(/\s+/).collect do |prog| + Program.new(prefix, prog) + end + + when 'SCRIPTS' + scripts += args.split(/\s+/).collect do |script| + Script.new(prefix, script) end when 'SOURCES' @@ -323,6 +354,8 @@ while l = gets print util.rule(args.split(/\s+/)) elsif program = programs.detect() {|u| u.name.to_var == prefix} print program.rule(args.split(/\s+/)) + elsif script = scripts.detect() {|s| s.name.to_var == prefix} + print script.rule(args.split(/\s+/)) end end end diff --git a/util/i386/pc/grub-install.in b/util/i386/pc/grub-install.in new file mode 100644 index 000000000..6dc50da56 --- /dev/null +++ b/util/i386/pc/grub-install.in @@ -0,0 +1,221 @@ +#! /bin/sh + +# Install GRUB on your drive. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc. +# +# This file 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., 51 Franklin St - Suite 330, Boston, MA 02110, USA. + +# Initialize some variables. +prefix=@prefix@ +exec_prefix=@exec_prefix@ +sbindir=@sbindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +host_cpu=@host_cpu@ +host_os=@host_os@ +host_vendor=@host_vendor@ +pkgdatadir=${libdir}/${PACKAGE_TARNAME}/${host_cpu}-${host_vendor} + +grub_setup=${sbindir}/grub-setup +grub_mkimage=${sbindir}/grub-mkimage +grub_mkdevicemap=${sbindir}/grub-mkdevicemap +rootdir= +grub_prefix=/boot/grub + +install_device= +no_floppy= +force_lba= +recheck=no +debug=no + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --grub-setup=*) + grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --grub-mkdevicemap=*) + grub_setup=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + --no-floppy) + no_floppy="--no-floppy" ;; + --recheck) + recheck=yes ;; + # This is an undocumented feature... + --debug) + debug=yes ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$install_device" != x; then + echo "More than one install_devices?" 1>&2 + usage + exit 1 + fi + install_device="${option}" ;; + esac +done + +if test "x$install_device" = x; then + echo "install_device not specified." 1>&2 + usage + exit 1 +fi + +# If the debugging feature is enabled, print commands. +if test $debug = yes; then + set -x +fi + +# Initialize these directories here, since ROOTDIR was initialized. +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=/grub + bootdir=${rootdir} + ;; +*) + # Use /boot/grub by default. + bootdir=${rootdir}/boot + ;; +esac + +grubdir=${bootdir}/grub +device_map=${grubdir}/device.map + +# Check if GRUB is installed. +set $grub_setup dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +set $grub_mkdevicemap dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +# Create the GRUB directory if it is not present. +test -d "$bootdir" || mkdir "$bootdir" || exit 1 +test -d "$grubdir" || mkdir "$grubdir" || exit 1 + +# If --recheck is specified, remove the device map, if present. +if test $recheck = yes; then + rm -f $device_map +fi + +# Create the device map file if it is not present. +if test -f "$device_map"; then + : +else + # Create a safe temporary file. + test -n "$mklog" && log_file=`$mklog` + + $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 +fi + +# Make sure that there is no duplicated entry. +tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ + | sort | uniq -d | sed -n 1p` +if test -n "$tmp"; then + echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 + exit 1 +fi + +# Copy the GRUB images to the GRUB directory. +for file in ${grubdir}/*.mod ${grubdir}/*.lst ${grubdir}/*.img; do + if test -f $file; then + rm -f $file || exit 1 + fi +done +for file in ${pkgdatadir}/*.mod ${pkgdatadir}/*.lst ${pkgdatadir}/*.img; do + cp -f $file ${grubdir} || exit 1 +done + +# Create the core image. +modules="_chain pc" +# XXX This must be dynamic. I'm still thinking how to implement this. +modules="$modules fat" +$grub_mkimage --output=${grubdir}/core.img $modules || exit 1 + +# Now perform the installation. +$grub_setup --boot-file=${grubdir}/boot.img --core-file=${grubdir}/core.img \ + --directory=${grubdir} --device-map=${device_map} || exit 1 + +# Prompt the user to check if the device map is correct. +echo "Installation finished. No error reported." +echo "This is the contents of the device map $device_map." +echo "Check if this is correct or not. If any of the lines is incorrect," +echo "fix it and re-run the script \`grub-install'." +echo + +cat $device_map + +# Bye. +exit 0 diff --git a/util/i386/pc/grub-mkdevicemap.c b/util/i386/pc/grub-mkdevicemap.c index ed61e7301..527fbf18d 100644 --- a/util/i386/pc/grub-mkdevicemap.c +++ b/util/i386/pc/grub-mkdevicemap.c @@ -509,7 +509,6 @@ Usage: grub-mkdevicemap [OPTION]...\n\ \n\ Generate a device map file automatically.\n\ \n\ - -m, --device-map=FILE use FILE as the device map [default=%s]\n\ -n, --no-floppy do not probe any floppy drive\n\ -s, --probe-second-floppy probe the second floppy drive\n\ -m, --device-map=FILE use FILE as the device map [default=%s]\n\ @@ -519,7 +518,7 @@ Generate a device map file automatically.\n\ \n\ Report bugs to <%s>.\n\ ", - DEFAULT_DIRECTORY, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); + DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); exit (status); } diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 8ca0730f1..d0eb17dd0 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -605,19 +605,26 @@ main (int argc, char *argv[]) usage (1); } - dest_dev = get_device_name (argv[optind]); - - if (! dest_dev) - { - fprintf (stderr, "Invalid device `%s'.\n", argv[optind]); - usage (1); - } - - prefix = grub_get_prefix (dir ? : DEFAULT_DIRECTORY); - /* Initialize the emulated biosdisk driver. */ grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP); + dest_dev = get_device_name (argv[optind]); + if (! dest_dev) + { + /* Possibly, the user specified an OS device file. */ + dest_dev = grub_util_biosdisk_get_grub_dev (argv[optind]); + if (! dest_dev) + { + fprintf (stderr, "Invalid device `%s'.\n", argv[optind]); + usage (1); + } + } + else + /* For simplicity. */ + dest_dev = xstrdup (dest_dev); + + prefix = grub_get_prefix (dir ? : DEFAULT_DIRECTORY); + /* Initialize filesystems. */ grub_fat_init (); grub_ext2_init (); @@ -664,6 +671,7 @@ main (int argc, char *argv[]) free (dev_map); free (root_dev); free (prefix); + free (dest_dev); return 0; }