diff --git a/ChangeLog b/ChangeLog index 0dcc3c275..0d4097c4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,31 @@ (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 Correct GPT definition diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index f7cb58dd8..1284fe4ca 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -51,7 +51,8 @@ sbin_UTILITIES += grub-emu 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 diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index fdb83b825..717683b3a 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -28,7 +28,8 @@ util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile # 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 diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index cb41cce37..cb32c73c5 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -50,7 +50,8 @@ sbin_UTILITIES += grub-emu 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 diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 265b250d8..d74a5fabf 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -114,7 +114,8 @@ grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ 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 diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d8d35d5d9..84f91d897 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -35,7 +35,8 @@ sbin_UTILITIES += grub-emu 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 diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 029bca2c6..e1929d1e3 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -1,162 +1,156 @@ # -*- 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 +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_elf_HEADERS)) config.h gensymlist.sh +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 +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/sparc64/ieee1275/grub-install.in # 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 +pkglib_MODULES = halt.mod \ + linux.mod \ + normal.mod \ + reboot.mod \ + memdisk.mod \ + lsmmap.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) - -# For affs.mod. -affs_mod_SOURCES = fs/affs.c -affs_mod_CFLAGS = $(COMMON_CFLAGS) -affs_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For sfs.mod. -sfs_mod_SOURCES = fs/sfs.c -sfs_mod_CFLAGS = $(COMMON_CFLAGS) -sfs_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# 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 @@ -166,7 +160,7 @@ sfs_mod_LDFLAGS = $(COMMON_LDFLAGS) # 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 \ @@ -179,116 +173,24 @@ normal_mod_CFLAGS = $(COMMON_CFLAGS) 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 memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For default.mod -default_mod_SOURCES = commands/default.c -default_mod_CFLAGS = $(COMMON_CFLAGS) -default_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_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 gzio.mod. -gzio_mod_SOURCES = io/gzio.c -gzio_mod_CFLAGS = $(COMMON_CFLAGS) -gzio_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 diff --git a/include/grub/util/deviceiter.h b/include/grub/util/deviceiter.h new file mode 100644 index 000000000..a8af03cfe --- /dev/null +++ b/include/grub/util/deviceiter.h @@ -0,0 +1,11 @@ +#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER +#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER 1 + +#include + +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 */ diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h new file mode 100644 index 000000000..78f24d784 --- /dev/null +++ b/include/grub/util/ofpath.h @@ -0,0 +1,6 @@ +#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 */ diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c new file mode 100644 index 000000000..5114f7694 --- /dev/null +++ b/kern/sparc64/ieee1275/init.c @@ -0,0 +1,161 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 (); +} diff --git a/util/deviceiter.c b/util/deviceiter.c new file mode 100644 index 000000000..a36ad3122 --- /dev/null +++ b/util/deviceiter.c @@ -0,0 +1,621 @@ +/* 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 . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef __linux__ +# if !defined(__GLIBC__) || \ + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) +/* Maybe libc doesn't have large file support. */ +# include /* _llseek */ +# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ +# include /* 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 +# ifndef __FreeBSD_kernel_version +# define __FreeBSD_kernel_version __FreeBSD_version +# endif + + /* Runtime detection of kernel */ +# include +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 /* ioctl */ +# include +# include /* CDIOCCLRDEBUG */ +# if defined(__FreeBSD_kernel__) +# include +# if __FreeBSD_kernel_version >= 500040 +# include +# endif +# endif /* __FreeBSD_kernel__ */ +#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ + +#ifdef HAVE_OPENDISK +# include +#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/cdp. + + 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/cdp. */ + { + 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/cdp. */ + { + 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 */ + { + 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__ */ +} + diff --git a/util/devicemap.c b/util/devicemap.c new file mode 100644 index 000000000..c61864420 --- /dev/null +++ b/util/devicemap.c @@ -0,0 +1,13 @@ +#include + +#include + +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); +} diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index fa8b158dc..4f544f878 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -30,385 +30,26 @@ #include #include +#include #define _GNU_SOURCE 1 #include -#ifdef __linux__ -# if !defined(__GLIBC__) || \ - ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) -/* Maybe libc doesn't have large file support. */ -# include /* _llseek */ -# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ -# include /* 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 -# ifndef __FreeBSD_kernel_version -# define __FreeBSD_kernel_version __FreeBSD_version -# endif - - /* Runtime detection of kernel */ -# include -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 /* ioctl */ -# include -# include /* CDIOCCLRDEBUG */ -# if defined(__FreeBSD_kernel__) -# include -# if __FreeBSD_kernel_version >= 500040 -# include -# endif -# endif /* __FreeBSD_kernel__ */ -#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ - -#ifdef HAVE_OPENDISK -# include -#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) -{ - 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; -} - static void make_device_map (const char *device_map, int floppy_disks) { - FILE *fp; int num_hd = 0; - int i; + int num_fd = 0; + FILE *fp; + + auto int process_device (const char *name, int is_floppy); + + 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; + } if (strcmp (device_map, "-") == 0) fp = stdout; @@ -418,215 +59,7 @@ make_device_map (const char *device_map, int floppy_disks) 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/cdp. - - 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/cdp. */ - { - 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/cdp. */ - { - 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 */ - { - 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); diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c new file mode 100644 index 000000000..8e6eb39c4 --- /dev/null +++ b/util/ieee1275/devicemap.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include + +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); +} diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c new file mode 100644 index 000000000..7b464bf09 --- /dev/null +++ b/util/ieee1275/ofpath.c @@ -0,0 +1,415 @@ +/* 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 . + */ + +#undef OFPATH_STANDALONE + +#ifndef OFPATH_STANDALONE +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/util/sparc64/ieee1275/grub-install.in b/util/sparc64/ieee1275/grub-install.in new file mode 100644 index 000000000..e2af5e8d9 --- /dev/null +++ b/util/sparc64/ieee1275/grub-install.in @@ -0,0 +1,276 @@ +#! /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 . + +# 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 +} + +# 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 diff --git a/util/sparc64/ieee1275/grub-mkimage.c b/util/sparc64/ieee1275/grub-mkimage.c new file mode 100644 index 000000000..247f13846 --- /dev/null +++ b/util/sparc64/ieee1275/grub-mkimage.c @@ -0,0 +1,294 @@ +/* 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 . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +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; +} diff --git a/util/sparc64/ieee1275/grub-ofpathname.c b/util/sparc64/ieee1275/grub-ofpathname.c new file mode 100644 index 000000000..092826c21 --- /dev/null +++ b/util/sparc64/ieee1275/grub-ofpathname.c @@ -0,0 +1,39 @@ +/* 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 . + */ + +#include +#include + +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; +} diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c new file mode 100644 index 000000000..6ca3a7aa1 --- /dev/null +++ b/util/sparc64/ieee1275/grub-setup.c @@ -0,0 +1,625 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +/* 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; +} diff --git a/util/sparc64/ieee1275/misc.c b/util/sparc64/ieee1275/misc.c new file mode 100644 index 000000000..99b95132e --- /dev/null +++ b/util/sparc64/ieee1275/misc.c @@ -0,0 +1,33 @@ +/* + * 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 . + */ + +#include + +#include + +void +grub_reboot (void) +{ + longjmp (main_env, 1); +} + +void +grub_halt (void) +{ + grub_reboot (); +}