* util/sparc64/ieee1275/grub-setup.c: New file.
* util/sparc64/ieee1275/grub-ofpathname.c: New file.
* util/sparc64/ieee1275/grub-mkimage.c: New file.
* util/sparc64/ieee1275/grub-install.in: New file.
* util/ieee1275/ofpath.c: New file.
* util/ieee1275/devicemap.c: New file.
* util/devicemap.c: New file.
* util/deviceiter.c: New file.
* kern/sparc64/ieee1275/init.c: New file.
* include/grub/util/ofpath.h: New file.
* include/grub/util/deviceiter.h: New file.
* util/grub-mkdevicemap.c: Include deviceiter.h.
Implement using grub_util_emit_devicemap_entry and
grub_util_iterate_devices.
* conf/i386-corebook.rmk: Build util/deviceiter.c and
util/devicemap.c into grub-mkdevicemap
* conf/i386-efi.rmk: Likewise.
* conf/i386-ieee1275.rmk: Likewise.
* conf/i386-pc.rmk: Likewise.
* conf/powerpc-ieee1275.rmk: Likewise.
* conf/sparc64-ieee1275.rmk: Add rules to build boot block
images and installation utilities. Build kernel as image
instead of as elf binary. Use common rules as much as possible.
(grub_devalias_iterate): Dynamically allocate 'aliasname' and
'devtype'. Explicitly NULL terminate devalias expansion.
+ * util/sparc64/ieee1275/misc.c: New file.
+ * util/sparc64/ieee1275/grub-setup.c: New file.
+ * util/sparc64/ieee1275/grub-ofpathname.c: New file.
+ * util/sparc64/ieee1275/grub-mkimage.c: New file.
+ * util/sparc64/ieee1275/grub-install.in: New file.
+ * util/ieee1275/ofpath.c: New file.
+ * util/ieee1275/devicemap.c: New file.
+ * util/devicemap.c: New file.
+ * util/deviceiter.c: New file.
+ * kern/sparc64/ieee1275/init.c: New file.
+ * include/grub/util/ofpath.h: New file.
+ * include/grub/util/deviceiter.h: New file.
+ * util/grub-mkdevicemap.c: Include deviceiter.h.
+ Implement using grub_util_emit_devicemap_entry and
+ grub_util_iterate_devices.
+ * conf/i386-corebook.rmk: Build util/deviceiter.c and
+ util/devicemap.c into grub-mkdevicemap
+ * conf/i386-efi.rmk: Likewise.
+ * conf/i386-ieee1275.rmk: Likewise.
+ * conf/i386-pc.rmk: Likewise.
+ * conf/powerpc-ieee1275.rmk: Likewise.
+ * conf/sparc64-ieee1275.rmk: Add rules to build boot block
+ images and installation utilities. Build kernel as image
+ instead of as elf binary. Use common rules as much as possible.
+
2009-04-19 Vladimir Serbinenko <phcoder@gmail.com>
Correct GPT definition
endif
# For grub-mkdevicemap.
-grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+ util/devicemap.c util/misc.c
# For grub-emu.
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
# kern/fs.c kern/env.c fs/fshelp.c
# For grub-mkdevicemap.
-grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+ util/devicemap.c util/misc.c
# For grub-emu.
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
endif
# For grub-mkdevicemap.
-grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+ util/devicemap.c util/misc.c
# For grub-emu.
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_setup_init.c
# For grub-mkdevicemap.
-grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+ util/devicemap.c util/misc.c
# For grub-emu.
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
endif
# For grub-mkdevicemap.
-grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+ util/devicemap.c util/misc.c
# For grub-emu
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
# -*- makefile -*-
-COMMON_ASFLAGS = -nostdinc
-COMMON_CFLAGS = -ggdb -ffreestanding -m64 -mno-app-regs
-COMMON_LDFLAGS = -melf64_sparc -nostdlib
+COMMON_ASFLAGS = -nostdinc -m64
+COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs
+COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax
# Used by various components. These rules need to precede them.
normal/lexer.c_DEPENDENCIES = grub_script.tab.h
# Images.
+pkglib_IMAGES = boot.img diskboot.img kernel.img
+
+# For boot.img.
+boot_img_SOURCES = boot/sparc64/ieee1275/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
+boot_img_FORMAT = a.out-sunos-big
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/sparc64/ieee1275/diskboot.S
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
+diskboot_img_FORMAT = binary
MOSTLYCLEANFILES += symlist.c kernel_syms.lst
DEFSYMFILES += kernel_syms.lst
-kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
- env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \
- symbol.h term.h time.h types.h sparc64/libgcc.h loader.h partition.h \
- pc_partition.h ieee1275/ieee1275.h machine/kernel.h
-
-symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+ partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+ list.h handler.h command.h \
+ sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \
+ sparc64/ieee1275/ieee1275.h
+kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
+ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \
+ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
+ kern/misc.c kern/mm.c kern/rescue.c kern/term.c \
+ kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+ kern/sparc64/ieee1275/ieee1275.c \
+ kern/sparc64/ieee1275/init.c \
+ kern/ieee1275/mmap.c \
+ term/ieee1275/ofconsole.c \
+ kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
+ kern/parser.c kern/partition.c kern/env.c kern/sparc64/dl.c \
+ kern/generic/millisleep.c kern/time.c \
+ symlist.c kern/sparc64/cache.S
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc
+kernel_img_FORMAT = binary
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
-# For the parser.
-grub_script.tab.c grub_script.tab.h: normal/parser.y
- $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/normal/parser.y
-
-kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
-# Programs
-pkglib_PROGRAMS = kernel.elf
-
# Utilities.
-#bin_UTILITIES = grub-mkimage
-#ifeq ($(enable_grub_emu), yes)
-#bin_UTILITIES += grub-emu
-#endif
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup grub-mkdevicemap grub-ofpathname
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
# For grub-mkimage.
grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
util/resolve.c
+# For grub-setup.
+util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \
+ util/misc.c util/getroot.c kern/device.c kern/disk.c \
+ kern/err.c kern/misc.c kern/parser.c kern/partition.c \
+ kern/file.c kern/fs.c kern/env.c fs/fshelp.c \
+ \
+ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
+ fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
+ fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \
+ \
+ partmap/amiga.c partmap/apple.c partmap/pc.c \
+ partmap/sun.c partmap/acorn.c \
+ \
+ disk/raid.c disk/mdraid_linux.c disk/lvm.c \
+ util/raid.c util/lvm.c \
+ grub_setup_init.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+ util/ieee1275/ofpath.c util/ieee1275/devicemap.c util/misc.c
+
+# For grub-ofpathname.
+grub_ofpathname_SOURCES = util/sparc64/ieee1275/grub-ofpathname.c \
+ util/ieee1275/ofpath.c util/misc.c
+
# For grub-emu
-#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
-# commands/configfile.c commands/default.c commands/help.c \
-# commands/search.c commands/terminal.c commands/ls.c \
-# commands/timeout.c commands/test.c \
-# commands/halt.c commands/reboot.c \
-# disk/loopback.c \
-# fs/affs.c fs/fat.c fs/ext2.c fs/fshelp.c fs/hfs.c fs/iso9660.c \
-# fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c \
-# grub_script.tab.c \
-# io/gzio.c \
-# kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c \
-# kern/file.c kern/fs.c commands/boot.c kern/main.c kern/misc.c \
-# kern/parser.c kern/partition.c kern/rescue.c kern/term.c \
-# kern/list.c kern/handler.c \
-# normal/arg.c normal/cmdline.c normal/command.c normal/datetime.c \
-# normal/completion.c normal/context.c normal/execute.c \
-# normal/function.c normal/lexer.c \
-# normal/main.c normal/menu.c normal/menu_entry.c \
-# normal/menu_text.c \
-# normal/menu_viewer.c normal/misc.c \
-# partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \
-# partmap/acorn.c \
-# util/console.c util/grub-emu.c util/misc.c \
-# util/hostdisk.c util/getroot.c \
-# commands/parttool.c parttool/pcpart.c \
-# util/sparc64/ieee1275/misc.c
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
+ commands/configfile.c commands/help.c \
+ commands/search.c commands/handler.c commands/test.c \
+ commands/ls.c commands/blocklist.c commands/hexdump.c \
+ lib/hexdump.c commands/halt.c commands/reboot.c \
+ disk/loopback.c \
+ \
+ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
+ fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
+ fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \
+ \
+ io/gzio.c \
+ kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \
+ kern/err.c kern/file.c kern/fs.c kern/loader.c kern/main.c \
+ kern/misc.c kern/parser.c kern/partition.c kern/rescue.c \
+ kern/term.c fs/fshelp.c \
+ kern/list.c kern/handler.c \
+ lib/arg.c normal/cmdline.c normal/command.c \
+ normal/completion.c normal/execute.c \
+ normal/function.c normal/lexer.c normal/main.c normal/menu.c \
+ normal/menu_text.c \
+ normal/menu_entry.c normal/menu_viewer.c normal/misc.c \
+ normal/script.c \
+ normal/color.c \
+ partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \
+ partmap/acorn.c \
+ util/console.c util/hostfs.c util/grub-emu.c util/misc.c \
+ util/hostdisk.c util/getroot.c \
+ util/sparc64/ieee1275/misc.c \
+ \
+ disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
+ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
+ grub_script.tab.c grub_emu_init.c
grub_emu_LDFLAGS = $(LIBCURSES)
-kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \
- kern/main.c kern/device.c kern/disk.c kern/dl.c kern/file.c \
- kern/fs.c kern/err.c kern/misc.c kern/mm.c \
- kern/rescue.c kern/term.c term/ieee1275/ofconsole.c \
- kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
- kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \
- kern/generic/millisleep.c kern/generic/get_time_ms.c \
- kern/sparc64/cache.S kern/parser.c
-kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h
-kernel_elf_CFLAGS = $(COMMON_CFLAGS)
-kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc
-
-# Modules.
-#_linux.mod linux.mod
-pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \
- hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
- pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
- configfile.mod search.mod gzio.mod xfs.mod \
- affs.mod sfs.mod acorn.mod
-
-# For fshelp.mod.
-fshelp_mod_SOURCES = fs/fshelp.c
-fshelp_mod_CFLAGS = $(COMMON_CFLAGS)
-fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For fat.mod.
-fat_mod_SOURCES = fs/fat.c
-fat_mod_CFLAGS = $(COMMON_CFLAGS)
-fat_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ext2.mod.
-ext2_mod_SOURCES = fs/ext2.c
-ext2_mod_CFLAGS = $(COMMON_CFLAGS)
-ext2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ufs.mod.
-ufs_mod_SOURCES = fs/ufs.c
-ufs_mod_CFLAGS = $(COMMON_CFLAGS)
-ufs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For minix.mod.
-minix_mod_SOURCES = fs/minix.c
-minix_mod_CFLAGS = $(COMMON_CFLAGS)
-minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For hfs.mod.
-hfs_mod_SOURCES = fs/hfs.c
-hfs_mod_CFLAGS = $(COMMON_CFLAGS)
-hfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For jfs.mod.
-jfs_mod_SOURCES = fs/jfs.c
-jfs_mod_CFLAGS = $(COMMON_CFLAGS)
-jfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For iso9660.mod.
-iso9660_mod_SOURCES = fs/iso9660.c
-iso9660_mod_CFLAGS = $(COMMON_CFLAGS)
-iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For xfs.mod.
-xfs_mod_SOURCES = fs/xfs.c
-xfs_mod_CFLAGS = $(COMMON_CFLAGS)
-xfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# Scripts.
+sbin_SCRIPTS = grub-install
-# For affs.mod.
-affs_mod_SOURCES = fs/affs.c
-affs_mod_CFLAGS = $(COMMON_CFLAGS)
-affs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For grub-install.
+grub_install_SOURCES = util/sparc64/ieee1275/grub-install.in
-# For sfs.mod.
-sfs_mod_SOURCES = fs/sfs.c
-sfs_mod_CFLAGS = $(COMMON_CFLAGS)
-sfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# Modules.
+pkglib_MODULES = halt.mod \
+ linux.mod \
+ normal.mod \
+ reboot.mod \
+ memdisk.mod \
+ lsmmap.mod
-# For _linux.mod.
-#_linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
-#_linux_mod_CFLAGS = $(COMMON_CFLAGS)
-#_linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
# For linux.mod.
-#linux_mod_SOURCES = loader/sparc64/ieee1275/linux_normal.c
-#linux_mod_CFLAGS = $(COMMON_CFLAGS)
-#linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
#
# Only arch dependant part of normal.mod will be here. Common part for
# Please put arch dependant part of normal.mod at the end of list to
# keep it simpler to update to different architectures.
#
-normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \
+normal_mod_SOURCES = lib/arg.c normal/cmdline.c normal/command.c \
normal/datetime.c normal/completion.c normal/execute.c \
normal/function.c normal/lexer.c normal/main.c normal/menu.c \
normal/handler.c normal/menu_text.c \
normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For hello.mod.
-hello_mod_SOURCES = hello/hello.c
-hello_mod_CFLAGS = $(COMMON_CFLAGS)
-hello_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For boot.mod.
-boot_mod_SOURCES = commands/boot.c
-boot_mod_CFLAGS = $(COMMON_CFLAGS)
-boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ls.mod.
-ls_mod_SOURCES = commands/ls.c
-ls_mod_CFLAGS = $(COMMON_CFLAGS)
-ls_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For cmp.mod.
-cmp_mod_SOURCES = commands/cmp.c
-cmp_mod_CFLAGS = $(COMMON_CFLAGS)
-cmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For cat.mod.
-cat_mod_SOURCES = commands/cat.c
-cat_mod_CFLAGS = $(COMMON_CFLAGS)
-cat_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For font.mod.
-font_mod_SOURCES = font/manager.c
-font_mod_CFLAGS = $(COMMON_CFLAGS)
-font_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For amiga.mod
-amiga_mod_SOURCES = partmap/amiga.c
-amiga_mod_CFLAGS = $(COMMON_CFLAGS)
-amiga_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For apple.mod
-apple_mod_SOURCES = partmap/apple.c
-apple_mod_CFLAGS = $(COMMON_CFLAGS)
-apple_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For pc.mod
-pc_mod_SOURCES = partmap/pc.c
-pc_mod_CFLAGS = $(COMMON_CFLAGS)
-pc_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For sun.mod
-sun_mod_SOURCES = partmap/sun.c
-sun_mod_CFLAGS = $(COMMON_CFLAGS)
-sun_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For acorn.mod
-acorn_mod_SOURCES = partmap/acorn.c
-acorn_mod_CFLAGS = $(COMMON_CFLAGS)
-
-# For loopback.mod
-loopback_mod_SOURCES = disk/loopback.c
-loopback_mod_CFLAGS = $(COMMON_CFLAGS)
-loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For suspend.mod
-suspend_mod_SOURCES = commands/ieee1275/suspend.c
-suspend_mod_CFLAGS = $(COMMON_CFLAGS)
-suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For reboot.mod
+# For reboot.mod.
reboot_mod_SOURCES = commands/reboot.c
reboot_mod_CFLAGS = $(COMMON_CFLAGS)
reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For halt.mod
+# For halt.mod.
halt_mod_SOURCES = commands/halt.c
halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For help.mod.
-help_mod_SOURCES = commands/help.c
-help_mod_CFLAGS = $(COMMON_CFLAGS)
-help_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For default.mod
-default_mod_SOURCES = commands/default.c
-default_mod_CFLAGS = $(COMMON_CFLAGS)
-default_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For timeout.mod
-timeout_mod_SOURCES = commands/timeout.c
-timeout_mod_CFLAGS = $(COMMON_CFLAGS)
-timeout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For configfile.mod
-configfile_mod_SOURCES = commands/configfile.c
-configfile_mod_CFLAGS = $(COMMON_CFLAGS)
-configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For search.mod.
-search_mod_SOURCES = commands/search.c
-search_mod_CFLAGS = $(COMMON_CFLAGS)
-search_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For gzio.mod.
-gzio_mod_SOURCES = io/gzio.c
-gzio_mod_CFLAGS = $(COMMON_CFLAGS)
-gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For test.mod.
-test_mod_SOURCES = commands/test.c
-test_mod_CFLAGS = $(COMMON_CFLAGS)
-test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+include $(srcdir)/conf/common.mk
--- /dev/null
+#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER
+#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER 1
+
+#include <config.h>
+
+void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
+ int floppy_disks);
+void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
+ int *num_fd, int *num_hd);
+
+#endif /* ! GRUB_DEVICEITER_MACHINE_UTIL_HEADER */
--- /dev/null
+#ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER
+#define GRUB_OFPATH_MACHINE_UTIL_HEADER 1
+
+char *grub_util_devname_to_ofpath (char *devname);
+
+#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
--- /dev/null
+/* init.c -- Initialize GRUB on SPARC64. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/time.h>
+#include <grub/ieee1275/ofdisk.h>
+#include <grub/ieee1275/ieee1275.h>
+
+void
+grub_exit (void)
+{
+ grub_ieee1275_exit ();
+}
+
+static grub_uint64_t
+ieee1275_get_time_ms (void)
+{
+ grub_uint32_t msecs = 0;
+
+ grub_ieee1275_milliseconds (&msecs);
+
+ return msecs;
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+ return ieee1275_get_time_ms ();
+}
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+ extern char _end[];
+ return (grub_addr_t) _end;
+}
+
+void
+grub_machine_set_prefix (void)
+{
+ if (grub_prefix[0] != '(')
+ {
+ char bootpath[IEEE1275_MAX_PATH_LEN];
+ grub_ssize_t actual;
+ char *prefix, *path;
+
+ if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
+ &bootpath, sizeof (bootpath), &actual))
+ {
+ /* Should never happen. */
+ grub_printf ("/chosen/bootpath property missing!\n");
+ grub_env_set ("prefix", "");
+ return;
+ }
+
+ /* Transform an OF device path to a GRUB path. */
+ prefix = grub_ieee1275_encode_devname (bootpath);
+
+ path = grub_malloc (grub_strlen (grub_prefix)
+ + grub_strlen (prefix)
+ + 2);
+ grub_sprintf(path, "%s%s", prefix, grub_prefix);
+
+ grub_strcpy (grub_prefix, path);
+
+ grub_free (path);
+ grub_free (prefix);
+ }
+
+ grub_env_set ("prefix", grub_prefix);
+}
+
+static void
+grub_heap_init (void)
+{
+ grub_mm_init_region ((void *)(long)0x4000UL, 0x200000 - 0x4000);
+}
+
+static void
+grub_parse_cmdline (void)
+{
+ grub_ssize_t actual;
+ char args[256];
+
+ if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
+ sizeof args, &actual) == 0
+ && actual > 1)
+ {
+ int i = 0;
+
+ while (i < actual)
+ {
+ char *command = &args[i];
+ char *end;
+ char *val;
+
+ end = grub_strchr (command, ';');
+ if (end == 0)
+ i = actual; /* No more commands after this one. */
+ else
+ {
+ *end = '\0';
+ i += end - command + 1;
+ while (grub_isspace(args[i]))
+ i++;
+ }
+
+ /* Process command. */
+ val = grub_strchr (command, '=');
+ if (val)
+ {
+ *val = '\0';
+ grub_env_set (command, val + 1);
+ }
+ }
+ }
+}
+
+void
+grub_machine_init (void)
+{
+ grub_ieee1275_init ();
+ grub_console_init ();
+ grub_heap_init ();
+
+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
+ grub_ofdisk_init ();
+
+ grub_parse_cmdline ();
+ grub_install_get_time_ms (ieee1275_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+ grub_ofdisk_fini ();
+ grub_console_fini ();
+}
--- /dev/null
+/* deviceiter.c - iterate over system devices */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#include <grub/util/misc.h>
+#include <grub/util/deviceiter.h>
+
+#ifdef __linux__
+# if !defined(__GLIBC__) || \
+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
+/* Maybe libc doesn't have large file support. */
+# include <linux/unistd.h> /* _llseek */
+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
+# include <sys/ioctl.h> /* ioctl */
+# ifndef HDIO_GETGEO
+# define HDIO_GETGEO 0x0301 /* get device geometry */
+/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
+ defined. */
+struct hd_geometry
+{
+ unsigned char heads;
+ unsigned char sectors;
+ unsigned short cylinders;
+ unsigned long start;
+};
+# endif /* ! HDIO_GETGEO */
+# ifndef FLOPPY_MAJOR
+# define FLOPPY_MAJOR 2 /* the major number for floppy */
+# endif /* ! FLOPPY_MAJOR */
+# ifndef MAJOR
+# define MAJOR(dev) \
+ ({ \
+ unsigned long long __dev = (dev); \
+ (unsigned) ((__dev >> 8) & 0xfff) \
+ | ((unsigned int) (__dev >> 32) & ~0xfff); \
+ })
+# endif /* ! MAJOR */
+# ifndef CDROM_GET_CAPABILITY
+# define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
+# endif /* ! CDROM_GET_CAPABILITY */
+# ifndef BLKGETSIZE
+# define BLKGETSIZE _IO(0x12,96) /* return device size */
+# endif /* ! BLKGETSIZE */
+#endif /* __linux__ */
+
+/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
+ kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
+#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
+# define __FreeBSD_kernel__
+#endif
+#ifdef __FreeBSD_kernel__
+ /* Obtain version of kFreeBSD headers */
+# include <osreldate.h>
+# ifndef __FreeBSD_kernel_version
+# define __FreeBSD_kernel_version __FreeBSD_version
+# endif
+
+ /* Runtime detection of kernel */
+# include <sys/utsname.h>
+int
+get_kfreebsd_version (void)
+{
+ struct utsname uts;
+ int major;
+ int minor;
+ int v[2];
+
+ uname (&uts);
+ sscanf (uts.release, "%d.%d", &major, &minor);
+
+ if (major >= 9)
+ major = 9;
+ if (major >= 5)
+ {
+ v[0] = minor/10; v[1] = minor%10;
+ }
+ else
+ {
+ v[0] = minor%10; v[1] = minor/10;
+ }
+ return major*100000+v[0]*10000+v[1]*1000;
+}
+#endif /* __FreeBSD_kernel__ */
+
+#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/ioctl.h> /* ioctl */
+# include <sys/disklabel.h>
+# include <sys/cdio.h> /* CDIOCCLRDEBUG */
+# if defined(__FreeBSD_kernel__)
+# include <sys/param.h>
+# if __FreeBSD_kernel_version >= 500040
+# include <sys/disk.h>
+# endif
+# endif /* __FreeBSD_kernel__ */
+#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
+
+#ifdef HAVE_OPENDISK
+# include <util.h>
+#endif /* HAVE_OPENDISK */
+
+#ifdef __linux__
+/* Check if we have devfs support. */
+static int
+have_devfs (void)
+{
+ struct stat st;
+ return stat ("/dev/.devfsd", &st) == 0;
+}
+#endif /* __linux__ */
+
+/* These three functions are quite different among OSes. */
+static void
+get_floppy_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+ /* GNU/Linux */
+ if (have_devfs ())
+ sprintf (name, "/dev/floppy/%d", unit);
+ else
+ sprintf (name, "/dev/fd%d", unit);
+#elif defined(__GNU__)
+ /* GNU/Hurd */
+ sprintf (name, "/dev/fd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+ /* kFreeBSD */
+ if (get_kfreebsd_version () >= 400000)
+ sprintf (name, "/dev/fd%d", unit);
+ else
+ sprintf (name, "/dev/rfd%d", unit);
+#elif defined(__NetBSD__)
+ /* NetBSD */
+ /* opendisk() doesn't work for floppies. */
+ sprintf (name, "/dev/rfd%da", unit);
+#elif defined(__OpenBSD__)
+ /* OpenBSD */
+ sprintf (name, "/dev/rfd%dc", unit);
+#elif defined(__QNXNTO__)
+ /* QNX RTP */
+ sprintf (name, "/dev/fd%d", unit);
+#elif defined(__CYGWIN__)
+ /* Cygwin */
+ sprintf (name, "/dev/fd%d", unit);
+#elif defined(__MINGW32__)
+ (void) unit;
+ *name = 0;
+#else
+# warning "BIOS floppy drives cannot be guessed in your operating system."
+ /* Set NAME to a bogus string. */
+ *name = 0;
+#endif
+}
+
+static void
+get_ide_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+ /* GNU/Linux */
+ sprintf (name, "/dev/hd%c", unit + 'a');
+#elif defined(__GNU__)
+ /* GNU/Hurd */
+ sprintf (name, "/dev/hd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+ /* kFreeBSD */
+ if (get_kfreebsd_version () >= 400000)
+ sprintf (name, "/dev/ad%d", unit);
+ else
+ sprintf (name, "/dev/rwd%d", unit);
+#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
+ /* NetBSD */
+ char shortname[16];
+ int fd;
+
+ sprintf (shortname, "wd%d", unit);
+ fd = opendisk (shortname, O_RDONLY, name,
+ 16, /* length of NAME */
+ 0 /* char device */
+ );
+ close (fd);
+#elif defined(__OpenBSD__)
+ /* OpenBSD */
+ sprintf (name, "/dev/rwd%dc", unit);
+#elif defined(__QNXNTO__)
+ /* QNX RTP */
+ /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
+ contain SCSI disks. */
+ sprintf (name, "/dev/hd%d", unit);
+#elif defined(__CYGWIN__)
+ /* Cygwin emulates all disks as /dev/sdX. */
+ (void) unit;
+ *name = 0;
+#elif defined(__MINGW32__)
+ sprintf (name, "//./PHYSICALDRIVE%d", unit);
+#else
+# warning "BIOS IDE drives cannot be guessed in your operating system."
+ /* Set NAME to a bogus string. */
+ *name = 0;
+#endif
+}
+
+static void
+get_scsi_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+ /* GNU/Linux */
+ sprintf (name, "/dev/sd%c", unit + 'a');
+#elif defined(__GNU__)
+ /* GNU/Hurd */
+ sprintf (name, "/dev/sd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+ /* kFreeBSD */
+ if (get_kfreebsd_version () >= 400000)
+ sprintf (name, "/dev/da%d", unit);
+ else
+ sprintf (name, "/dev/rda%d", unit);
+#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
+ /* NetBSD */
+ char shortname[16];
+ int fd;
+
+ sprintf (shortname, "sd%d", unit);
+ fd = opendisk (shortname, O_RDONLY, name,
+ 16, /* length of NAME */
+ 0 /* char device */
+ );
+ close (fd);
+#elif defined(__OpenBSD__)
+ /* OpenBSD */
+ sprintf (name, "/dev/rsd%dc", unit);
+#elif defined(__QNXNTO__)
+ /* QNX RTP */
+ /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
+ disable the detection of SCSI disks here. */
+ *name = 0;
+#elif defined(__CYGWIN__)
+ /* Cygwin emulates all disks as /dev/sdX. */
+ sprintf (name, "/dev/sd%c", unit + 'a');
+#elif defined(__MINGW32__)
+ (void) unit;
+ *name = 0;
+#else
+# warning "BIOS SCSI drives cannot be guessed in your operating system."
+ /* Set NAME to a bogus string. */
+ *name = 0;
+#endif
+}
+
+#ifdef __linux__
+static void
+get_virtio_disk_name (char *name, int unit)
+{
+#ifdef __sparc__
+ sprintf (name, "/dev/vdisk%c", unit + 'a');
+#else
+ sprintf (name, "/dev/vd%c", unit + 'a');
+#endif
+}
+
+static void
+get_dac960_disk_name (char *name, int controller, int drive)
+{
+ sprintf (name, "/dev/rd/c%dd%d", controller, drive);
+}
+
+static void
+get_ataraid_disk_name (char *name, int unit)
+{
+ sprintf (name, "/dev/ataraid/d%c", unit + '0');
+}
+
+static void
+get_i2o_disk_name (char *name, char unit)
+{
+ sprintf (name, "/dev/i2o/hd%c", unit);
+}
+
+static void
+get_cciss_disk_name (char *name, int controller, int drive)
+{
+ sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
+}
+
+static void
+get_ida_disk_name (char *name, int controller, int drive)
+{
+ sprintf (name, "/dev/ida/c%dd%d", controller, drive);
+}
+
+static void
+get_mmc_disk_name (char *name, int unit)
+{
+ sprintf (name, "/dev/mmcblk%d", unit);
+}
+
+static void
+get_xvd_disk_name (char *name, int unit)
+{
+ sprintf (name, "/dev/xvd%c", unit + 'a');
+}
+#endif
+
+/* Check if DEVICE can be read. If an error occurs, return zero,
+ otherwise return non-zero. */
+static int
+check_device (const char *device)
+{
+ char buf[512];
+ FILE *fp;
+
+ /* If DEVICE is empty, just return error. */
+ if (*device == 0)
+ return 0;
+
+ fp = fopen (device, "r");
+ if (! fp)
+ {
+ switch (errno)
+ {
+#ifdef ENOMEDIUM
+ case ENOMEDIUM:
+# if 0
+ /* At the moment, this finds only CDROMs, which can't be
+ read anyway, so leave it out. Code should be
+ reactivated if `removable disks' and CDROMs are
+ supported. */
+ /* Accept it, it may be inserted. */
+ return 1;
+# endif
+ break;
+#endif /* ENOMEDIUM */
+ default:
+ /* Break case and leave. */
+ break;
+ }
+ /* Error opening the device. */
+ return 0;
+ }
+
+ /* Make sure CD-ROMs don't get assigned a BIOS disk number
+ before SCSI disks! */
+#ifdef __linux__
+# ifdef CDROM_GET_CAPABILITY
+ if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
+ return 0;
+# else /* ! CDROM_GET_CAPABILITY */
+ /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
+ {
+ struct hd_geometry hdg;
+ struct stat st;
+
+ if (fstat (fileno (fp), &st))
+ return 0;
+
+ /* If it is a block device and isn't a floppy, check if HDIO_GETGEO
+ succeeds. */
+ if (S_ISBLK (st.st_mode)
+ && MAJOR (st.st_rdev) != FLOPPY_MAJOR
+ && ioctl (fileno (fp), HDIO_GETGEO, &hdg))
+ return 0;
+ }
+# endif /* ! CDROM_GET_CAPABILITY */
+#endif /* __linux__ */
+
+#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# ifdef CDIOCCLRDEBUG
+ if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
+ return 0;
+# endif /* CDIOCCLRDEBUG */
+#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
+
+ /* Attempt to read the first sector. */
+ if (fread (buf, 1, 512, fp) != 512)
+ {
+ fclose (fp);
+ return 0;
+ }
+
+ fclose (fp);
+ return 1;
+}
+
+void
+grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
+ int floppy_disks)
+{
+ int i;
+
+ /* Floppies. */
+ for (i = 0; i < floppy_disks; i++)
+ {
+ char name[16];
+ struct stat st;
+
+ get_floppy_disk_name (name, i);
+ if (stat (name, &st) < 0)
+ break;
+ /* In floppies, write the map, whether check_device succeeds
+ or not, because the user just may not insert floppies. */
+ if (hook (name, 1))
+ return;
+ }
+
+#ifdef __linux__
+ if (have_devfs ())
+ {
+ i = 0;
+ while (1)
+ {
+ char discn[32];
+ char name[PATH_MAX];
+ struct stat st;
+
+ /* Linux creates symlinks "/dev/discs/discN" for convenience.
+ The way to number disks is the same as GRUB's. */
+ sprintf (discn, "/dev/discs/disc%d", i++);
+ if (stat (discn, &st) < 0)
+ break;
+
+ if (realpath (discn, name))
+ {
+ strcat (name, "/disc");
+ if (hook (name, 0))
+ return;
+ }
+ }
+ return;
+ }
+#endif /* __linux__ */
+
+ /* IDE disks. */
+ for (i = 0; i < 20; i++)
+ {
+ char name[16];
+
+ get_ide_disk_name (name, i);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+
+#ifdef __linux__
+ /* Virtio disks. */
+ for (i = 0; i < 20; i++)
+ {
+ char name[16];
+
+ get_virtio_disk_name (name, i);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+
+ /* ATARAID disks. */
+ for (i = 0; i < 8; i++)
+ {
+ char name[20];
+
+ get_ataraid_disk_name (name, i);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+
+ /* Xen virtual block devices. */
+ for (i = 0; i < 16; i++)
+ {
+ char name[16];
+
+ get_xvd_disk_name (name, i);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+#endif /* __linux__ */
+
+ /* The rest is SCSI disks. */
+ for (i = 0; i < 16; i++)
+ {
+ char name[16];
+
+ get_scsi_disk_name (name, i);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+
+#ifdef __linux__
+ /* This is for DAC960 - we have
+ /dev/rd/c<controller>d<logical drive>p<partition>.
+
+ DAC960 driver currently supports up to 8 controllers, 32 logical
+ drives, and 7 partitions. */
+ {
+ int controller, drive;
+
+ for (controller = 0; controller < 8; controller++)
+ {
+ for (drive = 0; drive < 15; drive++)
+ {
+ char name[24];
+
+ get_dac960_disk_name (name, controller, drive);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+ }
+ }
+
+ /* This is for CCISS - we have
+ /dev/cciss/c<controller>d<logical drive>p<partition>. */
+ {
+ int controller, drive;
+
+ for (controller = 0; controller < 3; controller++)
+ {
+ for (drive = 0; drive < 10; drive++)
+ {
+ char name[24];
+
+ get_cciss_disk_name (name, controller, drive);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+ }
+ }
+
+ /* This is for Compaq Intelligent Drive Array - we have
+ /dev/ida/c<controller>d<logical drive>p<partition>. */
+ {
+ int controller, drive;
+
+ for (controller = 0; controller < 3; controller++)
+ {
+ for (drive = 0; drive < 10; drive++)
+ {
+ char name[24];
+
+ get_ida_disk_name (name, controller, drive);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+ }
+ }
+
+ /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
+ {
+ char unit;
+
+ for (unit = 'a'; unit < 'f'; unit++)
+ {
+ char name[24];
+
+ get_i2o_disk_name (name, unit);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+ }
+
+ /* MultiMediaCard (MMC). */
+ for (i = 0; i < 10; i++)
+ {
+ char name[16];
+
+ get_mmc_disk_name (name, i);
+ if (check_device (name))
+ {
+ if (hook (name, 0))
+ return;
+ }
+ }
+#endif /* __linux__ */
+}
+
--- /dev/null
+#include <stdio.h>
+
+#include <grub/util/deviceiter.h>
+
+void
+grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
+ int *num_fd, int *num_hd)
+{
+ if (is_floppy)
+ fprintf (fp, "(fd%d)\t%s\n", (*num_fd)++, name);
+ else
+ fprintf (fp, "(hd%d)\t%s\n", (*num_hd)++, name);
+}
#include <limits.h>
#include <grub/util/misc.h>
+#include <grub/util/deviceiter.h>
#define _GNU_SOURCE 1
#include <getopt.h>
-#ifdef __linux__
-# if !defined(__GLIBC__) || \
- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
-/* Maybe libc doesn't have large file support. */
-# include <linux/unistd.h> /* _llseek */
-# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
-# include <sys/ioctl.h> /* ioctl */
-# ifndef HDIO_GETGEO
-# define HDIO_GETGEO 0x0301 /* get device geometry */
-/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
- defined. */
-struct hd_geometry
-{
- unsigned char heads;
- unsigned char sectors;
- unsigned short cylinders;
- unsigned long start;
-};
-# endif /* ! HDIO_GETGEO */
-# ifndef FLOPPY_MAJOR
-# define FLOPPY_MAJOR 2 /* the major number for floppy */
-# endif /* ! FLOPPY_MAJOR */
-# ifndef MAJOR
-# define MAJOR(dev) \
- ({ \
- unsigned long long __dev = (dev); \
- (unsigned) ((__dev >> 8) & 0xfff) \
- | ((unsigned int) (__dev >> 32) & ~0xfff); \
- })
-# endif /* ! MAJOR */
-# ifndef CDROM_GET_CAPABILITY
-# define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
-# endif /* ! CDROM_GET_CAPABILITY */
-# ifndef BLKGETSIZE
-# define BLKGETSIZE _IO(0x12,96) /* return device size */
-# endif /* ! BLKGETSIZE */
-#endif /* __linux__ */
-
-/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
- kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
-#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
-# define __FreeBSD_kernel__
-#endif
-#ifdef __FreeBSD_kernel__
- /* Obtain version of kFreeBSD headers */
-# include <osreldate.h>
-# ifndef __FreeBSD_kernel_version
-# define __FreeBSD_kernel_version __FreeBSD_version
-# endif
-
- /* Runtime detection of kernel */
-# include <sys/utsname.h>
-int
-get_kfreebsd_version (void)
-{
- struct utsname uts;
- int major;
- int minor;
- int v[2];
-
- uname (&uts);
- sscanf (uts.release, "%d.%d", &major, &minor);
-
- if (major >= 9)
- major = 9;
- if (major >= 5)
- {
- v[0] = minor/10; v[1] = minor%10;
- }
- else
- {
- v[0] = minor%10; v[1] = minor/10;
- }
- return major*100000+v[0]*10000+v[1]*1000;
-}
-#endif /* __FreeBSD_kernel__ */
-
-#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
-# include <sys/ioctl.h> /* ioctl */
-# include <sys/disklabel.h>
-# include <sys/cdio.h> /* CDIOCCLRDEBUG */
-# if defined(__FreeBSD_kernel__)
-# include <sys/param.h>
-# if __FreeBSD_kernel_version >= 500040
-# include <sys/disk.h>
-# endif
-# endif /* __FreeBSD_kernel__ */
-#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
-
-#ifdef HAVE_OPENDISK
-# include <util.h>
-#endif /* HAVE_OPENDISK */
-
-#ifdef __linux__
-/* Check if we have devfs support. */
-static int
-have_devfs (void)
-{
- struct stat st;
- return stat ("/dev/.devfsd", &st) == 0;
-}
-#endif /* __linux__ */
-
-/* These three functions are quite different among OSes. */
static void
-get_floppy_disk_name (char *name, int unit)
-{
-#if defined(__linux__)
- /* GNU/Linux */
- if (have_devfs ())
- sprintf (name, "/dev/floppy/%d", unit);
- else
- sprintf (name, "/dev/fd%d", unit);
-#elif defined(__GNU__)
- /* GNU/Hurd */
- sprintf (name, "/dev/fd%d", unit);
-#elif defined(__FreeBSD_kernel__)
- /* kFreeBSD */
- if (get_kfreebsd_version () >= 400000)
- sprintf (name, "/dev/fd%d", unit);
- else
- sprintf (name, "/dev/rfd%d", unit);
-#elif defined(__NetBSD__)
- /* NetBSD */
- /* opendisk() doesn't work for floppies. */
- sprintf (name, "/dev/rfd%da", unit);
-#elif defined(__OpenBSD__)
- /* OpenBSD */
- sprintf (name, "/dev/rfd%dc", unit);
-#elif defined(__QNXNTO__)
- /* QNX RTP */
- sprintf (name, "/dev/fd%d", unit);
-#elif defined(__CYGWIN__)
- /* Cygwin */
- sprintf (name, "/dev/fd%d", unit);
-#elif defined(__MINGW32__)
- (void) unit;
- *name = 0;
-#else
-# warning "BIOS floppy drives cannot be guessed in your operating system."
- /* Set NAME to a bogus string. */
- *name = 0;
-#endif
-}
-
-static void
-get_ide_disk_name (char *name, int unit)
-{
-#if defined(__linux__)
- /* GNU/Linux */
- sprintf (name, "/dev/hd%c", unit + 'a');
-#elif defined(__GNU__)
- /* GNU/Hurd */
- sprintf (name, "/dev/hd%d", unit);
-#elif defined(__FreeBSD_kernel__)
- /* kFreeBSD */
- if (get_kfreebsd_version () >= 400000)
- sprintf (name, "/dev/ad%d", unit);
- else
- sprintf (name, "/dev/rwd%d", unit);
-#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
- /* NetBSD */
- char shortname[16];
- int fd;
-
- sprintf (shortname, "wd%d", unit);
- fd = opendisk (shortname, O_RDONLY, name,
- 16, /* length of NAME */
- 0 /* char device */
- );
- close (fd);
-#elif defined(__OpenBSD__)
- /* OpenBSD */
- sprintf (name, "/dev/rwd%dc", unit);
-#elif defined(__QNXNTO__)
- /* QNX RTP */
- /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
- contain SCSI disks. */
- sprintf (name, "/dev/hd%d", unit);
-#elif defined(__CYGWIN__)
- /* Cygwin emulates all disks as /dev/sdX. */
- (void) unit;
- *name = 0;
-#elif defined(__MINGW32__)
- sprintf (name, "//./PHYSICALDRIVE%d", unit);
-#else
-# warning "BIOS IDE drives cannot be guessed in your operating system."
- /* Set NAME to a bogus string. */
- *name = 0;
-#endif
-}
-
-static void
-get_scsi_disk_name (char *name, int unit)
-{
-#if defined(__linux__)
- /* GNU/Linux */
- sprintf (name, "/dev/sd%c", unit + 'a');
-#elif defined(__GNU__)
- /* GNU/Hurd */
- sprintf (name, "/dev/sd%d", unit);
-#elif defined(__FreeBSD_kernel__)
- /* kFreeBSD */
- if (get_kfreebsd_version () >= 400000)
- sprintf (name, "/dev/da%d", unit);
- else
- sprintf (name, "/dev/rda%d", unit);
-#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
- /* NetBSD */
- char shortname[16];
- int fd;
-
- sprintf (shortname, "sd%d", unit);
- fd = opendisk (shortname, O_RDONLY, name,
- 16, /* length of NAME */
- 0 /* char device */
- );
- close (fd);
-#elif defined(__OpenBSD__)
- /* OpenBSD */
- sprintf (name, "/dev/rsd%dc", unit);
-#elif defined(__QNXNTO__)
- /* QNX RTP */
- /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
- disable the detection of SCSI disks here. */
- *name = 0;
-#elif defined(__CYGWIN__)
- /* Cygwin emulates all disks as /dev/sdX. */
- sprintf (name, "/dev/sd%c", unit + 'a');
-#elif defined(__MINGW32__)
- (void) unit;
- *name = 0;
-#else
-# warning "BIOS SCSI drives cannot be guessed in your operating system."
- /* Set NAME to a bogus string. */
- *name = 0;
-#endif
-}
-
-#ifdef __linux__
-static void
-get_virtio_disk_name (char *name, int unit)
-{
- sprintf (name, "/dev/vd%c", unit + 'a');
-}
-
-static void
-get_dac960_disk_name (char *name, int controller, int drive)
-{
- sprintf (name, "/dev/rd/c%dd%d", controller, drive);
-}
-
-static void
-get_ataraid_disk_name (char *name, int unit)
-{
- sprintf (name, "/dev/ataraid/d%c", unit + '0');
-}
-
-static void
-get_i2o_disk_name (char *name, char unit)
-{
- sprintf (name, "/dev/i2o/hd%c", unit);
-}
-
-static void
-get_cciss_disk_name (char *name, int controller, int drive)
-{
- sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
-}
-
-static void
-get_ida_disk_name (char *name, int controller, int drive)
-{
- sprintf (name, "/dev/ida/c%dd%d", controller, drive);
-}
-
-static void
-get_mmc_disk_name (char *name, int unit)
-{
- sprintf (name, "/dev/mmcblk%d", unit);
-}
-
-static void
-get_xvd_disk_name (char *name, int unit)
-{
- sprintf (name, "/dev/xvd%c", unit + 'a');
-}
-#endif
-
-/* Check if DEVICE can be read. If an error occurs, return zero,
- otherwise return non-zero. */
-static int
-check_device (const char *device)
+make_device_map (const char *device_map, int floppy_disks)
{
- char buf[512];
+ int num_hd = 0;
+ int num_fd = 0;
FILE *fp;
- /* If DEVICE is empty, just return error. */
- if (*device == 0)
- return 0;
-
- fp = fopen (device, "r");
- if (! fp)
- {
- switch (errno)
- {
-#ifdef ENOMEDIUM
- case ENOMEDIUM:
-# if 0
- /* At the moment, this finds only CDROMs, which can't be
- read anyway, so leave it out. Code should be
- reactivated if `removable disks' and CDROMs are
- supported. */
- /* Accept it, it may be inserted. */
- return 1;
-# endif
- break;
-#endif /* ENOMEDIUM */
- default:
- /* Break case and leave. */
- break;
- }
- /* Error opening the device. */
- return 0;
- }
-
- /* Make sure CD-ROMs don't get assigned a BIOS disk number
- before SCSI disks! */
-#ifdef __linux__
-# ifdef CDROM_GET_CAPABILITY
- if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
- return 0;
-# else /* ! CDROM_GET_CAPABILITY */
- /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
- {
- struct hd_geometry hdg;
- struct stat st;
-
- if (fstat (fileno (fp), &st))
- return 0;
-
- /* If it is a block device and isn't a floppy, check if HDIO_GETGEO
- succeeds. */
- if (S_ISBLK (st.st_mode)
- && MAJOR (st.st_rdev) != FLOPPY_MAJOR
- && ioctl (fileno (fp), HDIO_GETGEO, &hdg))
- return 0;
- }
-# endif /* ! CDROM_GET_CAPABILITY */
-#endif /* __linux__ */
+ auto int process_device (const char *name, int is_floppy);
-#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
-# ifdef CDIOCCLRDEBUG
- if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
+ int process_device (const char *name, int is_floppy)
+ {
+ grub_util_emit_devicemap_entry (fp, (char *) name,
+ is_floppy, &num_fd, &num_hd);
return 0;
-# endif /* CDIOCCLRDEBUG */
-#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
-
- /* Attempt to read the first sector. */
- if (fread (buf, 1, 512, fp) != 512)
- {
- fclose (fp);
- return 0;
- }
-
- fclose (fp);
- return 1;
-}
-
-static void
-make_device_map (const char *device_map, int floppy_disks)
-{
- FILE *fp;
- int num_hd = 0;
- int i;
+ }
if (strcmp (device_map, "-") == 0)
fp = stdout;
if (! fp)
grub_util_error ("cannot open %s", device_map);
- /* Floppies. */
- for (i = 0; i < floppy_disks; i++)
- {
- char name[16];
- struct stat st;
-
- get_floppy_disk_name (name, i);
- if (stat (name, &st) < 0)
- break;
- /* In floppies, write the map, whether check_device succeeds
- or not, because the user just may not insert floppies. */
- if (fp)
- fprintf (fp, "(fd%d)\t%s\n", i, name);
- }
-
-#ifdef __linux__
- if (have_devfs ())
- {
- while (1)
- {
- char discn[32];
- char name[PATH_MAX];
- struct stat st;
-
- /* Linux creates symlinks "/dev/discs/discN" for convenience.
- The way to number disks is the same as GRUB's. */
- sprintf (discn, "/dev/discs/disc%d", num_hd);
- if (stat (discn, &st) < 0)
- break;
-
- if (realpath (discn, name))
- {
- strcat (name, "/disc");
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- }
-
- num_hd++;
- }
-
- goto finish;
- }
-#endif /* __linux__ */
-
- /* IDE disks. */
- for (i = 0; i < 20; i++)
- {
- char name[16];
-
- get_ide_disk_name (name, i);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
-
-#ifdef __linux__
- /* Virtio disks. */
- for (i = 0; i < 20; i++)
- {
- char name[16];
-
- get_virtio_disk_name (name, i);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
-
- /* ATARAID disks. */
- for (i = 0; i < 8; i++)
- {
- char name[20];
-
- get_ataraid_disk_name (name, i);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
-
- /* Xen virtual block devices. */
- for (i = 0; i < 16; i++)
- {
- char name[16];
-
- get_xvd_disk_name (name, i);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
-#endif /* __linux__ */
-
- /* The rest is SCSI disks. */
- for (i = 0; i < 16; i++)
- {
- char name[16];
-
- get_scsi_disk_name (name, i);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
-
-#ifdef __linux__
- /* This is for DAC960 - we have
- /dev/rd/c<controller>d<logical drive>p<partition>.
-
- DAC960 driver currently supports up to 8 controllers, 32 logical
- drives, and 7 partitions. */
- {
- int controller, drive;
-
- for (controller = 0; controller < 8; controller++)
- {
- for (drive = 0; drive < 15; drive++)
- {
- char name[24];
-
- get_dac960_disk_name (name, controller, drive);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
- }
- }
-
- /* This is for CCISS - we have
- /dev/cciss/c<controller>d<logical drive>p<partition>. */
- {
- int controller, drive;
-
- for (controller = 0; controller < 3; controller++)
- {
- for (drive = 0; drive < 10; drive++)
- {
- char name[24];
-
- get_cciss_disk_name (name, controller, drive);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
- }
- }
-
- /* This is for Compaq Intelligent Drive Array - we have
- /dev/ida/c<controller>d<logical drive>p<partition>. */
- {
- int controller, drive;
-
- for (controller = 0; controller < 3; controller++)
- {
- for (drive = 0; drive < 10; drive++)
- {
- char name[24];
-
- get_ida_disk_name (name, controller, drive);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
- }
- }
-
- /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
- {
- char unit;
-
- for (unit = 'a'; unit < 'f'; unit++)
- {
- char name[24];
-
- get_i2o_disk_name (name, unit);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
- }
-
- /* MultiMediaCard (MMC). */
- for (i = 0; i < 10; i++)
- {
- char name[16];
-
- get_mmc_disk_name (name, i);
- if (check_device (name))
- {
- fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
- num_hd++;
- }
- }
-
- finish:
-#endif /* __linux__ */
+ grub_util_iterate_devices (process_device, floppy_disks);
if (fp != stdout)
fclose (fp);
--- /dev/null
+#include <stdio.h>
+#include <grub/types.h>
+#include <grub/util/deviceiter.h>
+#include <grub/util/ofpath.h>
+
+void
+grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED,
+ int *num_fd UNUSED, int *num_hd UNUSED)
+{
+ const char *ofpath = grub_util_devname_to_ofpath (name);
+
+ fprintf(fp, "(%s)\t%s\n", ofpath, name);
+}
--- /dev/null
+/* ofpath.c - calculate OpenFirmware path names given an OS device */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#undef OFPATH_STANDALONE
+
+#ifndef OFPATH_STANDALONE
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/util/ofpath.h>
+#endif
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#ifdef OFPATH_STANDALONE
+#define UNUSED __attribute__((unused))
+#define xmalloc malloc
+void
+grub_util_error (const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf (stderr, "ofpath: error: ");
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+ fputc ('\n', stderr);
+ exit (1);
+}
+
+#endif
+
+static void
+kill_trailing_dir(char *path)
+{
+ char *end = path + strlen(path) - 1;
+
+ while (end >= path)
+ {
+ if (*end != '/')
+ {
+ end--;
+ continue;
+ }
+ *end = '\0';
+ break;
+ }
+}
+
+static void
+trim_newline (char *path)
+{
+ char *end = path + strlen(path) - 1;
+
+ while (*end == '\n')
+ *end-- = '\0';
+}
+
+#define OF_PATH_MAX 256
+
+static void
+find_obppath(char *of_path, const char *sysfs_path_orig)
+{
+ char *sysfs_path, *path;
+
+ sysfs_path = xmalloc (PATH_MAX);
+ path = xmalloc (PATH_MAX);
+
+ strcpy(sysfs_path, sysfs_path_orig);
+ while (1)
+ {
+ int fd;
+
+ snprintf(path, PATH_MAX, "%s/obppath", sysfs_path);
+#if 0
+ printf("Trying %s\n", path);
+#endif
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ {
+ kill_trailing_dir(sysfs_path);
+ if (!strcmp(sysfs_path, "/sys"))
+ grub_util_error("'obppath' not found in parent dirs of %s",
+ sysfs_path_orig);
+ continue;
+ }
+ memset(of_path, 0, OF_PATH_MAX);
+ read(fd, of_path, OF_PATH_MAX);
+ close(fd);
+
+ trim_newline(of_path);
+ break;
+ }
+
+ free (path);
+ free (sysfs_path);
+}
+
+static void
+block_device_get_sysfs_path_and_link(const char *devicenode,
+ char *sysfs_path, int sysfs_path_len)
+{
+ char *rpath = xmalloc (PATH_MAX);
+
+ snprintf(sysfs_path, sysfs_path_len, "/sys/block/%s", devicenode);
+
+ if (!realpath (sysfs_path, rpath))
+ grub_util_error ("Cannot get the real path of `%s'", sysfs_path);
+
+ strcat(rpath, "/device");
+
+ if (!realpath (rpath, sysfs_path))
+ grub_util_error ("Cannot get the real path of `%s'", rpath);
+
+ free (rpath);
+}
+
+static const char *
+trailing_digits (const char *p)
+{
+ const char *end;
+
+ end = p + strlen(p) - 1;
+ while (end >= p)
+ {
+ if (! isdigit(*end))
+ break;
+ end--;
+ }
+
+ return end + 1;
+}
+
+static void
+__of_path_common(char *of_path, char *sysfs_path,
+ const char *device, int devno)
+{
+ const char *digit_string;
+ char disk[64];
+
+ find_obppath(of_path, sysfs_path);
+
+ digit_string = trailing_digits (device);
+ if (*digit_string == '\0')
+ {
+ sprintf(disk, "/disk@%d", devno);
+ }
+ else
+ {
+ int part;
+
+ sscanf(digit_string, "%d", &part);
+ sprintf(disk, "/disk@%d:%c", devno, 'a' + (part - 1));
+ }
+ strcat(of_path, disk);
+}
+
+static char *
+get_basename(char *p)
+{
+ char *ret = p;
+
+ while (*p)
+ {
+ if (*p == '/')
+ ret = p + 1;
+ p++;
+ }
+
+ return ret;
+}
+
+static void
+of_path_of_vdisk(char *of_path,
+ const char *devname UNUSED, const char *device,
+ const char *devnode UNUSED, const char *devicenode)
+{
+ char *sysfs_path, *p;
+ int devno, junk;
+
+ sysfs_path = xmalloc (PATH_MAX);
+ block_device_get_sysfs_path_and_link(devicenode,
+ sysfs_path, PATH_MAX);
+ p = get_basename (sysfs_path);
+ sscanf(p, "vdc-port-%d-%d", &devno, &junk);
+ __of_path_common(of_path, sysfs_path, device, devno);
+
+ free (sysfs_path);
+}
+
+static void
+of_path_of_ide(char *of_path,
+ const char *devname UNUSED, const char *device,
+ const char *devnode UNUSED, const char *devicenode)
+{
+ char *sysfs_path, *p;
+ int chan, devno;
+
+ sysfs_path = xmalloc (PATH_MAX);
+ block_device_get_sysfs_path_and_link(devicenode,
+ sysfs_path, PATH_MAX);
+ p = get_basename (sysfs_path);
+ sscanf(p, "%d.%d", &chan, &devno);
+
+ __of_path_common(of_path, sysfs_path, device, devno);
+
+ free (sysfs_path);
+}
+
+static int
+vendor_is_ATA(const char *path)
+{
+ int fd, err;
+ char *buf;
+
+ buf = xmalloc (PATH_MAX);
+
+ snprintf(buf, PATH_MAX, "%s/vendor", path);
+ fd = open(buf, O_RDONLY);
+ if (fd < 0)
+ grub_util_error ("Cannot open 'vendor' node of `%s'", path);
+
+ memset(buf, 0, PATH_MAX);
+ err = read(fd, buf, PATH_MAX);
+ if (err < 0)
+ grub_util_error ("Cannot read 'vendor' node of `%s'", path);
+
+ close(fd);
+
+ free (buf);
+
+ if (!strncmp(buf, "ATA", 3))
+ return 1;
+ return 0;
+}
+
+static void
+check_sas (char *sysfs_path, int *tgt)
+{
+ char *ed = strstr (sysfs_path, "end_device");
+ char *p, *q, *path;
+ char phy[16];
+ int fd;
+
+ if (!ed)
+ return;
+
+ /* SAS devices are identified using disk@$PHY_ID */
+ p = strdup (sysfs_path);
+ ed = strstr(p, "end_device");
+
+ q = ed;
+ while (*q && *q != '/')
+ q++;
+ *q = '\0';
+
+ path = xmalloc (PATH_MAX);
+ sprintf (path, "%s/sas_device:%s/phy_identifier", p, ed);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ grub_util_error("Cannot open SAS PHY ID '%s'\n", path);
+
+ memset (phy, 0, sizeof (phy));
+ read (fd, phy, sizeof (phy));
+
+ sscanf (phy, "%d", tgt);
+
+ free (path);
+ free (p);
+}
+
+static void
+of_path_of_scsi(char *of_path,
+ const char *devname UNUSED, const char *device,
+ const char *devnode UNUSED, const char *devicenode)
+{
+ const char *p, *digit_string, *disk_name;
+ int host, bus, tgt, lun;
+ char *sysfs_path, disk[64];
+
+ sysfs_path = xmalloc (PATH_MAX);
+
+ block_device_get_sysfs_path_and_link(devicenode,
+ sysfs_path, PATH_MAX);
+ p = get_basename (sysfs_path);
+ sscanf(p, "%d:%d:%d:%d", &host, &bus, &tgt, &lun);
+ check_sas (sysfs_path, &tgt);
+
+ if (vendor_is_ATA(sysfs_path))
+ {
+ __of_path_common(of_path, sysfs_path, device, tgt);
+ free (sysfs_path);
+ return;
+ }
+
+ find_obppath(of_path, sysfs_path);
+ free (sysfs_path);
+
+ if (strstr (of_path, "qlc"))
+ strcat (of_path, "/fp@0,0");
+
+ if (strstr (of_path, "sbus"))
+ disk_name = "sd";
+ else
+ disk_name = "disk";
+
+ digit_string = trailing_digits (device);
+ if (*digit_string == '\0')
+ {
+ sprintf(disk, "/%s@%x,%d", disk_name, tgt, lun);
+ }
+ else
+ {
+ int part;
+
+ sscanf(digit_string, "%d", &part);
+ sprintf(disk, "/%s@%x,%d:%c", disk_name, tgt, lun, 'a' + (part - 1));
+ }
+ strcat(of_path, disk);
+}
+
+static char *
+strip_trailing_digits (const char *p)
+{
+ char *new, *end;
+
+ new = strdup (p);
+ end = new + strlen(new) - 1;
+ while (end >= new)
+ {
+ if (! isdigit(*end))
+ break;
+ *end-- = '\0';
+ }
+
+ return new;
+}
+
+char *
+grub_util_devname_to_ofpath (char *devname)
+{
+ char *name_buf, *device, *devnode, *devicenode, *ofpath;
+
+ name_buf = xmalloc (PATH_MAX);
+ name_buf = realpath (devname, name_buf);
+ if (! name_buf)
+ grub_util_error ("Cannot get the real path of `%s'", devname);
+
+ device = get_basename (devname);
+ devnode = strip_trailing_digits (devname);
+ devicenode = strip_trailing_digits (device);
+
+ ofpath = xmalloc (OF_PATH_MAX);
+
+ if (device[0] == 'h' && device[1] == 'd')
+ of_path_of_ide(ofpath, name_buf, device, devnode, devicenode);
+ else if (device[0] == 's'
+ && (device[1] == 'd' || device[1] == 'r'))
+ of_path_of_scsi(ofpath, name_buf, device, devnode, devicenode);
+ else if (device[0] == 'v' && device[1] == 'd' && device[2] == 'i'
+ && device[3] == 's' && device[4] == 'k')
+ of_path_of_vdisk(ofpath, name_buf, device, devnode, devicenode);
+
+ free (devnode);
+ free (devicenode);
+ free (name_buf);
+
+ return ofpath;
+}
+
+#ifdef OFPATH_STANDALONE
+int main(int argc, char **argv)
+{
+ char *of_path;
+
+ if (argc != 2)
+ {
+ printf("Usage: grub-ofpathname DEVICE\n");
+ return 1;
+ }
+
+ of_path = grub_util_devname_to_ofpath (argv[1]);
+ printf("%s\n", of_path);
+
+ return 0;
+}
+#endif
--- /dev/null
+#! /bin/sh
+
+# Install GRUB on your drive.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
+grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
+grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+rootdir=
+grub_prefix=`echo /boot/grub | sed ${transform}`
+modules=
+
+install_device=
+no_floppy=
+force_lba=
+recheck=no
+debug=no
+
+# Usage: usage
+# Print the usage.
+usage () {
+ cat <<EOF
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+ -h, --help print this message and exit
+ -v, --version print the version information and exit
+ --modules=MODULES pre-load specified modules MODULES
+ --root-directory=DIR install GRUB images under the directory DIR
+ instead of the root directory
+ --grub-setup=FILE use FILE as grub-setup
+ --grub-mkimage=FILE use FILE as grub-mkimage
+ --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+ --grub-probe=FILE use FILE as grub-probe
+ --no-floppy do not probe any floppy drive
+ --recheck probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specified by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+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 ;;
+ --modules=*)
+ modules=`echo "$option" | sed 's/--modules=//'` ;;
+ --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_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+ --grub-probe=*)
+ grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
+ --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
+
+# for make_system_path_relative_to_its_root()
+. ${libdir}/grub/grub-mkconfig_lib
+
+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.
+setup_verbose=
+if test $debug = yes; then
+ set -x
+ setup_verbose="--verbose"
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+bootdir=${rootdir}/boot
+grubdir=${bootdir}/`echo grub | sed ${transform}`
+device_map=${grubdir}/device.map
+
+grub_probe="${grub_probe} --device-map=${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 && [ "`basename $file`" != menu.lst ]; then
+ rm -f $file || exit 1
+ fi
+done
+for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+ cp -f $file ${grubdir} || exit 1
+done
+
+for file in ${pkglibdir}/*.img; do
+ cp -f $file ${grubdir} || exit 1
+done
+
+# Write device to a variable so we don't have to traverse /dev every time.
+grub_device=`$grub_probe --target=device ${grubdir}`
+
+# Create the core image. First, auto-detect the filesystem module.
+fs_module=`$grub_probe --target=fs --device ${grub_device}`
+if test "x$fs_module" = x -a "x$modules" = x; then
+ echo "Auto-detection of a filesystem module failed." 1>&2
+ echo "Please specify the module with the option \`--modules' explicitly." 1>&2
+ exit 1
+fi
+
+# Then the partition map module. In order to support partition-less media,
+# this command is allowed to fail (--target=fs already grants us that the
+# filesystem will be accessible).
+partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`
+
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}`
+
+modules="$modules $fs_module $partmap_module $devabstraction_module"
+
+prefix_drive=
+if [ "x${devabstraction_module}" = "x" ] ; then
+ if echo "${install_device}" | grep -qx "(.*)" ; then
+ install_drive="${install_device}"
+ else
+ install_drive="`$grub_probe --target=drive --device ${install_device}`"
+ fi
+ grub_drive="`$grub_probe --target=drive --device ${grub_device}`"
+
+ # Strip partition number
+ install_drive="`echo ${install_drive} | sed -e s/,[0-9]*//g`"
+ grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*//g`"
+ if [ "x${grub_drive}" != "x${install_drive}" ] ; then
+ uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`"
+ if [ "x${uuid}" = "x" ] ; then
+ echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+ exit 1
+ fi
+ prefix_drive="(UUID=${uuid})"
+ modules="$modules fs_uuid"
+ fi
+else
+ prefix_drive=`$grub_probe --target=drive --device ${grub_device}`
+fi
+
+relative_grubdir=`make_system_path_relative_to_its_root ${grubdir}` || exit 1
+if [ "x${relative_grubdir}" = "x" ] ; then
+ relative_grubdir=/
+fi
+
+$grub_mkimage --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
+
+# Now perform the installation.
+$grub_setup ${setup_verbose} --directory=${grubdir} --device-map=${device_map} \
+ ${install_device} || 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
--- /dev/null
+/* grub-mkimage.c - make a bootable image */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <config.h>
+#include <grub/types.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <grub/kernel.h>
+#include <grub/disk.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/misc.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define _GNU_SOURCE 1
+#include <getopt.h>
+
+static void
+compress_kernel (char *kernel_img, size_t kernel_size,
+ char **core_img, size_t *core_size)
+{
+ /* No compression support yet. */
+ grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
+ *core_img = xmalloc (kernel_size);
+ memcpy (*core_img, kernel_img, kernel_size);
+ *core_size = kernel_size;
+}
+
+static void
+generate_image (const char *dir, const char *prefix, FILE *out, char *mods[], char *memdisk_path)
+{
+ size_t kernel_size, total_module_size, memdisk_size, core_size, boot_size, offset;
+ char *kernel_path, *kernel_img, *core_img, *boot_path, *boot_img;
+ struct grub_util_path_list *path_list, *p;
+ struct grub_module_info *modinfo;
+ grub_addr_t module_addr;
+ unsigned int num;
+
+ path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
+
+ kernel_path = grub_util_get_path (dir, "kernel.img");
+ kernel_size = grub_util_get_image_size (kernel_path);
+
+ total_module_size = sizeof (struct grub_module_info);
+ for (p = path_list; p; p = p->next)
+ total_module_size += (grub_util_get_image_size (p->name)
+ + sizeof (struct grub_module_header));
+
+ memdisk_size = 0;
+ if (memdisk_path)
+ {
+ memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
+ grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
+ total_module_size += memdisk_size + sizeof (struct grub_module_header);
+ }
+
+ grub_util_info ("the total module size is 0x%x", total_module_size);
+
+ kernel_img = xmalloc (kernel_size + total_module_size);
+ grub_util_load_image (kernel_path, kernel_img);
+
+ if ((GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1)
+ > GRUB_KERNEL_MACHINE_DATA_END)
+ grub_util_error ("prefix too long");
+ strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix);
+
+ /* Fill in the grub_module_info structure. */
+ modinfo = (struct grub_module_info *) (kernel_img + kernel_size);
+ modinfo->magic = GRUB_MODULE_MAGIC;
+ modinfo->offset = sizeof (struct grub_module_info);
+ modinfo->size = total_module_size;
+
+ offset = kernel_size + sizeof (struct grub_module_info);
+ for (p = path_list; p; p = p->next)
+ {
+ struct grub_module_header *header;
+ size_t mod_size;
+
+ mod_size = grub_util_get_image_size (p->name);
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_cpu_to_be32 (OBJ_TYPE_ELF);
+ header->size = grub_cpu_to_be32 (mod_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (p->name, kernel_img + offset);
+ offset += mod_size;
+ }
+
+ if (memdisk_path)
+ {
+ struct grub_module_header *header;
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_cpu_to_be32 (OBJ_TYPE_MEMDISK);
+ header->size = grub_cpu_to_be32 (memdisk_size + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (memdisk_path, kernel_img + offset);
+ offset += memdisk_size;
+ }
+
+ compress_kernel (kernel_img, kernel_size + total_module_size,
+ &core_img, &core_size);
+
+ grub_util_info ("the core size is 0x%x", core_size);
+
+ num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
+ num <<= GRUB_DISK_SECTOR_BITS;
+
+ boot_path = grub_util_get_path (dir, "diskboot.img");
+ boot_size = grub_util_get_image_size (boot_path);
+ if (boot_size != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("diskboot.img is not one sector size");
+
+ boot_img = grub_util_read_image (boot_path);
+
+ /* sparc is a big endian architecture. */
+ *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
+ - GRUB_BOOT_MACHINE_LIST_SIZE + 8))
+ = grub_cpu_to_be32 (num);
+
+ grub_util_write_image (boot_img, boot_size, out);
+ free (boot_img);
+ free (boot_path);
+
+ module_addr = (path_list
+ ? (GRUB_BOOT_MACHINE_IMAGE_ADDRESS + kernel_size)
+ : 0);
+
+ grub_util_info ("the first module address is 0x%x", module_addr);
+
+ *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
+ = grub_cpu_to_be32 (total_module_size);
+ *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
+ = grub_cpu_to_be32 (kernel_size);
+
+ /* No compression support yet. */
+ *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
+ = grub_cpu_to_be32 (0);
+
+ grub_util_write_image (core_img, core_size, out);
+ free (kernel_img);
+ free (core_img);
+ free (kernel_path);
+
+ while (path_list)
+ {
+ struct grub_util_path_list *next = path_list->next;
+ free ((void *) path_list->name);
+ free (path_list);
+ path_list = next;
+ }
+}
+
+static struct option options[] =
+ {
+ {"directory", required_argument, 0, 'd'},
+ {"prefix", required_argument, 0, 'p'},
+ {"memdisk", required_argument, 0, 'm'},
+ {"output", required_argument, 0, 'o'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {"verbose", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+
+static void
+usage (int status)
+{
+ if (status)
+ fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n");
+ else
+ printf ("\
+Usage: grub-mkimage [OPTION]... [MODULES]\n\
+\n\
+Make a bootable image of GRUB.\n\
+\n\
+ -d, --directory=DIR use images and modules under DIR [default=%s]\n\
+ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\
+ -m, --memdisk=FILE embed FILE as a memdisk image\n\
+ -o, --output=FILE output a generated image to FILE [default=stdout]\n\
+ -h, --help display this message and exit\n\
+ -V, --version print version information and exit\n\
+ -v, --verbose print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+
+ exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *output = NULL;
+ char *dir = NULL;
+ char *prefix = NULL;
+ char *memdisk = NULL;
+ FILE *fp = stdout;
+
+ progname = "grub-mkimage";
+ while (1)
+ {
+ int c = getopt_long (argc, argv, "d:p:m:o:hVv", options, 0);
+
+ if (c == -1)
+ break;
+ else
+ switch (c)
+ {
+ case 'o':
+ if (output)
+ free (output);
+ output = xstrdup (optarg);
+ break;
+
+ case 'd':
+ if (dir)
+ free (dir);
+ dir = xstrdup (optarg);
+ break;
+
+ case 'm':
+ if (memdisk)
+ free (memdisk);
+ memdisk = xstrdup (optarg);
+
+ if (prefix)
+ free (prefix);
+ prefix = xstrdup ("(memdisk)/boot/grub");
+ break;
+
+ case 'h':
+ usage (0);
+ break;
+
+ case 'p':
+ if (prefix)
+ free (prefix);
+ prefix = xstrdup (optarg);
+ break;
+
+ case 'V':
+ printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+ return 0;
+
+ case 'v':
+ verbosity++;
+ break;
+
+ default:
+ usage (1);
+ break;
+ }
+ }
+
+ if (output)
+ {
+ fp = fopen (output, "wb");
+ if (! fp)
+ grub_util_error ("cannot open %s", output);
+ }
+
+ generate_image (dir ? : GRUB_LIBDIR,
+ prefix ? : DEFAULT_DIRECTORY, fp,
+ argv + optind, memdisk);
+
+ fclose (fp);
+
+ if (dir)
+ free (dir);
+
+ return 0;
+}
--- /dev/null
+/* grub-ofpathname.c - Find OpenBOOT path for a given device */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/misc.h>
+#include <grub/util/ofpath.h>
+
+int main(int argc, char **argv)
+{
+ char *of_path;
+
+ if (argc != 2)
+ {
+ printf("Usage: grub-ofpathname DEVICE\n");
+ return 1;
+ }
+
+ of_path = grub_util_devname_to_ofpath (argv[1]);
+ printf("%s\n", of_path);
+
+ free (of_path);
+
+ return 0;
+}
--- /dev/null
+/* grub-setup.c - make GRUB usable */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/partition.h>
+#include <grub/pc_partition.h>
+#include <grub/gpt_partition.h>
+#include <grub/env.h>
+#include <grub/util/hostdisk.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <grub/term.h>
+#include <grub/util/raid.h>
+#include <grub/util/lvm.h>
+
+#include <grub_setup_init.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <grub/util/getroot.h>
+
+#define _GNU_SOURCE 1
+#include <getopt.h>
+
+/* This program fills in various fields inside of the 'boot' and 'core'
+ * image files.
+ *
+ * The 'boot' image needs to know the OBP path name of the root
+ * device. It also needs to know the initial block number of
+ * 'core' (which is 'diskboot' concatenated with 'kernel' and
+ * all the modules, this is created by grub-mkimage). This resulting
+ * 'boot' image is 512 bytes in size and is placed in the first block
+ * of a partition.
+ *
+ * The initial 'diskboot' block acts as a loader for the actual GRUB
+ * kernel. It contains the loading code and then a block list.
+ *
+ * The block list of 'core' starts at the end of the 'diskboot' image
+ * and works it's way backwards towards the end of the code of 'diskboot'.
+ *
+ * We patch up the images with the necessary values and write out the
+ * result.
+ */
+
+#define DEFAULT_BOOT_FILE "boot.img"
+#define DEFAULT_CORE_FILE "core.img"
+
+/* This is the blocklist used in the diskboot image. */
+struct boot_blocklist
+{
+ grub_uint64_t start;
+ grub_uint32_t len;
+} __attribute__ ((packed));
+
+void
+grub_putchar (int c)
+{
+ putchar (c);
+}
+
+int
+grub_getkey (void)
+{
+ return -1;
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
+void
+grub_refresh (void)
+{
+ fflush (stdout);
+}
+
+static void
+setup (const char *prefix, const char *dir,
+ const char *boot_file, const char *core_file,
+ const char *root, const char *dest)
+{
+ char *boot_path, *core_path;
+ char *boot_img, *core_img;
+ size_t boot_size, core_size;
+ grub_uint16_t core_sectors;
+ grub_device_t root_dev, dest_dev;
+ char *boot_devpath;
+ grub_disk_addr_t *kernel_sector;
+ struct boot_blocklist *first_block, *block;
+ char *tmp_img;
+ int i;
+ grub_disk_addr_t first_sector;
+ grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE;
+ grub_file_t file;
+ FILE *fp;
+ struct { grub_uint64_t start; grub_uint64_t end; } embed_region;
+ embed_region.start = embed_region.end = ~0UL;
+
+ auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector,
+ unsigned int offset,
+ unsigned int length);
+ auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector,
+ unsigned int offset,
+ unsigned int length);
+
+ void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector,
+ unsigned int offset,
+ unsigned int length)
+ {
+ grub_util_info ("first sector is <%llu,%u,%u>", sector, offset, length);
+
+ if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("The first sector of the core file "
+ "is not sector-aligned");
+
+ first_sector = sector;
+ }
+
+ void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector,
+ unsigned int offset,
+ unsigned int length)
+ {
+ struct boot_blocklist *prev = block + 1;
+
+ grub_util_info ("saving <%llu,%u,%u>", sector, offset, length);
+
+ if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("Non-sector-aligned data is found in the core file");
+
+ if (block != first_block
+ && (grub_be_to_cpu64 (prev->start)
+ + grub_be_to_cpu16 (prev->len)) == sector)
+ prev->len = grub_cpu_to_be16 (grub_be_to_cpu16 (prev->len) + 1);
+ else
+ {
+ block->start = grub_cpu_to_be64 (sector);
+ block->len = grub_cpu_to_be16 (1);
+
+ block--;
+ if (block->len)
+ grub_util_error ("The sectors of the core file are too fragmented");
+ }
+
+ last_length = length;
+ }
+
+ /* Read the boot image by the OS service. */
+ boot_path = grub_util_get_path (dir, boot_file);
+ boot_size = grub_util_get_image_size (boot_path);
+ if (boot_size != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("The size of `%s' is not %d",
+ boot_path, GRUB_DISK_SECTOR_SIZE);
+ boot_img = grub_util_read_image (boot_path);
+ free (boot_path);
+
+ /* Set the addresses of variables in the boot image. */
+ boot_devpath = (char *) (boot_img
+ + GRUB_BOOT_AOUT_HEADER_SIZE
+ + GRUB_BOOT_MACHINE_BOOT_DEVPATH);
+ kernel_sector = (grub_disk_addr_t *) (boot_img
+ + GRUB_BOOT_AOUT_HEADER_SIZE
+ + GRUB_BOOT_MACHINE_KERNEL_SECTOR);
+
+ core_path = grub_util_get_path (dir, core_file);
+ core_size = grub_util_get_image_size (core_path);
+ core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1)
+ >> GRUB_DISK_SECTOR_BITS);
+ if (core_size < GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("The size of `%s' is too small", core_path);
+
+ core_img = grub_util_read_image (core_path);
+ free (core_path);
+
+ /* Have FIRST_BLOCK to point to the first blocklist. */
+ first_block = (struct boot_blocklist *) (core_img
+ + GRUB_DISK_SECTOR_SIZE
+ - sizeof (*block));
+
+ grub_util_info ("root is '%s' and dest is '%s'", root, dest);
+
+ /* Open the root device and the destination device. */
+ grub_util_info ("Opening root");
+ root_dev = grub_device_open (root);
+ if (! root_dev)
+ grub_util_error ("%s", grub_errmsg);
+
+ grub_util_info ("Opening dest");
+ dest_dev = grub_device_open (dest);
+ if (! dest_dev)
+ grub_util_error ("%s", grub_errmsg);
+
+ grub_util_info ("setting the root device to `%s'", root);
+ if (grub_env_set ("root", root) != GRUB_ERR_NONE)
+ grub_util_error ("%s", grub_errmsg);
+
+ /* The core image must be put on a filesystem unfortunately. */
+ grub_util_info ("will leave the core image on the filesystem");
+
+ /* Make sure that GRUB reads the identical image as the OS. */
+ tmp_img = xmalloc (core_size);
+ core_path = grub_util_get_path (prefix, core_file);
+
+ /* It is a Good Thing to sync two times. */
+ sync ();
+ sync ();
+
+#define MAX_TRIES 5
+
+ for (i = 0; i < MAX_TRIES; i++)
+ {
+ grub_util_info ("attempting to read the core image `%s' from GRUB%s",
+ core_path, (i == 0) ? "" : " again");
+
+ grub_disk_cache_invalidate_all ();
+
+ file = grub_file_open (core_path);
+ if (file)
+ {
+ if (grub_file_size (file) != core_size)
+ grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
+ (int) grub_file_size (file), (int) core_size);
+ else if (grub_file_read (file, tmp_img, core_size)
+ != (grub_ssize_t) core_size)
+ grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
+ (int) core_size);
+ else if (memcmp (core_img, tmp_img, core_size) != 0)
+ {
+#if 0
+ FILE *dump;
+ FILE *dump2;
+
+ dump = fopen ("dump.img", "wb");
+ if (dump)
+ {
+ fwrite (tmp_img, 1, core_size, dump);
+ fclose (dump);
+ }
+
+ dump2 = fopen ("dump2.img", "wb");
+ if (dump2)
+ {
+ fwrite (core_img, 1, core_size, dump2);
+ fclose (dump2);
+ }
+
+#endif
+ grub_util_info ("succeeded in opening the core image but the data is different");
+ }
+ else
+ {
+ grub_file_close (file);
+ break;
+ }
+
+ grub_file_close (file);
+ }
+ else
+ grub_util_info ("couldn't open the core image");
+
+ if (grub_errno)
+ grub_util_info ("error message = %s", grub_errmsg);
+
+ grub_errno = GRUB_ERR_NONE;
+ sync ();
+ sleep (1);
+ }
+
+ if (i == MAX_TRIES)
+ grub_util_error ("Cannot read `%s' correctly", core_path);
+
+ /* Clean out the blocklists. */
+ block = first_block;
+ while (block->len)
+ {
+ block->start = 0;
+ block->len = 0;
+
+ block--;
+
+ if ((char *) block <= core_img)
+ grub_util_error ("No terminator in the core image");
+ }
+
+ /* Now read the core image to determine where the sectors are. */
+ file = grub_file_open (core_path);
+ if (! file)
+ grub_util_error ("%s", grub_errmsg);
+
+ file->read_hook = save_first_sector;
+ if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
+ != GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("Failed to read the first sector of the core image");
+
+ block = first_block;
+ file->read_hook = save_blocklists;
+ if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE)
+ != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
+ grub_util_error ("Failed to read the rest sectors of the core image");
+
+ grub_file_close (file);
+
+ free (core_path);
+ free (tmp_img);
+
+ *kernel_sector = grub_cpu_to_be64 (first_sector);
+
+ strcpy(boot_devpath, dest);
+
+ grub_util_info ("boot device path %s, prefix is %s, dest is %s",
+ boot_devpath, prefix, dest);
+
+ /* Write the first two sectors of the core image onto the disk. */
+ core_path = grub_util_get_path (dir, core_file);
+ grub_util_info ("opening the core image `%s'", core_path);
+ fp = fopen (core_path, "r+b");
+ if (! fp)
+ grub_util_error ("Cannot open `%s'", core_path);
+
+ grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE, fp);
+ fclose (fp);
+ free (core_path);
+
+ /* Write the boot image onto the disk. */
+ if (grub_disk_write (dest_dev->disk, 1, 0, GRUB_DISK_SECTOR_SIZE, boot_img))
+ grub_util_error ("%s", grub_errmsg);
+
+ /* Sync is a Good Thing. */
+ sync ();
+
+ free (core_img);
+ free (boot_img);
+ grub_device_close (dest_dev);
+ grub_device_close (root_dev);
+}
+
+static struct option options[] =
+ {
+ {"boot-image", required_argument, 0, 'b'},
+ {"core-image", required_argument, 0, 'c'},
+ {"directory", required_argument, 0, 'd'},
+ {"device-map", required_argument, 0, 'm'},
+ {"root-device", required_argument, 0, 'r'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {"verbose", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+
+static void
+usage (int status)
+{
+ if (status)
+ fprintf (stderr, "Try ``grub-setup --help'' for more information.\n");
+ else
+ printf ("\
+Usage: grub-setup [OPTION]... DEVICE\n\
+\n\
+Set up images to boot from DEVICE.\n\
+DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\
+\n\
+ -b, --boot-image=FILE use FILE as the boot image [default=%s]\n\
+ -c, --core-image=FILE use FILE as the core image [default=%s]\n\
+ -d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n\
+ -m, --device-map=FILE use FILE as the device map [default=%s]\n\
+ -r, --root-device=DEV use DEV as the root device [default=guessed]\n\
+ -h, --help display this message and exit\n\
+ -V, --version print version information and exit\n\
+ -v, --verbose print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+",
+ DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY,
+ DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+
+ exit (status);
+}
+
+struct grub_setup_info
+{
+ char *boot_file;
+ char *core_file;
+ char *dir;
+ char *dev_map;
+ char *root_dev;
+ char *prefix;
+ char *dest_dev;
+};
+
+static void
+init_info (struct grub_setup_info *gp)
+{
+ gp->boot_file = NULL;
+ gp->core_file = NULL;
+ gp->dir = NULL;
+ gp->dev_map = NULL;
+ gp->root_dev = NULL;
+ gp->prefix = NULL;
+ gp->dest_dev = NULL;
+}
+
+static int
+parse_options (struct grub_setup_info *gp, int argc, char *argv[])
+{
+ while (1)
+ {
+ int c = getopt_long (argc, argv, "b:c:d:m:r:hVv", options, 0);
+
+ if (c == -1)
+ break;
+ else
+ switch (c)
+ {
+ case 'b':
+ if (gp->boot_file)
+ free (gp->boot_file);
+
+ gp->boot_file = xstrdup (optarg);
+ break;
+
+ case 'c':
+ if (gp->core_file)
+ free (gp->core_file);
+
+ gp->core_file = xstrdup (optarg);
+ break;
+
+ case 'd':
+ if (gp->dir)
+ free (gp->dir);
+
+ gp->dir = xstrdup (optarg);
+ break;
+
+ case 'm':
+ if (gp->dev_map)
+ free (gp->dev_map);
+
+ gp->dev_map = xstrdup (optarg);
+ break;
+
+ case 'r':
+ if (gp->root_dev)
+ free (gp->root_dev);
+
+ gp->root_dev = xstrdup (optarg);
+ break;
+
+ case 'h':
+ usage (0);
+ break;
+
+ case 'V':
+ printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+ return 0;
+
+ case 'v':
+ verbosity++;
+ break;
+
+ default:
+ usage (1);
+ break;
+ }
+ }
+
+ if (verbosity > 1)
+ grub_env_set ("debug", "all");
+
+ if (optind >= argc)
+ {
+ fprintf (stderr, "No device is specified.\n");
+ usage (1);
+ }
+
+ if (optind + 1 != argc)
+ {
+ fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]);
+ usage (1);
+ }
+ return 1;
+}
+
+static char *
+get_device_name (char *dev)
+{
+ size_t len = strlen (dev);
+
+ if (dev[0] != '(' || dev[len - 1] != ')')
+ return 0;
+
+ dev[len - 1] = '\0';
+ return dev + 1;
+}
+
+static void
+find_dest_dev (struct grub_setup_info *gp, char *argv[])
+{
+ gp->dest_dev = get_device_name (argv[optind]);
+ if (! gp->dest_dev)
+ {
+ /* Possibly, the user specified an OS device file. */
+ gp->dest_dev = grub_util_get_grub_dev (argv[optind]);
+ if (! gp->dest_dev)
+ {
+ fprintf (stderr, "Invalid device `%s'.\n", argv[optind]);
+ usage (1);
+ }
+ grub_util_info ("transformed OS device '%s' into GRUB device '%s'",
+ argv[optind], gp->dest_dev);
+ }
+ else
+ {
+ /* For simplicity. */
+ gp->dest_dev = xstrdup (gp->dest_dev);
+ grub_util_info ("Using '%s' as GRUB device", gp->dest_dev);
+ }
+}
+
+static void
+check_root_dev (struct grub_setup_info *gp)
+{
+ if (gp->root_dev)
+ {
+ char *tmp = get_device_name (gp->root_dev);
+
+ if (! tmp)
+ grub_util_error ("Invalid root device `%s'", gp->root_dev);
+
+ tmp = xstrdup (tmp);
+ free (gp->root_dev);
+ gp->root_dev = tmp;
+ }
+ else
+ {
+ char *dir = gp->dir ? gp->dir : DEFAULT_DIRECTORY;
+ char *root_device = grub_guess_root_device (dir);
+
+ gp->root_dev = grub_util_get_grub_dev (root_device);
+ if (! gp->root_dev)
+ {
+ grub_util_info ("guessing the root device failed, because of `%s'",
+ grub_errmsg);
+ grub_util_error ("Cannot guess the root device. "
+ "Specify the option ``--root-device''.");
+ }
+ grub_util_info ("Guessed root device '%s' and root_dev '%s' from "
+ "dir '%s'", root_device, gp->root_dev, dir);
+ }
+}
+
+static void
+free_memory (struct grub_setup_info *gp)
+{
+ free (gp->boot_file);
+ free (gp->core_file);
+ free (gp->dir);
+ free (gp->dev_map);
+ free (gp->root_dev);
+ free (gp->prefix);
+ free (gp->dest_dev);
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct grub_setup_info ginfo;
+
+ progname = "grub-setup";
+
+ init_info (&ginfo);
+ if (!parse_options (&ginfo, argc, argv))
+ return 0;
+
+ /* Initialize the emulated biosdisk driver. */
+ grub_util_biosdisk_init (ginfo.dev_map ? ginfo.dev_map : DEFAULT_DEVICE_MAP);
+
+ /* Initialize all modules. */
+ grub_init_all ();
+
+ find_dest_dev (&ginfo, argv);
+
+ ginfo.prefix = grub_get_prefix (ginfo.dir ? : DEFAULT_DIRECTORY);
+
+ check_root_dev (&ginfo);
+
+ /* Do the real work. */
+ setup (ginfo.prefix,
+ ginfo.dir ? ginfo.dir : DEFAULT_DIRECTORY,
+ ginfo.boot_file ? ginfo.boot_file : DEFAULT_BOOT_FILE,
+ ginfo.core_file ? ginfo.core_file : DEFAULT_CORE_FILE,
+ ginfo.root_dev, ginfo.dest_dev);
+
+ /* Free resources. */
+ grub_fini_all ();
+
+ free_memory (&ginfo);
+
+ return 0;
+}
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <setjmp.h>
+
+#include <grub/util/misc.h>
+
+void
+grub_reboot (void)
+{
+ longjmp (main_env, 1);
+}
+
+void
+grub_halt (void)
+{
+ grub_reboot ();
+}